在同一平面内具有相同原点的两个 3D 矢量之间的符号角 [英] Signed angle between two 3D vectors with same origin within the same plane
问题描述
我需要的是位于同一 3D 平面内且具有相同原点的两个向量 Va 和 Vb 之间的有符号旋转角,知道:
What I need is a signed angle of rotation between two vectors Va and Vb lying within the same 3D plane and having the same origin knowing that:
- 包含两个向量的平面是任意的,并且不平行于 XY 或任何其他基平面
- Vn - 平面法线
- 两个向量和法线都具有相同的原点 O = { 0, 0, 0 }
- Va - 是在 Vn 处测量左手旋转的参考
角度应该以这样的方式测量,所以如果平面是 XY 平面,Va 将代表它的 X 轴单位向量.
The angle should be measured in such a way so if the plane would be XY plane the Va would stand for X axis unit vector of it.
我想我应该使用 Va 作为 X 轴,Vb 和 Vn 的叉积作为 Y 轴,然后只使用一些 2d 方法,如 atan2() 或其他东西,来执行一种坐标空间变换.有任何想法吗?公式?
I guess I should perform a kind of coordinate space transformation by using the Va as the X-axis and the cross product of Vb and Vn as the Y-axis and then just using some 2d method like with atan2() or something. Any ideas? Formulas?
推荐答案
这里好像没有我目前使用的解决方案.假设平面法线被归一化(|Vn| == 1
),有符号的角度很简单:
The solution I'm currently using seems to be missing here.
Assuming that the plane normal is normalized (|Vn| == 1
), the signed angle is simply:
对于从 Va 到 Vb 的右手旋转:
For the right-handed rotation from Va to Vb:
atan2((Va x Vb) . Vn, Va . Vb)
对于从 Va 到 Vb 的左旋:
For the left-handed rotation from Va to Vb:
atan2((Vb x Va) . Vn, Va . Vb)
返回 [-PI, +PI] 范围内的角度(或任何可用的 atan2 实现返回).
which returns an angle in the range [-PI, +PI] (or whatever the available atan2 implementation returns).
.
和 x
分别是点积和叉积.
.
and x
are the dot and cross product respectively.
无需显式分支,也无需计算除法/向量长度.
No explicit branching and no division/vector length calculation is necessary.
解释为什么这样做:让 alpha 是向量之间的直接角度(0° 到 180°),而 beta 是我们正在寻找的角度(0° 到 360°),beta == alpha
或 beta == 360° - alpha
Explanation for why this works: let alpha be the direct angle between the vectors (0° to 180°) and beta the angle we are looking for (0° to 360°) with beta == alpha
or beta == 360° - alpha
Va . Vb == |Va| * |Vb| * cos(alpha) (by definition)
== |Va| * |Vb| * cos(beta) (cos(alpha) == cos(-alpha) == cos(360° - alpha)
Va x Vb == |Va| * |Vb| * sin(alpha) * n1
(by definition; n1 is a unit vector perpendicular to Va and Vb with
orientation matching the right-hand rule)
Therefore (again assuming Vn is normalized):
n1 . Vn == 1 when beta < 180
n1 . Vn == -1 when beta > 180
==> (Va x Vb) . Vn == |Va| * |Vb| * sin(beta)
终于
tan(beta) = sin(beta) / cos(beta) == ((Va x Vb) . Vn) / (Va . Vb)
这篇关于在同一平面内具有相同原点的两个 3D 矢量之间的符号角的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!