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

Is there a way to convert a quaternion to angles?

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

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

XMMatrixDecompose(&Scale, &RotationQ, &Translation, Matrix);

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

XMQuaternionToAxisAngle(&Axis, &Angle, RotationQ);

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

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

PS2:好的,所以我按照 Gene 的 link 进行了操作(我已经看过那里,但当时没有找到我需要的东西)。我根据在维基百科中找到的这个等式编写了这段代码:

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));

在输出中我有不同的角度。 (90°, 0°, 90°) 的输出似乎等同于 (45°, 45°, 45°).

的输出

你有两个选择。

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

另一方面,如果您真的需要以欧拉角的形式获取它,则没有适合您的函数。虽然这些公式很容易获得。来自维基百科:

根据维基百科的定义,phi 是围绕全局 Z 轴的角度,theta 是围绕 "normal axis" N(穿过局部原点并与全局 Z 平面正交的轴)的角度轴和最终的局部 Z 轴——是的,这有点奇怪),而 psi 是围绕局部(即旋转的)Z 轴的角度。

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

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