《計算機圖形學原理及實踐》學習筆記之第十一章

白菊花瓣、發表於2020-12-11

第十一章 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=(2xn)n
於是 x ′ = ( 2 x ⋅ n ) ∗ n − x x' = (2x \cdot n) * n - x x=(2xn)nx
x n = − x ′ = x − ( 2 x ⋅ n ) ∗ n x_n = -x' = x - (2x \cdot n) * n xn=x=x(2xn)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} I2nnT=12nx22nxny2nxnz02nxny12ny22nynz02nxnz2nynz12nz200001
不好記,直接記 I − 2 n n T I - 2nn^T I2nnT 就完事兒了, 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θ0sinθ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θ0sinθ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θ0sinθ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φ0sinφcosφcosθ0sinθ010sinθ0cosθcosΦsinΦ0sinΦ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(m11m12)
同樣的方式可以通過 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=0wzwywz0wxwywx0
我稱之為 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+(1cosθ)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+(1cosθ)JwJww=w+0+(1cosθ)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+wxwzvzwy2vx+wxwyvy=vx(wz2+wy2)+wx(wzvz+wyvy)=vx(1wx2)+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+(1cosθ)w×(w×v)=v+sin(θ)w×v+(1cosθ)(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)+(1cosθ)tr(Jw2)=3+(1cosθ)(2(wx2+wy2+wz2))=1+2cosθ
所以得 θ = c o s − 1 ( t r ( M ) − 1 2 ) θ = cos^{-1}(\frac{tr(M) - 1}{2}) θ=cos1(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) MMT=I+sin(θ)Jw+(1cos(θ))Jw2(IT+sin(θ)JwT+(1cos(θ))(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 MMT=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+b2c2d22(ad+bc)2(bdac)2(bcad)a2b2+c2d22(ab+cd)2(ac+bd)2(cdab)a2b2c2+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(q1q2)
在這裡插入圖片描述

再來看 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(q2q1)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 q1q2<0 q 1 ⋅ − q 2 > 0 q_1 \cdot -q_2 > 0 q1q2>0,所以 q 1 q_1 q1 − q 2 -q_2 q2 就是較短弧,這樣我們就可以找到較短弧了。
找到較短弧後,我們只需要進行 球面線性插值,即可對這兩個四元數進行插值
得到插值後的四元數 q q q後,我們通過 K ( q ) K(q) K(q) 在得到 q q q 對應的旋轉矩陣即可。

旋轉表示間的比較

現在我們有四種表示 3D剛性參考座標系的方式:

  1. 一個 4x4 矩陣 M M M,將其作用於始於原點的三個基向量,得到的是三個新的基向量,作用於原點得到新的基點 P P P,該矩陣最後一行一定是 ( 0 , 0 , 0 , 1 ) (0, 0, 0, 1) (0,0,0,1), 該矩陣左上角是一個 3x3 的旋轉矩陣 S S S
  2. 一個 3x3 旋轉矩陣 S S S 和 一個平移向量 t = P - 原點
  3. 三個尤拉角 和 一個平移向量
  4. 一個單位四元數 和 一個平移向量

方式1的優點是很容易將它看作一個變換,可以通過矩陣相乘將其與其它變換組合起來,在幾何建模中採用這種表示較為合適。

方式2可以和方式1 互相轉換,但 方式2 可以通過 S T S = I S^TS = I STS=I 來檢查矩陣 S S S 是否正交。如果 方式1、方式2 這類矩陣多個進行相乘,則會產生 殘差累積,可以用 Gram-Schmidt 正交化處理對結果進行調整以恢復正交形式,但計算量過大。

方式3 對於第一人稱 或者 以物體為中心的操作方式 非常合適。但是將其轉換為 矩陣 和 由矩陣轉化回來,較為麻煩。

方式4 在剛性動畫中頗受歡迎(可以進行插值)。將它轉化為 矩陣形式很容易,但由矩陣轉化回來較為麻煩,這是因為它是 二對一的對映。採用四元數表示時插值十分容易,且可以用四元數來對矩陣進行重新正交化,這樣就不需要進行 Gram-Schmidt 處理方式,計算會非常快(這一部分進階篇會專門探討,這裡只講述幾種表示間的優缺點)。

相關文章