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

标签 c++ matrix directx quaternions directxmath

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

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

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

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

XMQuaternionToAxisAngle(&Axis, &Angle, RotationQ);

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

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

PS2:好的,所以我点击了 Gene 的链接(我已经看过那里但当时没有找到我需要的东西)。我根据在维基百科中找到的这个等式编写了这段代码: equation

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

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

Quaternion to Euler formula

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

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

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

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

相关文章:

c++ - 我不明白为什么 map 会导致段错误

c++ - 如何在 C++ 中转发声明 typedef?

c++ - 当用户输入错误的数据类型时从单独的文件循环调用函数

python - 通过对像素求和来重新调整矩阵

c - C语言中双变量数据类型的算术位移位

c++ - 如何正确中断 QThread 无限循环

c# - 旋转多维数组的部分

c# - 如何使 DirectX 控件在 C# 窗体上部分透明

c++ - D3D11屏幕桌面复制到ID3D11Texture2D

c++ - 使用 IDirect3DTexture9::LockRect 时出现 ACCESS_VIOLATION 异常 (0xC0000005)