Skip to content

Commit ae40fb7

Browse files
docs: add quaternion
1 parent 7427af6 commit ae40fb7

21 files changed

Lines changed: 2597 additions & 1 deletion

docs/math/geometry/index.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Geometry
2+
3+
- [Quaternion](quaternion/index.md)
Lines changed: 306 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,306 @@
1+
<link rel="stylesheet" href="../../../../css/counter.css" />
2+
3+
# 基础:复数和旋转
4+
5+
!!! info "notes of https://github.com/Krasjet/quaternion, chapter 1 & 2"
6+
7+
## 复数和 2D 旋转
8+
9+
### 复数乘法矩阵形式
10+
11+
对于复数 $z_1 = a + bi$ 和 $z_2 = c + di$,它们最基础的乘法形式为:
12+
13+
$$
14+
z_1 z_2 = (a + bi)(c + di) = ac + adi + bci + bdi^2 = (ac - bd) + (ad + bc)i
15+
$$
16+
17+
实际上,我们可以将复数看作是一个 $2 \times 2$ 的反对称矩阵。
18+
19+
!!! info "复数的反对称矩阵表示"
20+
对于复数 $z=a + bi$,可以表示为如下的反对称矩阵:
21+
22+
$$
23+
z=\begin{bmatrix}
24+
a & -b \\
25+
b & a
26+
\end{bmatrix}
27+
$$
28+
29+
只将 $z_1$ 视为矩阵,就足够将复数乘法表示为**矩阵和向量的乘法**
30+
31+
$$
32+
z_1z_2 = \begin{bmatrix}
33+
a & -b \\
34+
b & a
35+
\end{bmatrix}
36+
\begin{bmatrix}
37+
c \\
38+
d
39+
\end{bmatrix} =
40+
\begin{bmatrix}
41+
ac - bd \\
42+
ad + bc
43+
\end{bmatrix}
44+
$$
45+
46+
或者,将 $z_1$ 和 $z_2$ 都视为矩阵,那最终的结果也得是反对称矩阵表示,那么复数乘法可以表示为**矩阵乘法**
47+
48+
$$
49+
z_1z_2 = \begin{bmatrix}
50+
a & -b \\
51+
b & a
52+
\end{bmatrix}
53+
\begin{bmatrix}
54+
c & -d \\
55+
d & c
56+
\end{bmatrix} =
57+
\begin{bmatrix}
58+
ac - bd & -ad - bc \\
59+
ad + bc & ac - bd
60+
\end{bmatrix}
61+
$$
62+
63+
> 从可以表示为矩阵乘法也可以看出复数乘法是**可交换**
64+
65+
### 复数乘法极坐标形式
66+
67+
只把 $z_1$ 视为矩阵,可以认为是对向量 $z_2$ 进行了 $z_1$ 矩阵形式对应的变换。而 $z_1$ 的矩阵形式既可以简单地看作是把 $(1, 0)^{\top}$ 变换到 $(a, b)^{\top}$、$(0, 1)^{\top}$ 变换到 $(-b, a)^{\top}$ 的变换,也可以将其拆解为一个缩放变换和一个旋转变换的复合:
68+
69+
$$
70+
\begin{aligned}
71+
\begin{bmatrix}
72+
a & -b \\
73+
b & a
74+
\end{bmatrix}
75+
&=
76+
\begin{bmatrix}
77+
\sqrt{a^2 + b^2} & 0 \\
78+
0 & \sqrt{a^2 + b^2}
79+
\end{bmatrix}
80+
\begin{bmatrix}
81+
\frac{a}{\sqrt{a^2 + b^2}} & -\frac{b}{\sqrt{a^2 + b^2}} \\
82+
\frac{b}{\sqrt{a^2 + b^2}} & \frac{a}{\sqrt{a^2 + b^2}}
83+
\end{bmatrix}
84+
&=
85+
\underbrace{\begin{bmatrix}
86+
\|z_1\| & 0 \\
87+
0 & \|z_1\|
88+
\end{bmatrix}}_{\text{scaling}}
89+
\underbrace{\begin{bmatrix}
90+
\cos \theta & -\sin \theta \\
91+
\sin \theta & \cos \theta
92+
\end{bmatrix}}_{\text{rotation}}
93+
\end{aligned}
94+
$$
95+
96+
这是否十分熟悉?利用欧拉公式 $e_{i\theta} = cos \theta + i \sin \theta$,可以很容易地导出复数的极坐标形式:
97+
98+
$$
99+
z_1 = \|z_1\|\begin{bmatrix}
100+
\cos \theta _1 & -\sin \theta _1 \\
101+
\sin \theta _1 & \cos \theta _1
102+
\end{bmatrix}
103+
= \|z_1\|(\cos \theta _1 + i \sin \theta _1) = \|z_1\|e^{i\theta _1}
104+
$$
105+
106+
也就有我们十分熟悉的极坐标形式下的复数乘法了
107+
108+
$$
109+
z_1z_2 = \|z_1\|\|z_2\|e^{i(\theta _1 + \theta _2)}
110+
$$
111+
112+
可以认为先将复数乘法视为矩阵乘法,再将 $z_1, z_2$ 对应的矩阵都视为缩放和旋转的复合变换,最后交换变换顺序让两个缩放变换相复合、两个旋转变换相复合,最后就得到了极坐标形式下的复数乘法。
113+
114+
!!! tip "复数乘法形式总结"
115+
- 原始形式
116+
117+
$$
118+
z_1 z_2 = (a + bi)(c + di) = (ac - bd) + (ad + bc)i
119+
$$
120+
121+
- 矩阵和向量乘法形式
122+
123+
$$
124+
z_1z_2 = \begin{bmatrix}
125+
a & -b \\
126+
b & a
127+
\end{bmatrix}
128+
\begin{bmatrix}
129+
c \\
130+
d
131+
\end{bmatrix} =
132+
\begin{bmatrix}
133+
ac - bd \\
134+
ad + bc
135+
\end{bmatrix}
136+
$$
137+
138+
- 矩阵乘法形式
139+
140+
$$
141+
z_1z_2 = \begin{bmatrix}
142+
a & -b \\
143+
b & a
144+
\end{bmatrix}
145+
\begin{bmatrix}
146+
c & -d \\
147+
d & c
148+
\end{bmatrix} =
149+
\begin{bmatrix}
150+
ac - bd & -ad - bc \\
151+
ad + bc & ac - bd
152+
\end{bmatrix}
153+
$$
154+
155+
- 极坐标形式
156+
157+
$$
158+
z_1z_2 = \|z_1\|\|z_2\|e^{i(\theta _1 + \theta _2)}
159+
$$
160+
161+
### 2D 旋转
162+
163+
由此,2D 旋转可以有如下三种表示形式(将 2D 向量 $v$ 旋转到 $v'$):
164+
165+
!!! abstract "2D 旋转的表示形式"
166+
167+
- 矩阵形式
168+
169+
$$
170+
v' = Rv
171+
= \begin{bmatrix}
172+
\cos \theta & -\sin \theta \\
173+
\sin \theta & \cos \theta
174+
\end{bmatrix}v
175+
$$
176+
177+
- 复数积形式
178+
179+
$$
180+
v' = zv = (\cos \theta + i \sin \theta)v
181+
$$
182+
183+
- 极坐标形式
184+
185+
$$
186+
v' = e^{i\theta}v
187+
$$
188+
189+
## 3D 旋转
190+
191+
### 轴角式表示
192+
193+
将主要讨论轴角 (axis-angle) 式的 3D 旋转表示,即以旋转轴和围绕旋转轴进行旋转的角度确定旋转:
194+
195+
- 旋转轴由其在 3D 空间中的方向向量 $\mathbf{u}=(u_x, u_y, u_z)^{\top}\in \mathbb{R}^3$ 确定
196+
- 旋转角 $\theta$ 为一个实数,取正时的方向默认由右手定则确定
197+
198+
<div style="text-align:center;">
199+
<img src="../../../imgs/quaternion/basics-axis-angle-rotation.svg" alt="basics-axis-angle-rotation" style="width: 40%;">
200+
</div>
201+
202+
看似变量一共为 4 个实数,实际上由于方向向量满足约束 $\|\mathbf{u}\|=\sqrt{u_x^2 + u_y^2 + u_z^2}=1$,实际自由度为 3。
203+
204+
除了轴角式,欧拉角也常用来表示 3D 旋转,但是欧拉角存在死锁问题 (**Gimbal Lock**),而且依赖于三个坐标轴的标定,使用轴角式表示就可以解决这个问题。
205+
206+
> 关于 Gimbal Lock 的部分,将专门开一块进行讨论;对于采取左手定则确定旋转角正方向的情况,也将开一块进行讨论
207+
208+
### 旋转分解
209+
210+
把即将进行旋转的向量 $\mathbf{v}$ 分解为
211+
212+
$$
213+
\mathbf{v} = \mathbf{v}_{\parallel} + \mathbf{v}_{\perp}
214+
$$
215+
216+
其中 $\mathbf{v}_{\perp}$ 正交于 $\mathbf{u}$,$\mathbf{v}_{\parallel}$ 平行于 $\mathbf{u}$,如下图所示,可以看出 $\mathbf{v}_{\parallel}$ 就是 $\mathbf{v}$ 在旋转轴 $\mathbf{u}$ 上的正交投影。
217+
218+
<div style="text-align:center;">
219+
<img src="../../../imgs/quaternion/basics-orthogonal-decomposition.svg" alt="basics-orthogonal-decomposition" style="width: 50%;">
220+
</div>
221+
222+
这样,我们可以通过 $\mathbf{v}' = \mathbf{v}_{\parallel}' + \mathbf{v}_{\perp}'$ 计算旋转后得到的向量 $\mathbf{v}'$,由于平行分量不会被旋转,即 $\mathbf{v}_{\parallel}'=\mathbf{v}_{\parallel}$,所以实际上只需要进行如下步骤:
223+
224+
!!! tip "利用向量正交分解进行 3D 旋转变换的步骤"
225+
1. 计算分解 $\mathbf{v}_{\parallel}$ 和 $\mathbf{v}_{\perp}$
226+
2. 旋转 $\mathbf{v}_{\perp}$ 得到 $\mathbf{v}_{\perp}'$
227+
3. 计算 $\mathbf{v}'=\mathbf{v}_{\perp}' + \mathbf{v}_{\parallel}$
228+
229+
### 3D 旋转
230+
231+
#### 计算分解
232+
233+
根据 $v_{\parallel}$ 是 $\mathbf{v}$ 的正交投影,可以得到
234+
235+
$$
236+
\begin{aligned}
237+
\mathbf{v}_{\parallel}
238+
&= \operatorname{proj}_{\mathbf{u}}\mathbf{v} \\
239+
&= \frac{\mathbf{u}\cdot \mathbf{v}}{\|\mathbf{u}\|} \cdot \frac{\mathbf{u}}{\|\mathbf{u}\|} \\
240+
&= (\mathbf{u}\cdot \mathbf{v}) \mathbf{u}
241+
\end{aligned}
242+
$$
243+
244+
这样,就有 $\mathbf{v}_{\perp} = \mathbf{v} - \mathbf{v} _{\parallel} = \mathbf{v} - (\mathbf{u}\cdot \mathbf{v}) \mathbf{u}$。
245+
246+
#### 旋转正交分量
247+
248+
接下来旋转 $\mathbf{v}$ 的正交分量 $\mathbf{v}_{\perp}$ 得到 $\mathbf{v}_{\perp}'$。这实际上是在垂直于旋转轴 $\mathbf{u}$ 的平面上的一个 2D 旋转,将这个平面视为一个 x-y 平面,我们就可以使用我们前面已经得到的 2D 旋转公式。但我们首先需要 x 方向和 y 方向来表征这个平面,或者说,用实轴方向和虚轴方向来表征复平面。
249+
250+
将 $\frac{\mathbf{v}_{\perp}}{\|\mathbf{v}_{\perp}\|}$ 视为 x 方向是很自然的,我们还需要构造一个这个平面上的和 $\mathbf{v}_{\perp}$ 正交的向量作为 y 方向,由于它同时和 $\mathbf{v}_{\perp}$ 以及 $\mathbf{u}$ 正交,我们很自然地想到可以通过**叉积**的方式构造这样一个正交于由 $\mathbf{v}_{\perp}$ 和 $\mathbf{u}$ 所确定的平面的向量:
251+
252+
$$
253+
\mathbf{w} = \mathbf{u}\times \mathbf{v}_{\perp}
254+
$$
255+
256+
然后将 $\frac{\mathbf{w}}{\|\mathbf{w}\|}$ 作为 y 方向。注意到:
257+
258+
1. $\|\mathbf{w}\| = \| \mathbf{u}\|\cdot \| \mathbf{v_{\perp}}\| \sin\frac{\pi}{2}= \| \mathbf{v_{\perp}}\|$,$\mathbf{w}$ 和 $\mathbf{v}_{\perp}$ 实际上位于同一个圆周上
259+
2. 叉积的方向由 $\mathbf{u}$ 到 $\mathbf{v}_{\perp}$ 的右手定则确定,我们一开始规定正旋转角方向由以 $\mathbf{u}$ 为轴的右手定则确定,容易得知以这种方式确定的 x-y 平面上的旋转角仍遵循 x 方向到 y 方向 $\frac{\pi}{2}$ 以内的旋转为正旋转角(即逆时针旋转)
260+
261+
<div style="text-align:center;">
262+
<img src="../../../imgs/quaternion/basics-perp-rotation.svg" alt="basics-perp-rotation" style="width: 70%;">
263+
</div>
264+
265+
所以,将 x 轴视为实轴,y 轴视为虚轴,$\mathbf{v}_{\perp}$ 可以表示为 $\|\mathbf{v}_{\perp}\|$,$\mathbf{w}$ 可以表示为 $\|\mathbf{v}_{\perp}\|i$,然后我们有
266+
267+
$$
268+
\mathbf{v}_{\perp}' = (\cos\theta + i\sin\theta)\|\mathbf{v}_{\perp}\|
269+
=\underbrace{\|\mathbf{v}_{\perp}\|\cos\theta}_{\in \mathbb{R}} + i\underbrace{\|\mathbf{v}_{\perp}\|\sin\theta}_{\in \mathbb{R}}
270+
$$
271+
272+
重新将复数表示转换为向量表示,就有
273+
274+
$$
275+
\begin{aligned}
276+
\mathbf{v}_{\perp}'
277+
&= \|\mathbf{v}_{\perp}\|\cos\theta \cdot \frac{\mathbf{v}_{\perp}}{\|\mathbf{v}_{\perp}\|} + \|\mathbf{v}_{\perp}\|\sin\theta \cdot \frac{\mathbf{w}}{\|\mathbf{w}\|} \\
278+
&= \mathbf{v}_{\perp} \cos\theta + (\mathbf{u}\times \mathbf{v}_{\perp})\sin\theta \\
279+
&= [\mathbf{v} - (\mathbf{u}\cdot \mathbf{v}) \mathbf{u}]\cos\theta + \{\mathbf{u}\times [\mathbf{v} - (\mathbf{u}\cdot \mathbf{v}) \mathbf{u}]\}\sin\theta \\
280+
&= \mathbf{v}\cos\theta - (\mathbf{u}\cdot \mathbf{v}) \mathbf{u}\cos\theta + (\mathbf{u}\times \mathbf{v})\sin\theta
281+
\end{aligned}
282+
$$
283+
284+
> 注意 $\mathbf{u}\times \mathbf{u}=0$
285+
286+
#### 组合两个分量
287+
288+
由于 $\mathbf{v}' = \mathbf{v}_{\perp}' + \mathbf{v}_{\parallel}$,我们有
289+
290+
$$
291+
\begin{aligned}
292+
\mathbf{v}'
293+
&= \underbrace{\mathbf{v}\cos\theta - (\mathbf{u}\cdot \mathbf{v}) \mathbf{u}\cos\theta + (\mathbf{u}\times \mathbf{v})\sin\theta}_{\mathbf{v}_{\perp}'}
294+
+ \underbrace{(\mathbf{u}\cdot \mathbf{v}) \mathbf{u}}_{\mathbf{v}_{\parallel}} \\
295+
&= \mathbf{v}\cos\theta + \mathbf{u}[(\mathbf{u}\cdot \mathbf{v})(1-\cos\theta)] + (\mathbf{u}\times \mathbf{v})\sin\theta
296+
\end{aligned}
297+
$$
298+
299+
由此我们就得到了著名的罗德里格斯旋转公式 (Rodrigues' rotation formula):
300+
301+
!!! abstract "罗德里格斯旋转公式 (Rodrigues' rotation formula)"
302+
在 3D 空间中,将任意向量 $\mathbf{v}$ 绕着旋转轴 $\mathbf{u}$ 进行右手定则正方向下 $\theta$ 的旋转 ($\|\mathbf{u}\|=1$),旋转后得到的向量 $\mathbf{v}'$ 为
303+
304+
$$
305+
\mathbf{v}'= \mathbf{v}\cos\theta + \mathbf{u}(\mathbf{u}\cdot \mathbf{v})(1-\cos\theta) + (\mathbf{u}\times \mathbf{v})\sin\theta
306+
$$
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Quaternion
2+
3+
!!! info "notes of https://github.com/Krasjet/quaternion"
4+
5+
## Contents
6+
7+
- [基础:复数和旋转](basics.md)
8+
- [四元数](quaternion.md)
9+
- [四元数插值](interpolation.md)
10+
- ...

0 commit comments

Comments
 (0)