旋转矩阵与欧拉角:三维空间旋转的数学表示
三维空间中的旋转,说白了就是描述一个物体怎么「转」起来。我在做惯性导航系统时,每天都要跟这些旋转表示法打交道。今天咱们就聊聊最常用的两种:旋转矩阵和欧拉角。
旋转矩阵的性质
旋转矩阵是个3x3的方阵,它描述了一个坐标系相对于另一个坐标系的姿态。你想想看,一个刚体在三维空间里转来转去,总得有个数学工具来精确描述吧?旋转矩阵就是干这个的。
旋转矩阵有几个关键性质,我建议你牢牢记住:
- 正交性:RTR = I,也就是说矩阵的逆等于它的转置
- 行列式为+1:det(R) = 1,这保证了旋转不会改变物体的手性
- 保持向量长度:||R·v|| = ||v||,旋转不改变向量的模长
重要提示:我在项目中遇到过有人把旋转矩阵和一般的线性变换矩阵搞混。记住,旋转矩阵必须是正交矩阵且行列式为+1。如果行列式是-1,那叫反射变换,不是旋转。
旋转矩阵还有一个很实用的性质——组合性。多个旋转可以连续相乘:R = R3·R2·R1。注意乘法的顺序,因为矩阵乘法不满足交换律。嗯,这里要注意:先转的矩阵在右边,后转的在左边。
欧拉角定义与万向锁问题
欧拉角用三个角度来描述旋转,直观又好理解。常见的定义方式有:
- ZYX顺序:先绕Z轴转偏航角(yaw),再绕Y轴转俯仰角(pitch),最后绕X轴转滚转角(roll)
- ZYZ顺序:先绕Z轴转,再绕Y轴转,最后再绕Z轴转
- XYZ顺序:依次绕X、Y、Z轴旋转
我个人习惯用ZYX顺序,因为它在航空领域用得最多,跟飞机的姿态控制直接对应。
万向锁问题:这是欧拉角最让人头疼的坑。当第二个旋转角达到±90°时,第一个和第三个旋转轴会重合,导致丢失一个自由度。我曾经在无人机飞控里遇到过这个问题——飞机做俯仰动作时突然失控,查了半天才发现是万向锁导致的。
为什么会这样?说白了就是欧拉角的奇异性。当pitch=90°时,yaw和roll的旋转轴都指向同一个方向,你没法区分到底是yaw在转还是roll在转。这在实际应用中非常危险。
旋转矩阵与欧拉角互转
实际工程中,我们经常需要在旋转矩阵和欧拉角之间来回转换。下面给出ZYX顺序的转换公式:
从欧拉角到旋转矩阵:
R = Rz(yaw) * Ry(pitch) * Rx(roll)
其中:
Rz(yaw) = [[cos(yaw), -sin(yaw), 0],
[sin(yaw), cos(yaw), 0],
[0, 0, 1]]
Ry(pitch) = [[cos(pitch), 0, sin(pitch)],
[0, 1, 0],
[-sin(pitch), 0, cos(pitch)]]
Rx(roll) = [[1, 0, 0],
[0, cos(roll), -sin(roll)],
[0, sin(roll), cos(roll)]]
从旋转矩阵到欧拉角:
给定旋转矩阵 R = [[r11, r12, r13],
[r21, r22, r23],
[r31, r32, r33]]
pitch = asin(-r31)
yaw = atan2(r21, r11)
roll = atan2(r32, r33)
注意:当 pitch = ±90° 时,会出现万向锁
此时 yaw 和 roll 无法唯一确定
避坑指南:我曾经在写代码时直接用asin和atan2做转换,结果在万向锁附近数值不稳定。后来我加了个判断:当|r31|接近1时,改用四元数做中间过渡。这个技巧在工程中非常实用。
下面我用SVG画了一张图,帮你理清旋转矩阵和欧拉角的关系:
在实际工程中,我建议你这样选择:
| 应用场景 | 推荐表示法 | 原因 |
|---|---|---|
| 连续旋转/插值 | 旋转矩阵或四元数 | 避免万向锁,数值稳定 |
| 人机交互 | 欧拉角 | 直观,容易理解 |
| 姿态控制 | 欧拉角+防万向锁处理 | 物理意义明确 |
| SLAM/导航 | 旋转矩阵 | 便于组合和优化 |
核心总结:旋转矩阵和欧拉角各有优劣。旋转矩阵没有奇异性,但参数多、不够直观;欧拉角直观易懂,但万向锁是个大坑。我个人在工程中通常用旋转矩阵做内部计算,用欧拉角做用户界面展示。记住一点:没有完美的表示法,只有最适合你场景的选择。
可可精品资料库