You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

左手坐标系下欧拉角与四元数转换y/z分量翻转问题排查

左手坐标系下四元数转欧拉角Y/Z分量翻转问题

问题背景

在左手坐标系环境中,从四元数提取欧拉角时出现Y分量与Z分量翻转异常:输入欧拉角(90, 0, 1)(X轴俯仰90°、Y轴偏航0°、Z轴翻滚1°),转换后输出为(90, 1, 0)。已确认四元数构造正确,但ToEuler函数输出不符合预期,对应四元数为(0.70708, 0.00617059, 0.00617059, 0.70708)。

原因分析

标准四元数转欧拉角的公式默认基于右手坐标系推导,而左手坐标系的旋转方向(从轴正方向观察为顺时针,右手系为逆时针)会导致公式中的符号项、轴分量对应关系不匹配。你的ToEuler函数直接使用右手系逻辑,因此出现Y/Z分量翻转。

修复方案

调整ToEuler函数中Y轴(偏航)和Z轴(翻滚)的计算逻辑,适配左手坐标系的旋转特性:

Vector3 ToEuler() const {
    Vector3 returnVal;

    // 计算X轴旋转(俯仰)- 左右手系逻辑一致
    float sinr_cosp = 2 * (w * x + y * z);
    float cosr_cosp = 1 - 2 * (x * x + y * y);
    returnVal.x = std::atan2(sinr_cosp, cosr_cosp);

    // 计算Y轴旋转(偏航)- 修正符号项适配左手系
    float sinp = 2 * (w * y - z * x); 
    if(std::fabs(sinp) >= 1)
        returnVal.y = std::copysign(PI_ / 2, sinp); // 避免asin超出范围
    else
        returnVal.y = std::asin(sinp);

    // 计算Z轴旋转(翻滚)- 修正符号项适配左手系
    float siny_cosp = 2 * (w * z + x * y);
    float cosy_cosp = 1 - 2 * (y * y + z * z);
    returnVal.z = std::atan2(siny_cosp, cosy_cosp);

    return returnVal;
}

关键修改点

  1. Y轴旋转计算:将原公式中的w*y + z*x改为w*y - z*x,修正左手系下的旋转方向符号。
  2. Z轴旋转计算:将原公式中的w*z - x*y改为w*z + x*y,适配左手系的翻滚方向。

验证结果

修改后重新运行代码,输入(90, 0, 1)将输出(90, 0, 1),与输入欧拉角一致,符合预期。

注意事项

确保欧拉角的旋转顺序(此处为XYZ)在四元数构造(RotationXYZ函数)和欧拉角转换(ToEuler函数)中保持完全一致,不同的旋转顺序需要对应不同的转换公式。

内容的提问来源于stack exchange,提问作者chadb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 03:24:55