原文地址:http://www.3dgep.com/understanding-quaternios/
轉(zhuǎn)自文章:http://www.qiujiawei.com/understanding-quaternions/
Understanding Quaternions 中文翻譯《理解四元數(shù)》
Tags:math,quaternion
正文
在這篇文章中我會(huì)嘗試用簡(jiǎn)單的方式去解釋四元數(shù)的概念移怯,即用可視化的方式解釋四元數(shù)以及幾種對(duì)四元數(shù)的操作。我將把矩陣杉编、歐拉角和四元數(shù)放在一起比較,并解釋什么時(shí)候該用四元數(shù)域仇、什么時(shí)候該用歐拉角或矩陣洲押。
內(nèi)容結(jié)構(gòu)
介紹
復(fù)數(shù)
復(fù)數(shù)的加減
復(fù)數(shù)的系數(shù)縮放
復(fù)數(shù)的積
復(fù)數(shù)的平方
共軛復(fù)數(shù)
復(fù)數(shù)的絕對(duì)值
兩復(fù)數(shù)的商
i的冪
復(fù)數(shù)平面
旋轉(zhuǎn)數(shù)(Rotors)
四元數(shù)
作為有序數(shù)的四元數(shù)
四元數(shù)的加減
四元數(shù)的積
實(shí)四元數(shù)
四元數(shù)的系數(shù)縮放
純四元數(shù)
四元數(shù)的加法形式
單位四元數(shù)
四元數(shù)的二元形式
共軛四元數(shù)
四元數(shù)范數(shù)
四元數(shù)規(guī)范化
四元數(shù)的逆
四元數(shù)的點(diǎn)積
旋轉(zhuǎn)
四元數(shù)插值
SLERP
四元數(shù)的差
四元數(shù)的冪運(yùn)算
2個(gè)四元數(shù)的分?jǐn)?shù)差
注意事項(xiàng)
SQUARD
總結(jié)
下載Demo
介紹
在計(jì)算機(jī)圖形學(xué)中喇闸,我們使用轉(zhuǎn)換矩陣來(lái)表示空間中的一個(gè)位置以及朝向修赞。一個(gè)轉(zhuǎn)換矩陣還可以表示對(duì)一個(gè)目標(biāo)的縮放(scale)或錯(cuò)切(shear)等。
? 我們可以把轉(zhuǎn)換矩陣想象成一個(gè)空間稚配,當(dāng)你用這個(gè)矩陣乘以向量畅涂、點(diǎn)(甚至矩陣)后, 你就把向量道川、點(diǎn)午衰、矩陣轉(zhuǎn)換進(jìn)這個(gè)空間了。
在這篇文章中愤惰,我不會(huì)討論轉(zhuǎn)換矩陣的細(xì)節(jié)。你可以查看我前面的文章赘理,文章中描述了轉(zhuǎn)換矩陣的細(xì)節(jié)宦言。
在這篇文章中,我想要討論一個(gè)可替代的方案商模,即用四元數(shù)來(lái)描述空間里的物體的朝向奠旺。
四元數(shù)的概念是由愛爾蘭數(shù)學(xué)家Sir William Rowan
Hamilton發(fā)明的(1843年,都柏林)施流。Hamilton當(dāng)時(shí)正和他的妻子前往愛爾蘭皇家研究院响疚,當(dāng)他從Brougham橋通過(guò)皇家運(yùn)河時(shí),他領(lǐng)悟到了一個(gè)激動(dòng)人心的東西瞪醋,并立刻把它刻在橋的一個(gè)石頭上:
i2=j2=k2=ijk=?1
William Rowan Hamilton Plaque on Broome Bridge on the Royal Canal
commemorating his discovery of the fundamental formula for quaternion
multiplication.
復(fù)數(shù)
在我們能夠完全理解四元數(shù)之前忿晕,我們必須先知道四元數(shù)是怎么來(lái)的。四元數(shù)的根源其實(shí)是復(fù)數(shù)银受。
除了知名的數(shù)集(自然數(shù)践盼、整數(shù)、實(shí)數(shù)宾巍、分?jǐn)?shù))之外咕幻,復(fù)數(shù)系統(tǒng)引入了一個(gè)新的數(shù)集——虛數(shù)。虛數(shù)的發(fā)明是為了解決一些特定的無(wú)解的方程顶霞,例如:
x2+1=0
要解決這個(gè)等式肄程,必須讓x2=?1
,這當(dāng)然是不行的选浑,因?yàn)槿我鈱?shí)數(shù)的平方都是非負(fù)數(shù)蓝厌。
一般而言,數(shù)學(xué)家是不能忍受一個(gè)等式是無(wú)解的古徒。于是褂始,一個(gè)新的術(shù)語(yǔ)被發(fā)明了,它就是虛數(shù)描函,一個(gè)可以解決上面這個(gè)等式的數(shù)崎苗。
虛數(shù)有這樣的形式:
i2=?1
不要為這個(gè)術(shù)語(yǔ)較真狐粱,因?yàn)檫壿嬌线@個(gè)數(shù)是不存在的。只要知道i是一個(gè)平方等于-1的東西即可胆数。
虛數(shù)的集合可以用??
來(lái)表示肌蜻。
復(fù)數(shù)的集合?
是一個(gè)實(shí)數(shù)和一個(gè)虛數(shù)的和,形式如下:
z=a+bi?a,b∈R,?i2=?1
可以認(rèn)為所有實(shí)數(shù)都是b=0的復(fù)數(shù)必尼、所有虛數(shù)都是a=0的復(fù)數(shù)蒋搜。
復(fù)數(shù)的加減
加法:
(a1+b1i)+(a2+b2i)=(a1+a2)+(b1+b2)i
減法:
(a1+b1i)?(a2+b2i)=(a1?a2)+(b1?b2)i
復(fù)數(shù)的系數(shù)縮放
λ(a1+b1i)=λa1+λb1i
復(fù)數(shù)的積
z1=(a1+b1i)
z2=(a2+b2i)
z1z2=(a1+b1i)(a2+b2i)=a1a2+a1b2i+b1a2i+b1b2i2
z1z2=(a1a2?b1b2)+(a1b2+b1a2)i
復(fù)數(shù)的平方
z=(a+bi)
z2=(a+bi)(a+bi)
z2=(a2?b2)+2abi
共軛復(fù)數(shù)
復(fù)數(shù)的共軛就是指把復(fù)數(shù)的虛數(shù)部分變成負(fù)的。共軛復(fù)數(shù)的符號(hào)是zˉ
或z?
判莉。
z=(a+bi)
z?=(a?bi)
復(fù)數(shù)和它的共軛復(fù)數(shù)的乘積是:
zz?=(a+bi)(a?bi)=a2?abi+abi+b2=a2+b2
復(fù)數(shù)的絕對(duì)值
我們使用共軛復(fù)數(shù)來(lái)計(jì)算復(fù)數(shù)的絕對(duì)值:
z=(a+bi)
|z|=zz? ̄ ̄ ̄√=(a+bi)(a?bi) ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄√=a2+b2 ̄ ̄ ̄ ̄ ̄ ̄ ̄√
兩復(fù)數(shù)的商
z1=(a1+b1i)
z2=(a2+b2i)
z1z2=a1+b1ia2+b2i=(a1+b1i)(a2?b2i)(a2+b2i)(a2?b2i)
=a1a2?a1b2i+b1a2i?b1b2i2a22+b22
=a1a2+b1b2a22+b22+b1a2?a1b2a22+b22i
i的冪
如果i
的平方等于-1豆挽,那么i
的n次冪也應(yīng)該存在:
i0=1
i1=i
i2=?1
i3=ii2=?i
i4=i2i2=1
i5=ii4=i
i6=ii5=i2=?1
如果按照這個(gè)順序?qū)懴氯ィ瑫?huì)出現(xiàn)這樣一個(gè)模式:
(1,\mathbf i,-1,-\mathbf i,1,...)
一個(gè)類似的模式也出現(xiàn)在遞增的負(fù)數(shù)冪:
i0=1
i?1=?i
i?2=?1
i?3=i
i?4=1
i?5=?i
i?6=?1
你可能已經(jīng)在數(shù)學(xué)里頭見過(guò)類似的模式券盅,但是是以(x,y,-x,-y,x,...)的形式帮哈,這是在2D笛卡爾平面對(duì)一個(gè)點(diǎn)逆時(shí)針旋轉(zhuǎn)90度時(shí)生成的;(x,-y,-x,y,x,...)則是在2D笛卡爾平面對(duì)一個(gè)點(diǎn)順時(shí)針旋轉(zhuǎn)90度時(shí)生成的锰镀。
復(fù)數(shù)平面
我們也能夠把復(fù)數(shù)映射到一個(gè)2D網(wǎng)格平面——復(fù)數(shù)平面娘侍,只需要把實(shí)數(shù)映射到橫軸、虛數(shù)映射到縱軸泳炉。
如前面的序列所示憾筏,我們可以認(rèn)為,對(duì)一個(gè)復(fù)數(shù)乘以i花鹅,這個(gè)復(fù)數(shù)就在復(fù)數(shù)平面上旋轉(zhuǎn)了90度氧腰。
讓我們看看這是不是真的。我們隨機(jī)地在復(fù)數(shù)平面上取一個(gè)點(diǎn):
p=2+i
p乘以i后得到q:
q=pi=(2+i)i=2i+i2=?1+2i
q乘以i后得到r:
r=qi=(?1+2i)i=?i+2i2=?2?i
r乘以i后得到s:
s=ri=(?2?i)i=?2i?i2=1?2i
s乘以i后得到t:
t=si=(1?2i)i=i?2i2=2+i
t剛好是開始的p刨肃。如果我們把這些復(fù)數(shù)放到復(fù)數(shù)平面上容贝,就得到下面的圖:
我們也可以按順時(shí)針?lè)较蛐D(zhuǎn),只需要把上面的乘數(shù)i改成-i之景。
旋轉(zhuǎn)數(shù)(Rotors)
我們也可以在復(fù)數(shù)平面上進(jìn)行任意角度的旋轉(zhuǎn)斤富,只需要定義下面這個(gè)復(fù)數(shù):
q=cosθ+isinθ
任意的復(fù)數(shù)乘以q:
p=a+bi
q=cosθ+isinθ
pq=(a+bi)(cosθ+isinθ)
a′+b′i=acosθ?bsinθ+(asinθ+bcosθ)i
也可以寫成矩陣的形式:
[a′b′?b′a′]=[cosθsinθ?sinθcosθ][ab?ba]
這也是一個(gè)在復(fù)數(shù)平面繞原點(diǎn)逆時(shí)針旋轉(zhuǎn)任意點(diǎn)的方法。(譯注:這句話應(yīng)該是在說(shuō)旋轉(zhuǎn)矩陣)
四元數(shù)
了解了復(fù)數(shù)系統(tǒng)和復(fù)數(shù)平面后锻狗,我們可以額外增加2個(gè)虛數(shù)到我們的復(fù)數(shù)系統(tǒng)满力,從而把這些概念拓展到3維空間。
四元數(shù)的一般形式:
q=s+xi+yj+zk???s,x,y,z∈?
上面的公式是根據(jù)Hamilton的著名的表達(dá)式得到的:
i2=j2=k2=ijk=?1
以及:
ij=k???jk=i???ki=j
ji=?k???kj=?i???ik=?j
你可能已經(jīng)注意到了轻纪,i油额、j、k之間的關(guān)系非常像笛卡爾坐標(biāo)系下單位向量的叉積規(guī)則:
x×y=z???y×z=x???z×x=y
y×x=?z???z×y=?x???x×z=?y
Hamilton自己也發(fā)現(xiàn)i刻帚、j潦嘶、k虛數(shù)可以被用來(lái)表達(dá)3個(gè)笛卡爾坐標(biāo)系單位向量i、j崇众、k掂僵,并且仍然保持有虛數(shù)的性質(zhì)航厚,也即i2=j2=k2=?1
。
(\mathbf i \mathbf j, \mathbf j \mathbf k, \mathbf k \mathbf i這幾個(gè)性質(zhì)的可視化)
上圖展示了如何用i锰蓬、j幔睬、k作為笛卡爾坐標(biāo)系的單位向量。
作為有序數(shù)的四元數(shù)
我們可以用有序?qū)Φ男问角叟ぃ瑏?lái)表示四元數(shù):
[s,v]???s∈?,v∈???
其中的v麻顶,也可以用它各自獨(dú)立的3個(gè)分量表示:
q=[s,xi+yj+zk]???s,x,y,z∈?
使用這種表示法,我們可以更容易地展示四元數(shù)和復(fù)數(shù)之間的相似性舱卡。
四元數(shù)的加減
和復(fù)數(shù)類似辅肾,四元數(shù)也可以被加減:
qa=[sa,a]
qb=[sb,b]
qa+qb=[sa+sb,a+b]
qa?qb=[sa?sb,a?b]
四元數(shù)的積
我們也可以表示四元數(shù)的乘積:
qaqb=[sa,a][sb,b]
=(sa+xai+yaj+zak)(sb+xbi+ybj+zbk)
=(sasb?xaxb?yayb?zazb)
+(saxb+sbxa+yazb?ybza)i
+(sayb+sbya+zaxb?zbxa)j
+(sazb+sbza+xayb?xbya)k
可以看到,四元數(shù)的乘積依然還是一個(gè)四元數(shù)轮锥。如果我們把虛數(shù)i矫钓、j、k
替換成有序?qū)Γ?/p>
i=[0,i]???j=[0,j]???k=[0,k]
以及還有[1,0] = 1交胚,將它們代入前面的表達(dá)式份汗,就得到了:
qaqb=(sasb?xaxb?yayb?zazb)[1,0]
+(saxb+sbxa+yazb?ybza)[0,i]
+(sayb+sbya+zaxb?zbxa)[0,j]
+(sazb+sbza+xayb?xbya)[0,k]
再把這個(gè)表達(dá)式擴(kuò)展成多個(gè)有序?qū)Φ暮停?/p>
qaqb=[(sasb?xaxb?yayb?zazb),0]
+[0,(saxb+sbxa+yazb?ybza)i]
+[0,(sayb+sbya+zaxb?zbxa)j]
+[0,(sazb+sbza+xayb?xbya)k]
如果把后3個(gè)四元數(shù)相加盈电,并提取公共部分蝴簇,就可以把等式改寫成:
qaqb=[(sasb?xaxb?yayb?zazb),0]
+[0,sa(xbi+ybj+zbk)+sb(xai+yaj+zak)
+(yazb?ybza)i+(zaxb?zbxa)j+(xayb?xbya)k]
這個(gè)等式是2個(gè)有序?qū)Φ暮汀5?個(gè)有序?qū)κ且粋€(gè)實(shí)四元數(shù)匆帚,第2個(gè)是一個(gè)純四元數(shù)熬词。這兩個(gè)四元數(shù)也可以合并成一個(gè):
qaqb=[(sasb?xaxb?yayb?zazb),
sa(xbi+ybj+zbk)+sb(xai+yaj+zak)
+(yazb?ybza)i+(zaxb?zbxa)j+(xayb?xbya)k]
如果把下面的表達(dá)式代入上面的等式:
a=xai+yaj+zak
b=xbi+ybj+zbk
a?b=xaxb+yayb+zazb
a×b=(yazb?ybza)i+(zaxb?zbxa)j+(xayb?xbya)k
(譯注:注意,第三條和第四條并不是四元數(shù)的點(diǎn)積和叉積吸重,而是向量的點(diǎn)積和叉積)
我們就得到了:
qaqb=[sasb?a?b,sab+sba+a×b]
這就是四元數(shù)乘積的一般式互拾。
實(shí)四元數(shù)
一個(gè)實(shí)四元數(shù)是一個(gè)虛部向量為零向量的四元數(shù):
q=[s,0]
兩個(gè)實(shí)四元數(shù)的乘積是另一個(gè)實(shí)四元數(shù):
qa=[sa,0]
qb=[sb,0]
qaqb=[sa,0][sb,0]=[sasb,0]
這和2個(gè)虛部為0的復(fù)數(shù)的乘積幾乎一樣:
z1=a1+0i
z2=a2+0i
z1z2=(a1+0i)(a2+0i)=a1a2
四元數(shù)的系數(shù)縮放
我們也可以用一個(gè)系數(shù)(實(shí)數(shù))去乘四元數(shù):
q=[s,v]
λq=λ[s,v]=[λs,λv]
我們可以用實(shí)四元數(shù)與普通四元數(shù)的乘積,來(lái)確認(rèn)這個(gè)等式是否正確:
q=[s,v]
λ=[λ,0]
λq=[λ,0][s,v]=[λs,λv]
純四元數(shù)
和實(shí)四元數(shù)相似嚎幸,Hamilton也定義了純四元數(shù)颜矿。純四元數(shù)是s=0的四元數(shù):
q=[0,v]
也可以寫成下面的形式:
q=xi+yk+zk
然后是2個(gè)純四元數(shù)的乘積:
qa=[0,a]
qb=[0,b]
qaqb=[0,a][0,b]=[?a?b,a×b]
四元數(shù)的加法形式
我們可以把四元數(shù)寫成實(shí)四元數(shù)和純四元數(shù)的和:
q=[s,v]
=[s,0]+[0,v]
單位四元數(shù)
給定任意的向量v,我們可以把這個(gè)向量寫成一個(gè)系數(shù)和一個(gè)單位方向向量的乘積:
v=vv???v=|v|,|v?|=1
將這個(gè)定義和純四元數(shù)的定義結(jié)合嫉晶,就得到了:
q=[0,v]
=[0,vv?]
=v[0,v?]
然后骑疆,我們可以定義單位四元數(shù)了,它是一個(gè)s=0替废、v
為單位向量的四元數(shù):
q?=[0,v?]
四元數(shù)的二元形式
我們現(xiàn)在可以把單位四元數(shù)的定義和四元數(shù)的加法形式結(jié)合到一起箍铭,就創(chuàng)造了一種新的四元數(shù)的表示法,這種表示法和復(fù)數(shù)的表示法形似:
q=[s,v]
=[s,0]+[0,v]
=[s,0]+v[0,v?]
=s+vq?
這就給了我們一種和復(fù)數(shù)非常相似的四元數(shù)表示法:
z=a+bi
q=s+vq?
共軛四元數(shù)
共軛四元數(shù)的計(jì)算椎镣,就是將四元數(shù)的虛向量取反:
q=[s,v]
q?=[s,?v]
四元數(shù)和它的共軛四元數(shù)的乘積:
qq?=[s,v][s,?v]
=[s2?v?(?v),?sv+sv+v×(?v)]
=[s2+v?v,0]
=[s2+v2,0]
四元數(shù)范數(shù)
回憶下復(fù)數(shù)范數(shù)的定義:
|z|=a2+b2 ̄ ̄ ̄ ̄ ̄ ̄ ̄√
zz?=|z|2
類似的诈火,四元數(shù)的范數(shù)可以這樣定義:
q=[s,v]
|q|=s2+v2 ̄ ̄ ̄ ̄ ̄ ̄ ̄√
這也讓我們可以這樣表達(dá)四元數(shù)范數(shù):
qq?=|q|2
四元數(shù)規(guī)范化
利用四元數(shù)范數(shù)的定義,就可以對(duì)四元數(shù)進(jìn)行規(guī)范化状答。要讓一個(gè)四元數(shù)規(guī)范化冷守,只需要讓這個(gè)四元數(shù)去除以它的范數(shù):
q′=qs2+v2 ̄ ̄ ̄ ̄ ̄ ̄ ̄√
舉一個(gè)例子刀崖,讓我們規(guī)范化下面這個(gè)四元數(shù):
q=[1,4i+4j?4k]
第一步,先計(jì)算q的范數(shù):
|q|=12+42+42+(?4)2 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄√
=49 ̄ ̄ ̄√=7
然后教沾,q除以|q|:
q′=q|q|
=(1+4i+4j?4k)7
=17+47i+47j?47k
四元數(shù)的逆
四元數(shù)的逆用q?1
表示蒲跨。要計(jì)算四元數(shù)的逆,需要用四元數(shù)的共軛四元數(shù)去除以四元數(shù)的范數(shù)的平方:
q?1=q?|q|2
為了證明這個(gè)式子授翻,我們先根據(jù)逆的定義或悲,有:
qq?1=[1,0]=1
兩邊都左乘共軛四元數(shù)q?
:
q?qq?1=q?
將上文中的qq?=|q|2
代入這個(gè)式子,得到:
|q|2q?1=q?
q?1=q?|q|2
對(duì)于單位四元數(shù)堪唐,它的范數(shù)是1巡语,所以可以寫成:
q?1=q?
四元數(shù)的點(diǎn)積
和向量的點(diǎn)積相似,我們也可以計(jì)算2個(gè)四元數(shù)的點(diǎn)積淮菠,只需要將各個(gè)對(duì)應(yīng)的系數(shù)相乘男公,然后相加:
q1=[s1,x1i+y1j+z1k]
q2=[s2,x2i+y2j+z2k]
q1?q2=s1s2+x1x2+y1y2+z1z2
我們也可以利用四元數(shù)點(diǎn)積,來(lái)計(jì)算四元數(shù)之間的角度差:
cosθ=s1s2+x1x2+y1y2+z1z2|q1||q2|
對(duì)于單位四元數(shù)合陵,我們可以簡(jiǎn)化上面的等式:
cosθ=s1s2+x1x2+y1y2+z1z2
旋轉(zhuǎn)
前面我們定義了一個(gè)特殊的復(fù)數(shù):旋轉(zhuǎn)數(shù)枢赔。它是用來(lái)旋轉(zhuǎn)2D復(fù)數(shù)平面的點(diǎn)的:
q=cosθ+isinθ
根據(jù)四元數(shù)和復(fù)數(shù)的相似性,應(yīng)該有可能設(shè)計(jì)一個(gè)可以旋轉(zhuǎn)3D空間的點(diǎn)的四元數(shù):
q=[cosθ,sinθv]
讓我們測(cè)試一下這個(gè)理論是否可靠拥知,方法就是計(jì)算四元數(shù)q和向量p的積踏拜。第一步,我們把p寫成純四元數(shù)的形式:
p=[0,p]
以及單位四元數(shù)q:
q=[s,λv?]
從而:
p′=qp=[s,λv?][0,p]
=[?λv??p,sp+λv?×p]
我們可以看到結(jié)果是一個(gè)同時(shí)有系數(shù)低剔、有虛向量的四元數(shù)速梗。
讓我們先考慮特殊的情形:p
與v?正交。這種情況下襟齿,點(diǎn)乘部分等于0:?λv??p=0
姻锁。所以上面的四元數(shù)就變成了純四元數(shù):
p′=[0,sp+λv?×p]
這時(shí)候,要使p
繞v?旋轉(zhuǎn)猜欺,我們只需要代入s=cosθ和λ=sinθ
:
p′=[0,cosθp+sinθv?×p]
現(xiàn)在位隶,讓我們找一個(gè)例子來(lái)測(cè)試上面的公式。譬如繞z軸(就是k軸)旋轉(zhuǎn)45度开皿,那么我們的四元數(shù)q就變成:
q=[cosθ,sinθk]
=[2 ̄√2,2 ̄√2k]
然后涧黄,選一個(gè)特殊的p,并且p要和k軸正交副瀑,譬如把p放到i軸上弓熏,也就是:
p=[0,2i]
好了,現(xiàn)在計(jì)算下qp:
p′=qp
=[2 ̄√2,2 ̄√2k][0,2i]
=[0,22 ̄√2i+22 ̄√2k×i]
=[0,2 ̄√i+2 ̄√j]
結(jié)果是一個(gè)繞了k軸轉(zhuǎn)了45度的純四元數(shù)糠睡。
我們可以確認(rèn)這個(gè)四元數(shù)的向量部分的長(zhǎng)度是:
p′=2 ̄√2+2 ̄√2 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄√=2
這正是我們所期望的挽鞠!
我們可以用圖像展示旋轉(zhuǎn)過(guò)程:
現(xiàn)在,讓我們考慮更一般化的四元數(shù),即和p不正交的四元數(shù)⌒湃希現(xiàn)在讓我們把p的向量部分偏移45度:
v?=2 ̄√2i+2 ̄√2k
p=2i
q=[cosθ,sinθv?]
p=[0,p]
然后算qp:
p′=qp
=[cosθ,sinθv?][0,p]
[?sinθv??p,cosθp+sinθv?×p]
代入我們?cè)O(shè)定的v?,p
材义,以及θ=45°
嫁赏,得到:
p′=[?2 ̄√2(2 ̄√2i+2 ̄√2k)?(2i),2 ̄√22i+2 ̄√2(2 ̄√2i+2 ̄√2k)×2i]
=[?1,2 ̄√i+j]
注意潦蝇,算出來(lái)的結(jié)果已經(jīng)不是純四元數(shù)了款熬,并且,它并沒(méi)有旋轉(zhuǎn)45度贤牛、范數(shù)也不再是2(反而變小了则酝,變成3 ̄√
)
我們可以用圖像展示旋轉(zhuǎn)過(guò)程:
嚴(yán)格來(lái)說(shuō)殉簸,這樣子在3維空間中表示p′
是不正確的。因?yàn)樗鋵?shí)是一個(gè)4維的向量般卑!為了簡(jiǎn)單起見爽雄,我只將這個(gè)四元數(shù)的向量部分顯示出來(lái)盲链。
然而迟杂,還有一線生機(jī)排拷。Hamilton發(fā)現(xiàn)(但沒(méi)有正式宣布),如果對(duì)qp右乘q的逆布蔗,出來(lái)的結(jié)果是一個(gè)純四元數(shù)纵揍,并且四元數(shù)向量部分的范數(shù)可以保持不變议街。讓我們?cè)囋噾?yīng)用在我們的例子里。
首先計(jì)算:
q=[cosθ,sinθ(2 ̄√2i+2 ̄√2k)]
q?1=[cosθ,?sinθ(2 ̄√2i+2 ̄√2k)]
(譯注:這里q?1=q?
是因?yàn)閝是單位四元數(shù))
再代入θ=45°
骨杂,得到:
q?1=[2 ̄√2,?2 ̄√2(2 ̄√2i+2 ̄√2k)]
12[2 ̄√,?i?k]
現(xiàn)在搓蚪,把前面算出來(lái)的qp再次拿出來(lái):
qp=[?1,2 ̄√i+j]
qpq?1=[?1,2 ̄√i+j]12[2 ̄√,?i?k]
=12[?2 ̄√?(2 ̄√i+j)?(?i?k),i+k+2 ̄√(2 ̄√i+j)?i+2 ̄√j+k]
=12[?2 ̄√+2 ̄√,i+k+2i+2 ̄√j?i+2 ̄√j+k]
=[0,i+2 ̄√j+k]
這下是純四元數(shù)了丁鹉,并且它的范數(shù)是:
|qpq?1|=12+2 ̄√2+12 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄√=4 ̄√=2
這和原始的p的范數(shù)一致揣钦。
下面的圖像展示了旋轉(zhuǎn)結(jié)果:
所以我們可以看到拂盯,這個(gè)結(jié)果是一個(gè)純四元數(shù),并且原四元數(shù)的向量的范數(shù)也保持住了团驱。但是還有一個(gè)問(wèn)題:向量被旋轉(zhuǎn)了90度而不是45度嚎花。這剛好是我們需要的度數(shù)的兩倍紊选!為了正確地讓一個(gè)向量繞某個(gè)軸向量旋轉(zhuǎn)某個(gè)角度道逗,我們必須以目標(biāo)角度的一半來(lái)計(jì)算滓窍。因此吏夯,我們構(gòu)造了下面的四元數(shù):
q=[cos12θ,sin12θv?]
這就是旋轉(zhuǎn)四元數(shù)的一般形式!
四元數(shù)插值
在計(jì)算機(jī)圖形學(xué)中使用四元數(shù)裆赵,其中一個(gè)重要原因是四元數(shù)非常適合用來(lái)表示空間中的旋轉(zhuǎn)战授。四元數(shù)解決了其他3維空間旋轉(zhuǎn)算法會(huì)遇到的惱人的問(wèn)題,比如使用歐拉角來(lái)表示旋轉(zhuǎn)操作時(shí)會(huì)遇到的萬(wàn)向節(jié)鎖問(wèn)題(Gimbal lock)惕橙。
使用四元數(shù)弥鹦,我們可以定義好幾種方案來(lái)表示3維空間的轉(zhuǎn)動(dòng)插值彬坏。第一種是SLERP膝晾,它被用來(lái)把一個(gè)點(diǎn)(物體)從一個(gè)朝向平滑地插值到另一個(gè)朝向血当。第二個(gè)是SLERP的擴(kuò)展版本臊旭,被稱為SQAD,它被用來(lái)處理用一系列朝向定義得到的一條路徑的插值佳谦。
SLERP
SLERP代表SphericalLinear Int*erp*olation钻蔑。SLERP可以在2個(gè)朝向之間平滑地插值咪笑。
第一個(gè)朝向設(shè)為q1
府喳,第二個(gè)朝向設(shè)為q2(請(qǐng)記住钝满,這2個(gè)指示朝向的四元數(shù)是單位四元數(shù)弯蚜,不然閱讀下文會(huì)混亂)剃法。被插值前的點(diǎn)設(shè)為p,插值后的點(diǎn)設(shè)為p′晋柱。而插值參數(shù)t诵叁,當(dāng)t=0時(shí)會(huì)把p轉(zhuǎn)到q1,當(dāng)t=1時(shí)會(huì)轉(zhuǎn)到q2
碑诉。
標(biāo)準(zhǔn)的線性插值公式是(譯注:這個(gè)公式是笛卡爾坐標(biāo)系下的进栽,不是指四元數(shù)):
p′=p1+t(p2?p1)
應(yīng)用這個(gè)等式的一般步驟是:
計(jì)算p1快毛、p2
之間的差番挺。
根據(jù)參數(shù)t建芙,計(jì)算兩個(gè)點(diǎn)的差的小數(shù)值(因?yàn)?<=t<=1)
把第二步的值加上原始點(diǎn)的值禁荸,算出結(jié)果
我們可以把這個(gè)基礎(chǔ)公式,套用到2個(gè)用四元數(shù)表示的朝向的插值上瑰妄。
四元數(shù)的差
根據(jù)上面的公式的第一步间坐,我們必須先計(jì)算q1竹宋、q2
的差蜈七。對(duì)于四元數(shù)來(lái)說(shuō)莫矗,這等價(jià)于計(jì)算2個(gè)四元數(shù)的角度差(angular difference):
diff=q?11q2
(譯注:由q1pdiff=q2
推出 )
四元數(shù)的冪運(yùn)算
接下來(lái)的目標(biāo)是干掉上面四元數(shù)的差的分?jǐn)?shù)部分,方法是計(jì)算四元數(shù)的t次冪(就是上面的那個(gè)插值參數(shù)t庵芭,區(qū)間是[0,1])喳挑。
四元數(shù)的冪運(yùn)算的一般化公式是:
qt=exp(tlogq)
其中滔悉,(純)四元數(shù)的exp函數(shù)的公式是:
eq=exp(q)=exp([0,θv?])
=[cosθ,sinθv?]
(純)四元數(shù)的對(duì)數(shù)公式是:
logq=log(cosθ+sinθv?)
=log(exp(θv?))
=θv?
=[0,θv?]
(譯注:上述的2次公式推導(dǎo)回官,其實(shí)省略了很多證明過(guò)程歉提。具體可以參考:四元數(shù)公式的補(bǔ)充)
對(duì)于t = 0苔巨,我們有:
q0=exp(0logq)
=exp([cos(0),sin(0)v?])
=exp([1,0])
=[1,0]
而對(duì)于t = 1侄泽,有:
q1=exp(1logq)=q
2個(gè)四元數(shù)的分?jǐn)?shù)差
對(duì)于角旋轉(zhuǎn)的插值計(jì)算悼尾,我們利用q1和q2的角度分?jǐn)?shù)差來(lái)調(diào)整原始朝向q1:
q′=q1(q?11q2)t
這也就是使用四元數(shù)的球面線性插值的一般形式。然而未状,這不是slerp函數(shù)的常用形式司草。
我們可以應(yīng)用類似的用于計(jì)算向量的球面插值公式埋虹,到四元數(shù)里吨岭。計(jì)算向量的球面插值的一般形式定義如下:
vt=sin((1?t)θ)sinθv1+sin(tθ)sinθv2
用圖像表示如下:
這個(gè)公式可以原封不動(dòng)地應(yīng)用到四元數(shù):
qt=sin((1?t)θ)sinθq1+sin(tθ)sinθq2
但這個(gè)公式需要提供角度θ
辣辫,我們可以計(jì)算q1和q2的點(diǎn)積從而得出角度θ
:
cosθ=q1?q2|q1||q2|
cosθ=s1s2+x1x2+y1y2+z1z2|q1||q2|
θ=cos?1(s1s2+x1x2+y1y2+z1z2|q1||q2|)
注意事項(xiàng)
這個(gè)方案有2個(gè)問(wèn)題急灭,必須在實(shí)現(xiàn)過(guò)程中加以考慮葬馋。
第一肾扰,如果四元數(shù)點(diǎn)積的結(jié)果是負(fù)值集晚,那么后面的插值就會(huì)在4D球面上繞遠(yuǎn)路偷拔,這并不是我們想要的莲绰。為了解決這個(gè)問(wèn)題蛤签,我們測(cè)試點(diǎn)積的結(jié)果,當(dāng)結(jié)果是負(fù)值時(shí)踏枣,我們將2個(gè)四元數(shù)的其中一個(gè)取反茵瀑,取反它的系數(shù)和向量部分马昨,并不會(huì)改變它代表的朝向鸿捧。而經(jīng)過(guò)這一步操作匙奴,可以保證這個(gè)旋轉(zhuǎn)走的是最短路徑妄荔。
當(dāng)q1
和q2的角度差非常小,小到導(dǎo)致sinθ=0時(shí)荒揣,會(huì)出現(xiàn)第二個(gè)問(wèn)題系任。如果這個(gè)情況出現(xiàn)了俩滥,當(dāng)我們除以sinθ時(shí)就會(huì)得到一個(gè)未定義的結(jié)果霜旧。在這個(gè)情況下敞嗡,我們可以回退去使用q1和q2
的線性插值喉悴。
SQUAD
正如一個(gè)SLERP可以被用來(lái)計(jì)算四元數(shù)之間的插值箕肃,一個(gè)SQUAD (Spherical andQuadrangle)可以被用來(lái)對(duì)旋轉(zhuǎn)路徑進(jìn)行平滑插值勺像。
如果我們有四元數(shù)序列:
q1,q2,q3,?,qn?2,qn?1,qn
然后我們?cè)俣x一個(gè)"輔助"四元數(shù)(si
)吟宦,它是一個(gè)中間控制點(diǎn):
si=exp(?log(qi+1q?1i)+log(qi?1q?1i)4)qi
所以殃姓,沿著子曲線的朝向可以定義為:
qi?1,qi,qi+1,qi+2
在t時(shí)刻的朝向就是:
squad(qi,qi+1,si,si+1,t)=slerp(slerp(qi,qi+1,t),slerp(si,si+1,t),2t(1?t))
總結(jié)
除了特別難理解之外蜗侈,相比矩陣或歐拉角踏幻,四元數(shù)在表示旋轉(zhuǎn)這個(gè)事情上,擁有一些明顯的優(yōu)點(diǎn)信卡。SLERP和SQUAD坐求,提供了一種使得在朝向之間可以平滑過(guò)渡的方法晌梨。使用四元數(shù)來(lái)串聯(lián)"旋轉(zhuǎn)"仔蝌,要比使用矩陣快得多敛惊。對(duì)于單位四元數(shù)瞧挤,逆向旋轉(zhuǎn)可以通過(guò)對(duì)向量部分取反來(lái)實(shí)現(xiàn)特恬。而計(jì)算一個(gè)矩陣的逆矩陣是被認(rèn)為比較慢的癌刽,如果這個(gè)矩陣未被標(biāo)準(zhǔn)正交化的話(標(biāo)準(zhǔn)正交矩陣的逆矩陣是它的轉(zhuǎn)置矩陣)显拜。從四元數(shù)轉(zhuǎn)換到矩陣远荠,要比從歐拉角轉(zhuǎn)換到矩陣快一點(diǎn)譬淳。四元數(shù)只需要4個(gè)數(shù)字(如果旋轉(zhuǎn)四元數(shù)已經(jīng)單位化了那么只需要3個(gè)瘦赫,實(shí)數(shù)部分可以在運(yùn)行時(shí)計(jì)算)來(lái)表示一個(gè)旋轉(zhuǎn)确虱,而矩陣需要至少9個(gè)數(shù)字校辩。盡管使用四元數(shù)有這么多優(yōu)點(diǎn)宜咒,還是有缺點(diǎn)存在的故黑。因?yàn)楦↑c(diǎn)數(shù)的舍入運(yùn)算錯(cuò)誤场晶,四元數(shù)可能會(huì)變無(wú)效诗轻。不過(guò)扳炬,這個(gè)錯(cuò)誤可以通過(guò)重新單位化四元數(shù)來(lái)避免恨樟。使用四元數(shù)最具威懾性的地方厌杜,還是四元數(shù)的理解難度大。我希望這個(gè)問(wèn)題可以通過(guò)閱讀本文來(lái)解決。存在一些已經(jīng)實(shí)現(xiàn)了四元數(shù)咆槽、并且是正確的的數(shù)學(xué)程序庫(kù)秦忿。在我的個(gè)人經(jīng)驗(yàn)里灯谣,我發(fā)現(xiàn)GLM(OpenGL Math Library)是一個(gè)優(yōu)秀的數(shù)學(xué)庫(kù)胎许,它的四元數(shù)的實(shí)現(xiàn)極其不錯(cuò)辜窑。如果你對(duì)在你的程序中使用四元數(shù)感興趣穆碎,那么我會(huì)推薦你使用這個(gè)數(shù)學(xué)庫(kù)所禀。