> ## Documentation Index
> Fetch the complete documentation index at: https://kensou.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Rotation intuition primer

# Rotation Intuition Primer (3D 旋转直觉入门)

> **发布时间**: 2026-05-22
> **核心定位**: SE(3)/SO(3) primer 太硬？这是它的**前置课**。从"手机翻一下"到"为什么需要李群"的桥梁。

**Status:** v1 — beginner-friendly。读完它再去读 [se3\_so3\_lie\_groups\_primer.md](./se3_so3_lie_groups_primer.md) 会顺很多。
**TL;DR:** 3D 旋转表面是 3×3 矩阵相乘，骨子里是个**弯曲的几何对象**。本文用日常物体（手机、骰子、Rubik）的实例，从最简单的 2D 旋转开始，一步步推到为什么 Euler 角不够、为什么需要四元数、为什么 SLAM 圈用李群。**不需要任何机器人 / SLAM 背景**，会一点高中线性代数就行。

**X-Ray.** 任何 spatial AI 系统都要回答"机器人现在朝哪？""下一步它该转到哪？"。3D 旋转有 4 种主流表达方式（Euler 角 / 旋转矩阵 / 轴-角 / 四元数）—— 它们都对，但各自在某些场景会坑你。**踩遍这些坑你才理解为什么 SLAM 圈用李群**。这篇是踩坑前的导览图，让你看一眼地图再下水。

***

## 1 · 从 2D 旋转开始（你已经会）

平面上一个点 `(x, y)` 转 θ 度后变成什么？

```
                                              
     原点                                       
       ●─────────────●  P = (1, 0)               
       │              \                          
       │   θ           \                         
       │     \          \                        
       │      \          \                       
       │       ●  P' = (cos θ, sin θ)            
       │      /                                  
       │     /                                   
       │    /                                    
       │   /                                     
                                                
   2D 旋转矩阵:                                   
                                                
   R(θ) = [ cos θ   -sin θ ]                     
          [ sin θ    cos θ ]                     
   
   P' = R(θ) · P
```

**关键事实**:

* `R(θ)` 是 2×2 矩阵，**只有 1 个参数 θ**（旋转角度）
* 复合两次旋转 = 矩阵相乘：`R(θ₁) · R(θ₂) = R(θ₁ + θ₂)`
* **可逆**：`R(θ)⁻¹ = R(-θ) = R(θ)ᵀ`（旋转矩阵的转置就是它的逆）

**SLAM 圈把这种性质的矩阵集合叫 SO(2)** —— 2D special orthogonal group。2D 世界很简单：1 个角度就够。

***

## 2 · 跳到 3D：突然变成 3 个角度（Euler 角）

3D 空间里转一个手机，你需要描述**绕 3 个轴各转多少**：

```
                                            
              y (yaw 偏航 — 左右)             
              │                              
              │                              
              │                              
              ●─────────► x (roll 翻滚 — 前后)
             ╱                               
            ╱                                
           ╱                                  
          ╱                                   
         z (pitch 俯仰 — 上下)                  
```

**手机的 Euler 角直觉**：

* **Yaw**（绕 y 轴，左右转）：手机面朝东 → 面朝南
* **Pitch**（绕 z 轴，上下倾斜）：手机水平 → 手机面朝天
* **Roll**（绕 x 轴，前后翻滚）：手机自己围绕中轴转一圈

3 个角度 `(roll, pitch, yaw)` = `(φ, θ, ψ)` —— 看起来够用。**SLAM 新手 99% 第一次都用 Euler 角，因为最直观。**

### Euler 角的旋转矩阵（看一眼记一下）

```
   R = R_z(ψ) · R_y(θ) · R_x(φ)
       
   = [ cos ψ·cos θ                cos ψ·sin θ·sin φ - sin ψ·cos φ    cos ψ·sin θ·cos φ + sin ψ·sin φ ]
     [ sin ψ·cos θ                sin ψ·sin θ·sin φ + cos ψ·cos φ    sin ψ·sin θ·cos φ - cos ψ·sin φ ]
     [    -sin θ                            cos θ·sin φ                          cos θ·cos φ            ]
```

**不用记**。重点：**3 个角度 → 1 个 3×3 旋转矩阵**。

***

## 3 · Euler 角的第一个坑：**Gimbal Lock（万向锁）**

把手机调成 pitch = 90° （面朝正上方）。**此时 roll 和 yaw 都让手机绕同一根轴转** —— **两个自由度退化成一个！**

```
                                            
   Pitch = 0° (水平):                           
   ─────────────────                          
     yaw 转 → 围绕 y 轴 (水平平面内换方向)        
     roll 转 → 围绕 x 轴 (前后翻)               
     两个轴垂直 → 独立                          
                                              
   Pitch = 90° (朝天):                          
   ─────────────────                          
     yaw 转 → 还是围绕 y 轴 (但 y 轴已经指天)     
     roll 转 → 围绕 x 轴 (但 x 轴现在指水平)     
     这两个轴是同一个! (都在水平面内)           
     **3 个独立自由度变成 2 个**                  
                                              
   后果: 系统看到 (pitch = 90°, yaw = α, roll = β)
         和 (pitch = 90°, yaw = α+δ, roll = β-δ) 
         **几何上完全一样**！                    
```

**真实事故**：Apollo 11 月球登陆器靠 Euler 角，宇航员在某个高仰角让飞船 gimbal lock，险些丢失姿态。

**SLAM 后果**：

* 用 Euler 角写 BA / EKF → 在某些位姿 Jacobian 奇异 → 优化器跳出"我没法继续了"
* 这就是为什么 production 永远不用 Euler 角做内部状态（除了 debug 显示）

***

## 4 · 第二个尝试：旋转矩阵（直接存 3×3 矩阵）

**Idea**：不用 3 个角度，直接存 3×3 矩阵 `R` 本身。

```
   优点:
     - 没有 gimbal lock
     - 复合: R₁ · R₂ 直接矩阵相乘
     - 反转: Rᵀ (转置)
   
   缺点:
     - 9 个数表示只有 3 个自由度的东西 (浪费)
     - 数值漂移: 优化时矩阵 R 慢慢不再正交 (因为浮点)
     - 不能简单线性插值: (R₁ + R₂)/2 不再是合法的旋转矩阵
```

**约束**：旋转矩阵必须满足 `R · Rᵀ = I` 且 `det(R) = +1` —— 这 6 个等式约束 9 个变量，留下 3 个自由度。SLAM 优化时如果不小心，迭代几步后矩阵就变形了。

**SLAM 圈叫这个集合 SO(3)** —— 3D special orthogonal group。

***

## 5 · 第三个尝试：轴-角（Axis-Angle）—— 真正几何起点

**关键观察**（Euler 定理 1775）：**任何 3D 旋转都可以表达成"绕一个轴 ω 转 θ 角度"**。

```
                                              
        ω (旋转轴, 单位向量)                       
       │                                       
       │   θ                                   
       ├─/                                     
       │/ \      物体绕 ω 转 θ 角              
       │   ●─── ───── ─→ 新位置                 
       ●                                       
                                              
   编码: 3D 向量 v = θ · ω = (θω_x, θω_y, θω_z)
                                              
   只有 3 个数 → 自由度刚好对!
```

* `|v| = θ` （向量的长度 = 旋转角度）
* `v / |v| = ω` （向量的方向 = 旋转轴）

**优点**：

* 最少的数（3 个）
* 没有 gimbal lock
* 几何直观

**缺点**：

* 复合两个旋转：`v_3 ≠ v_1 + v_2` （因为旋转不交换）
* 求复合需要先转成矩阵或四元数

这一节是关键 —— **轴-角是连接所有其他表达方式的纽带**。SLAM 圈的"李代数 so(3)" 就是这个 3D 向量空间。

### 转换公式（Rodrigues 公式）

```
   轴-角 v = θω → 旋转矩阵 R:
   
   R = I + sin(θ) · [ω]× + (1 - cos(θ)) · [ω]×²
   
   其中 [ω]× = [  0    -ω_z   ω_y ]   (反对称矩阵)
                [  ω_z    0   -ω_x ]
                [ -ω_y   ω_x    0  ]
```

不用记。重点：**`[ω]×` 这个反对称矩阵的 exponential 就是旋转矩阵**：

```
   R = exp([ω]× · θ)         ← 矩阵指数!
```

**Aha 时刻**：旋转和 exp / log 函数有内在联系。**这就是李群理论的起点。**

***

## 6 · 第四个尝试：四元数（Quaternions）

Hamilton 1843 发明四元数，让 3D 旋转有了**最实用的表达**：

```
   四元数 q = (w, x, y, z) = w + xi + yj + zk
   
   单位四元数 (|q| = 1) ↔ 旋转
   
   从轴-角 (θ, ω) 来:
     w = cos(θ/2)
     (x, y, z) = sin(θ/2) · ω
   
   优点:
     - 4 个数, 1 个约束 (|q| = 1) → 3 自由度
     - 没有 gimbal lock
     - 复合: q₁ ⊗ q₂  (四元数乘法, 不交换)
     - 反转: q⁻¹ = (w, -x, -y, -z)  (共轭, 取负虚部)
     - 球面插值 (Slerp): 平滑插值两个旋转
     - 数值稳定: 漂移只破坏单位长度, 容易归一化修复
```

**SLAM 圈最常用** —— OpenVINS / VINS-Mono / 所有飞控代码都用四元数表示姿态。

⚠️ **Hamilton vs JPL convention 坑**：四元数有两种约定（顺序不同），混用会让 IMU 静默错。详见 [quaternions\_and\_rotations.md](./quaternions_and_rotations.md)。

***

## 7 · 为什么还需要"李群"？

到这里你已经会 4 种旋转表达方式。**李群理论是把这些统一起来的一套语言**。

### 7.1 SO(3) 是个弯曲的几何对象

3D 旋转的集合 SO(3) 不是平的向量空间。**它是个 3 维流形** —— 局部像 R³，整体弯成一个奇怪的形状。

```
                                              
   平的空间 (R³):                                
     任意两点都能加: a + b ∈ R³                  
     梯度下降: x_{k+1} = x_k - η · ∇f           
   
   旋转的集合 SO(3) (弯的):                       
     不能加: R₁ + R₂ 不再是旋转!                
     "梯度下降"必须沿着流形走                    
     R_{k+1} = R_k · exp([ω]× · η · ∇f)         
                       ↑                       
                  指数把切空间的小步带回流形上
```

### 7.2 切空间 = 李代数

在某一点 `R` 处的"无穷小变化"住在一个平的 3D 空间里 —— **这就是李代数 so(3)**，就是我们前面看到的 `[ω]×` 反对称矩阵。

```
                                              
       SO(3) 流形                                
         (弯曲)                                  
                                              
              ⌒⌒                                
            ●●●●●  ← 切空间 (so(3))               
           ●     ●   平的 R³                      
          ●  R  ●    住所有 [ω]× 矩阵             
           ●     ●                              
            ●●●●●                                
              ⌒⌒                                
                                              
   exp: so(3) → SO(3)  (切空间 → 流形, "走一小步")  
   log: SO(3) → so(3)  (流形 → 切空间, "测量距离")  
```

**这就是 [se3\_so3\_lie\_groups\_primer.md](./se3_so3_lie_groups_primer.md) 的核心**：用切空间做加减，用 exp/log 来回流形 ↔ 切空间。

### 7.3 为什么 SLAM 必须用李群？

* BA 优化 = 在流形上找最低点 → 必须用切空间 line search
* IMU 预积分 = 在切空间累加 → 必须用 exp 取出最终旋转
* EKF / MSCKF = 误差状态住切空间 → covariance 才能正确传播

***

## 8 · 一张图总结：4 种表达 + 何时用

```
                                              
   2D 角度 θ (你已会)                              
        │                                      
        │ +1 维                                  
        ▼                                      
   ─────────────────────────────────────────   
   3D 旋转 (4 种表达, 选一个):                    
   ─────────────────────────────────────────   
                                              
   Euler 角  →  3 个数,  容易理解,    💥 gimbal lock
   旋转矩阵   →  9 个数,  没奇异,     💥 数值漂移
   轴-角     →  3 个数,  几何漂亮,   💥 不能简单复合
   四元数    →  4 个数,  生产最爱,   ⚠️ Hamilton vs JPL
                                              
        │ + 数学结构                              
        ▼                                      
   ─────────────────────────────────────────   
   李群 SO(3) (统一框架):                          
   ─────────────────────────────────────────   
     - 流形 + 切空间 (so(3) 是 R³)                  
     - exp / log 来回切换                          
     - 内部计算 / SLAM 优化都靠它                   
```

**选哪个**：

| 场景                | 用什么       | 为什么                          |
| ----------------- | --------- | ---------------------------- |
| 给人显示              | Euler 角   | 直观，"yaw 90° pitch 45°" 人能读   |
| 内部状态 (production) | 四元数       | 最稳，最快，球面插值                   |
| 优化器内部             | 旋转矩阵      | Forster preintegration 公式用 R |
| 增量更新 / IMU 积分     | 李代数 + exp | 切空间小步走                       |
| Debug log         | Euler     | 看数字一眼知道 90° 还是 180°          |

***

## 9 · 你现在该读什么

```
                                              
   ┌────────────────────────────────────────┐   
   │   你刚读完: 旋转直觉 (本文)              │   
   └────────────┬───────────────────────────┘   
                │                              
                ▼                              
   ┌────────────────────────────────────────┐   
   │   下一步选项 (按需求):                    │   
   ├────────────────────────────────────────┤   
   │   想正式入门李群 → se3_so3 primer        │   
   │   想搞清楚四元数细节 → quaternions      │   
   │   想看 BA 怎么用李群 → bundle_adjustment │   
   │   想看 IMU 积分用李群 → imu_preint      │   
   └────────────────────────────────────────┘   
```

***

## 10 · 常见陷阱清单（新手必避）

1. **混用度数和弧度** — Python `math.sin(90)` 是 `sin(90 radians)` ≠ `sin(90°)`。所有 SLAM 库内部用弧度。
2. **认为旋转可以相加** — `R₁ + R₂` 不是旋转。要用矩阵乘法 / 四元数乘法。
3. **认为旋转可以平均** — `(R₁ + R₂) / 2` 不是合法旋转。要用 Slerp 或 quaternion mean。
4. **忘记单位化四元数** — 数值漂移会让 `|q|` 偏离 1，要每 N 步归一化。
5. **混用 Hamilton vs JPL convention** — IMU 默认 JPL，Eigen 默认 Hamilton，跨边界要明示。
6. **以为 Euler 角顺序不重要** — XYZ 和 ZYX 转出来不一样。
7. **以为旋转可交换** — `R_x(90°) · R_y(90°) ≠ R_y(90°) · R_x(90°)`。3D 旋转**不交换**。

***

## 玩具例子：90° 复合不交换（自己验证）

拿一本书：

1. 先绕水平 x 轴翻 90°（书脊向上）→ 再绕垂直 y 轴转 90°（书脊朝你右边）
2. 反过来：先绕 y 轴转 90° → 再绕 x 轴翻 90°

**两次操作后书的姿态不一样！** 这就是矩阵乘法不交换的几何证明。

***

## Boundary

* 严格的 SE(3)/SO(3) 数学 → [`./se3_so3_lie_groups_primer.md`](./se3_so3_lie_groups_primer.md)
* 四元数 Hamilton vs JPL 详细 → [`./quaternions_and_rotations.md`](./quaternions_and_rotations.md)
* 看 BA 怎么用旋转 → [`./bundle_adjustment.md`](./bundle_adjustment.md)
* 看 IMU 怎么用旋转 → [`./imu_preintegration_math.md`](./imu_preintegration_math.md)

## References

* Euler (1775) *Formulae generales pro translatione quacunque corporum rigidorum*. Euler 旋转定理来源。
* Hamilton (1843) *On Quaternions*. 四元数发明。
* Rodrigues (1840) *Des lois géométriques qui régissent les déplacements*. Rodrigues 公式。
* Sola (2017) *Quaternion kinematics for the error-state Kalman filter*. [arXiv 1711.02508](https://arxiv.org/abs/1711.02508) — 工程师视角，比教科书友好。
* 3Blue1Brown video: *Visualizing quaternions* [https://www.youtube.com/watch?v=d4EgbgTm0Bg](https://www.youtube.com/watch?v=d4EgbgTm0Bg) — 视频直觉。

[← Back to Spatial Math](./overview.md)
