本文介绍了计算两个向量之间顺时针角度的直接方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想找出 2 个向量(2D、3D)之间的顺时针角度.

I want to find out the clockwise angle between 2 vectors(2D, 3D).

点积的经典方法给了我内角(0-180 度),我需要使用一些 if 语句来确定结果是我需要的角度还是它的补角.

The clasic way with the dot product gives me the inner angle(0-180 degrees) and I need to use some if statements to determine if the result is the angle I need or its complement.

你知道计算顺时针角度的直接方法吗?

Do you know a direct way of computing clockwise angle?

推荐答案

2D case

就像点积与角度的余弦成正比一样,行列式 与其正弦成正比.所以你可以像这样计算角度:

2D case

Just like the dot product is proportional to the cosine of the angle, the determinant is proprortional to its sine. So you can compute the angle like this:

dot = x1*x2 + y1*y2      # dot product between [x1, y1] and [x2, y2]
det = x1*y2 - y1*x2      # determinant
angle = atan2(det, dot)  # atan2(y, x) or atan2(sin, cos)

这个角度的方向与坐标系的方向一致.在左手坐标系中,即x指向右侧和 y 向下,这在计算机图形学中很常见,这意味着您会得到顺时针角度的正号.如果坐标系的方向是数学的,y 向上,你会得到逆时针角度,这是数学中的惯例.改变输入的顺序会改变符号,所以如果你对符号不满意,只需交换输入.

The orientation of this angle matches that of the coordinate system. In a left-handed coordinate system, i.e. x pointing right and y down as is common for computer graphics, this will mean you get a positive sign for clockwise angles. If the orientation of the coordinate system is mathematical with y up, you get counter-clockwise angles as is the convention in mathematics. Changing the order of the inputs will change the sign, so if you are unhappy with the signs just swap the inputs.

在 3D 中,两个任意放置的向量定义了它们自己的旋转轴,垂直于两者.该旋转轴没有固定方向,这意味着您也无法唯一确定旋转角度的方向.一个常见的约定是让角度始终为正,并以适合正角度的方式定位轴.在这种情况下,归一化向量的点积足以计算角度.

In 3D, two arbitrarily placed vectors define their own axis of rotation, perpendicular to both. That axis of rotation does not come with a fixed orientation, which means that you cannot uniquely fix the direction of the angle of rotation either. One common convention is to let angles be always positive, and to orient the axis in such a way that it fits a positive angle. In this case, the dot product of the normalized vectors is enough to compute angles.

dot = x1*x2 + y1*y2 + z1*z2    #between [x1, y1, z1] and [x2, y2, z2]
lenSq1 = x1*x1 + y1*y1 + z1*z1
lenSq2 = x2*x2 + y2*y2 + z2*z2
angle = acos(dot/sqrt(lenSq1 * lenSq2))

嵌入 3D 的平面

一种特殊情况是,您的向量不是随意放置的,而是位于具有已知法向量 n 的平面内.然后旋转轴也将在 n 方向上,并且 n 的方向将固定该轴的方向.在这种情况下,您可以调整上面的 2D 计算,包括 ndeterminant 使其大小为 3×3.

Plane embedded in 3D

One special case is the case where your vectors are not placed arbitrarily, but lie within a plane with a known normal vector n. Then the axis of rotation will be in direction n as well, and the orientation of n will fix an orientation for that axis. In this case, you can adapt the 2D computation above, including n into the determinant to make its size 3×3.

dot = x1*x2 + y1*y2 + z1*z2
det = x1*y2*zn + x2*yn*z1 + xn*y1*z2 - z1*y2*xn - z2*yn*x1 - zn*y1*x2
angle = atan2(det, dot)

此方法起作用的一个条件是法线向量 n 具有单位长度.如果没有,您必须对其进行标准化.

One condition for this to work is that the normal vector n has unit length. If not, you'll have to normalize it.

这个决定因素也可以表示为三重产品,如@Excrubulent 在建议的编辑中指出.

This determinant could also be expressed as the triple product, as @Excrubulent pointed out in a suggested edit.

det = n · (v1 × v2)

这在某些 API 中可能更容易实现,并且对这里发生的事情给出了不同的观点:叉积与角度的正弦成正比,并且垂直于平面,因此是 n.因此,点积基本上会测量该向量的长度,但会附加正确的符号.

This might be easier to implement in some APIs, and gives a different perspective on what's going on here: The cross product is proportional to the sine of the angle, and will lie perpendicular to the plane, hence be a multiple of n. The dot product will therefore basically measure the length of that vector, but with the correct sign attached to it.

这篇关于计算两个向量之间顺时针角度的直接方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-06 05:27