c++ - 从欧拉角到四元数和后退的 GLM 转换不成立

标签 c++ quaternions glm-math euler-angles openvr

我正在尝试转换已存储为 glm::vec3 的 OpenVR Controller 的方向欧拉角转换成 glm::fquat然后返回,但我得到了截然不同的结果,并且游戏中的行为是错误的(难以解释,但对象的方向在小角度范围内表现正常,然后在奇怪的轴上翻转)。

这是我的转换代码:

// get `orientation` from OpenVR controller sensor data

const glm::vec3 eulerAnglesInDegrees{orientation[PITCH], orientation[YAW], orientation[ROLL]};
debugPrint(eulerAnglesInDegrees);

const glm::fquat quaternion{glm::radians(eulerAnglesInDegrees)};
const glm::vec3 result{glm::degrees(glm::eulerAngles(quaternion))};
debugPrint(result);

// `result` should represent the same orientation as `eulerAnglesInDegrees`

我希望 eulerAnglesInDegreesresult是相同方向的相同或等效表示,但显然情况并非如此。这些是我打印出来的一些示例值:
39.3851 5.17816 3.29104 
39.3851 5.17816 3.29104 

32.7636 144.849 44.3845 
-147.236 35.1512 -135.616 

39.3851 5.17816 3.29104 
39.3851 5.17816 3.29104 

32.0103 137.415 45.1592 
-147.99 42.5846 -134.841 

正如您在上面看到的,对于某些方向范围,转换是正确的,但对于其他方向则完全不同。

我究竟做错了什么?

我查看了现有问题并尝试了一些方法,包括尝试 every possible rotation order listed here , conjugating the quaternion ,以及其他随机的东西,如翻转俯仰/偏航/滚动。没有什么给了我预期的结果。

如何使用 glm 将欧拉角转换为四元数并返回,代表原始方向?

更多的差异示例:
original:      4; 175;   26; 
computed:   -175;   4; -153; 
difference:  179; 171;  179; 

original:     -6; 173;   32; 
computed:    173;   6; -147; 
difference: -179; 167;  179; 

original:      9; 268;  -46; 
computed:   -170; -88;  133; 
difference:  179; 356; -179; 

original:    -27; -73;  266; 
computed:    -27; -73;  -93; 
difference:    0;   0;  359; 

original:    -33; 111;  205; 
computed:    146;  68;   25; 
difference: -179;  43;  180; 

我试图找到一种模式来修复最终 computed结果,但似乎并不容易识别。

行为的 GIF + 视频:

Video excerpt
  • Full video on YouTube


  • 我的直觉/当前理解的视觉表示:

    Visual diagram
  • 上图是一个球体,我在中心。当我将枪对准球体的绿色一半时,方向是正确的。当我将枪对准球体的红色部分时,这是不正确的 - 似乎每个轴都是倒置的,但我不能 100% 确定情况确实如此。
  • 最佳答案

    32.7636 144.849 44.3845
    -147.236 35.1512 -135.616

    那些是一样的。左 33 或右 147。你们相差 180。现在向上看 145 - 从地平线上过去 35,你的背部是拱形的。
    现在滚动让你回到天空。

    如果需要使用欧拉,尽量保持俯仰在-90到+90,滚转在-180到+180;

    if (pitch > 90) {
       pitch -= 90;
       yaw += 180;
       roll += 180;
    }
    if (roll > 180) {
       roll = 360 - roll;
    }
    

    或类似的东西。

    关于c++ - 从欧拉角到四元数和后退的 GLM 转换不成立,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60347256/

    相关文章:

    c++ - 如何在现代 Opengl 中添加 View 矩阵

    python - 如何在 Python 中修复 "No module named ' quaternion'"?

    octave - 查找 Octave 四元数的向量部分

    3d - 简单的3D投影和方向处理?

    c++ - 窗口坐标到摄像机角度?

    c++ - Open_gl 1 颜色着色器

    c++ - 在 A 类中创建一个类型为 B 类的 vector - 问题访问数据 [C++] [成员在两个类中都是私有(private)的]

    c++ - 通过读取文件检测 C++ 中的空行

    c++ - 如何在 C/C++ 中将 12 位图像转换为 8 位图像?

    c++ - 参数类型的编译时类型检测