3、二维旋转矩阵:推导与几何意义,从平面几何到代数表达
各位同学,今天我们来聊聊二维旋转矩阵。说实话,这东西在气动坐标系里太常用了。我当年刚入行时,总觉得旋转矩阵就是个数学公式,背下来就行。直到有一次做风洞数据处理,发现姿态角算出来总对不上,折腾了两天才意识到是旋转方向搞反了。嗯,从那以后,我对旋转矩阵的几何意义再也不敢马虎了。
3.1 从平面几何说起
想象一下,你手里有一张坐标纸,上面画着一个点 P。现在你把这张纸逆时针转一个角度 θ,点 P 的位置就变了。你想想看,这个新位置和原来的位置有什么关系?
这就是二维旋转的核心问题。说白了,就是给定一个点原来的坐标 (x, y),以及旋转角度 θ,求它旋转后的新坐标 (x', y')。
我们先从平面几何的角度来推导。假设点 P 到原点的距离是 r,它和 x 轴的夹角是 α。那么:
x = r · cos(α)
y = r · sin(α)
现在把这个点逆时针旋转 θ 角,新位置和 x 轴的夹角就变成了 α + θ。所以:
x' = r · cos(α + θ)
y' = r · sin(α + θ)
这里要用到三角函数的和角公式:
cos(α + θ) = cos(α)·cos(θ) - sin(α)·sin(θ)
sin(α + θ) = sin(α)·cos(θ) + cos(α)·sin(θ)
把 x 和 y 代进去,就得到了:
x' = x·cos(θ) - y·sin(θ)
y' = x·sin(θ) + y·cos(θ)
你看,这个推导过程其实很简单。但我个人习惯,每次推导完都会随手画个草图验证一下。比如取 θ = 90°,点 (1, 0) 旋转后应该变成 (0, 1),代入公式确实成立。
3.2 从几何到矩阵表达
上面那组公式,写成矩阵形式就是:
[x'] [cos(θ) -sin(θ)] [x]
[y'] = [sin(θ) cos(θ)] [y]
中间这个 2×2 的矩阵,就是二维旋转矩阵 R(θ):
R(θ) = [cos(θ) -sin(θ)]
[sin(θ) cos(θ)]
为什么要用矩阵?我刚开始学的时候也觉得多此一举。但后来做实际项目才发现,矩阵表达有两大好处:
- 简洁:一次旋转就是一个矩阵乘法,写起来方便
- 可组合:多次旋转就是矩阵相乘,计算效率高
举个例子,你要先转 30° 再转 45°,直接算两个矩阵的乘积就行:
R(75°) = R(45°) · R(30°)
注意顺序!矩阵乘法不满足交换律,先转 30° 再转 45° 和先转 45° 再转 30°,结果是一样的(因为都是绕同一个点旋转),但如果是三维空间里的不同轴旋转,顺序就非常重要了。这个我们后面章节会详细讲。
3.3 旋转矩阵的几何意义
旋转矩阵的每一列,其实都有明确的几何意义。我建议你把这个记牢,因为后面学三维旋转时,这个思路会帮你省很多事。
你看,R(θ) 的第一列是 [cos(θ), sin(θ)]^T,它表示 x 轴单位向量 (1,0) 旋转后的位置。第二列是 [-sin(θ), cos(θ)]^T,表示 y 轴单位向量 (0,1) 旋转后的位置。
为什么会这样?因为矩阵乘法本质上就是线性变换。你把单位矩阵的每一列看作一个基向量,旋转矩阵就是把这些基向量映射到新的位置。
核心要点:旋转矩阵的列向量,就是原坐标系的基向量在新坐标系中的坐标表示。
这个性质在实际应用中非常有用。比如你在做风洞实验时,需要把模型坐标系的数据转换到风洞坐标系,只要知道两个坐标系之间的夹角,直接构造旋转矩阵就行。
3.4 旋转矩阵的重要性质
二维旋转矩阵有几个性质,我在项目中经常用到:
| 性质 | 表达式 | 说明 |
|---|---|---|
| 正交性 | R^T · R = I | 旋转矩阵的转置等于它的逆 |
| 行列式为 1 | det(R) = 1 | 旋转不改变面积 |
| 逆旋转 | R(-θ) = R^T(θ) | 反向旋转就是转置 |
正交性这个性质特别重要。我曾经在写代码时,直接用旋转矩阵的转置来代替求逆,结果算出来的姿态角完全不对。后来才发现,我用的矩阵不是严格正交的——因为数值计算中的舍入误差,导致 R^T · R 不等于单位矩阵。从那以后,我每次构造旋转矩阵后,都会顺手检查一下正交性。
小技巧:在实际编程中,如果频繁使用旋转矩阵的逆,建议直接用转置代替。但前提是你要确保矩阵是严格正交的。可以用 R^T · R 是否接近单位矩阵来验证。
3.5 顺时针 vs 逆时针
这里有个容易踩的坑——旋转方向的定义。不同的教材、不同的软件,对旋转正方向的定义可能不一样。
我们上面推导的是逆时针旋转为正。如果你需要顺时针旋转 θ 角,有两种做法:
- 直接用 R(-θ),也就是把 θ 换成 -θ
- 或者用 R(θ) 的转置,因为 R(-θ) = R^T(θ)
我建议你养成一个习惯:在代码里明确注释旋转方向。比如:
# 逆时针旋转 30 度
theta = 30 * pi / 180
R = [[cos(theta), -sin(theta)],
[sin(theta), cos(theta)]]
我曾经接手过一个项目,前同事写的旋转矩阵没有注释,代码里到处是正负号。我花了整整一个下午才理清楚他用的到底是左手系还是右手系。嗯,从那以后,我自己的代码里,旋转矩阵旁边一定会写上「逆时针为正」或者「顺时针为正」。
3.6 知识体系总览
下面这张图总结了二维旋转矩阵的核心逻辑,从平面几何出发,到矩阵表达,再到实际应用:
3.7 小结
二维旋转矩阵,说白了就是用一个 2×2 的矩阵来描述平面上的旋转操作。它的推导从平面几何出发,经过三角恒等变换,最终得到简洁的矩阵形式。
我个人觉得,理解旋转矩阵的关键不在于背公式,而在于理解它的几何意义——每一列代表一个基向量旋转后的位置。这个思路在三维旋转中同样适用,而且会更加重要。
最后提醒一句:写代码时一定要明确旋转方向,最好加上注释。这个习惯能帮你省下不少调试时间。
避坑指南:我曾经在项目中直接用旋转矩阵的转置代替逆矩阵,结果因为矩阵不是严格正交的(数值误差导致),算出来的结果偏差很大。建议每次构造旋转矩阵后,用 R^T · R 验证一下正交性,误差在 1e-12 以内才算合格。
公众号:蓝海资料掘金营,微信deep3321