如何使用javascript计算基于曲面角度的法线向量?

时间:2014-12-15 13:54:43

标签: javascript math vector

对于图片中显示的表面,我有这3个(a,b和c)角度,我需要找到这两个法向量的(x,y,z)。

其中一个载体铺设在表面上,另一个载体垂直于它。

向量指向原点(0,0,0)。

有人可以帮忙吗?

enter image description here

2 个答案:

答案 0 :(得分:2)

由于您只使用基本旋转,因此每个旋转都有简单的公式:

wikipedia's formulas for basic rotations

您想要操作的旋转是这些矩阵的乘法。顺序很重要,但是因为你从陀螺仪装置获得角度,我将假设一个传统的顺序:滚动(围绕x轴,a或这个帖子的符号中的伽玛),音高(绕y轴,b或β),最后偏航(围绕z轴,c或alpha)。

以下是适用于您的一般显式(并且非常难看)矩阵公式,显示必须执行三次旋转的顺序(来自http://planning.cs.uiuc.edu/node102.html)。

direct formulation of R

然后你将矢量乘以这个矩阵R(你的矢量作为右边的列矢量),你就完成了。

所以你的矩阵的javascript代码是:

var ca = Math.cos(a), sa = Math.sin(a);
var cb = Math.cos(b), sb = Math.sin(b);
var cc = Math.cos(c), sc = Math.sin(c);

var mat = [[cc*cb, cc*sb*sa-sc*ca, cc*sb*ca+sc*sa],
           [sc*cb, sc*sb*sa+cc*ca, sc*sb*ca-cc*sa],
           [-sb,   cb*sa,          cb*ca]];

// x is any vector you want to rotate
var x = [/* value on x axis */, /* value on y axis */, /* value on z axis */];

// this is the value of x once it is rotated
var rot_x = [mat[0][0]*x[0]+mat[0][1]*x[1]+mat[0][2]*x[2],
             mat[1][0]*x[0]+mat[1][1]*x[1]+mat[1][2]*x[2],
             mat[2][0]*x[0]+mat[2][1]*x[1]+mat[2][2]*x[2]];

从通用公式可以看出,如果旋转标准基础的矢量,则得到[1,0,0]的矩阵的第一列,[0,1,0]的第二列和[0,0,1]的第三列,更简单。然而,上述公式是通用的,并且始终有效。

答案 1 :(得分:1)

答案:

[x1] = [cos(b)cos(c)]
[y1] = [sin(c)cos(b)]
[z1] = [-sin(b)]


[x2] = [sin(b)cos(a)cos(c) + sin(a)sin(c)]
[y2] = [sin(b)sin(c)cos(a) - sin(a)cos(c)]
[z2] = [cos(a)cos(b)]

其中a =围绕x轴旋转,b =围绕y轴旋转,c =围绕z轴旋转。

额外信用答案:

如果(x3,y3,z3)是垂直于(x1,y1,z1)的平面上的另一个向量,那么它如下:

[x3] = [sin(a)sin(b)cos(c) - sin(c)cos(a)]
[y3] = [sin(a)sin(b)sin(c) + cos(a)cos(c)]
[z3] = [sin(a)cos(b)]

Explination:

(我在我的探索中使​​用英国对矩阵的定义,所以美国人记得你通常会把它做回到前面。它不影响结果,只影响探索。)

我假设你的飞机在桌子上开始平坦,它是x-y飞机。 z轴指向页面外。围绕x轴旋转一度,围绕y轴旋转b度,围绕z轴旋转c度。

因此,将(x1,y1,z1)向量视为向量(1,0,0)按顺序旋转a,b,c。类似地(x2,y2,z2)是按顺序旋转a,b,c的矢量(0,0,1)。 (如果你想在平面上垂直于(x1,y1,z1)的另一个矢量,只需在(0,1,0)上进行旋转。

以下是按顺序围绕x轴,y轴和z轴旋转的矩阵。其中c =角度的cos和角度的s = sin

[1 0 0]
[0 c -s]
[0 s c]

[c 0 s]
[0 1 0]
[-s 0 c]

[c -s 0]
[s c 0]
[0 0 1]

所以我们要做的就是一个接一个地应用它们(所以美国人以相反的顺序这样做)

Final matrix = [cos(c) -sin(c) 0] [cos(b)  0   sin(b)] [ 1      0       0   ]
               [sin(c) cos(c)  0] [   0    1     0   ] [ 0    cos(a) -sin(a)]
               [0       0      1] [-sin(b) 0   cos(b)] [ 0    sin(a)  cos(a)]

             = [cos(c) -sin(c) 0] [cos(b)   (sin(a)sin(b))   (sin(b)cos(a))] 
               [sin(c) cos(c)  0] [  0           cos(a)         -sin(a)    ]
               [0       0      1] [-sin(b)  (sin(a)cos(b))   (cos(a)cos(b))]

             = [cos(b)cos(c)       (sin(a)sin(b)cos(c) - sin(c)cos(a))     (sin(b)cos(a)cos(c) + sin(a)sin(c))]
               [(sin(c)cos(b))     (sin(a)sin(b)sin(c) + cos(a)cos(c))     (sin(b)sin(c)cos(a) - sin(a)cos(c))]
               [-sin(b)                   (sin(a)cos(b))              (cos(a)cos(b))]

那么你将这个matix乘以你的向量,得到上面的答案。