2012-04-13 156 views
11

(在三维中)我正在寻找一种方法来计算两个向量之间的带符号夹角,除非是这些向量,否则不给出任何信息。如在this question中回答的那样,在给定矢量垂直的平面的法线的情况下计算符号角是足够简单的。但是如果没有这个价值,我无法找到办法。很显然,两个向量的叉积产生这样一个正常的,但我已经使用上面的答案碰上以下矛盾:没有参考平面的两个向量之间的符号夹角

signed_angle(x_dir, y_dir) == 90 
signed_angle(y_dir, x_dir) == 90 

在那里我希望第二个结果为阴性。这是由于这样的事实,叉积cross(x_dir, y_dir)是在cross(y_dir, x_dir)相反的方向,给出归一化输入下列伪代码:

signed_angle(Va, Vb) 
    magnitude = acos(dot(Va, Vb)) 
    axis = cross(Va, Vb) 
    dir = dot(Vb, cross(axis, Va)) 
    if dir < 0 then 
     magnitude = -magnitude 
    endif 
    return magnitude 

我不相信目录将永远是负面的上方。

我看到了与建议的atan2解决方案相同的问题。

我正在寻找一种方法,使:

signed_angle(a, b) == -signed_angle(b, a) 
+1

是不是这个:http://www.jtaylor1142001.net/calcjat/Solutions/VDotProduct/VDPTheta3D.htm你在找什么? – Jack 2012-04-13 01:05:03

+0

以上评论中的链接不起作用 – ephere 2013-08-16 13:11:40

回答

1

谢谢大家。在回顾这里的评论并回顾我想要做的事情之后,我意识到我可以完成我需要用给定的标准公式来完成我需要做的事情。我刚刚在单元测试中挂了我的签名角度函数。

作为参考,我将产生的角度反馈回旋转函数。我没有考虑到这样一个事实,即它自然会使用与signed_angle(输入向量的叉积)相同的轴,并且正确的旋转方向将遵循该轴面向哪个方向。

更简单地说,这两个应该只是“做正确的事”,并旋转不同的方向:

rotate(cross(Va, Vb), signed_angle(Va, Vb), point) 
rotate(cross(Vb, Va), signed_angle(Vb, Va), point) 

其中第一个参数是旋转和第二的轴线旋转量。

3
两个向量之间

符号的角度,而不参考平面

angle = acos(dotproduct(normalized(a), normalized(b))); 

signed_angle(A, b)== -signed_angle(b,a)

我认为没有某种参考矢量是不可能的。

+0

我在想更多,这是对的。角度的符号取决于您将哪个旋转轴用作参考。当然,还有两个不同的轴,一个在叉积的方向,另一个在相反的方向。 – 2012-04-13 23:50:44

+0

@JeffE:是的,虽然通过使用叉积可以找到“旋转”轴,但您无法确定它最初面向哪个方向 - 在“交叉b”或“b交叉a”交换向量中,你会得到轴朝相反的方向。因此,不可能确定旋转角度是否在0 ...π范围内,或者是否在pi..pi * 2范围内。 – SigTerm 2012-04-14 02:03:13

-2

如果你想要的是一个一致的结果,然后一个×b之间进行选择b×一个为您的正常会做的任意方式。也许选择字典上较小的那个?

(但你可能要解释你其实是想解决什么问题:也许有,不涉及计算任意3向量之间的一致的符号的角度解决方案)

18

相关的数学公式:

dot_product(a,b) == length(a) * length(b) * cos(angle) 
    length(cross_product(a,b)) == length(a) * length(b) * sin(angle) 

对于3-d向量之间的稳健角度,你的实际的计算应该是:

s = length(cross_product(a,b)) 
    c = dot_product(a,b) 
    angle = atan2(s, c) 

如果使用单独使用时,角度较小时会出现严重的精度问题。计算s并使用atan2()为您提供了一个强大的结果,适用于所有可能的情况。

由于s总是非负的,因此得到的角度范围从0到pi。总是会有一个等效的负角(angle - 2*pi),但没有几何理由更喜欢它。

+0

谢谢,我会继续关于acos。我想这是显而易见的,当你可视化的功能。 – metatheorem 2012-04-19 05:14:52

+0

警告:此功能是可交换的,不应该是:从+ x方向(1 0 0)到+ y方向(0 1 0)的角度应为+ 90°。反之亦然,从+ y到+ x应该是-90°。但是用这个函数,'f(x,y)== f(y,x)'。它不能说明区别,因为's'不是负面的,而且交叉产品是唯一可以告诉你关于两者之间的方向的东西。 – 2016-03-11 05:16:24

+0

如果它在2维中,它将是反交换的。然而,在三维中,它是(也应该是)可交换的 - 因为在三维中,需要第三个矢量来确定手性。如果没有第三个向量来区分前两个的正向和反向角度,则没有几何原因可以偏向于另一个方向。 – comingstorm 2016-03-11 05:29:30