我需要计算3D对象面对任意3D点的2个角度(偏航角和俯仰角)。这些旋转被称为“欧拉(Euler)”旋转,是因为在第一次旋转之后(根据下面的图片,Z称为Z),Y轴也随对象一起旋转。
这是我正在使用的代码,但无法完全正常工作。在地平面(Y = 0)上,对象正确旋转以面向该点,但是当我在Y中向上移动该点时,旋转看起来不正确。
// x, y, z represent a fractional value between -[1] and [1]
// a "unit vector" of the point I need to rotate towards
yaw = Math.atan2( y, x )
pitch = Math.atan2( z, Math.sqrt( x * x + y * y ) )
您知道如何计算给定点的2个欧拉角吗?
下图显示了我的旋转方式。这些是我需要计算的角度。
(唯一的区别是我按X,Y,Z而不是Z,Y,X的顺序旋转对象)
这是我的系统。
坐标系是x =右侧,y =向下,z =靠后
默认情况下,对象在(0,0,1)处朝后
旋转顺序为X,Y,Z,其中X上的旋转为俯仰,Y偏航且Z为滚动
最佳答案
这是我的工作假设:
坐标系(x,y,z)使得正数x向右,正数y向下,而z为剩余方向。特别地,y = 0是接地平面。
当前面向(0,0,1)的(0,0,0)处的对象正转向面向(x,y,z)的位置。
为此,将绕x轴旋转,然后绕y轴旋转。最后,围绕z轴旋转以使物体垂直放置。
(术语“偏航”,“俯仰”和“横滚”可能会造成混淆,因此我想避免使用它,但粗略地说,对应关系是x = pitch,y = yaw,z = roll。)
鉴于此设置,这是我尝试解决的问题:
rotx = Math.atan2( y, z )
roty = Math.atan2( x * Math.cos(rotx), z )
rotz = Math.atan2( Math.cos(rotx), Math.sin(rotx) * Math.sin(roty) )
希望这是正确的迹象。我认为修复标志的最简单方法是反复试验。确实,您似乎已经正确理解了
rotx
和roty
上的符号-包括有关z的细微问题-因此您只需要在rotz
上固定符号。我希望这并非易事(可能取决于您所处的八位圆),但是在说错之前,请尝试一些可能性。祝好运!
这是最终对我有用的代码。
我注意到对象从任何前象限(正Z)移动到任何后象限时都会发生“翻转”效果。在前象限中,对象的前部将始终面向该点。在后象限中,对象的后部始终面向该点。
该代码纠正了翻转效果,因此对象的前部始终面向该点。我通过反复试验遇到了它,所以我真的不知道发生了什么!
rotx = Math.atan2( y, z );
if (z >= 0) {
roty = -Math.atan2( x * Math.cos(rotx), z );
}else{
roty = Math.atan2( x * Math.cos(rotx), -z );
}