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
相关产品推荐
相关产品推荐

