如何从 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 中提取yawpitchroll 信息? (这是一个已经应用了平移、旋转和缩放的世界变换矩阵

这是我正在试验的一些代码:

    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::mat4glm::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::mat4glm::quat 的转换。我正在做每件事~好的。这里需要注意的重要一点是,如果您在变换矩阵中使用缩放,则需要对四元数进行归一化!

glm::quat rotation = glm::normalize(glm::quat_cast(matrix));

我发现的另一件事是 GLM 有一个名为 glm::extractEulerAngleXYZ 的函数。因此,如果您只想从变换矩阵中提取欧拉角,则实际上不需要对四元数进行任何转换。

我仍然不完全满意,因为我没有找到任何方法将 GLM 的欧拉角值转换回用户提供的原始值。

【讨论】:

以上是关于如何从 glm::quat 和 glm::mat4 中提取偏航俯仰滚动的主要内容,如果未能解决你的问题,请参考以下文章

将 glm.mat4 从 Python 传回 C++ (glm::mat4)

glm::mat4 构造函数如何工作?

如何使用 glm::mat4 手动正确编写旋转矩阵?

如何在 glRotatef 中使用 glm::mat4

如何在glRotatef中使用glm :: mat4

glm - 将 mat4 分解为平移和旋转?