2. 旋转矩阵与欧拉角

三维空间中的旋转,说白了就是描述一个物体怎么「转」起来。我在做惯性导航系统时,每天都要跟这些旋转表示法打交道。今天咱们就聊聊最常用的两种:旋转矩阵和欧拉角。

旋转矩阵的性质

旋转矩阵是个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画了一张图,帮你理清旋转矩阵和欧拉角的关系:

旋转表示法知识体系 旋转矩阵 R 3x3正交矩阵 det(R)=1, RᵀR=I 可组合、无奇异性 欧拉角 (yaw, pitch, roll) 直观易理解 存在万向锁问题 顺序敏感 互转 atan2/asin 旋转矩阵适用场景 • 连续旋转组合 • 计算机图形学 • 机器人运动学 欧拉角适用场景 • 飞行器姿态控制 • 人机交互界面 • 动画关键帧 选择哪种表示法?看你的应用场景和对奇异性的容忍度

在实际工程中,我建议你这样选择:

应用场景 推荐表示法 原因
连续旋转/插值 旋转矩阵或四元数 避免万向锁,数值稳定
人机交互 欧拉角 直观,容易理解
姿态控制 欧拉角+防万向锁处理 物理意义明确
SLAM/导航 旋转矩阵 便于组合和优化

核心总结:旋转矩阵和欧拉角各有优劣。旋转矩阵没有奇异性,但参数多、不够直观;欧拉角直观易懂,但万向锁是个大坑。我个人在工程中通常用旋转矩阵做内部计算,用欧拉角做用户界面展示。记住一点:没有完美的表示法,只有最适合你场景的选择。

可可精品资料库