Adv*_*mer 50 math 3d geometry vector
我需要的是位于同一3D平面内且具有相同原点的两个矢量Va和Vb之间的有符号旋转角度,知道:
应该以这样的方式测量角度,因此如果平面是XY平面,则Va将代表它的X轴单位矢量.
我想我应该通过使用Va作为X轴并将Vb和Vn的叉积作为Y轴来执行一种坐标空间变换,然后使用像atan2()或其他东西一样的2d方法.有任何想法吗?公式?
mse*_*ell 61
使用两个向量的叉积来得到由两个向量形成的平面的法线.然后检查它与原始平面法线之间的点积,看它们是否面向同一方向.
angle = acos(dotProduct(Va.normalize(), Vb.normalize()));
cross = crossProduct(Va, Vb);
if (dotProduct(Vn, cross) < 0) { // Or > 0
angle = -angle;
}
Run Code Online (Sandbox Code Playgroud)
Adr*_*ard 35
我目前使用的解决方案似乎在这里缺失.假设平面法线是标准化的(|Vn| == 1
),则有符号角度就是:
atan2((Vb x Va) . Vn, Va . Vb)
返回[-PI,+ PI]范围内的角度(或任何可用的atan2实现返回的角度).
.
并且x
分别是点和交叉产品.
没有明确的分支,也不需要除法/向量长度计算.使用Va x Vb
了右手旋转代替左手一个
解释为什么这样做:让alpha为矢量之间的直接角度(0°到180°)和beta我们正在寻找的角度(0°到360°)beta == alpha
或者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)
Run Code Online (Sandbox Code Playgroud)
最后
tan(beta) = sin(beta) / cos(beta) == ((Va x Vb) . Vn) / (Va . Vb)
Run Code Online (Sandbox Code Playgroud)
小智 13
您可以分两步完成此操作:
确定两个向量之间的角度
theta = acos(Va,Vb的点积).假设Va,Vb被归一化.这将给出两个矢量之间的最小角度
确定角度的符号
求向量V3 = Va,Vb的叉积.(顺序很重要)
如果(V3,Vn的点积)为负,则θ为负.否则,theta是积极的.
将一个向量与另一个向量交叉并标准化以获得单位向量。
两个向量之间角度的正弦等于叉积的大小除以两个向量的大小:
http://mathworld.wolfram.com/CrossProduct.html