有没有办法将四元数转换为角度?

时间:2015-05-30 00:07:27

标签: c++ matrix directx quaternions directxmath

我有一个(世界)矩阵,它将平移,旋转和缩放应用到3D对象中。它是使用函数RotationQuaternion(DirectXMath)创建的,参数XMQuaternionRotationRollPitchYaw是通过调用XMMatrixDecompose(&Scale, &RotationQ, &Translation, Matrix); 创建的。然后将其与其他数据一起存储在文件中。

然后我需要恢复这些值,所以我可以使用这个函数将它分解为每个组件:

XMQuaternionToAxisAngle(&Axis, &Angle, RotationQ);

缩放和平移是向量,旋转是四元数。如果矩阵在单个轴上旋转对象,我可以使用它将四元数转换回角度:

float Roll = atan2(2.0*(F.x*F.y + F.z*F.w), 1 - 2 * (F.y*F.y + F.z*F.z));
float Pitch = asin(2.0*(F.x*F.z - F.w*F.y));
float Yaw = atan2(2.0*(F.x*F.w + F.y*F.z), 1 - 2 * (F.y*F.y + F.z*F.z));

工作正常。但是当它在两个或更多轴上旋转时,我该怎么做呢?有没有办法做到这一点?

PS:我不在乎输出角度是否与输入相同。他们只需要等同。

PS2:好的,所以我跟着Gene的链接(我已经看过那里了,但那段时间没找到我需要的东西)。我根据维基百科中的公式制作了这段代码: equation

(90°, 0°, 90°)

在输出中我有不同的角度。输出似乎与(45°, 45°, 45°)相同,但不适用于SELECT A, B FROM TUser UNION IF EXISTS(SELECT dataUserId FROM TUserData WHERE DataId = @dataId AND UserId = @userId) BEGIN SELECT @dataUserId = dataUserId FROM TUserData WHERE DataId = @dataId AND UserId = @userId SELECT A, B FROM TUser WHERE UserId =()

1 个答案:

答案 0 :(得分:1)

您有两种选择。

您仍然可以使用XMQuaternionToAxisAngle()函数,它将使用基数轴以外的轴。任何旋转都可以表示为围绕给定轴旋转的单个角度。

另一方面,如果你真的需要将它作为欧拉角,那么为你做这个没有好的功能。这些公式很容易获得。来自维基百科:

Quaternion to Euler formula

根据维基百科的定义,phi是围绕全局Z轴的角度,θ是围绕“法线轴”N的角度(通过局部原点并且与全局Z轴的平面正交的轴和最终局部Z轴 - 是的,它有点奇怪),psi是局部(即旋转)Z轴周围的角度。

如果我是一位更好的数学家,我可以帮助你将其转化为全局空间X,Y,Z旋转,但不幸的是,这超出了我的能力范围。

只要知道四元数和欧拉角之间没有严格的1-1相关性;例如,万向节锁意味着存在共享相同欧拉角的某些角度。真的要考虑你是否真的需要欧拉角 - 大多数情况下,轴角旋转可以以相同的方式工作,而没有欧拉角的重大问题。