四元數小總結


四元數記法:

一個四元數包含一個標量分量和一個3D向量分量。記標量為w,記向量為v或分開的x,y,z。如下:

[w,v]

[w,(x,y,z)]

 

四元數與復數:

四元數擴展了復數系統 ,它使用三個虛部i,j,k。它們的關系如下:

i2=j2=k2=-1

ij=k,ji=-k

jk=i,kj=-i

ki=j,ik=-j

一個四元數[w,(x,y,z)]定義了復數 w+xi+yj+zk。

 

四元數和軸-角對:

四元數能被解釋為角位移的軸-角對方式。其公式為下:

設向量n為旋轉軸,θ為繞軸旋轉的量。

q=[cos(θ/2)  sin(θ/2)n]

  =[cos(θ/2)  (sin(θ/2)nx  sin(θ/2)ny  sin(θ/2)nz)]

 

負四元數:

-q=[-w (-x -y -z)]=[-w -v]

q和-q代表的實際角位移是相同的,很奇怪吧!如果我們將θ加上360度的倍數,不會改變q代表的角位移,但它使q的四個分量變負了。因此,3D中的任意角位移都有兩種不同的四元數表示方式,它們互相為負。

 

單位四元數:

幾何上存在2個單位四元數:[1,0]和[-1,0]。它們的意義是:當旋轉角為360度的整數倍時,方位並沒有改變,並且旋轉軸也是無關緊要的。

數學上只有一個單位四元數:[1,0]。任意四元數q乘以單位四元數[1,0]仍為q。

 

四元數的模:

公式如下:

||q||=||[w (x y z)]||=sqrt(w2+x2+y2+z2)

    =||[w v]||=sqrt(w2+||v||2)

幾何意義:

||q||=sqrt(cos(θ/2)2+sin(θ/2)2||n||2)

若n為單位向量,則:||q||=1

 

四元數共軛:

q*=[w -v]=[w (-x -y -z)]

 

四元數的逆:

q-1=q*/||q||

但我們只使用單位四元數,故q-1=q*

幾何解釋:使向量v反向,則旋轉方向也反向了。因此q繞軸旋轉θ角,而q*沿相反的方向旋轉相同的角度。

 

四元數乘法(叉乘):

[w1  v1][w2  v2]=[w1w2-v1v2  w1v2+w2v1+v2×v1]

 

四元數叉乘滿足結合律但不滿足交換律:

(ab)c=a(bc)

ab!=ba

 

四元數乘積的模等於模的乘積:

||q1q2||=||q1|| ||q2||

 

四元數乘積的逆等於各個四元數的逆以相反的順序相乘:

(ab)-1=b-1a-1

 

如何用四元數將3D點繞軸旋轉:

讓我們“擴展”一個標准3D點(x,y,z)到四元數空間,通過定義四元數p=[0, (x,y,z)]即可。設q為我們討論的旋轉四元數形式[cos(θ/2)  sin(θ/2)n],n為旋轉軸,單位向量,θ為旋轉角。你會驚奇地發現,執行下面乘法可使3D點p繞n旋轉:

p'=qpq-1

 

四元數乘法的優勢在哪?對點p先執行a旋轉再執行b旋轉:

p'=b(apa-1)b-1=(ba)p(a-1b-1)=(ba)p(ba)-1

注意,先進行a旋轉再進行b旋轉等價於執行乘積ba代表的單一旋轉。因此,四元數乘法可用來連接多次旋轉,這和矩陣乘法效果一樣。

 

四元數的“差”:

定義:從一個方位到另一個方位的角位移。

如給定方位a和方位b,求a到b的角位移d。用四元數表示為:ad=b  =>  d=a-1b

 

四元數點乘:

q1·q2=[w1  v1]·[w2  v2]=w1w2+v1·v2

幾何解釋:類似於向量點乘的幾何解釋,兩四元數點乘絕對值越大,其代表的角位移越相似。

 

四元數的對數:

首先,令α=θ/2,||n||=1,則q=[cosα  nsinα]=[cosα  xsinα  ysinα   zsinα],公式如下:

log q=log[cosα  nsinα]=[0  αn]

注意log q的結果,它一般不是單位四元數。

 

四元數的指數:

設四元數p的形式為[0, αn],n為單位向量:

p=[0  αn]=[0  (αx  αy  αz)]

||n||=1

公式如下:

exp p=exp([0  αn])=[cosα  nsinα]

根據定義,exp p問題返回單位四元數。

四元數指數運算為四元數對數運算的逆運算:

exp(log q)=q

 

四元數與標量相乘:

kq=k[w  v]=[kw  kv]

  =k[w  (x  y  z)]=[kw  kx  ky  kz]

 

四元數求冥:

qt=exp(tlog q)

幾何意義:對數運算log q提取了軸n和角度θ;接着和指數t進行標量乘時,結果是θ乘以t;最后,指數運算“撤消”了對數運算,以tθ和n重新計算w和v。

求四元數冥的代碼如下:

 1     /// <summary>
 2     /// 四元數求冥
 3     /// </summary>
 4     /// <param name="e">指數</param>
 5     /// <param name="w,x,y,z">四元數輸入,輸出</param>
 6     static void Calc(float e, ref float w, ref float x, ref float y, ref float z)
 7     {
 8         // 檢查單位四元數的情況,避免除零
 9         if (Mathf.Abs(w) < 0.9999f)
10         {
11             // 提取半角(θ/2)
12             float alpha = Mathf.Acos(w);
13             // 計算新的alpha值
14             float newAlpha = alpha * e;
15             // 計算數的w值
16             w = Mathf.Cos(newAlpha);
17             float multi = Mathf.Sin(newAlpha) / Mathf.Sin(alpha);
18             // 計算新的xyz值
19             x *= multi;
20             y *= multi;
21             z *= multi;
22         }
23     }

 

四元數插值——"slerp":

 當今3D數學中四元數存在的理由是由於一種稱作slerp的運算,即球面線性插值(Spherical Linear Interpolation)。slerp運算非常有用,因為它可以在兩個四元數之間平常插值。slerp插值避免了歐拉角插值的所有問題(如萬向鎖)。

 

求法一:

設開始與結束的四元數為q0,q1,插值變量設為t,t在[0, 1]之間變化 。則slerp函數定義為: slerp(q0,q1,t)

計算此函數的思路如下:

△a=a1-a0

lerp(a0,a1,t)=a0+t△a

四元數中,

1. 計算差值:q0△q=q1  =>  △q=q0-1q1

2. 取插值的一部分,應用求冥的辦法,即(△q)t

3. 初始值加上插值的一部分,應用四元數乘法。

綜上,公式如下:

slerp(q0,q1,t)=q0(q0-1q1)t

這是理論上的公式,實踐中,將使用更有效的一種辦法。

 

求法二:

slerp的基本思想是沿着4D球面上連接兩個四元數的弧插值。

可以把這種思想表現在平面上,如向量v0,v1都是單位向量,w是之間的夾角,t在[0,1]區間,求vt

求得:vt=(sin(1-t)w/sinw)v0+(sintw/sinw)v1

將同樣的思想擴展到四元數上,重寫slerp可得:

slerp(q0,q1,t)=(sin(1-t)w/sinw)q0+(sintw/sinw)q1

可以用點乘來計算兩個四元數間的“角度”。

這里有2點需要考慮:第一,四元數q和-q代表相同的方位,但它們作為slerp參數時可能導致不一樣的結果,這是因為4D球面不是歐氏空間的直接擴展。而這種現象在2D和3D中不會發生。解決方法是選擇q0和q1的符號使得點乘q0·q1的結果是非負。第二個要考慮的是如果q0和q1非常接近,sinθ會非常小,這時除法可能會出現問題。為了避免這樣的問題,當sinθ非常小時使用簡單的線性插值。

 

 

轉載請注明出處:http://www.cnblogs.com/jietian331/p/5671101.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM