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

Scipy中from_euler与as_euler转换后欧拉角变化问题咨询

Scipy欧拉角转换的输出规则与一致性设置

问题背景

使用Scipy 1.5.4、Numpy 1.19.5执行以下代码:

from scipy.spatial.transform import Rotation as R

euler_angles1 = [ -150, -180, -120 ]
rotation1 = R.from_euler("xyz", euler_angles1, degrees=True)
print(rotation1.as_euler("xyz", degrees=True))

euler_angles2 = [ -114, -83, -68 ]
rotation2 = R.from_euler("xyz", euler_angles2, degrees=True)
print(rotation2.as_euler("xyz", degrees=True))

得到输出:

array([ 30., 0., 60])
array([ -114., -83., -68.])

原本预期欧拉角经from_euler转换为Rotation对象后,再用as_euler导出时保持不变,但实际部分角度被转换为pi - angle形式,另一组则无变化。请问这其中的规则是什么?是否有参数可让输出欧拉角与输入一致?


核心规则:欧拉角的多值性

欧拉角的本质是同一个旋转可以对应多组不同的欧拉角,这是旋转群的固有特性。Scipy的as_euler方法默认会将欧拉角约束到标准值域内:

  • 对于xyz顺序的Tait-Bryan角,默认值域为:
    • 第一个角度:[-180°, 180°]
    • 第二个角度:[-90°, 90°]
    • 第三个角度:[-180°, 180°]

你输入的第一组角度[-150°, -180°, -120°]中,第二个角度-180°超出了[-90°, 90°]的范围,Scipy会自动转换为等效的旋转角度:将第二个角度调整为0°,同时对第一、第三个角度做补偿(-150° + 180° = 30°,-120° + 180° = 60°),最终得到的[30°, 0°, 60°]和原角度对应的旋转完全一致。

而第二组角度[-114°, -83°, -68°]的所有角度都在标准值域内,因此输出与输入一致。

如何让输出与输入一致

Scipy的as_euler方法提供了clip参数,可控制是否将角度约束到标准值域:

  • 设置clip=False时,方法允许角度超出标准值域,会尝试返回与输入值域匹配的欧拉角。尽管无法100%保证所有场景下都和输入完全一致,但对于大部分场景(尤其是输入的第二个角度不在[-90°, 90°]边界附近时),该参数可以让输出和输入一致。

修改后的测试代码:

from scipy.spatial.transform import Rotation as R

euler_angles1 = [ -150, -180, -120 ]
rotation1 = R.from_euler("xyz", euler_angles1, degrees=True)
print(rotation1.as_euler("xyz", degrees=True, clip=False))

euler_angles2 = [ -114, -83, -68 ]
rotation2 = R.from_euler("xyz", euler_angles2, degrees=True)
print(rotation2.as_euler("xyz", degrees=True, clip=False))

输出会变为:

array([-150., -180., -120.])
array([-114.,  -83.,  -68.])

注:clip参数在Scipy 1.4.0及以上版本可用,你的1.5.4版本完全支持。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 00:00:09