四元數——旋轉
四元數系列:
四元數——基本概念
四元數——旋轉
四元數應用——轉矩陣、Slerp插值與萬向節
四元數應用——順序無關的旋轉混合
—————————————————————————————————————————
首先很感謝各位的支持,本來我也就是說寫個自己看的筆記啥的,沒想到那麼多人點贊。本篇主要介紹旋轉相關的知識,其中會盡量把我認為精彩的部分說細一點,更像教程的方式去敘述,但是基礎性的公式證明應該還是不會提,畢竟篇幅有限。
0.胡爾韋茲定理
這部分內容很尷尬,本想都塞到下文中用到的地方講,但又怕跳戲。正好結合上篇中評論區的一些反饋,把部分四元數的性質單拎出來放在最前面講。
上篇四元數定義中,為了完整性,我提到了三元數或五元數理論上可能存在,但因為不滿足模運算,所以沒有意義。這裡先將三元數放在一邊,我們著重討論一下為什麼存在四元數、八元數,換種說法,它們有什麼非常重要的共通性質?
我參考的教材提到這樣一個詞Composition Algebras,恕我愚笨沒有在Wiki找到對應的中文譯名。不過找到更為有意思的兩個詞條,賦范可除代數和胡爾韋茲(Hurwitz)定理。我們下面分別來看這兩個定義。
賦范可除代數是一個在實數域或複數域上的可除代數,即對所有處於域中的x和y均滿足
也就是說兩個數(這裡可能是數,可能是向量,取決於代數域的維度)相「乘」後的模長等於分別模長的乘積。那到底有多少個域滿足這個代數的條件呢?胡爾韋茲就證明了 賦范可除代數只同構於一下四個代數:(1)實數R;(2)複數,記號為C;(3)四元數,記號為H;(4)八元數,記號為O。這個就被稱為胡爾韋茲定理,也叫做1, 2, 4, 8定理。
這就厲害了,也就是說對於「乘法」而言,只有一維實數,二維複數,四維四元數等是滿足可除的,其中四元數的「乘法」是操作。我之前所提到的模運算也就是指這個。下面我們舉兩個例子說明一下這個賦范可除代數到底容不容易滿足,我們研究旋轉,就挑三維向量的內積和外積。內積|x·y|=|x|·|y|·cosθ,外積|x×y|=|x|·|y|·sinθ,可以很明顯看到不滿足可除性,所以說即使是單位向量之間叉乘,得到的法向量也未必是單位長度的。
這個性質別看簡單,但基本上算是非常核心的一個性質。為什麼我要用四元數表示旋轉?旋轉最本質的特點是什麼,就是不改變相對距離,你轉個手臂不可能轉個60度手變長了。用數學公式說明,就是假如x是單位四元數,當我一個任意向量y通過x進行旋轉後,模長是不會發生變化的。因此,賦范可除代數的應用就在這。當然四元數旋轉比這複雜,這個後文慢慢說。
1.複數和二維旋轉
複數相乘可以旋轉的性質想必大家都很清楚,乘以i可以逆時針(朝+i方向)旋轉90°,乘以-i可以順時針旋轉90°。我這裡就不想再畫圖解釋一下浪費筆墨了,僅列出一個公式。
其中推導公式中暗含了一個歐拉公式,包含sinθ和cosθ的矩陣就是我們常見的二維旋轉矩陣。可以發現二維旋轉矩陣其實也對應著一個類似四元數的一個向量表達形式,就是複數。我們對矩陣進行求逆(主交換,次變號),發現其實對應的就是複數的共軛形式。也就是說cosθ+i·sinθ可以旋轉θ,而cosθ-i·sinθ可以旋轉-θ。這個特性上的優勢在四元數和三維旋轉矩陣中就更明顯了。
那我們來討論兩個關於複數與四元數的問題。
第一個問題是為什麼單位複數的公式里不像四元數一樣用θ/2,而用θ表示?當然,複數表示旋轉可以用θ/2表示,我們設a=cos(θ/2),b=sin(θ/2),可以得到下面的式子。
這個公式有用嗎,其實用處不大,但確實有教材去討論這個形式。那我們把問題換一下,為什麼複數可以用一個θ去完成旋轉,而四元數只能分兩個θ/2去完成呢?這個問題後面四元數再說,我先把結論說了,也就是馬上說的第二個問題。
第二問題是為什麼二維旋轉可以交換?在三維旋轉中先繞x旋轉,在繞y旋轉和先繞y旋轉,在繞x旋轉肯定是不一樣的,具體看圖。那我們在二維旋轉中先轉90°再轉45°肯定和先轉45°再轉90°是一樣的。究其根本,是二維旋轉它首先就隱藏了一個非常重要的因素,就是旋轉軸永遠是垂直於二維平面的,也是固定的,在二維中無論怎麼旋轉,都是共面的。放到三維空間,旋轉之所以存在次序性,之所以不能交換,是旋轉軸可以跟向量成任意角度。如果你放到一個二維子空間裡面去旋轉,你依然可以滿足交換性。至於這個旋轉軸垂直為啥可以解釋第一個問題,我後面會慢慢說的。
2.三維旋轉
這部分我就不說了,什麼歐拉角、矩陣的正交性、四元數轉矩陣等等與其看我說,不如找本Graphics教材,基本靠譜點的書都會有說,不過再往深點估計就要找一些數學書看了。這裡分享一個軸角公式的推導方法,該方法的思路基本用於動畫或者是遊戲的方方面面。
首先,我們又扯到上篇文章說的two-sphere,也就是通常意義上的球體。軸角一般表示為旋轉軸和角度,概念就跟力矩沒兩樣,那我們單看旋轉軸,歸一化後的旋轉軸其實就是球體上面的一個點。那我們用極坐標來表示(cosα·sinβ,sinα·sinβ,cosβ)。
然後,我們就要去旋轉角度了。歐拉角是一種應用很廣但其實很有缺陷的旋轉表現形式,那為啥有缺陷為啥還應用廣泛呢?主要原因就是簡單。我們繞著x軸旋轉比繞任意軸要簡單許多,那麼處理軸角的思路就是把軸旋轉到z軸,進行旋轉後,再旋轉回原來位置。具體公式(軸角公式)和示意圖如下。
這種繞回去再繞回來思路很常用。比如現在做場景都分世界坐標和局部坐標,把動畫角色放在局部坐標,那麼旋轉就很方便。如果非要把動畫角色放世界坐標,那麼旋轉就很痛苦,要把角色先移回原點旋轉後在移回原來的位置。類似的問題還有很多,當然四元數旋轉公式其實也是這種思路。
3.四元數旋轉
扯了一大堆,要說到正題了。雖說廢話了點,但我上面說的每一個知識點這一節都會用到。
用作旋轉的是單位四元數這一點毋庸置疑,那三維向量我們怎麼表示?這裡就要提到我們上次所說的純四元數(Pure Quaternion),表示為{0, p},就是w=0的四元數。其實上回已經分析過這個空間了,處於四維空間中w=0的三維子空間(可以和三維空間z=0的二維子空間XOZ平面進行類比理解)。純四元數不等同於單位四元數,它們是不同的東西,但有交集,交集就是three-sphere在該空間的投影,是一個two-sphere的球體。純四元數中p中i, j, k就可以跟三維向量x, y, z對應起來。
接著我們對其乘以單位四元數,也就進行旋轉得到如下式子。
不著急往下算,我們先來觀察這個式子,我們希望最終得到的四元數是什麼樣子?
第一,和原來模長一樣。我們把兩邊取模,根據胡爾韋茲定理,右邊的模長就是q的模長乘以p的模長,q是單位四元數,所以前後模長一致,很符合我們的要求。
第二,還得是純四元數,因為我三維向量映射到四維還得映射回去,那麼純四元數是必須的,如果脫離這個三維子空間,映射關係就變了。看看結果,這個就比較麻煩了,因為我們發現w不為0,它是有值得。
3.1 四元數旋轉的特例
什麼時候w=0,垂直。這就是特例,我們先研究特例。我們把w=0,s=cosθ,λ=sinθ代入上面的式子,得到
其中叉乘的部分模長等於p,所以s2+λ2=1,又從代數的角度證明了模長前後不變。那我們拿實例去證明一下。
這是旋轉45°的情況。
這是旋轉-45°的情況。上面例子暗含了兩個點,其一就是共軛其實就是逆,其二就是左乘右乘也是一個逆的操作。
這種特殊情況下的四元數旋轉其實就跟複數是非常類似的,因為旋轉軸與向量垂直,導致旋轉後的結果永遠都是在三維子空間中,所以一次θ旋轉就可以得到結果(這句話說的不妥,參照一般形式就可以理解),跟複數很類似。而且共軸旋轉之間是可以交換的,它們的旋轉軸是固定的,就是先轉90°再轉45°肯定和先轉45°再轉90°是一樣的。但是注意,p和q之間是不滿足交換的,例子就是很好的說明。
3.2 四元數旋轉的一般形式
不垂直,w≠0,那麼問題就麻煩了。在解決問題之前,還是來想一下,我們可以知道旋轉過後的向量模長不變,但w有值,意味著它不在純四元數所在的三維子空間了,它跑到四維空間了,那我們沒辦法映射回去了。怎麼辦?那我們用一下三維旋轉思路,就是把旋轉出去的向量給旋轉回來,根據三維旋轉的公式,向量在右邊成了一個旋轉矩陣的轉置,正交矩陣轉置等於逆,四元數的逆也就是共軛,那我們在q·p的右邊再乘以一個逆。
我們首先證明一下向量旋轉後模長不變,如下圖。
然後就兩個問題深入的分析一下。一是為什麼乘以共軛就變成了純四元數?這個就比較難從幾何角度去思考,畢竟四維的一個旋轉,我們從代數的角度看一下。
已經寫得很清楚了,在這種情況w是恆等於0的。另一個問題就是為什麼要換成θ/2,很多人說要旋轉二次,所以均值一下,每次旋轉一半。道理是沒錯,不過我們還是繼續用代數的角度去看一看,上面的式子還能往下化簡。
這個證明我少個步驟,不過後面會給證明。寫到這,我估計大家都看明白了,向量結果里θ全都變成2倍了,所以需要改為θ/2以保證最終只旋轉θ角度。我們這時再來看複數當中的第一個問題,為什麼複數直接旋轉θ就可以了。因為當旋轉軸與向量垂直時,旋轉後的向量永遠與原向量處於同一個空間;而一般形式下的四元數旋轉,旋轉軸與向量並不是垂直的,旋轉會將原向量偏離三維子空間,需要再乘以共軛形式旋轉回來,所以需要兩次旋轉,所以不能直接旋轉θ角度。
四元數與旋轉整體體系就寫完了!基本到這從理解上這麼多就夠用了,如果只是用,我覺得公式拿過來就OK了。後面還會有兩篇關於四元數的應用,一篇我自己來寫,也就是常用的 Slerp、Gimbal Lock等問題;另一篇請了個高人來寫,內容是什麼就暫且保密,盡情期待,雖然不知道什麼時候能發出來。
附錄
最後再來點乾貨,四元數矩陣一般形式那塊其實用了一個公式
這個公式叫二重外積公式,就是(x×y)×z=(x·z)·y-(y·z)·x,英文名稱叫vector triple product,大家自己也可以去Google上面找方法。比較常見的一種是用行列式硬算,比較笨自然不推薦;另一種是用Einsteins求和約定,這個呢又是耍流氓,我還得去理解新的知識點。不過好在我從一本張量分析的教材看到了比較優雅又不難懂的方法,在加上自己一點理解,現在分享給大家。
先看特例,就是上面的公式。其中v為單位向量,左邊叉乘的結果一定是與p和v共面的,且與v垂直的,因為平面和法向量是一一對應的。再看下圖,證畢。
在看一半形式,其中叉乘的結果一定是與x和y共面的,下面我直接粘貼原文了,畢竟不是自己的乾貨,內容也不太多,手動打字畫圖實在是太累了。
推薦閱讀:
※如何證明奇數個手勢的石頭剪子布是公平的?
※運籌學與博弈論有哪些相交的地方?
※一維隨機遊走,帶移動吸收壁,吸收的期望時間是否有限?
※如何研究變步長隨機遊走?