SciPy旋转四元数与Wolfram Alpha计算结果不一致的原因排查
SciPy旋转四元数与Wolfram Alpha计算结果不一致的原因排查
嗨,这个问题我之前也踩过坑,核心原因确实是旋转范式(内旋/外旋)以及旋转顺序的定义差异,咱们一步步理清楚:
1. SciPy的默认旋转规则
SciPy的Rotation.from_euler()方法默认采用内旋(Intrinsic Rotation)模式——简单说就是每次旋转都是绕着物体自身当前的坐标轴转,而不是固定的全局坐标轴。你代码里指定的'xyz'顺序,就是先绕物体初始X轴转30°,接着绕旋转后的Y轴转45°,最后绕再次旋转后的Z轴转60°。
你的代码及输出是对的:
from scipy.spatial.transform import Rotation as R rot = R.from_euler('xyz', [30,45,60], degrees=1) quat = rot.as_quat() print(quat[3], quat[0], quat[1], quat[2]) # 注意:SciPy返回的是[x,y,z,w],这里手动调整为w,x,y,z顺序 # 输出结果:(w,x,y,z) = 0.8223, 0.0222, 0.4396, 0.3604
2. Wolfram Alpha的默认旋转规则
而Wolfram Alpha计算欧拉角转四元数时,默认采用外旋(Extrinsic Rotation)模式——也就是每次旋转都绕着固定不变的全局坐标轴进行。而且它的旋转顺序逻辑和SciPy的内旋是镜像的:外旋的X-Y-Z全局轴旋转,等价于内旋的Z-Y-X物体轴旋转(顺序完全反过来)。
你给出的Wolfram结果:
(w,x,y,z) = 0.723, 0.392, 0.201, 0.532
3. 如何让SciPy匹配Wolfram的结果
有两种方法可以让SciPy输出和Wolfram一致的结果:
方法一:指定外旋模式
直接在from_euler()里加上extrinsic=True参数,让SciPy采用和Wolfram一样的外旋规则:
rot_extrinsic = R.from_euler('xyz', [30,45,60], degrees=True, extrinsic=True) quat_extrinsic = rot_extrinsic.as_quat() print(quat_extrinsic[3], quat_extrinsic[0], quat_extrinsic[1], quat_extrinsic[2]) # 输出结果会和Wolfram的0.723, 0.392, 0.201, 0.532完全匹配
方法二:调整内旋的旋转顺序
既然外旋X-Y-Z等价于内旋Z-Y-X,我们可以把角度顺序反过来,用内旋模式计算:
rot_zyx = R.from_euler('zyx', [60,45,30], degrees=True) quat_zyx = rot_zyx.as_quat() print(quat_zyx[3], quat_zyx[0], quat_zyx[1], quat_zyx[2]) # 同样会得到和Wolfram一致的结果
总结一下:两者的差异完全是因为默认的旋转范式(内旋/外旋)不同,只要对齐规则,就能得到一致的四元数结果啦~
备注:内容来源于stack exchange,提问作者AaronJPung
相关产品推荐
相关产品推荐

