通俗的解釋歐拉角,之後為何要引入四元數?

最近在學習人體工學自由度的問題,裡面需要理解歐拉角和四元數相關的概念,但是對於這些沒有接觸的數學知識網上的信息不太能理解


為何要引入四元數?首先是因為歐拉角有萬向節死鎖的問題。

3D遊戲或者3D電影中,比如黑客帝國中酷炫的旋轉是怎麼實現的?

旋轉的演算法有很多,這裡主要介紹其中一種:歐拉角。

1 歐拉角

1.1 歐拉角的演算法思想是什麼

陌生的你來到了成都,站在鹽市口茫然四顧,想知道春熙路怎麼走?

這個時候你選擇了去問路,得到了兩種回答:

  • 往東經104°04′、北緯30°40′走
  • 右轉後一直走

第一種回答,告訴了你春熙路的絕對坐標,可是很反人類啊!

第二種回答,告訴了你春熙路的相對坐標,很具有操作性。

歐拉角演算法的思想就是採用的第二種回答的方式,優點在於很好理解。

1.2 具體實現步驟

維基百科 中,有這麼一副動圖,清楚的表明了如何通過歐拉角來完成旋轉:

具體來拆解下旋轉步驟,先看圖:

圖中有兩組坐標:

  • xyz 為全局坐標,保持不動
  • XYZ 為局部坐標,隨著物體一起運動

旋轉步驟如下:

  • 物體繞全局z 軸旋轉 alpha
  • 繼續繞自己X 軸(也就是圖中的 N 軸)旋轉 eta
  • 最後繞自己Z 軸旋轉 gamma

這裡有一副動圖很直觀的展示了旋轉過程(角度標記的有點不一樣: psi 對應 alpha 	heta 對應 eta phi 對應 gamma ),圖來自gfycat:

可能你感到奇怪,為什麼第一步是繞著全局坐標旋轉?因為要和世界保持聯繫,否則就和世界完全沒有關係了。

還不理解?沒有關係,自己動手試試(有三個可以操作的點,分別對應三個角度):

此處有互動內容,點擊此處前往操作。

很顯然,按照不同的旋轉步驟,旋轉的結果是不一樣的。

就好比剛才問路的時候,回答你,「左轉再右轉」,和「右轉再左轉」,肯定到達的地點是不一樣的。

我們需要把上面的旋轉步驟按照順序標記為 zXZ ,加上角度就是一個完整的歐拉角:

zXZ-(alpha , eta , gamma )

2 萬向節死鎖(Gimbal Lock)

局部坐標是很直觀,但是導致歐拉角有一個重大缺陷,萬向節死鎖!

本節大部分參考了博文: 歐拉角與萬向節死鎖(圖文版) ,博主: andrewfan 。

2.1 什麼是萬向節(Gimbal)

平衡環架(英語:Gimbal)為一具有樞紐的裝置,使得一物體能以單一軸旋轉。由彼此垂直的樞紐軸所組成的一組三隻平衡環架,則可使架在最內的環架的物體維持旋轉軸不變,而應用在船上的陀螺儀、羅盤、飲料杯架等用途上,而不受船體因波浪上下震動、船身轉向的影響。

----維基百科

長這個樣子:

中間有一根豎軸,穿過一個金屬圓盤。金屬圓盤稱為轉子,豎軸稱為旋轉軸。轉子用金屬製成,應該是了增加質量,從而增大慣性。豎軸外側是三層嵌套的圓環,它們互相交叉,帶來了三個方向自由度的旋轉。

看著不停轉來轉去,有點暈,接下來看下靜態的。圖來自百度百科:

2.2 歐拉角與萬向節

其實歐拉角的工作方式與萬向節幾乎一樣。

看幾幅動圖就知道(圖來自 Euler Angle Class )。

這個旋轉叫pitch,中文是俯仰:

這個旋轉叫Yaw,中文叫偏航:

這個旋轉叫Roll,中文叫桶滾:

可以看出,確實工作方式和萬向節一樣。

2.3 死鎖的產生

為了解釋清楚問題,畫了一個簡單的萬向節示意圖(金屬圓盤就省略了,丑點兒也就別管了):

把三個Gimbal環用不同的顏色做了標記,底部三個軸向,RGB分別對應 XYZ

假設現在這個萬向節被放在一艘船上,船頭的方向沿著+Z軸,也就是右前方。

2.3.1 桶滾

現在假設,船體發生了搖晃,是沿著前方進行旋轉的搖晃,也就是桶滾。由於轉子和旋轉軸具有較大的慣性,只要沒有直接施加扭矩,就會保持原有的姿態。由於上圖中綠色的活動的連接頭處是可以靈活轉動的,此時將發生相對旋轉,從而出現以下的情形:

2.3.2 俯仰

再次假設,船體發生了pitch搖晃,也就是俯仰。同樣,由於存在相應方向的可以相對旋轉的連接頭(紅色連接頭),轉子和旋轉軸將仍然保持平衡,如下圖:

2.3.3 偏航

最後假設,船體發生了yaw搖晃,也就是偏航,此時船體在發生水平旋轉。相對旋轉發生在藍色連接頭。如下圖:

最終,在船體發生Pitch、Yaw、Roll的情況下,萬向節都可以通過自身的調節,而讓轉子和旋轉軸保持平衡。

2.3.4 死鎖

現在看起來,這個萬向節一切正常,在船體發生任意方向搖晃都可以通過自身調節來應對。然而,真的是這樣嗎?

假如,船體發生了劇烈的變化,此時船首仰起了90度(這是要翻船的節奏。。。。),此時的陀螺儀調節狀態如下圖:

此時,船體再次發生轉動,沿著當前世界坐標的+Z軸(藍色軸,應該正指向船底)進行轉動,那麼來看看發生了什麼情況:

現在,轉子不平衡了,萬向節的三板斧不起作用了。它失去了自身的調節能力。那麼這是為什麼呢?

之前萬向節之所以能通過自身調節,保持平衡,是因為存在可以相對旋轉的連接頭。在這種情況下,已經不存在可以相對旋轉的連接頭了。

那麼連接頭呢?去了哪裡?顯然,它還是在那裡,只不過從上圖中,我們清楚地看到:

  • 紅色連接頭:可以給予一個相對俯仰的自由度。
  • 綠色連接頭:可以給予一個相對偏航的自由度。
  • 藍色連接頭:可以給予一個相對偏航的自由度。

沒錯,三個連接頭,提供的自由度只對應了俯仰和偏航兩個自由度,桶滾自由度丟失了。

我們可以回頭去試試之前的 操作頁面 ,在下面這樣子的情況下其實就是死鎖了:

3 視頻

還不懂?沒有關係,這裡還有做得非常好的視頻,以供參考:

視頻封面歐拉角旋轉以及萬向節死鎖_騰訊視頻v.qq.com視頻

我對視頻主要內容總結如下:

  • 萬向節死鎖的根源在於歐拉角的定義方式
  • 萬向節死鎖的結果,不是說不能旋轉了,而是會導致旋轉不自然
  • 要規避萬向節死鎖,需要選擇合適的旋轉順序(有12種旋轉順序)

4 總結

在編程中很難規避死鎖問題,所以現在很多時候都使用四元數實現旋轉,四元數那又是另外的話題了。


簡單說一下三維旋轉群 SO(3) 和四元數的關係。

1,對於轉動群 SO(n) 的不可約投影表示 Pi:G	o PU(H) ,我們希望通過它的universal cover left( Phi,	ilde{G} 
ight) 來得到正常表示 Sigma:	ilde{G}	o U(H) ,且 PicircPhi=PcircSigma 。其中 P:U(H)	o PU(H)

2,為了達到這個目的,我們希望有如下正合列:

1	o Z_2	o Spin(n)	o SO(n)	o 1 ,當 n>2Spin(n) 為單連通Lie群,其為 SO(n)的universal cover。

3,為了達到我們之前的目的,我們考慮 n 維內積空間 V (其內積為: Q(v)=phi(v,v) ) 上的張量代數 T(V)=igoplus_{n=0}^{infty}T^{n}(V) ,而對於某個代數,我們可以很自然的考慮其模掉理想之後的商代數,來生成新的代數。如果模掉 votimes v ,就可以得到exterior algebra;模掉 votimes w-wotimes v ,就可以得到symmetric algebra。這裡我們模掉 votimes v-Q(v)cdot 1 ,由此可以得到Clifford algebra:Cl(n)

4,考慮 dim(V)=3 的情況,選取其上一組單位正交基: e_1,e_2,e_3 ,此時我們可以得到 Cl^k0leq k leq n )的基底分別為:

Cl^0:1

Cl^1:e_1,e_2,e_3

Cl^2:e_1e_2,e_2e_3,e_1e_3

Cl^3:e_1e_2e_3

很顯然,作為矢量空間: Cl(V)simeqigwedge(V) 。令, 1=e_0,i=e_1,j=e_2,k=e_3 ,可以發現,四元數 mathbb{H}simeq Cl^0oplus Cl^1

5,對於上面 dim(V)=3 時的 Cl^2(V) ,容易證明其,在Lie括弧 [u,v]=uv-vu 下構成Lie代數,且 mathfrak{spin}(3)=Cl^2(V)simeq mathfrak{so}(3)simeqmathfrak{su}(2) 。由此,我們可以利用指數映射我們可以生成Lie群 :Spin(3)=Pin(3)cap Cl^{even} ,其為 SO(3) 的universal cover。Phi:Spin(3)	o SO(3)的核為 {I,-I} 。這個同態的具體表達形式為: Phi(a)v=ava^t,forall ain Spin(3),vin V 。這可看做是 Spin(n)Cl^1=V 上的表示,稱為矢量表示。對於 n=3 的情況,三維空間中的旋轉可以通過,四元數 mathbb{H} 之間的乘法來完成。

6,物理上,考慮洛倫茲群,gamma矩陣 gamma^mu 可以構成 Cl^1 的一組基底。此時 mathfrak{spin}^+(3,1)simeqmathfrak{so}^{+}(3,1) ,我們可以利用 gamma^mu 構造洛倫茲群的Lie代數: S^{mu
u}=frac{i}{4}[gamma^mu,gamma^
u] 。同流形上的微分形式類似,我們可以嘗試取 V=T_xM ,把這些東西搬到流形 M 上,去定義所謂的spin structures。


歐拉角一般是指在三維空間通過指定與三個旋轉軸相關聯的三個角度來最小參數化SO(3)以表示任意方向的方法。這是這個回答里最難看懂的一句話,也是最沒用的一句話。

歐拉角是用來表示三維坐標系中方向方向變換的。要指出,我們平時說的歐拉角其實還可以細分為歐拉角(Euler-angles)和泰特布萊恩角(Tait-Bryan-angles),這兩種方法都利用了笛卡爾坐標系的三軸作為旋轉軸,主要區別在於選取順序。歐拉角的選取順序有 (x, y, x), (x, z, x), (y, x, y), (y, z, y), (z, x, z), (z, y, z) 這6種,可見選取順序是a,b,a這樣的順序,也就是繞a軸旋轉某角度後,繞新生成的b軸旋轉一個角度,最後繞兩次旋轉以後的a軸再旋轉一個角度,以此表示最終的方向。泰特布萊恩角的旋轉軸選取有 (x, y, z), (x, z, y), (y, x, z), (y, z, x), (z, x, y), (z, y, x) 這6種,也就是歷遍笛卡爾坐標系的三軸,比如我們最常見到的Roll-Pitch-Yaw角就是其中 (x,y,z) 的情況。但這兩種方法,其實都是在空間中用最直觀的方式和最少的參數表示任意方向的通用方法,用它們表示方向沒有計算要求和容量需求的區別。

下面來簡單解釋一下這種表示方法。其實最簡單和直觀的解釋只要一張維基百科上的圖就夠了:

圖中演示的就是用 (z,x,z 方法表示方向的過程。在此過程中,有如下圖展示的 alpha,eta,gamma 三個角,分別繞著原坐標z軸(藍),一次旋轉以後的x軸(綠)以及兩次旋轉以後的z軸(紅)旋轉,最終產生的紅色坐標系即表示出目標方向。

這個過程中新生成的坐標系 left(egin{matrix}X \Y \Zend{matrix}
ight) 可以通過運算由原坐標系 left(egin{matrix}x \y \zend{matrix}
ight) 得到:

left(egin{matrix}X \Y \Zend{matrix}
ight) = Mleft(egin{matrix}x \y \zend{matrix}
ight)

其中,矩陣M表示了上面三次旋轉的總過程。我們簡單推一下:

M = Rot(z,alpha)cdot Rot(x,eta)cdot Rot(z,gamma) = left( egin{matrix}cosgammasingamma0\-singammacosgamma0 \001end{matrix}
ight)left(egin{matrix}100\0cosetasineta \0-sinetacosetaend{matrix}
ight)left( egin{matrix}cosalphasinalpha0\-sinalphacosalpha0 \001end{matrix}
ight)

M = left(egin{matrix} cosalpha cosgamma-sinalpha coseta singamma sinalpha cosgamma+cosalpha coseta singamma  sineta singamma\ -cosalpha singamma-sinalpha coseta cosgamma -sinalpha singamma+cosalpha coseta cosgamma sineta cosgamma\ sinalpha sineta  -cosalpha sineta coseta end{matrix}
ight)

(說好的簡單推一下,打這式子出來就累得夠嗆。。)

當然,這是歐拉角 (z,x,z) 的情況,大家如果感興趣,可以去畫畫看其他的歐拉角和泰特布萊恩角,也可以試著去推一推公式,我們可以看出,無論哪種表示方式,記錄這樣一個變換,至少需要三個角的sine和cosine值,也就是一共存儲6個單位數據。至於為什麼要考慮存儲單位問題,我們後面再作解釋。

我們說過,用歐拉角表示方向(或者說,方向變換)只需要用到三個參數,即三個旋轉角度(因為坐標軸是旋轉軸,所以不用增加特別的參數描述旋轉軸),這樣做有一個非常大的優點,就是表述清晰易懂。但隨之而來的有一個很重要的問題,就是Ambiguity(歧義問題?我不太清楚中文表述應該是什麼),簡單來說就是,當給定了歐拉角以後,我們很容易找到歐拉角表述的方向,但是當我們獲得了一個方向以後,卻不一定能反推回目標歐拉角(在這裡用「反推」一詞不是非常恰當,其實多數情況我們都是先得到方向再去推測計算歐拉角來表述它),原因很簡單,三維空間中的任意一個方向都可以通過至少兩種不同歐拉角表示。舉個很過分的例子,當我們想要利用 (z,x,z) 歐拉角表示原坐標方向的時候(真的是很過分的例子,這不僅是Ambiguity,同時也是一個singularity奇點,這裡只是用來更直觀地反應問題),我們可以簡單地寫成 (0,0,0) ,同時也可以寫成 (frac{2pi}{3},0,-frac{2pi}{3}) (作為補充:由於此時 eta 是0,所以只要 alphagamma 的和為0,都可以表示出這個方向,此時旋轉矩陣M的行列式為0,也就是說在滿足 eta 是0的情況下的任何方向都有無數多種表示方法,這就是一種singularity的情況,會產生這種情況也是歐拉角的一個缺點),然而在沒有其他條件的約束的情況下,我們並不確定此時哪一種歐拉角的表述更為合理。

為了規避Ambiguity的問題,我們給出另一種表述方向的方法:軸角表示(Axis-Angle-Representation)。跟歐拉角不同的是,我們這次不再採取多次旋轉的方式來找到目標方向,而是找到一根旋轉軸,只通過繞這根軸旋轉一次就可以得到目標方向。這樣就不會產生Ambiguity了嗎?是的,證明方法很簡單,首先以目標矩陣原點為一角,三軸為三邊建立一個立方體,這個立方體中通過原點的對角線就是我們要找的旋轉軸,顯然,這個旋轉軸是唯一的,而我們知道,繞一個旋轉軸旋轉不同角度,對應的方向也是不同的(角度範圍 left(-pi, pi
ight] ),由此可見,空間中任一位置的軸角表示是唯一的,不存在Ambiguity的問題。旋轉軸我們可以通過向量 left[egin{matrix}x\y\zend{matrix}
ight] 來表示,旋轉角度我們可以通過一個度數 	heta 來表示,至此我們可以通過軸角表示 (axis, angle) = left(left[egin{matrix}x\y\zend{matrix}
ight],	heta
ight) 來描述方向。

一般來說,軸角表示方向時,會出現4個參數,其中3個用於表示旋轉軸,1個用於表示旋轉角大小。而如果我們規定了表示旋轉軸的向量為單位向量 e ,考慮到 sqrt{x^2+y^2+z^2}=1 ,我們就可以用兩個參數表示出旋轉軸,總共只需要三個參數,跟歐拉角一樣多。旋轉向量我們可以用 m{	heta} = 	heta e 表示,其中 e 是單位向量。順便提一句,這裡的旋轉軸我們稱為歐拉軸(Euler axis),這裡的旋轉向量我們稱為歐拉向量(Euler vector)。是的,全是這個人自己在玩兒。

現在我們可以說說四元數了。我們引入四元數是為了更方便地計算軸角表示的方向變換。四元數是什麼?四元數是複數,更具體地說四元數是存在三個虛部的複數。q = w + ix + jy +kz ,其中i,j,k是虛數單位,滿足 i^2=j^2=k^2 = -1 ,且 icdot j=kj cdot i=-k 。為了讓大家更直觀地明白用四元數運算的優點,我們簡單回顧一下高中學的複數運算。

加法

q_1+q_2 = (w_1 + w_2) + i(x_1+x_2) + j(y_1 + y_2) + k(z_1 + z_2) = [(w_1 + w_2), (v_1 + v_2)]

乘法

q_1cdot q_2 = (w_1w_2-x_1x_2-y_1y_2-z_1z_2)+\i(w_1x_2+x_1w_2+y_1z_2-z_1y_2)+\j(w_1y_2-x_1z_2+y_1w_2+z_1x_2)+\k(w_1z_2+x_1y_2-y_1x_2+z_1w_2)

將四元數用於計算軸角表示運算時,我們通常寫成向量形式(vector representation) q = [w,vec{v}] = left[w,left(egin{matrix}x\y\zend{matrix}
ight)
ight],為了表達清晰和計算方便,我們將w,x,y,z的取值定位 w^2+x^2+y^2+z^2 = 1 ,並稱之為單位四元數,在方向計算時單位四元數中w,x,y,z分飾的角色我們後面會解釋。此時,複數乘法可表示為向量形式

q_1cdot q_2 = [w_1, vec{v_1}]cdot[w_2, vec{v_2}] = [w_1w_2-v_1v_2,v_1	imes v_2 + w_1cdot v_2+w_2cdot v_1]

要注意這裡出現的向量叉乘沒有交換率。

同時,我們也可以將乘法寫成矩陣形式,以用於和歐拉角計算作比較:

q_1q_2 = left[egin{matrix} w_1-x_1  -y_1  -z_1\ x_1  w_1  -z_1  y_1\ y_1  z_1  w_1  -x_1\ z_1  -y_1  x_1  w_1 end{matrix}
ight]left[egin{matrix} w_2\x_2\y_2\z_2 end{matrix}
ight]

觀察此式,我們發現兩個四元數相乘,需要存儲8個單位數據,也就是說,每個參與運算的四元數只要存儲4個單位數據 (w,x,y,z)即可。

此外我們還需要幾個特殊量和性質:

  • 四元數的模: |q | = sqrt{w^2+x^2+y^2+z^2}
  • 四元數共軛: q^*=(w+ix+jy+kz)^*=w-ix-jy-kz
  • 共軛的向量形式: q^* = ([w, vec{v}])^* = [w,-vec{v}]
  • 四元數倒數: qcdot q^{-1} = q^{-1}cdot q = 1
  • 共軛與倒數的關係: q^{-1} = frac{q^*}{w^2+x^2+y^2+z^2} 可見對於單位四元數 q^* = q^{-1}
  • 共軛與倒數的性質: (q_aq_b)^{-1} = q_b^{-1}q_a^{-1}(q_aq_b)^* = q_b^*q_a^*
  • 四元數運算同時滿足結合律和分配律:

(q_1+q_2)+q_3 = q_1+(q_2+q_3)

(q_1q_2)q_3 = q_1(q_2q_3)

(q_1+q_2)q_3 = q_1q_3+q_2q_3

q_1(q_2+q_3) = q_1q_2+q_1q_3

了解了上面的計演算法則,我們就可以利用四元數來計算方向變換過程了。還記得我們之前說過計算時四元數我們用向量形式表示,且保證它是單位四元數嗎?其實四元數的向量形式我們還可以進一步改寫為極形式(polar representation)

q = |q|[cos	heta, vec{n}cdot sin	heta]

其中 |q| 代表了四元數的模,單位四元數模為1,而 	heta 是四元數表示的旋轉過程的半形大小,也就是說(2	heta) 就是旋轉角大小n 則是表示旋轉軸方向的單位向量。用這種表示方法,四元數即可表示任意軸角表達的方向變換。方向變換的計算方法我們這裡給出結論,大家可以自己通過計算來驗證一下,如有興趣也可以推導一下過程:

先將原向量坐標表示為四元數 p=[0,vec{v}] ,將旋轉角度及旋轉軸表示為單位四元數 q ,旋轉後的向量坐標可通過 r = qcdot pcdot q^*r = q cdot pcdot q^{-1} 計算得出。

至此,四元數算是正式引入完了,下面我們來看看為什麼我們要引入四元數。

先說結論,四元數的引用是為了減少計算量和計算時存儲佔用的空間

但是,如果你足夠細心,一定可以發現兩個四元數相乘的過程其實是一個4×4矩陣與一個4×1矩陣相乘的過程,而四元數計算一次變換需要兩次這個過程,其中包括24次加法運算和32次乘法運算,反觀歐拉角的矩陣變換隻要進行一次3×3矩陣和3×1矩陣的乘法運算,其中包括6次加法運算和9次乘法運算,運算量明顯是四元數更大一些。如果你再細心一些可以發現,四元數運算時雖然有個4×4矩陣參與運算,但是矩陣中的每一項都是已經存儲過的單位數據,而參與歐拉角運算的3×3矩陣則要通過另外已存儲的單位數據進行的16次乘法運算,4次加法運算以及4次符號改變運算來求出,不過即使加上這些運算過程,矩陣運算也只要25次乘法運算,10次加法運算以及4次符號改變運算,運算量上來說,歐拉角的矩陣運算依然比四元數運算要有優勢

但事實上,我們一般遇到的運動學問題很少會有隻做一次方向轉換的情況出現,對於複雜的系統和機器人來說,我們往往會面對數量龐大的轉變方向過程。這種情況下四元數的優勢就體現出來了,我們考慮多次變換的四元數運算:

R = R_1R_2...R_{n-1}R_n=q_n(q_{n-1}...(q_2(q_1cdot pcdot q_1^*)q_2^*)...q_{n-1}^*)q_n^*

我們利用結合律來看:

R = R_1R_2...R_{n-1}R_n=(q_nq_{n-1}...q_2q_1) p( q_1^*q_2^*...q_{n-1}^*q_n^*)

考慮到四元數共軛有性質: (q_aq_b)^* = q_b^*q_a^* ,我們可以把原式改寫為

R = R_1R_2...R_{n-1}R_n=(q_nq_{n-1}...q_2q_1) p(q_nq_{n-1}...q_2q_1)^*

可以發現,原向量 p 左右兩側括弧里的運算結果是一對共軛四元數,也就是說可以利用3次易號運算代替n次四元數相乘運算,大大減少了計算量。反觀歐拉角的矩陣計算,雖然一次旋轉時,僅僅是3×3矩陣和3×1矩陣的乘法運算,但是對於多次運算來說, M_nM_{n-1}...M_2M_1 的運算卻是多個3×3矩陣相乘,與四元數 q_nq_{n-1}...q_2q_1 的每組4×4矩陣與4×1矩陣的相乘相比運算量要大上不少,加上3×3矩陣中多數元素都是需要通過單位數據再次運算才能得到的,更是增加了運算量的需求。總體看來,在複雜的多次變換情況下,四元數比矩陣運算所需要的運算量更小

另外,我們之前提到過,每一個3×3的矩陣至少需要存儲6個單位數據才可以記錄,而每個四元數僅需要4個單位數據即可(其實考慮到四元數是單位四元數,在保證w已知的前提下,x,y,z缺少任意一個都是可以通過運算推導出四元數的,也就是說可能只要佔用三個數據的存儲空間,前提是對x,y,z的定義域要有限制),在大量變換的運算中,四元數的應用可以節約非常多的存儲空間

擁有以上兩個優點,加上規避了Ambiguity的問題,我們在表示方向和方向變換時會經常使用四元數的運算。不過四元數也是有缺點的,在複雜運動中,方向旋轉和位移往往是同時發生的,在運用歐拉角矩陣運算時,我們考慮平移運算只要改寫矩陣為4×4 homogeneous matrix left[ egin{matrix} left[ egin{matrix} \R\ end{matrix}
ight]egin{matrix} x\y\z end{matrix}\ egin{matrix} 0001 end{matrix} end{matrix} 
ight] 即可,而四元數則必須重新寫為 Rot(vec{n}, 	heta) 的形式以找到homogeneous matrix,非常麻煩。

Rot(vec{n},	heta)=left[egin{matrix} n_x^2+(1-n_x^2)c  n_xn_y(1-c)-n_zs  n_xn_z(1-c)+n_ys  0\ n_xn_y(1-c)+n_zs  n_y^2+(1-n_y^2)c  n_yn_z(1-c)-n_xs  0\ n_xn_z(1-c)-n_ys  n_yn_z(1-c)+n_xs  n_z^2+(1-n_z^2)c  0\ 0  0  0  1 end{matrix}
ight] ,其中 c = cos	heta, s = sin	heta

全部手打,真的是好累啊,希望看到點個贊鼓勵哈!


四元數方便通過插值實現連續轉動的效果,比如轉動用四元數 q=cosfrac{	heta}{2}+vec{u}sinfrac{	heta}{2}

表示繞 vec{u} 軸旋轉 	heta ,那麼連續乘以 Ncosfrac{	heta}{2N}+vec{u}sinfrac{	heta}{2N} 就可以實現分 N 個步驟完成旋轉的過程。

歐拉角的代表了旋轉矩陣,乘法一般是不可以交換的,你算出圍繞三個轉軸的轉角, phi,	heta,gamma ,也只有按照約定的順序依次轉完這三個角。 重複 Nfrac{phi}{N},frac{	heta}{N},frac{gamma}{N} 肯定不可以的。

而且不同的庫,對於到底是圍繞哪三個軸,以怎樣的先後次序旋轉,約定都是有可能不同的,也帶來了兼容性的坑。


簡單來講,因為歐拉角會卡頓,而且經常不可插值。


最近正好在證一些類似的東西,強行答一下。

歐拉角和四元數都是旋轉的一種表示方式,同時還有旋轉矩陣,與四元數很像的 k,	heta等等。(parameterizations of rotations)

1. 旋轉矩陣

用九個數字定義的一個矩陣,矩陣乘法作用於其他的矩陣時得到的結果相當於做旋轉運算。其本身也可以理解為新坐標系在原坐標系下三個坐標軸的單位向量。為了有這些優秀的性質,雖然有九個數字但是還有附加了幾個條件,同列或行內積為一(單位向量),不同列或行內積為零(坐標系互相垂直),實際上只有三個自由度。

因此為什麼不寫三個來代替負責的寫九個呢?

2. 歐拉角

歐拉角是最常見的用三個數值來表示旋轉的辦法,因為比較直觀容易想像。用先後三次當前圍繞坐標系軸的旋轉(三個自由度為一的旋轉)來表示一個三維的自由旋轉。

優點還有少六個受限制的數,記錄傳達都很方便。而缺點除了很多人提到的萬向節死鎖,特殊角度丟失會一個自由度,三個角度也不連續,兩個相鄰的旋轉姿態三個角度值差別很大。比如在對於二維用一個 	heta 表示旋轉時,為了連續有時會用兩套值域( (-pi,pi] 以及 [0,2pi) ,在不連續處使用另外一套),這對於程序來說增加的if else會帶來不必要的麻煩(bug)。同時給定旋轉後的姿態逆寫出三個角度也不算方便(開根還要atan2)且不唯一( 	heta 正負兩組解, 	heta 為零無窮組)。

(以上為 sin 	heta > 0 時的解)

三角函數在電腦中運算也都只是近似解,誤差可能會疊加。

外加運算時白白多乘兩個矩陣好累的。什麼,你說你背出了這個?嘛,那你很棒棒啊。

3. 四元數

四元數和繞k向量轉 	heta 度與二維的x+yi虛坐標旋轉都有相似之處。

Q = (cos frac{	heta}{2}, k_{x} sin frac{	heta}{2}, k_{y} sin frac{	heta}{2}, k_{z} sin frac{	heta}{2})

可以用 R_{k,	heta} 來勉強理解各項的意義但主要還是為了計算上的優勢。只需要四個數(比九個少),不需要if else語句,而且計算不算太難誤差也小。


前段時間正好用到過這方面的知識,嘗試答一發。

數學上來講,可以用四元數表示三維空間中的旋轉,其原因是SO(3)與S(3)同構,即三維空間中的旋轉群與四維空間中的三維單位球面上的元素存在一一對應關係,並且有對應的運演算法則約束。我們用於旋轉的一般是單位四元數,本質上就是四維空間中的三維單位球面上的某一元素。在實際操作過程中,存在一個將四元數映射到3*3的旋轉矩陣的函數,形式有一點複雜,在維基百科的旋轉矩陣頁面有詳細的對應關係及表達式。


歐拉角和四元數都能表示一個旋轉,同樣還有轉換矩陣也能表示一個旋轉,它們三者之間可以互相轉換。具體公式百度可查。

歐拉角是給人看的,對控制系統也好分開單獨處理。

四元數是給計算機用的,避免了大量三角函數運算和死鎖問題。

轉換矩陣是一個矩陣,主要是便於向量的轉換計算。直接一個矩陣左乘原坐標系向量就得到了新坐標系的向量。


可以看看physics from symmetry裡面關於SU(2)比較簡單的介紹


講一講自己的一點理解,不知道對錯。

歐拉角就是旋轉的角度,是對三維空間運動的一種描述。四元數相當於一組4個基,可張成一個空間,多用於描述三維空間的旋轉。

我始終不理解的點在於為什麼三維運動,比如旋轉,要用四個數來描述。看了一些文章後感覺可能是因為,由於基是人為用來描述空間的,因此按照基依次取值組合成的空間運動描述所包含的信息,與實際空間運動信息相比,有可能出現信息丟失。

回到三維空間,用三個基來描述三維空間運動,由於是按照三個基上的依次運動的組合,因此會出現gamble lock等問題。而在用四個基張成的空間中,通過約束將運動約束在三維的子空間中時,可以很好的描述三維空間運動。

雖然四個基的運算依然存在三個基的運算中的信息丟失。正如前面所說是基對空間描述過程是有順序的,而實際運動是一蹴而就的,因此這種描述本身存在問題。但是可以看作是犧牲了一個維度來補償這種描述過程中的信息丟失。

以上純屬一些個人的理解,不能保證正確…


四元數可以指定空間任意軸旋轉,歐拉角只能圍繞三個坐標軸旋轉。都是方便人直覺描述的表示方法,站在攝像機角度考慮,上下抬頭、左右看、滾動相機是歐拉角,讓你拿著相機圍繞人物旋轉就得四元數表示了。


(不懂強答一記)我目前是看著MATLAB裡面的程序學習的,還算簡明易懂。

Euler angle, DCM, Quaternion, and Euler Vector Conversion/Teaching GUI - File Exchange - MATLAB Central


用四元數或者歐拉角或者姿態矩陣都可以描述剛體的轉動。在坐標系變換的計算中必須得到姿態矩陣,姿態矩陣的時間更新也可以用這三種方式來進行,但是計算量和難度不同,也就是說問題中你說得這兩種方法描述坐標系轉動都可以。

為啥用四元數?在慣性導航中用四元數進行計算的最主要原因是在進行正交化時方便且誤差最小,次要原因是計算量小。

我簡單解釋下,描述轉動的矩陣一定是正交矩陣,我就叫它姿態矩陣。對於一般問題姿態矩陣是時變的,我們可以通過輸入角速度信息來更新這個矩陣。已知歐拉角或者四元數也可以計算出這個矩陣,我們可以用角速度信息更新歐拉角或者四元數,進而同樣可以得到新的姿態矩陣。但是在計算中會存在誤差,典型的誤差是數值積分的截斷誤差還有把角運動當矢量對待造成的交換性誤差,這些最終會使姿態矩陣出現誤差,誤差一方面會造成角位置漂移,一方面會使矩陣不再正交。在使用姿態矩陣或者四元數計算時,這兩方面的誤差都會出現,第二種誤差可以通過正交化減小,四元數正交化非常容易,但姿態矩陣就複雜很多。使用歐拉角計算時,只會有第一方面的誤差,但這並不是好事,因為誤差總量是相當的,這意味著誤差無法通過正交化方法減小。最終是四元數的計算誤差小同時計算量小。

此外歐拉角法還存在一個問題就是微分方程有可能存在奇點,應該和高贊答案說得死鎖是一回事。


推薦閱讀:

以關於東方之星游輪目前在水中的姿態和情況,採取什麼辦法才是最好的急救辦法才可能盡量多的就出生還者?
什麼是模態振型?

TAG:數學 | 幾何學 | 力學 |