我有一个方向向量,将其应用于位置可以得到摄像机应该看的点。如何从中获取偏航、俯仰和翻滚角度以便正确使用glRotatef函数?
提前致谢。
这些等式都不是“错误”的,但都有些笨拙。 Ryder052,你的示例没有考虑到一些情况,正如你所评论的那样。为什么不使用atan2呢?
给定单位(归一化)方向向量d
pitch = asin(-d.Y);
yaw = atan2(d.X, d.Z)
从方向向量无法获取偏航角、俯仰角和翻滚角,因为方向向量只会指示要看哪个方向(偏航角和俯仰角)。
要获得偏航角和俯仰角,您需要使用三角学 - 我假设您具有一些工作知识。请查看此维基页面以获取一些有用的图表来可视化这些角度。
令Y = 偏航角,P = 俯仰角。
首先要获取偏航角:
tan(Y) = x/(-y)
现在要获得音高:
tan(P) = sqrt(x^2 + y^2)/z
为了获得Y和P的实际值,您需要使用反正切函数,我已经使用正切函数编写了它,以使推导更清晰。
请注意,负号取决于如何定义角度和轴线,但您应该能够理解。
然后,您可以将滚转设置为0或任何您喜欢的值。
tan(P)
= distance-in-ground-plane / distance-along-up-axis
. 如图所示,z
是沿着垂直轴的距离,sqrt(..)
是平面上二维向量(x,y)的距离。还要注意,在实际应用中,使用 P = arctan(whatever)
不会给出正确的一半角度的符号(必须单独计算符号,未显示);在实践中,使用 atan2
。我认为这里应该是 P = atan2(z, distance-in-ground-plane)
。如果我错了,请交换参数。 - ToolmakerSteve您可能并不需要偏航、俯仰和翻滚。您只需要正确的变换即可。尝试使用gluLookAt
来构建它。文档。
pheelicks的方程式是错误的。亲爱的未来谷歌搜索者,这里有一个正确的方程式:
假设俯仰:绕X轴旋转,偏航:绕Y轴旋转,横滚:绕Z轴旋转。方向向量V(x,y,z)
pitch = asin(V.y / length(V));
yaw = asin( V.x / (cos(pitch)*length(V)) ); //Beware cos(pitch)==0, catch this exception!
roll = 0;
嗯,我不确定这些答案在说什么,因为我无法让它们中的任何一个起作用。
我创建了自己的解决方案...
// get world target offset
// convert world target offset to world direction normal
// get my world transposed (inverted)
// rotate world direction normal to my space normal
Vector3D lWorldTargetOffset = gWorldTargetLocation - gWorldMyLocation;
Vector3D lWorldTargetDirection = lWorldTargetOffset.Normalize();
MatrixD lMyWorldTransposed = MatrixD.Transpose(MyWorldMatrix);
Vector3D lMySpaceTargetDirection = Vector3D.Rotate(lWorldTargetDirection, lMyWorldTransposed);
你现在在我的空间中有世界目标方向的法线
lMySpaceTargetDirection.X = pitch
lMySpaceTargetDirection.Y = yaw.
lMySpaceTargetDirection.Z = <0 infront >0 behind.
根据方向法线,所有值都在-1到1之间,因此如果您想要度数,只需* 90。
并不是说这是最好的解决方案,但这是我在花费数小时搜索和浏览大量晦涩难懂的内容后能够得到的唯一解决方案。
我希望您、某人或任何人都能够享受简单地旋转目标方向法线,使其相对于我的空间,并发现它易于使用且有用 :)