如何从 glm::quat 和 glm::mat4 中提取偏航俯仰滚动
Posted
技术标签:
【中文标题】如何从 glm::quat 和 glm::mat4 中提取偏航俯仰滚动【英文标题】:How to extract yaw pitch roll from glm::quat and glm::mat4 【发布时间】:2020-02-21 20:05:31 【问题描述】:是否可以从glm::mat4
中提取yaw、pitch 和roll 信息?
(这是一个已经应用了平移、旋转和缩放的世界变换矩阵)
这是我正在试验的一些代码:
float yawDeg = 0;
float pitchDeg = 20;
float rollDeg = 80;
glm::mat4 transform = glm::eulerAngleYXZ(glm::radians(yawDeg), glm::radians(pitchDeg), glm::radians(rollDeg));
glm::quat rotation(transform); // Is this a correct way?
// glm::quat rotation(glm::quat_cast(transform)); // Gives the same results.
printf("pitch: %f\n", glm::degrees(glm::pitch(rotation))); // Output: 3.616443
printf("yaw: %f\n", glm::degrees(glm::yaw(rotation))); // Output: -19.683496
printf("roll: %f\n", glm::degrees(glm::roll(rotation))); // Output: 79.372414
但是我得到了一些奇怪的结果,这里有一些值:
yawDeg=92, pitchDeg=0, rollDeg=0
结果yaw: 88.0, pitch: 180.0, roll: 180.0
yawDeg=0, pitchDeg=92, rollDeg=0
结果yaw: 0.0, pitch: 92.0, roll: 0.0
- 看起来不错。
yawDeg=0, pitchDeg=0, rollDeg=92
结果yaw: 0.0, pitch: 0.0, roll: 92.0
- 看起来不错。
yawDeg=0, pitchDeg=10, rollDeg=92
结果yaw: -9.993845, pitch: -0.352578, roll: 92.030830
我想我的glm::mat4
到glm::quat
的转换可能不正确?
【问题讨论】:
【参考方案1】:我想补充一件事。 GLM的偏航度实际上在-90°~90°之间。这是因为GLM从反正弦得到偏航角,-90°~90°是你可以从中得到的通常主值的范围。
这里可以看到GLM的github上的sn-p代码, https://github.com/g-truc/glm/blob/master/glm/gtc/quaternion.inl#L41
【讨论】:
【参考方案2】:我得到这些意想不到的值的原因是因为在某些角度 GLM 在内部应用它自己的角度。即:
输入 yawDeg=60, pitchDeg=0, rollDeg=0
我们会得到yaw: 60.0, pitch: 0.0, roll: 0.0
- 如预期的那样。
对于:
输入 yawDeg=92, pitchDeg=0, rollDeg=0
我们会得到yaw: 88.0, pitch: 180.0, roll: 180.0
- 修改!
如果您在应用了这些变换的情况下直观地查看 3D 对象 - 即使 GLM 已在内部修改了值,所有旋转看起来都应该没问题。
我注意到的另一件事是 GLM 返回的欧拉角始终在 -180 的范围内,所有轴均为 180 度。
关于glm::mat4
到glm::quat
的转换。我正在做每件事~好的。这里需要注意的重要一点是,如果您在变换矩阵中使用缩放,则需要对四元数进行归一化!
glm::quat rotation = glm::normalize(glm::quat_cast(matrix));
我发现的另一件事是 GLM 有一个名为 glm::extractEulerAngleXYZ
的函数。因此,如果您只想从变换矩阵中提取欧拉角,则实际上不需要对四元数进行任何转换。
我仍然不完全满意,因为我没有找到任何方法将 GLM 的欧拉角值转换回用户提供的原始值。
【讨论】:
以上是关于如何从 glm::quat 和 glm::mat4 中提取偏航俯仰滚动的主要内容,如果未能解决你的问题,请参考以下文章