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

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

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


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

XMQuaternionToAxisAngle(&Axis, &Angle, RotationQ);


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

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

PS2:好的,所以我遵循了Gene的链接(我已经看过那里了,但是没有找到我当时需要的东西)。我根据在维基百科中找到的方程式编写了此代码:


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()函数,它将使用除基本轴以外的其他轴。任何旋转都可以表示为围绕给定轴旋转的单个角度。

另一方面,如果您确实需要将其作为欧拉角,则没有很好的功能为您完成此操作。这些公式很容易获得。从维基百科:



根据Wikipedia的定义,phi是围绕全局Z轴的角度,theta是围绕“法线轴” N(穿过局部原点并与全局Z轴和最终局部Z的平面正交的轴)的角度。轴-是的,这有点奇怪),而psi是围绕本地(即旋转的)Z轴的角度。

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

只知道四元数和欧拉角之间没有严格的1-1相关;万向锁定意味着例如某些角度共享相同的欧拉角。真正考虑您是否真的需要欧拉角-大多数时候,轴角旋转将以相同的方式工作,而不会遇到欧拉角的重大问题。

关于c++ - 有没有办法将四元数转换为角度?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30540819/

10-11 23:07
查看更多