Math 如何获得;逆时针;两个二维向量之间的角度?

Math 如何获得;逆时针;两个二维向量之间的角度?,math,Math,我有两个向量,我想得到这些向量之间的角度,我现在用这个公式: acos(dot(v1.unitVector, v2.unitVector)) 以下是我从中得到的: 我想要绿色的角度,而不是红色的角度,但我不知道我应该用什么公式 多谢各位 编辑:所以,当向量仍然处于某个位置时(就像前两对向量一样,没问题,但是当它处于第三对向量的配置中时,它就不再给我直角了)对于点积,始终会得到一个角度,该角度与向量的顺序无关,并且是两种可能性中较小的一种 对于您想要的,您需要复数的参数函数,该函数由atan2

我有两个向量,我想得到这些向量之间的角度,我现在用这个公式:

acos(dot(v1.unitVector, v2.unitVector))
以下是我从中得到的:

我想要绿色的角度,而不是红色的角度,但我不知道我应该用什么公式

多谢各位


编辑:所以,当向量仍然处于某个位置时(就像前两对向量一样,没问题,但是当它处于第三对向量的配置中时,它就不再给我直角了)

对于点积,始终会得到一个角度,该角度与向量的顺序无关,并且是两种可能性中较小的一种

对于您想要的,您需要复数的参数函数,该函数由
atan2
函数实现。从
a=ax+i*ay
b=bx+i*by
的角度是
a
乘以
b
的共轭变量(按
a
的角度向后旋转
b
,不考虑比例),坐标为

(ax-i*ay) * (bx+i*by) = ax*bx+ay*by + i*(ax*by-ay*bx)
所以角度是

atan2( ax*by-ay*bx, ax*bx+ay*by ).

除了公认的答案外,
atan2
的问题在于,如果你想象向量
a
是静态的,向量
b
逆时针旋转,你会看到返回值从0到π,但随后它突然变为负值,从-π到0,如果你对一个从0到2π的角度感兴趣,这就不太好了

为了解决这个问题,下面的函数方便地映射来自
atan2
的结果,并返回一个0到2π之间的值,正如人们所期望的那样:

const TAU=Math.PI*2;
/**
*以弧度表示逆时针方向从矢量a到矢量b的角度,
*从0到2π。
* 
*@param{Vector}a
*@param{Vector}b
*@返回{Number}
*/
静态角度(a,b){
设角度=Math.atan2(a.x*b.y-a.y*b.x,a.x*b.x+a.y*b.y);
如果(角度<0){
角度+=τ;
}
返回角;
}

它是用JavaScript编写的,但很容易移植到其他语言。

Lutz已经正确地回答了这个问题,但让我补充一点,我强烈建议将现代向量数学代码建立在几何代数的基础上,这大大提高了抽象级别

使用GA,您可以简单地将两个矢量U和V相乘,得到一个转子。转子内部看起来像+Bxy,其中A=U点V=|U | V | cos(角度)和Bxy=U楔V=|U | V | sin(角度)xy(与复数同构)。然后,您可以返回转子的签名CCW角度,即atan2(B,A)


因此,使用运算符重载,只需键入(u*v).Angle。最终的计算结果是一样的,但您思考和工作的抽象级别要高得多。

也许这一个更合适:

atan2( ax*by-ay*bx, ax*bx+ay*by ) % (PI*2)

可以获得完整逆时针弧度的计算。

这可能取决于您使用的语言/平台。“红色”答案是否定的吗?如果是这样的话,你可以做
(360+角度)MOD 360
(或者如果你的答案是弧度的话是2*PI)@DStanley红色角度是我不想要的,我想要的是总是通过逆时针旋转来获得角度,我知道,但是如果红色角度是负的,那么
绿色角度=360+红色角度=(360+红色角度)MOD 360
。如果你的答案是肯定的(比如紫色角度),那么
(360+紫色角度)MOD 360
仍然会给你紫色角度。所以它适用于所有情况(正面或负面)@DStanley不幸的是,我也不适用!这个问题在math.stackexchange.com更合适。非常感谢!这只适用于2D。。。在3D中,您必须投影到公共平面或使用
acos+点积
然后构造旋转向量进行CW/CCW检查,并根据需要更正结果角度。%值为负值时(欧几里德模)不起作用,您必须执行:((角度%tau)+tau)%tau,其中tau为2*pi