【OpenGL】-005 四元數

【OpenGL】-005 Understanding Quaternions翻譯

  本文是對《Understanding Quaternions》(https://www.3dgep.com/understanding-quaternions/)的翻譯。

Understanding Quaternions

  本文中,將會使用便於理解的方式解釋四元數的概念,四元數的表現形式,四元數支持的操作,對比矩陣、歐拉角、四元數的區別以及可以使用四元數替代矩陣或歐拉角的場景。
P8d4Re.png

1、簡介

  在計算機圖形學中,使用變形矩陣表示空間中的位置或朝向。單獨的一個變形矩陣可以用於表示一個物體的尺度變化或裁剪。可以認爲變形矩陣式一種基礎空間,當一個向量或點與變形矩陣相乘時,表示將該向量或點放入到該變形矩陣所描述的空間中。

  本文中,不會對變形矩陣進行詳細討論,可以參考上一篇文章《Matrices》(https://www.3dgep.com/3d-math-primer-for-game-programmers-matrices/)來獲取關於矩陣的詳細信息。

  四元數的概念是愛爾蘭數學家Sir William Rowan Hamilton在1843年10月16日在都柏林提出的。Hamilton在與妻子一起去往Royal Irish Academy(愛爾蘭皇家科學院)的路上,通過Royal Canal(皇家運河)上的Brougham Bridg(布魯厄姆橋)的時候,突然有了一個戲劇性的發現,他立即將其刻在了橋上。

i 2 = j 2 = k 2 = i j k = 1

P8wYSe.jpg

2、複數

  在理解四元數之前,首先需要理解四元數的由來。四元數的概念是基於複數系統的。
   作爲常見數字集合的補充,複數系統引入了一種新的數字集合稱爲虛數。虛數主要用於求解一些沒有解的方程,例如:

x 2 + 1 = 0

  爲了求解這個表達式, x 2 = 1 必須成立,由於無論正數或負數的平方始終是正數,所以這個表達式被認爲不可能成立。
  數學家們不能接受一個表達式沒有解,所以虛數被髮明出來用於解這類表達式。
  虛數具有如下的形式:
i 2 = 1

  不要試圖去真正的理解這個表達式,因爲它是沒有邏輯原因的。只需要接收 i 是一個平方之後等於 1 的東西就行。
  虛數的集合通常使用 I 表示。
  複數的集合(使用符號 C 表示)是實數和虛數的和,形式如下:
z = a + b i a , b R , i 2 = 1

  可以將所有實數理解爲虛部 b = 0 的複數,所有虛數理解爲實部 a = 0 的複數。

2.1 複數加減法

  複數可以通過分別對實部和虛部進行加減法來執行加減法。
加法

( a 1 + b 1 i ) + ( a 2 + b 2 i ) = ( a 1 + a 2 ) + ( b 1 + b 2 ) i

減法
( a 1 + b 1 i ) ( a 2 + b 2 i ) = ( a 1 a 2 ) + ( b 1 b 2 ) i

2.2 複數與標量乘法

  複數與標量的乘法是指用該標量分別乘以複數的實部和虛部:

λ ( a + b i ) = λ a + λ b

2.3 複數乘法

  複數的乘法遵循普通代數規則。

{ z 1   = ( a 1 + b 1 i ) z 2   = ( a 2 + b 2 i ) z 1 z 2   = ( a 1 + b 1 i ) ( a 2 + b 2 i ) = a 1 a 2 + a 1 b 2 i + b 1 a 2 i + b 1 b 2 i 2 = ( a 1 a 2 b 1 b 2 ) + ( a 1 b 2 + a 2 b 1 ) i

2.4 複數平方

  複數的平方表示複數乘以它自身。

{ z = ( a + b i ) z 2 = ( a + b i ) ( a + b i ) = ( a 2 b 2 ) + 2 a b i

2.5 共軛複數

  共軛複數是指具有相同的實部,虛部是原虛部的相反數的複數,用符號 z z ¯ 表示。

{ z = ( a + b i ) z = ( a b i )

  共軛複數的乘法結果如下:
{ z = ( a + b i ) z = ( a b i ) z z = ( a + b i ) ( a b i ) = a 2 a b i + a b i + b 2 = a 2 + b 2

2.6 複數絕對值

  可以使用共軛複數來計算複數的絕對值(範數或模),複數的絕對值是該複數與其共軛複數的乘積的平方根,記爲 | z | :

{ z = ( a + b i ) | z | = z z = ( a + b i ) ( a b i ) = a 2 + b 2

2.7 複數的商

  計算兩個複數的商,可以將分子與分母分別乘以分母的共軛複數,得到計算結果。

{ z 1 = ( a 1 + b 1 i ) z 2 = ( a 2 + b 2 i ) z 1 z 2 = a 1 + b 1 i a 2 + b 2 i = ( a 1 + b 1 i ) ( a 2 b 2 i ) ( a 2 + b 2 i ) ( a 2 b 2 i ) = a 1 a 2 a 1 b 2 i + b 1 a 2 i b 1 b 2 i 2 a 2 2 + b 2 2 = a 1 a 2 + b 1 b 2 a 2 2 + b 2 2 + b 1 a 2 a 2 b 1 a 2 2 + b 2 2 i

3、 i 的冪

  因爲 i 2 = 1 ,所以 i 的其他次冪可以按如下計算:

{ i 0 = 1 i 1 = i i 2 = 1 i 3 = i i 2 = i i 4 = i 2 i 2 = 1 i 5 = i i 4 = i i 6 = i i 5 = i 2 = 1

  如果繼續計算,結果符合以下規律:
( 1 , i , 1 , i , 1 , )

   i 的負次冪也滿足類似的規律:
{ i 0 = 1 i 1 = i i 2 = 1 i 3 = i i 4 = 1 i 5 = i i 6 = 1

  在二維笛卡爾座標平面中,通過不斷逆時針旋轉90°,可以得到行如 ( x , y , x , y , x , ) 的序列。通過順時針方向旋轉90°,可以得到行如 ( x , y , x , y , x , ) 的序列。
P8fC3n.png

4、複平面

  通過將實部映射到水平軸,虛部映射到垂直軸,可以將複數映射到二維平面中,稱之爲複平面。

P8fEHU.png
  觀察前面所講到的序列,可以認爲一個複數乘以 i 表示將該複數在複平面中逆時針旋轉90°。
  驗證如下。
  複平面中任意一點 p ,

p = 2 + i

  將 p 乘以 i 得到 q
{ p = 2 + i q = p i = ( 2 + i ) i = 2 i + i 2 = 1 + 2 i

  將 q 乘以 i 得到 r
{ q = 1 + 2 i r = q i = ( 1 + 2 i ) i = i + 2 i 2 = 2 i

  將 r 乘以 i 得到 s
{ r = 2 i s = r i = ( 2 i ) i = 2 i i 2 = 1 2 i

  將 s 乘以 i 得到 t
{ s = 1 2 i t = s i = ( 1 2 i ) i = i 2 i 2 = 2 + i

  此時 t 精確的回到了起點 p .將結果在複平面中畫出來,可以得到如下的結果。
P8f7aF.png
  通過將複數乘以 i ,可以得到順時針旋轉的序列。

4.1 旋轉因子

  定義複平面中的旋轉因子 q

q = c o s θ + i s i n θ

  任意的複數乘以旋轉因子 q
{ p = a + b i q = c o s θ + i s i n θ p q = ( a + b i ) ( c o s θ + i s i n θ ) a + b i = a c o s θ b s i n θ + ( a s i n θ + b c o s θ ) i

  也可以寫成如下的形式:
[ a b b a ] = [ c o s θ s i n θ s i n θ c o s θ ] [ a b b a ]

  上式表示在複平面中繞原點逆時針旋轉任意點。

5、四元數

  在以上關於複數和複平面的基礎上,可以通過在複數的虛數中添加另外兩個虛部,從而將點擴充值三維空間中。
  四元數的通用表達形式如下:

q = s + x i + y j + z k   s , x , y , z R

  通過Hamilton著名的表達式:
i 2 = j 2 = k 2 = i j k = 1

並且
i j = k j k = i k i = j j i = k k j = i i k = j

  從上可以看出 i , j , j 之間的關係類似於笛卡爾座標系下的單位向量的叉乘:
x × y = z y × z = x z × x = y y × x = z z × y = x x × z = y

  Hamiltion注意到 i , j , k 可以用來表示笛卡爾座標系下的單位向量 i , j , k , i 2 = j 2 = k 2 = 1 .
P84c1s.png
  上圖表示了笛卡爾座標系下的單位向量 i , j , k 的關係。

5.1 四元數的有序偶形式

  可以將四元數表示成有序偶形式:

q = [ s , v ]   s R , v R 3

  其中 v 也可以用它的獨立分量表示:
q = [ s , x i + y j + z k ]   s , x , y , z R

  用以上形式,可以更方便的對比四元數與複數之間的相似性。

5.2 四元數的加減法

  四元數的加減法類似於複數的加減法。

q a = [ s a , a ] q b = [ s b , b ] q a + q b = [ s a + s b , a + b ] q a q b = [ s a s b , a b ]

5.3 四元數乘法

  同樣可以計算四元數的乘法:

q a = [ s a , a ] q b = [ s b , b ] q a q b = [ s a a ] [ s b , b ] = ( s a + x a i + y a j + z a k ) ( s b + x b i , y b j + z b k ) = ( s a s b x a x b y a y b z a z b ) + ( s a x b + s b x a + y a z b y b z a ) i + ( s a y b + s b y a + z a x b z b x a ) j + ( s a z b + s b z a + x a y b x b y a ) k

  計算結果是一個新的四元數。將虛部 i , j , k 用有序偶的形式表示:
i = [ 0 , i ]   j = [ 0 , j ]   k = [ 0 , k ]

  代入上式,同時認爲 [ 1 , 0 ] = 1
[ s a , a ] [ s b b ] = ( s a s b x a x b y a y b z a z b ) [ 1 , 0 ] + ( s a x b + s b x a + y a z b y b z a ) [ 0 , i ] + ( s a y b + s b y a + z a x b z b x a ) [ 0 , j ] + ( s a z b + s b z a + x a y b x b y a ) [ 0 , k ]

  將表達式擴充成一組有序偶的和的形式:
[ s a , a ] [ s b , b ] = [ s a s b x a x b y a y b z a z b , 0 ] + [ 0 , ( s a x b + s b x a + y a z b y b z a ) i ] + [ 0 , ( s a y b + s b y a + z a x b z b x a ) j ] + [ 0 , ( s a z b + s b z a + x a y b x b y a ) k ]

  執行四元數單位向量乘法並提取同類型,可以將上式重寫成如下形式:
[ s a , a ] [ s b , b ] = [ s a s b x a x b y a y b z a z b , 0 ] + [ 0 , s a ( x b i + y b j + z b k ) + s b ( x a i + y a j + z a k ) + ( y a z b y b z a ) i + ( z a x b z b x a ) j + ( x a y b x b y a ) k ]

  上式給出了兩個有序偶的和,其中第一個是一個實四元數,第二個是一個虛四元數。這兩個有序偶可以組合成一個有序偶:
[ s a , a ] [ s b , b ] = [ s a s b x a x b y a y b z a z b , s a ( x b i + y b j + z b k ) + s b ( x a i + y a j + z a k ) + ( y a z b y b z a ) i + ( z a x b z b x a ) j + ( x a y b x b y a ) k ]

  代入:
a = x a i + y a j + z a k b = x b i + y b j + z b k a b = x a x b + y a y b + z a z b a × b = ( y a z b y b z a ) i + ( z a x b z b x a ) j + ( x a y b x b y a ) k

  可得:
[ s a , a ] [ s b , b ] = [ s a s b a b , s a b + s b a + a × b ]

  上式是四元數乘法的通用表達式。

5.4 實四元數

  實四元數是帶有 0 向量的四元數。

q = [ s , 0 ]

  兩個實四元數的乘積是另一個實四元數。
q a = [ s a , 0 ] q b = [ s b , 0 ] q a q b = [ s a , 0 ] [ s b , 0 ] = [ s a s b , 0 ]

  這類似於兩個虛部爲0的複數的乘法:
z 1 = a 1 + 0 i z 2 = a 2 + 0 i z 1 z 2 = ( a 1 + 0 i ) ( a + 2 + 0 i ) = a 1 a 2

5.5 四元數與標量乘法

  四元數與標量的乘法遵守如下規則:

q = [ s , v ] λ q = λ [ s , v ] = [ λ s , λ v ]

  可以通過將標量視爲一個實四元數的形式來驗證:
q = [ s , v ] λ = [ λ , 0 ] λ q = [ λ , 0 ] [ s , v ] = [ λ s , λ v ]

5.6 純四元數

  與實四元數類似,Hamiltion將純四元數定義爲標量部分爲0的四元數。

q = [ 0 , v ]

  或寫成分量形式:
q = x i + y j + z k

  可以執行兩個純四元數的乘法如下:
q a = [ 0 , a ] q b = [ 0 , b ] q a q b = [ 0 , a ] [ 0 , b ] = [ a b , a × b ]

5.7 四元數的加法形式

  可以將任意四元數表示成一個實四元數與一個純四元數的加法:

q = [ s , v ] = [ s , 0 ] + [ 0 , v ]

5.8 單位四元數

  對任意一個矢量 v ,可以將其表示成它的標量模和它的方向:

v = v v ^   w h e r e   v = | v |   a n d   | v ^ | = 1

  將純四元數的概念與上式相結合,可得:
q = [ 0 , v ] = [ 0 , v v ^ ] = v [ 0 , v ^ ]

  單位四元數是標量部分爲0,且矢量部分是單位向量的四元數。
q ^ = [ 0 , v ^ ]

5.9 四元數的二元形式

  將單位四元數與四元數的加法形式相結合,可以得到一種類似於複數表現形式的表示四元數的方式:

q = [ s , v ] = [ s , 0 ] + [ 0 , v ] = [ s , 0 ] + v [ 0 , v ^ ] = s + v q ^

  上式提供了一種類似於複數表示方式的方法來表示四元數:
z = a + b i q = s + v q ^

5.10 共軛四元數
  共軛四元數可以通過將矢量部分取反得到:

q = [ s , v ] q = [ s , v ]

  一對共軛四元數的乘積:
q q = [ s , v ] [ s , v ] = [ s 2 v v , s v + s v + v × v ] = [ s 2 + v v , 0 ] = [ s 2 + v 2 , 0 ]

5.11 四元數的範數

  類似於複數的範數的計算方式:

| z | = a 2 + b 2 z z = | z | 2

  四元數的範數或模的計算方法定義如下:
q = [ s , v ] | q | = s 2 + v 2

  四元數的範數可表示成:
q q = | q | 2

5.12 四元數歸一化

  可以使用四元數的範數來對四元數進行歸一化。四元數的歸一化是指四元數除以它的模 | q |

q = q s 2 + v 2

  例子:歸一化以下四元數:
q = [ 1 , 4 i + 4 j 4 k ]

  首先,計算該四元數的模:
| q | = 1 2 + 4 2 + 4 2 + ( 4 ) 2 = 49 = 7

  然後,將四元數除以它的模,得到歸一化的四元數:
q = q | q | = 1 + 4 i + 4 j 4 k 7 = 1 7 + 4 7 i + 4 7 j 4 7 k

5.13 四元數的逆

  四元數的逆記爲 q 1 。四元數的逆等於該四元數的共軛四元數除以模的平方:

q 1 = q | q | 2

  證明過程如下:
q q 1 = [ 1 , 0 ] = 1

  兩邊同時乘以共軛四元數:
q q q 1 = q

  代入後可得:
| q | 2 q 1 = q

q 1 = q | q | 2

  對於單位模長的四元數其模長爲1,那麼:
q 1 = q

5.14 四元數的點乘

  類似於複數的點乘,四元數的點乘可以按如下規則計算:

q 1 = [ s 1 , x 1 i + y 1 j + z 1 k ]

q 2 = [ s 2 , x 2 i + y 2 j + z 2 k ]

q 1 q 2 = s 1 s 2 + x 1 x 2 + y 1 y 2 + z 1 z 2

  可以使用四元數的點乘來求兩個四元數之間的夾角:
相關文章
相關標籤/搜索