旋转矩阵、四元数与欧拉角:三维旋转表示方法详解与工程选型
2026/9/20 16:49:02 网站建设 项目流程

简介:旋转坐标变换是飞机控制仿真、火控系统仿真等科研与工程中绕不开的基础问题,理解点旋转与坐标轴旋转的映射关系至关重要。这份资源系统梳理了几种常见推导方法,适合自动化、航空航天、机器人等相关专业学生或工程师快速建立坐标变换知识框架。内容以几何法、复数运算法、变换法、四元数法四条主线展开:几何法借助极坐标与三角公式直观推导;复数运算法利用复平面上的乘法特性描述旋转;变换法从基变换与坐标变换的关系入手;四元数法则深入讲解定义、基本运算、三角形式与数量-向量表示,并重点阐释如何用四元数表征三维矢量转动,为后续姿态解算等应用打下基础。资源共1个doc文档,压缩包大小约1009KB,内容结构清晰、公式完整,适合对照学习与复习参考。已有1062人学习下载,对需要系统掌握旋转坐标变换方法的读者来说是一份实用资料。

1. 从二维旋转说起:旋转的本质是“不变量”

刚开始接触坐标变换的人,往往会被一堆术语劝退:欧拉角、旋转矩阵、四元数、轴角……感觉每个都是新世界。但你先别急着钻进公式里,我建议从二维平面的旋转入手,把“旋转到底在做什么”这件事想明白,后面所有三维的东西都是它的自然延伸。

假设平面上有一个点,坐标是 (x, y),它绕原点逆时针旋转 θ 角之后变成 (x', y')。这个变换用三角函数写出来就是:

x' = x·cosθ - y·sinθ y' = x·sinθ + y·cosθ

这个式子的几何意义是:旋转前后,点到原点的距离不变,也就是向量的长度(模)不变,变化的只是方向。换句话说,旋转是一种保持长度的线性变换,专业术语叫“正交变换”。我当年第一次深入理解这个“不变量”思想,是在做机械臂末端位姿标定的时候——你旋转的是坐标系,但空间中同一个点的物理位置不会因为坐标系的选择而改变,变的只是它在坐标系里的读数。这个认知是所有坐标变换的地基。

有了二维的基础,扩展到三维就顺理成章了:绕不同轴旋转,只需要在对应维度上套用上面的二维公式,另一个维度保持不变。比如绕 Z 轴旋转时,z 坐标不变,x 和 y 按二维公式变化。而三维空间里的任意旋转,都可以分解成绕 X、Y、Z 三个轴的依次旋转,这就是欧拉角的基本思想。

2. 欧拉角:直观但容易踩坑的旋转描述方式

2.1 欧拉角的定义与旋转顺序

欧拉角用三个角度(通常记作 α、β、γ,或者 yaw、pitch、roll)来描述刚体在三维空间中的姿态。它在工程上极其直观,尤其是飞行器、车辆、机械臂的关节姿态描述里,大家一说“偏航角多少、俯仰角多少”,脑子里马上能浮现出物体的朝向。

但欧拉角有个致命的前提条件:必须规定旋转顺序。绕 X、Y、Z 三个轴按不同顺序旋转,最终姿态完全不一样。同一个角度组 (30°, 45°, 60°) 按 “Z→Y→X” 和按 “X→Y→Z” 旋转,得到的姿态是两码事。这是新手最容易忽略的坑,没有之一。我在实际项目里就见过同事把两个不同约定下的姿态数据直接做差值,结果控制系统一跑就飞了。

还有个更隐蔽的问题:欧拉角存在“万向锁”(Gimbal Lock)。当中间那个轴旋转到 ±90° 时,第一个和第三个旋转轴会重合,导致丢失一个自由度,姿态解算出现奇异。这不是数值误差,而是这种描述方式固有的数学缺陷。所以如果你是做实时姿态解算或者机器人控制的,我建议别把欧拉角当作内部计算的主格式,它更适合做“给人看的显示格式”或者“离线标定的输入格式”。

2.2 一个绕晕过很多人的“外旋”与“内旋”

解释一下:如果旋转是绕着固定坐标系(世界坐标系)的轴进行的,叫“外旋”;如果绕着刚体自身的坐标系轴进行的,叫“内旋”。同一个角度序列,外旋和内旋得到的结果也是不同的,而且两者之间存在一个对应关系——按固定轴顺序 “Z→Y→X” 外旋,等价于按自身轴顺序 “X→Y→Z” 内旋。如果你在读某份文献或接口文档时,发现姿态结果对不上,先别怀疑算法,先确认它用的是外旋还是内旋。

3. 旋转矩阵:精确但“冗余”的硬算派

3.1 旋转矩阵的构造与使用

把旋转用 3×3 的矩阵 R 来表示,点 p 旋转后得到 p',关系就是 p' = R·p(这里的 p 是列向量)。旋转矩阵是一个正交矩阵,满足 RᵀR = I,且行列式为 +1。这个性质意味着它的逆矩阵就是转置矩阵,求逆非常便宜——当你在代码里需要多次反变换时,直接用转置代替求逆,性能能快不少。

构造旋转矩阵最常用的方式是分别构建绕 X、Y、Z 轴的基本旋转矩阵,然后按你的旋转顺序连乘。比如按“Z→Y→X”顺序的旋转矩阵就是 R = Rx(roll) · Ry(pitch) · Rz(yaw)。注意矩阵乘法不满足交换律,所以连乘顺序和旋转顺序必须严格对应,这也是公式记错最容易出 bug 的地方。

旋转矩阵最大的优点是计算稳定、无奇异,任意姿态都能唯一表示,而且组合两次旋转只需要做一次矩阵乘法,非常方便。它的缺点是参数太多——9 个数只有 3 个自由度,内部有 6 个约束。这个“冗余”在实际工程里会带来两个麻烦:一是数值误差累积后,矩阵可能不再满足正交性,需要定期“正交化”(通常用奇异值分解或 Gram-Schmidt 正交化来修复);二是占用内存和传输带宽,如果通过网络频繁传姿态数据,用 9 个浮点数远不如 4 个浮点数的四元数划算。

3.2 旋转矩阵的“方向”问题:列向量到底代表什么

很多资料写得含糊:R 的每一列代表什么?我给一个简单记忆法:旋转矩阵的每一列,是旋转后坐标系各轴在原始坐标系中的方向向量;或者说,它把“被旋转坐标系下的坐标”映射到“参考坐标系下的坐标”。理解这一点,你在做多传感器标定时就不容易搞混坐标系的变换方向。

4. 旋转向量与四元数:工业界的两把利器

4.1 旋转向量(轴角):最直观的“转轴+转角”

旋转向量用一根过原点的轴(单位向量 v)和一个旋转角 θ 来描述旋转,记作 θ·v。它把“旋转”这个抽象动作可视化——想象一扇门绕着门轴转动,门轴方向就是旋转轴,转动角度就是旋转角。

旋转向量在工程里最出名的应用是“李代数 so(3)”——视觉 SLAM 和位姿优化里经常用它来做增量更新,因为它只有 3 个参数,没有约束,适合作为优化变量。从旋转向量到旋转矩阵的转换用罗德里格斯公式:

R = I + sinθ·[v]× + (1 - cosθ)·[v]ײ

其中 [v]× 是 v 的反对称矩阵。反过来,从旋转矩阵提取转轴和转角也有固定套路:θ = arccos((tr(R) - 1)/2),转轴是矩阵特征值 1 对应的特征向量。需要注意 θ 在 0 和 π 附近数值不稳定,遇到这种情况要单独处理,不然会得到奇怪的结果。

4.2 四元数:没有奇异的“终极方案”

四元数是一个超复数,形式是 q = w + xi + yj + zk,其中 i² = j² = k² = ijk = -1。单位四元数(模长为 1)可以用来表示三维旋转。它和旋转向量有直接对应关系:若旋转向量的轴是 (vx, vy, vz)、角度是 θ,则对应的单位四元数是:

w = cos(θ/2) x = vx·sin(θ/2) y = vy·sin(θ/2) z = vz·sin(θ/2)

四元数最强大的地方在于:没有任何奇异点,它的参数只有 4 个(比矩阵少 5 个)、只有一个单位模长约束,插值方便(slerp),组合旋转的运算也简单——两个四元数相乘即可,运算量远小于矩阵连乘。所以现代机器人、无人机、手机姿态传感器里,内部姿态解算几乎默认用四元数。

但是四元数也有反直觉的地方:q 和 -q 表示同一个旋转。所以在做四元数插值或融合时,要先检查两个四元数的点积,如果为负就把其中一个取反,保证走的是“短路径”。这是我当年在写姿态融合算法时多次栽过的地方,不加这个判断,插值轨迹会莫名其妙多绕一圈。

下面是一张四种方法的对比表,方便你按项目需求快速选型:

表示方法参数个数是否奇异组合旋转插值工程适用场景
欧拉角3有(万向锁)复杂人机交互、可视化显示
旋转矩阵9简单(乘法)坐标变换计算、离线标定
旋转向量3角度为0/π时退化一般(需转矩阵)优化求解、SLAM增量更新
四元数4简单(乘法)实时姿态解算、控制、滤波

5. 同一点在不同坐标系的变换:旋转之外还有平移

前面讲的都是“绕原点旋转”,但实际工程里,两个坐标系原点往往不重合。比如机械臂基座坐标系和相机坐标系,原点可能相差几十厘米,姿态也不一样。这时候要把空间中的同一个点从一个坐标系变换到另一个坐标系,需要“旋转+平移”一起做:

p_B = R_AB · p_A + t_AB

这里的 R_AB 表示“从 A 坐标系到 B 坐标系的旋转矩阵”,t_AB 是“A 坐标系原点在 B 坐标系中的位置”。这个公式是手眼标定、多传感器融合、机器人运动学里最基础也最常用的公式。

我教过一个取巧的整合方法:把它写成齐次变换矩阵(4×4 矩阵),把旋转矩阵和平移向量拼在一起,形式是:

T_AB = [ R_AB t_AB ] [ 0 0 0 1 ]

这样一次乘法就能完成旋转和平移。齐次变换矩阵还能表达变换的“链式传递”——比如机械臂末端到基座的变换,可以由相邻关节的变换矩阵连乘得到,这在运动学正解里几乎是标配写法。

6. 实操中的选型建议与我的个人经验

我把这几年做机器人控制和三维视觉项目时具体的选型标准整理一下,不一定适合所有场景,但能帮你少走弯路。

如果你只是给用户展示姿态、或者做离线离线标定,用欧拉角最舒服,人类可读性最好。但请务必在接口文档里写清楚旋转顺序和外旋/内旋约定,否则后续接手的人一定会骂你。我自己的习惯是:对外接口文档里永远附一个“验证样例”——给出一个已知角度组和对应的旋转矩阵/四元数,让调用方自己核对约定是否一致。

如果你的程序里要高频做坐标变换(比如机械臂的实时路径规划),内部表示用旋转矩阵就够,9 个数对现代 CPU 来说根本不算负担,而且矩阵乘法和逆变换都有现成的高性能库,写起来省心。但要注意周期性地做正交化,防止数值漂移。

如果你是做实时姿态解算、无人机/机器人控制、传感器融合,首选四元数。没有万向锁、插值平滑、运算量小,配合卡尔曼滤波或互补滤波都非常顺手。我个人的代码习惯是把四元数作为“内部流通货币”,只在打印日志或 UI 显示时转成欧拉角。

如果你是做视觉 SLAM 中的位姿优化,旋转向量(李代数)几乎是唯一的选择,因为它无约束的 3 参数形式可以直接丢给高斯牛顿或 LM 优化器。但优化完成之后,记得把结果转回四元数或旋转矩阵再输出,方便下游使用。

7. 常见坑位清单:花一个下午就能避掉的大坑

最后列一个我这些年整理的高频翻车清单,每一条都是实打实踩过的:

旋转顺序不一致:不同库、不同设备输出的欧拉角,旋转顺序可能完全不同。比如同一个姿态,某个传感器按 “Z→Y→X” 输出,另一个按 “X→Y→Z” 输出,如果你直接拿两组角度算差值,结果完全没意义。对策是统一在入口处转成旋转矩阵或四元数再处理。

外旋内旋混用:文档里写“按自身坐标系旋转”(内旋)的公式,被你用来处理固定坐标系的输入数据,姿态会差很离谱,而且很难肉眼察觉。对策是写个小的自检工具,用你已知的姿态数据过一遍,看输出是否符合预期。

四元数符号未归一化:连续相乘的四元数会因为浮点误差逐渐偏离单位模长,导致旋转后的点被缩放。对策是在关键位置做 q = q / norm(q) 归一化,这个操作很便宜,但绝大多数新手都会漏。

忽略 q 和 -q 等价:在做四元数差值或平均时,不判断点积正负会导致插值绕远路。对策是每次做插值之前检查一下点积,为负就取反一个。

矩阵转欧拉角时忽略象限判断:很多库里的反三角函数实现,直接返回的结果会丢失象限信息,导致角度不对。对策是使用 atan2 而不是 atan,并且仔细核对每个轴的象限映射表。

坐标变换这个东西,看起来全是公式,其实核心就一句话:角度的描述方式很多,但旋转本身是同一个物理事实。你需要的不是背公式,而是形成一套稳定的内部表示和转换流程,并且在工程入口把所有数据统一到你自己的约定上。做到这一点,后面就全是体力活了。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询