QQuaternion旋转原理及Qt与其他库欧拉角转四元数差异咨询
Qt与第三方库四元数转欧拉角的差异解析
核心差异根源
两个实现的差异本质是欧拉角旋转顺序、坐标系约定、参数映射逻辑这三点的不一致,下面逐一拆解:
1. 参数映射与旋转顺序
Qt实现细节
Qt的QQuaternion::fromEulerAngles(pitch, yaw, roll):
- 参数定义:
pitch(绕X轴旋转)、yaw(绕Y轴旋转)、roll(绕Z轴旋转) - 旋转顺序:采用**Yaw(Y) → Roll(Z) → Pitch(X)**的内旋顺序(自身坐标系下依次旋转),对应四元数乘法的右乘逻辑,符合常规欧拉角矩阵乘法的左乘规则。
- 核心计算逻辑:
// 变量对应:yaw→c1/s1,roll→c2/s2,pitch→c3/s3 w = cos(yaw/2)*cos(roll/2)*cos(pitch/2) + sin(yaw/2)*sin(roll/2)*sin(pitch/2) x = cos(yaw/2)*cos(roll/2)*sin(pitch/2) + sin(yaw/2)*sin(roll/2)*cos(pitch/2) y = sin(yaw/2)*cos(roll/2)*cos(pitch/2) - cos(yaw/2)*sin(roll/2)*sin(pitch/2) z = cos(yaw/2)*sin(roll/2)*cos(pitch/2) - sin(yaw/2)*cos(roll/2)*sin(pitch/2)
第三方库实现细节
第三方库的Quaternion_fromEulerZYX(eulerZYX, output):
- 函数名明确标注是Z-Y-X顺序的欧拉角转换,输入数组
eulerZYX对应:[0]=绕X轴Roll、[1]=绕Y轴Pitch、[2]=绕Z轴Yaw - 旋转顺序:采用**Z(Yaw) → Y(Pitch) → X(Roll)**的外旋顺序(固定坐标系下依次旋转),对应四元数乘法的左乘逻辑。
- 核心计算逻辑:
// 变量对应:yaw→cy/sy,roll→cr/sr,pitch→cp/sp w = cos(yaw/2)*cos(roll/2)*cos(pitch/2) + sin(yaw/2)*sin(roll/2)*sin(pitch/2) x = cos(yaw/2)*sin(roll/2)*cos(pitch/2) - sin(yaw/2)*cos(roll/2)*sin(pitch/2) y = cos(yaw/2)*cos(roll/2)*sin(pitch/2) + sin(yaw/2)*sin(roll/2)*cos(pitch/2) z = sin(yaw/2)*cos(roll/2)*cos(pitch/2) - cos(yaw/2)*sin(roll/2)*sin(pitch/2)
2. 旋转方向与坐标系约定
Qt默认遵循右手坐标系+右手定则(逆时针旋转为正方向),而第三方库的实现可能存在两种差异:
- 采用左手坐标系,旋转方向为顺时针为正,这会直接导致四元数虚部(x/y/z)的符号反转;
- 四元数应用方式不同:Qt使用
q * v * q^{-1}(右乘方式)实现向量旋转,部分库可能使用q^{-1} * v * q(左乘方式),同样会导致旋转方向反转。
3. 错误结果的原因
你遇到的错误本质是参数传递或旋转逻辑的约定不匹配:
- 参数顺序错误:如果直接将Qt的
(pitch,yaw,roll)传入第三方库的eulerZYX数组,会完全违背它的Z-Y-X输入顺序要求; - 坐标系/旋转方向不兼容:第三方库的坐标系或旋转方向约定与Qt相反,导致旋转结果反向;
- 四元数应用逻辑冲突:如果第三方库的旋转应用方式和Qt相反,即使四元数生成正确,最终向量旋转结果也会出错。
解决思路
- 查阅第三方库文档:明确它的欧拉角旋转顺序(外旋/内旋)、坐标系类型、旋转方向约定;
- 调整参数顺序:比如第三方库是Z-Y-X外旋,需要将Qt的
(roll,pitch,yaw)映射为第三方的eulerZYX数组; - 修正分量符号:如果是坐标系或旋转方向的问题,可以取四元数的共轭(反转x/y/z分量)后再应用旋转;
- 验证旋转逻辑:用已知的欧拉角(比如绕X轴转90度)生成四元数,对比两个库的旋转结果,确认差异点。
内容的提问来源于stack exchange,提问作者Василий Марков
相关产品推荐
相关产品推荐

