《計算機圖形學原理及實踐》學習筆記之第十一章
第十一章 3D變換
3D空間變換與2D空間有很多類似情況:
3D空間比2D空間要多一維,所以我們視3D空間是由
(
x
,
y
,
z
,
w
)
(x, y, z, w)
(x,y,z,w) 定義的 4D空間 w=1 的子集。
平移:
[
1
0
0
a
0
1
0
b
0
0
0
c
0
0
0
1
]
\begin{bmatrix} 1 & 0 & 0 & a \\ 0 & 1 & 0 & b \\ 0 & 0 & 0 & c \\ 0 & 0 & 0 & 1 \end{bmatrix}
⎣⎢⎢⎡100001000000abc1⎦⎥⎥⎤
旋轉我們待會兒單獨討論
縮放:
[
a
0
0
0
0
b
0
0
0
0
c
0
0
0
0
1
]
\begin{bmatrix} a & 0 & 0 & 0 \\ 0 & b & 0 & 0 \\ 0 & 0 & c & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix}
⎣⎢⎢⎡a0000b0000c00001⎦⎥⎥⎤
錯切:
[
1
a
b
0
0
1
c
0
0
0
1
0
0
0
0
1
]
\begin{bmatrix} 1 & a & b & 0 \\ 0 & 1 & c & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix}
⎣⎢⎢⎡1000a100bc100001⎦⎥⎥⎤
上面只是錯切的一個例子。錯切依然會使直線上的點保持在一條直線上
還要其它的線性變換,跟2D空間下的都是類似的。
投影變換也跟2D變換類似,即在矩陣變換之後進行齊次變換。3D空間中它定義在整個平面上而不是一條直線上。
點反射:
一個點關於一個平面反射:
如圖
x
n
x_n
xn 為
x
x
x 關於 法向為
n
n
n 的平面 的反射點。
可以得到
x
+
x
′
=
(
2
x
⋅
n
)
∗
n
x + x' = (2 x \cdot n) * n
x+x′=(2x⋅n)∗n
於是
x
′
=
(
2
x
⋅
n
)
∗
n
−
x
x' = (2x \cdot n) * n - x
x′=(2x⋅n)∗n−x
而
x
n
=
−
x
′
=
x
−
(
2
x
⋅
n
)
∗
n
x_n = -x' = x - (2x \cdot n) * n
xn=−x′=x−(2x⋅n)∗n
根據該式可得出 3D空間 的反射矩陣:
I
−
2
n
n
T
=
[
1
−
2
n
x
2
−
2
n
x
n
y
−
2
n
x
n
z
0
−
2
n
x
n
y
1
−
2
n
y
2
−
2
n
y
n
z
0
−
2
n
x
n
z
−
2
n
y
n
z
1
−
2
n
z
2
0
0
0
0
1
]
I - 2nn^T = \begin{bmatrix} 1 - 2n_x^2 & -2n_xn_y & -2n_xn_z & 0 \\ -2n_xn_y & 1 - 2n_y^2 & -2n_yn_z & 0 \\ -2n_xn_z & -2n_yn_z & 1 - 2n_z^2 & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix}
I−2nnT=⎣⎢⎢⎡1−2nx2−2nxny−2nxnz0−2nxny1−2ny2−2nynz0−2nxnz−2nynz1−2nz200001⎦⎥⎥⎤
不好記,直接記
I
−
2
n
n
T
I - 2nn^T
I−2nnT 就完事兒了,
I
I
I 是單位矩陣,
n
n
n 為平面法向
投影變換理論
3D空間的投影變換是 4D空間 w=1 子空間內的線性變換。它表示為一個 4x4矩陣
M
M
M 和 緊接著的 齊次變換。齊次變換:
H
(
x
,
y
,
z
,
w
)
=
(
x
w
,
y
w
,
z
w
,
1
)
H(x, y, z, w) = (\frac{x}{w}, \frac{y}{w}, \frac{z}{w}, 1)
H(x,y,z,w)=(wx,wy,wz,1)
那麼,如果 矩陣M 的最後一維 與 點乘積得到的結果為 0,即 點經過 矩陣M 變換後 w = 0,
那麼此時 齊次變換變得無意義,這裡我們認為 該點 經過投影變換後 被變換到了 無窮遠處。
旋轉
3D空間的旋轉 比 2D空間的旋轉要複雜。在 2D空間中,我們認為 點是在 xy平面,旋轉就是繞 z軸旋轉。而在 3D空間,我們的點可以繞 x、y、z 三個軸旋轉。
繞 z 軸,即在 xy平面上的旋轉矩陣 我們在 2D空間變換中已經給出:
R
x
y
(
θ
)
=
[
c
o
s
θ
−
s
i
n
θ
0
s
i
n
θ
c
o
s
θ
0
0
0
1
]
R_xy(θ) = \begin{bmatrix} cosθ & -sinθ & 0 \\ sinθ & cosθ & 0 \\ 0 & 0 & 1 \end{bmatrix}
Rxy(θ)=⎣⎡cosθsinθ0−sinθcosθ0001⎦⎤
繞 x 軸,即在 yz平面上的旋轉矩陣:
R
y
z
(
θ
)
=
[
1
0
0
0
c
o
s
θ
−
s
i
n
θ
0
s
i
n
θ
c
o
s
θ
]
R_yz(θ) = \begin{bmatrix} 1 & 0 & 0 \\ 0 & cosθ & -sinθ \\ 0 & sinθ & cosθ \end{bmatrix}
Ryz(θ)=⎣⎡1000cosθsinθ0−sinθcosθ⎦⎤
繞 y 軸,即在 xz平面上的旋轉矩陣:
R
x
z
(
θ
)
=
[
c
o
s
θ
0
s
i
n
θ
0
1
−
s
i
n
θ
0
c
o
s
θ
]
R_xz(θ) = \begin{bmatrix} cosθ & 0 & sinθ \\ 0 & 1 & \\ -sinθ & 0 & cosθ \end{bmatrix}
Rxz(θ)=⎣⎡cosθ0−sinθ010sinθcosθ⎦⎤
關於這三個軸的旋轉,我們可以用 尤拉角表示
尤拉角
尤拉角 是一種基於三種較簡單旋轉運動(稱為 俯仰、滾動 和 偏航)建立一般旋轉的機制。
用尤拉角表示旋轉,易於人的理解,即將一個物體的旋轉拆解為該物體繞 x、y、z 三個軸的旋轉。
其矩陣就為 繞三個軸旋轉的矩陣乘積:
M
=
[
1
0
0
0
c
o
s
φ
−
s
i
n
φ
0
s
i
n
φ
c
o
s
φ
]
[
c
o
s
θ
0
s
i
n
θ
0
1
0
−
s
i
n
θ
0
c
o
s
θ
]
[
c
o
s
Φ
−
s
i
n
Φ
0
s
i
n
Φ
c
o
s
Φ
0
0
0
1
]
=
[
c
o
s
θ
c
o
s
Φ
−
c
o
s
θ
s
i
n
Φ
s
i
n
θ
s
i
n
φ
s
i
n
θ
c
o
s
Φ
+
c
o
s
φ
s
i
n
Φ
−
s
i
n
φ
s
i
n
θ
s
i
n
Φ
+
c
o
s
φ
c
o
s
Φ
−
s
i
n
φ
c
o
s
θ
−
c
o
s
φ
s
i
n
θ
c
o
s
Φ
+
s
i
n
φ
s
i
n
Φ
c
o
s
φ
s
i
n
θ
s
i
n
Φ
+
s
i
n
φ
c
o
s
Φ
c
o
s
φ
s
i
n
θ
]
\begin{aligned} M = \begin{bmatrix} 1 & 0 & 0 \\ 0 & cosφ & -sinφ \\ 0 & sinφ & cos φ \end{bmatrix} \begin{bmatrix} cosθ & 0 & sinθ \\ 0 & 1 & 0 \\ -sinθ & 0 & cosθ \end{bmatrix} \begin{bmatrix} cosΦ & -sinΦ & 0 \\ sinΦ & cosΦ & 0 \\ 0 & 0 & 1 \end{bmatrix} \\ =\\ \begin{bmatrix} cosθcosΦ & -cosθsinΦ & sinθ \\ sinφsinθcosΦ + cosφsinΦ & -sinφsinθsinΦ + cosφcosΦ & -sinφcosθ \\ -cosφsinθcosΦ + sinφsinΦ & cosφsinθsinΦ + sinφcosΦ & cosφsinθ \end{bmatrix} \end{aligned}
M=⎣⎡1000cosφsinφ0−sinφcosφ⎦⎤⎣⎡cosθ0−sinθ010sinθ0cosθ⎦⎤⎣⎡cosΦsinΦ0−sinΦcosΦ0001⎦⎤=⎣⎡cosθcosΦsinφsinθcosΦ+cosφsinΦ−cosφsinθcosΦ+sinφsinΦ−cosθsinΦ−sinφsinθsinΦ+cosφcosΦcosφsinθsinΦ+sinφcosΦsinθ−sinφcosθcosφsinθ⎦⎤
我們來關注以下 最終得到的這矩陣的最上行 和 最右列。
首先,右上角元素 即
m
13
=
s
i
n
θ
m_{13} = sinθ
m13=sinθ,那麼我們只要取反正弦即可得到
θ
θ
θ
如果
c
o
s
θ
≠
0
cosθ \neq 0
cosθ=0 那麼
m
11
m_{11}
m11 和
m
12
m_{12}
m12 不為0,我們可以得到
Φ
=
a
r
c
t
a
n
(
−
m
12
m
11
)
Φ = arctan(\frac{-m_{12}}{m_{11}})
Φ=arctan(m11−m12)
同樣的方式可以通過
m
23
m_{23}
m23 和
m
33
m_{33}
m33 得到
φ
φ
φ
那麼如果
c
o
s
θ
=
0
cosθ = 0
cosθ=0 呢?例如
θ
=
π
/
2
θ = \pi/2
θ=π/2
此時:
M
=
[
0
0
s
i
n
θ
.
.
.
.
.
.
0
.
.
.
.
.
.
0
]
M = \begin{bmatrix} 0 & 0 & sinθ \\. .. & ... & 0 \\ ... & ... & 0 \end{bmatrix}
M=⎣⎡0......0......sinθ00⎦⎤
此時我們無法從矩陣
M
M
M求解出
φ
φ
φ和
Φ
Φ
Φ,或者說 它們可以是任意的角度,那麼矩陣
M
M
M就無法表示唯一的旋轉。這種現象稱為 萬向節鎖,該現象使得我們無法完美的將尤拉角融入矩陣變換,這也是尤拉角並非描述旋轉的理想方式的一個原因。
旋轉軸 和 旋轉角的描述
我們來看看另一種描述 3D空間 旋轉的方式:
對 3D空間實施旋轉的的一個方法是選擇一個特定的軸(即一個單位向量),然後繞該軸旋轉一定角度
對於每個旋轉都可以找出 其對應的 旋轉軸 和 旋轉角度嗎?這是已經被證明的,每個旋轉都可以找到其旋轉軸和旋轉角,證明較為複雜這裡就不給出了。
令
w
=
[
w
x
w
y
w
z
]
w = \begin{bmatrix} w_x \\ w_y \\ w_z \end{bmatrix}
w=⎣⎡wxwywz⎦⎤
是旋轉軸的單位向量
θ
θ
θ 是繞旋轉軸旋轉的角度
有矩陣:
J
w
=
[
0
−
w
z
w
y
w
z
0
−
w
x
−
w
y
w
x
0
]
J_w = \begin{bmatrix} 0 & -w_z & w_y \\ w_z & 0 & -w_x \\ -w_y & w_x & 0 \end{bmatrix}
Jw=⎣⎡0wz−wy−wz0wxwy−wx0⎦⎤
我稱之為 w 的 叉乘矩陣。因為
J
w
v
=
w
×
v
J_wv = w \times v
Jwv=w×v
於是有旋轉矩陣:
M
=
I
+
s
i
n
(
θ
)
J
w
+
(
1
−
c
o
s
θ
)
J
w
2
M = I + sin(θ)J_w + (1 - cosθ)J_w^2
M=I+sin(θ)Jw+(1−cosθ)Jw2
該矩陣由 Rodrigues 提出,因此稱為 Rodrigues 公式。證明書中未給出,大家可以自行了解,這裡給出知乎一篇相關的連結:
Rodrigues推導
我們來看一些關於 Rodrigues公式的性質:
我們可以計算一下
J
w
w
J_ww
Jww,可以得到
J
w
w
=
0
J_ww = 0
Jww=0
那麼,我們對
w
w
w 這個向量 繞其本身 旋轉θ 角度得到的是什麼呢?
M
w
=
I
w
+
s
i
n
(
θ
)
J
w
+
(
1
−
c
o
s
θ
)
J
w
J
w
w
=
w
+
0
+
(
1
−
c
o
s
θ
)
J
w
0
=
w
Mw = Iw + sin(θ)J_w + (1 - cosθ)J_wJ_ww = w + 0 + (1 - cosθ)J_w0 = w
Mw=Iw+sin(θ)Jw+(1−cosθ)JwJww=w+0+(1−cosθ)Jw0=w,沒錯得到的仍是其本身。
如果
v
v
v 是垂直於
w
w
w 的向量,那麼我們可以推匯出
w
×
(
w
×
v
)
=
−
v
w \times (w \times v) = -v
w×(w×v)=−v:
我們可以畫一下圖,用右手定則看一下
w
×
(
w
×
v
)
w \times (w \times v)
w×(w×v) 得到的方向,當然也可以進行運算驗證,但計算較為複雜,這裡只計算 第一個分量,另外兩個分量都是一樣的:
(
w
×
(
w
×
v
)
)
x
=
−
w
z
2
v
x
+
w
x
w
z
v
z
−
w
y
2
v
x
+
w
x
w
y
v
y
=
−
v
x
(
w
z
2
+
w
y
2
)
+
w
x
(
w
z
v
z
+
w
y
v
y
)
=
−
v
x
(
1
−
w
x
2
)
+
w
x
(
w
z
v
z
+
w
y
v
y
)
=
−
v
x
+
w
x
w
x
v
x
+
w
x
(
w
z
v
z
+
w
y
v
y
)
=
−
v
x
+
w
x
(
w
z
v
z
+
w
y
v
y
+
w
x
v
x
)
=
−
v
x
\begin{aligned} (w \times (w \times v))_x =\\ -w_z^2v_x + w_xw_zv_z - w_y^2v_x + w_xw_yv_y =\\ -v_x(w_z^2 + w_y^2) + w_x(w_zv_z + w_yv_y) =\\ -v_x(1 - w_x^2) + w_x(w_zv_z + w_yv_y) =\\ -v_x + w_xw_xv_x + w_x(w_zv_z + w_yv_y) =\\ -v_x + w_x(w_zv_z + w_yv_y + w_xv_x) =\\ -v_x \end{aligned}
(w×(w×v))x=−wz2vx+wxwzvz−wy2vx+wxwyvy=−vx(wz2+wy2)+wx(wzvz+wyvy)=−vx(1−wx2)+wx(wzvz+wyvy)=−vx+wxwxvx+wx(wzvz+wyvy)=−vx+wx(wzvz+wyvy+wxvx)=−vx
那麼 我們有,若向量
v
v
v 垂直於旋轉軸
w
w
w:
M
v
=
I
v
+
s
i
n
(
θ
)
w
×
v
+
(
1
−
c
o
s
θ
)
w
×
(
w
×
v
)
=
v
+
s
i
n
(
θ
)
w
×
v
+
(
1
−
c
o
s
θ
)
(
−
v
)
=
s
i
n
(
θ
)
w
×
v
+
c
o
s
t
θ
v
Mv = Iv + sin(θ)w \times v + (1-cosθ)w \times (w \times v) = v + sin(θ)w \times v + (1 - cosθ)(-v) = sin(θ)w \times v + costθv
Mv=Iv+sin(θ)w×v+(1−cosθ)w×(w×v)=v+sin(θ)w×v+(1−cosθ)(−v)=sin(θ)w×v+costθv
得到的結果可以看作是一個 極座標表示式,其描述了在
w
×
v
w \times v
w×v 和
v
v
v 組成的平面上的點的極座標 (v 為 ρ)
從旋轉矩陣中尋找 旋轉軸 和 旋轉角
求旋轉角:
我們來計算矩陣
M
M
M 對角線上的元素之和 記為
t
r
(
M
)
tr(M)
tr(M):
t
r
(
M
)
=
t
r
(
I
)
+
s
i
n
(
θ
)
t
r
(
J
w
)
+
(
1
−
c
o
s
θ
)
t
r
(
J
w
2
)
=
3
+
(
1
−
c
o
s
θ
)
(
−
2
(
w
x
2
+
w
y
2
+
w
z
2
)
)
=
1
+
2
c
o
s
θ
tr(M) = tr(I) + sin(θ)tr(J_w) + (1 - cosθ)tr(J_w^2) = 3 + (1 - cosθ)(-2(w_x^2 + w_y^2 + w_z^2)) = 1 + 2cosθ
tr(M)=tr(I)+sin(θ)tr(Jw)+(1−cosθ)tr(Jw2)=3+(1−cosθ)(−2(wx2+wy2+wz2))=1+2cosθ
所以得
θ
=
c
o
s
−
1
(
t
r
(
M
)
−
1
2
)
θ = cos^{-1}(\frac{tr(M) - 1}{2})
θ=cos−1(2tr(M)−1)
求旋轉軸:
M
−
M
T
=
I
+
s
i
n
(
θ
)
J
w
+
(
1
−
c
o
s
(
θ
)
)
J
w
2
−
(
I
T
+
s
i
n
(
θ
)
J
w
T
+
(
1
−
c
o
s
(
θ
)
)
(
J
w
2
)
T
)
M - M^T = I + sin(θ)J_w + (1 - cos(θ))J_w^2 - (I^T + sin(θ)J_w^T + (1 - cos(θ))(J_w^2)^T)
M−MT=I+sin(θ)Jw+(1−cos(θ))Jw2−(IT+sin(θ)JwT+(1−cos(θ))(Jw2)T)
而 可以計算得到
I
T
=
I
I^T = I
IT=I、
J
w
T
=
−
J
w
J_w^T = -J_w
JwT=−Jw 和
(
J
w
2
)
T
=
J
w
2
(J_w^2)^T = J_w^2
(Jw2)T=Jw2,所以可以簡化為
M
−
M
T
=
2
s
i
n
(
θ
)
J
w
M - M^T = 2sin(θ)J_w
M−MT=2sin(θ)Jw
所以在我們求出
θ
θ
θ 後就可以得到
J
w
J_w
Jw 進而得到
w
w
w
此時 如果
s
i
n
θ
=
0
sinθ = 0
sinθ=0 則似乎無法求解
J
w
J_w
Jw,但我們可以進一步討論:
θ
=
0
=
>
s
i
n
θ
=
0
θ = 0 => sinθ = 0
θ=0=>sinθ=0,此時
M
=
I
M = I
M=I(即 與矩陣相乘不會產生任何旋轉) 此時因為旋轉角為 0,所以可以採取任意單位向量作為旋轉軸。
θ
=
π
θ = \pi
θ=π,此時 如果我們再旋轉
π
\pi
π 的角度,那麼將回到自己,即和沒有產生旋轉一樣,那麼可以得到此時:
M
M
=
M
2
=
I
MM = M^2 = I
MM=M2=I,那麼此時就會有:
M
(
M
+
I
)
=
M
2
+
M
=
M
+
I
M(M + I) = M^2 + M = M + I
M(M+I)=M2+M=M+I
這意味著,
M
M
M 與
M
+
I
M + I
M+I 相乘後,
M
+
I
M + I
M+I 的每一列都沒有產生變化。此時
M
+
I
M + I
M+I 的任意非零列,歸一化(單位化)後都可以作為旋轉軸,且
M
+
I
M + I
M+I 至少會有一個非零列。
旋轉和3D球(四元數)
我們稱所有 3x3旋轉矩陣的集合為
S
O
(
3
)
SO(3)
SO(3),它實際上是 9維空間的一個子集,我們可以使用 四維空間中的“單位球”上的點來構建出
S
O
(
3
)
SO(3)
SO(3),而這個四維空間中單位球上的點
(
a
,
b
,
c
,
d
)
(a, b, c, d)
(a,b,c,d) 就是四元數。
這一概念非常抽象,因為我們很難具象化四維空間,關於這一部分的推導,書中沒有給出。這裡還是給出知乎相關的連結:
如何形象地理解四元數?
四元數——基本概念
不過對於圖形學上的應用,我們只需瞭解四元數下面的內容即可:
我們有 四維空間上單位球上的一點
(
a
,
b
,
c
,
d
)
(a, b, c, d)
(a,b,c,d),
(
a
2
+
b
2
+
c
2
+
d
2
)
=
1
(a^2 + b^2 + c^2 + d^2) = 1
(a2+b2+c2+d2)=1,即一個四元數
q
=
[
a
b
c
d
]
q = \begin{bmatrix} a \\ b \\ c \\ d \end{bmatrix}
q=⎣⎢⎢⎡abcd⎦⎥⎥⎤,那麼就可以得到其表示的旋轉矩陣:
M
=
[
a
2
+
b
2
−
c
2
−
d
2
2
(
b
c
−
a
d
)
2
(
a
c
+
b
d
)
2
(
a
d
+
b
c
)
a
2
−
b
2
+
c
2
−
d
2
2
(
c
d
−
a
b
)
2
(
b
d
−
a
c
)
2
(
a
b
+
c
d
)
a
2
−
b
2
−
c
2
+
d
2
]
M = \begin{bmatrix} a^2 + b^2 - c^2 - d^2 & 2(bc - ad) & 2(ac + bd) \\ 2(ad + bc) & a^2 -b^2 + c^2 -d^2 & 2(cd - ab) \\ 2(bd - ac) & 2(ab + cd) & a^2 -b^2 - c^2 + d^2 \end{bmatrix}
M=⎣⎡a2+b2−c2−d22(ad+bc)2(bd−ac)2(bc−ad)a2−b2+c2−d22(ab+cd)2(ac+bd)2(cd−ab)a2−b2−c2+d2⎦⎤
並稱 由
q
−
>
M
q -> M
q−>M 的對映為
K
K
K
其具有這些性質:
- 我們可以看到 M M M 中的項都是二次冪的,所以可以得到 K ( − q ) = K ( q ) K(-q) = K(q) K(−q)=K(q),即該對映是一個 二對一的對映
- K ( [ 1 0 0 0 ] ) = I K(\begin{bmatrix} 1 \\ 0 \\ 0 \\ 0 \end{bmatrix}) = I K(⎣⎢⎢⎡1000⎦⎥⎥⎤)=I
- 對映 K K K由 R 4 R^4 R4(四維空間)中的一種乘法定義,而 R 4 R^4 R4中的乘法不滿足交換律
- 可由四元數代表的旋轉矩陣 轉換為 Rodrigues公式:
設有 q = ( a , b , c , d ) q = (a, b, c, d) q=(a,b,c,d),因為 a 2 + b 2 + c 2 + d 2 = 1 a^2 + b^2 + c^2 + d^2 = 1 a2+b2+c2+d2=1,可得 − 1 < = a < = 1 -1 <= a <=1 −1<=a<=1,故而 a a a 可以這樣表示: a = c o s θ a = cosθ a=cosθ,有 θ = a r c c o s ( a ) θ = arccos(a) θ=arccos(a)
得到: c o s θ 2 + b 2 + c 2 + d 2 = 1 cosθ^2 + b^2 + c^2 + d^2 = 1 cosθ2+b2+c2+d2=1
所以: b 2 + c 2 + d 2 = s i n θ 2 b^2 + c^2 + d^2 = sinθ^2 b2+c2+d2=sinθ2
所以 [ b c d ] \begin{bmatrix} b \\ c \\ d \end{bmatrix} ⎣⎡bcd⎦⎤ 可表示為一個 模長平方為 s i n θ 2 sinθ^2 sinθ2 的向量。如果 a ≠ ± 1 a \neq \pm 1 a=±1(即 θ ≠ 0 ∣ ∣ π θ \neq 0 || \pi θ=0∣∣π, 注意 對於該情況,在Rodrigues公式中我們已經討論過),此時 s i n θ ≠ 0 sinθ \neq 0 sinθ=0
可令:
w = [ 0 b s i n θ c s i n θ d s i n θ ] w = \begin{bmatrix} 0 \\ \frac{b}{sinθ} \\ \frac{c}{sinθ} \\ \frac{d}{sinθ} \end{bmatrix} w=⎣⎢⎢⎡0sinθbsinθcsinθd⎦⎥⎥⎤
則 q q q 可以表示為:
q = c o s θ [ 1 0 0 0 ] + s i n θ w q = cosθ \begin{bmatrix} 1 \\ 0 \\ 0 \\ 0 \end{bmatrix} + sinθw q=cosθ⎣⎢⎢⎡1000⎦⎥⎥⎤+sinθw
我們將 a = c o s θ a = cosθ a=cosθ, b = s i n θ w x b = sinθw_x b=sinθwx, c = s i n θ w y c = sinθw_y c=sinθwy, d = s i n θ w z d = sinθw_z d=sinθwz (注意,這裡的 w x w_x wx 是 w w w 的第二個元素,在四維空間座標中 第一個元素 為 第四維值,即四維空間座標的表示: ( w , x , y , z ) (w, x, y, z) (w,x,y,z)),我們將 a、b、c、d 的這一表示 代入 K K K對映,得到的矩陣 與 Rodrigues 公式構造的 繞 xyz向量 w w w,旋轉 2 θ 2θ 2θ 的旋轉矩陣完全相同。
同樣,我們可以通過 Rodrigues公式 得到 四元數。
Rodrigues公式:
M
=
I
+
s
i
n
θ
J
w
+
c
o
s
θ
J
w
2
M = I + sinθJ_w + cosθJ_w^2
M=I+sinθJw+cosθJw2
之前,我們已經討論過,從 Rodrigues公式 計算得到
θ
θ
θ 和
w
w
w,那麼 就可以得到四元數:
q
=
(
c
o
s
(
θ
/
2
)
,
s
i
n
(
θ
/
2
)
w
x
,
s
i
n
(
θ
/
2
)
w
y
,
s
i
n
(
θ
/
2
)
w
z
)
q = (cos(θ/2), sin(θ/2)w_x, sin(θ/2)w_y, sin(θ/2)w_z)
q=(cos(θ/2),sin(θ/2)wx,sin(θ/2)wy,sin(θ/2)wz)
但上面我們知道 四元數有二對一的性質,即
K
(
−
q
)
=
K
(
q
)
K(-q) = K(q)
K(−q)=K(q),所以我們應該計算得到兩個結果,另一個是
−
q
=
(
−
c
o
s
(
θ
/
2
)
,
−
s
i
n
(
θ
/
2
)
w
x
,
−
s
i
n
(
θ
/
2
)
w
y
,
−
s
i
n
(
θ
/
2
)
w
z
)
-q = (-cos(θ/2), -sin(θ/2)w_x, -sin(θ/2)w_y, -sin(θ/2)w_z)
−q=(−cos(θ/2),−sin(θ/2)wx,−sin(θ/2)wy,−sin(θ/2)wz)
另外,在之前討論 尤拉角表示時,我們已經知道如何通過旋轉矩陣得到 尤拉角表示,所以 現在,這三個表示間是可以相互轉換的
球面線性插值
假設單位球上有兩點
q
1
q_1
q1 和
q
2
q_2
q2 且
q
1
≠
−
q
2
q_1 \neq -q_2
q1=−q2,即它們是非對徑點(在直徑的兩端),則它們之間存在一條唯一的最短路徑
構造一條從
q
1
q_1
q1到
q
2
q_2
q2的路徑
γ
γ
γ即
(
γ
(
0
)
=
q
1
,
γ
(
1
)
=
q
2
)
(γ(0) = q_1, γ(1) = q_2)
(γ(0)=q1,γ(1)=q2),且沿著兩點間較短弧勻速前進,這一問題稱為球面線性插值,該插值的英文為 slerp
球面線性插值這樣計算:將球面上兩點
q
1
,
q
2
q_1, q_2
q1,q2 看作 從球的球心 到 表面上該點的向量
在球上取
q
1
,
q
2
q_1, q_2
q1,q2 所在的平面,較短弧一定在該平面上(因為兩點間線段最短,而該線段對應的弧就是最短弧):
注意,這裡我們假設球是單位球,那麼
q
1
,
q
2
q_1, q_2
q1,q2 就是單位向量。我們可以得到該圓上點的公式:
v
v
v 垂直於
q
1
q_1
q1,那麼以
v
,
q
1
v, q_1
v,q1 即可構造該圓:
γ
(
t
)
=
c
o
s
(
t
)
q
1
+
s
i
n
(
t
)
v
γ(t) = cos(t)q_1 + sin(t)v
γ(t)=cos(t)q1+sin(t)v
設
θ
θ
θ 為
q
1
,
q
2
q_1, q_2
q1,q2 的夾角, 那麼,當
t
=
θ
t = θ
t=θ 時,
γ
(
θ
)
=
q
2
γ(θ) = q_2
γ(θ)=q2 (
γ
(
θ
)
γ(θ)
γ(θ) 本身就是通過將
q
1
q_1
q1 旋轉
θ
θ
θ角度 來表示圓上的點),同樣
γ
(
0
)
=
q
1
γ(0) = q_1
γ(0)=q1
這樣,我們就構造出了一個球面插值,但是一般插值都是 0~1 範圍的插值,我們可以讓
t
t
t 乘上一個
θ
θ
θ:
γ
(
t
θ
)
=
c
o
s
(
t
θ
)
q
1
+
s
i
n
(
t
θ
)
v
γ(tθ) = cos(tθ)q_1 + sin(tθ)v
γ(tθ)=cos(tθ)q1+sin(tθ)v
這樣,我們就得到了 球面線性插值公式。
剩下的問題就是如何 求解
θ
θ
θ 和
v
v
v
先來看
θ
θ
θ:
θ
θ
θ 是
q
1
,
q
2
q_1, q_2
q1,q2 的夾角,那麼之間對
q
1
,
q
2
q_1, q_2
q1,q2 的點積取反餘弦即可:
θ
=
a
r
c
c
o
s
(
q
1
⋅
q
2
)
θ = arccos(q_1 \cdot q_2)
θ=arccos(q1⋅q2)
再來看
v
v
v:
v
v
v 是垂直於
q
1
q_1
q1 的單位向量,而
q
2
q_2
q2 向
q
1
q_1
q1 的投影 也垂直於
q
1
q_1
q1:
可以得到:
v
=
n
o
r
m
a
l
i
z
e
(
q
2
−
(
q
2
⋅
q
1
)
∗
q
1
)
v = normalize(q_2 - (q_2 \cdot q_1) * q_1)
v=normalize(q2−(q2⋅q1)∗q1)
這樣我們就可以對球面線性插值進行計算啦。
旋轉插值
上面我們得到 球面線性插值後,就可以將其用來計算旋轉插值了。
四元數是
R
4
R^4
R4的單位球上的點,那麼就可以通過對 四元數 進行球面線性插值 從而對 旋轉進行插值。
首先,我們有旋轉矩陣
M
1
M_1
M1 和
M
2
M_2
M2
可以得到它倆對應的四元數:
±
q
1
\pm q_1
±q1 和
±
q
2
\pm q_2
±q2
我們一般對較小弧進行插值,即對較小的旋轉角度差進行插值,如何找到這個最小弧呢?
如圖
±
q
1
\pm q_1
±q1 是兩個對徑點,即直徑的兩個端點,
±
q
2
\pm q_2
±q2 同樣。那麼如圖我們可以得到
q
1
⋅
q
2
<
0
q_1 \cdot q_2 < 0
q1⋅q2<0 而
q
1
⋅
−
q
2
>
0
q_1 \cdot -q_2 > 0
q1⋅−q2>0,所以
q
1
q_1
q1 到
−
q
2
-q_2
−q2 就是較短弧,這樣我們就可以找到較短弧了。
找到較短弧後,我們只需要進行 球面線性插值,即可對這兩個四元數進行插值
得到插值後的四元數
q
q
q後,我們通過
K
(
q
)
K(q)
K(q) 在得到
q
q
q 對應的旋轉矩陣即可。
旋轉表示間的比較
現在我們有四種表示 3D剛性參考座標系的方式:
- 一個 4x4 矩陣 M M M,將其作用於始於原點的三個基向量,得到的是三個新的基向量,作用於原點得到新的基點 P P P,該矩陣最後一行一定是 ( 0 , 0 , 0 , 1 ) (0, 0, 0, 1) (0,0,0,1), 該矩陣左上角是一個 3x3 的旋轉矩陣 S S S
- 一個 3x3 旋轉矩陣 S S S 和 一個平移向量 t = P - 原點
- 三個尤拉角 和 一個平移向量
- 一個單位四元數 和 一個平移向量
方式1的優點是很容易將它看作一個變換,可以通過矩陣相乘將其與其它變換組合起來,在幾何建模中採用這種表示較為合適。
方式2可以和方式1 互相轉換,但 方式2 可以通過 S T S = I S^TS = I STS=I 來檢查矩陣 S S S 是否正交。如果 方式1、方式2 這類矩陣多個進行相乘,則會產生 殘差累積,可以用 Gram-Schmidt 正交化處理對結果進行調整以恢復正交形式,但計算量過大。
方式3 對於第一人稱 或者 以物體為中心的操作方式 非常合適。但是將其轉換為 矩陣 和 由矩陣轉化回來,較為麻煩。
方式4 在剛性動畫中頗受歡迎(可以進行插值)。將它轉化為 矩陣形式很容易,但由矩陣轉化回來較為麻煩,這是因為它是 二對一的對映。採用四元數表示時插值十分容易,且可以用四元數來對矩陣進行重新正交化,這樣就不需要進行 Gram-Schmidt 處理方式,計算會非常快(這一部分進階篇會專門探討,這裡只講述幾種表示間的優缺點)。
相關文章
- 計算機圖形學原理及實踐——C語言描述pdf計算機C語言
- 計算機組成原理學習 筆記一計算機筆記
- AD學習筆記----原理圖設計筆記
- 計算機圖形學之矩陣變換計算機矩陣
- JS高階程式設計第十一章.個人學習筆記JS程式設計筆記
- 工程倫理第十一章學習筆記2020最新筆記
- Mudo C++網路庫第十一章學習筆記C++筆記
- ThreadLoop實踐學習筆記threadOOP筆記
- 計算機知識學習路線及書籍筆記索引計算機筆記索引
- 圖形學學習筆記二:觀測變換筆記
- 機器學習之支援向量機原理和sklearn實踐機器學習
- 《深入理解計算機系統原理》學習筆記與習題答案(一)計算機筆記
- 計算機圖形學-線性過濾計算機
- 【學習筆記】計算幾何筆記
- 大學計算機必修課新講--編譯原理+作業系統+圖形學計算機編譯原理作業系統
- 計算機網路 - 運輸層 - 學習筆記計算機網路筆記
- 小白計算機網路學習筆記(更新中)計算機網路筆記
- [豪の學習筆記] 計算機網路#003筆記計算機網路
- 計算機圖形學 第四章 圖形變換計算機
- 計算機圖形學:虛擬和現實世界的融合計算機
- 機器學習之決策樹原理和sklearn實踐機器學習
- 計算機圖形學入門·光柵化計算機
- 機器學習之step by step實戰及知識積累筆記機器學習筆記
- 學習筆記專案實踐(python)筆記Python
- 《Golang學習筆記》error最佳實踐Golang筆記Error
- 美賽整理之Matlab的工程數學計算學習筆記(高等數學)Matlab筆記
- AQS原理學習筆記AQS筆記
- synchronized原理學習筆記synchronized筆記
- 計算機網路學習筆記:第二章計算機網路筆記
- 計算機網路傳輸層學習筆記---(四)計算機網路筆記
- 深入理解計算機系統-學習筆記 (1)計算機筆記
- 計算機組成原理學習 Part 2計算機
- 統計學習方法筆記-感知機學習方法筆記
- 4次Bezier曲線--計算機圖形學 opengl計算機
- 【動手學深度學習】第十二章筆記:非同步計算、資料並行深度學習筆記非同步並行
- GIT學習筆記——第一章Git筆記
- 機器學習學習筆記機器學習筆記
- 清華大學計算機系統課程筆記-第十一講和第十二講計算機筆記