2.2 空间变换的不同表示之间的互相转换与实战
在实际应用当中,不同空间变换的表示适用于不同的场景。比如欧拉角比较直观,容易理解,可视化或用户输出时可以用,但在实际计算时,四元数更有优势。其他参数化方法,往往用于不同的优化求解方案之中,因为在实际项目中,不同表示方式之间的变换也非常重要,本节主要介绍这些方式的原理以及对应的实现技术。
2.2.1 旋转矩阵与轴角
设旋转矩阵,轴角使用一个单位向量n和一个角度值θ来表示。仿射变换中如果已知轴角ω=θn,式中n=[nx,ny,nz]T。根据罗德里格斯公式[式(2-12)],则计算得到旋转矩阵:
如果已知旋转矩阵R,对式(2-12)两边取自身的迹,则有:
因此:
对于转轴n,在旋转后保持不变,因此:
因此,转轴n是矩阵R特征值1对应的特征向量,求解方程之后进行归一化得到旋转轴。
旋转矩阵与轴角定义及转换实战
源代码第2章文件夹下,如图2-5所示,在Visual Studio中配置eigen后可以直接在项目中编译执行。Eigen是一个高层次的C++库,有效支持线性代数、矩阵和矢量运算、数值分析及其相关的算法。由于Eigen是一个C++模板库,直接将库下载后放在项目目录下,然后在Visual Studio项目属性页的附加包的目录中添加eigen文件夹位置,在C++文件内直接包含头文件就能使用,非常方便。此外,Eigen的接口清晰且稳定高效。
图2-5 Visual Studio中的eigen配置
在程序源代码中首先定义轴角和旋转矩阵变量,在eigen中的旋转矩阵和轴角类型分别为:
其中alpha表示旋转角度所对应的弧度表示,Vector3d(x,y,z)为旋转轴对应的单位向量。
已知轴角,求旋转矩阵可以使用以下两种方式:
或
已知旋转矩阵,求轴角可以使用以下三种方式:
或
或
2.2.2 旋转矩阵与欧拉角
已知欧拉角,根据式(2-17)和式(2-18),ZYX顺序的内旋与XYZ顺序的外旋得到的旋转矩阵一致,因此R1=R2=Z(γ)Y(β)X(α),则:
如果已知旋转矩阵R,则以ZYX顺序的内旋计算出的欧拉角为:
旋转矩阵与欧拉角定义及转换实战
在eigen中欧拉角的表示比较简单,直接用一个三维向量表示,即:
已知旋转矩阵R,转换为欧拉角:
已知欧拉角,求旋转矩阵:
2.2.3 旋转矩阵与四元数
设四元数q=q0+q1i+q2j+q3k=[s,v]T,定义如下符号:
这两个符号运算将四元数映射成一个4×4的矩阵,因此四元数的乘法的矩阵形式为:
同理可得:
根据式(2-33)得:
带入两个符号矩阵,得:
因为p′和p都是虚四元数,则:
展开后得:
如果已知旋转矩阵R,则四元数计算:
式中,要满足q0≠0,1+r11+r22+r33>0,即1+tr(R)>0。
旋转矩阵与四元数定义及转换实战
在eigen中四元数数据类型为:
已知四元数转旋转矩阵:
或
已知旋转矩阵转四元数:
或
2.2.4 轴角与四元数
已知轴角,绕单位向量n=[nx,ny,nz]T旋转角度θ,则求得四元数:
如果已知四元数q=q0+q1i+q2j+q3k=[s,v]T,对式(2-46)两边同时求迹,得:
又根据式(2-37)得:
即:
所以:
对于旋转轴,虚部构成的向量在旋转时是不动的,只需要将其除以它的模,因此:
轴角与四元数定义及转换实战
已知轴角求四元数:
或
已知四元数求轴角:
或
2.2.5 轴角与欧拉角
轴角与欧拉角采用间接转换的方式,从轴角转到欧拉角需要先将轴角转换为旋转矩阵再转换为欧拉角,而从欧拉角转到轴角则需要先将欧拉角每个元素转换为单一的轴角再相乘之后转换为最终的轴角。
轴角与欧拉角定义及转换实战
已知轴角求欧拉角:
已知欧拉角求轴角:
2.2.6 欧拉角与四元数
将ZYX内旋方式旋转的欧拉角(或者说是绕固定轴X-Y-Z依次旋转α、β和γ)转换为四元数(四元数的变换叠加):
根据式(2-58)可以计算逆解,即q=q0+q1i+q2j+q3k=[s,v]T到欧拉角转换为:
由于arctan和arcsin的取值范围在,而绕某个轴旋转时最大为360°,因此使用atan2函数代替arctan函数:
欧拉角与四元数定义及转换实战
已知欧拉角求四元数:
已知四元数求欧拉角:
2.2.7 空间变换实战
欧式变换在eigen中对应:
设置旋转和平移,有左乘和右乘的区别:
如果对一个点做变换:
而仿射变换和射影变换在eigen中分别对应: