技術背景
在前面一篇文章中我們介紹了尤拉角死鎖問題的一些產生背景,還有基於四元數的求解方案。四元數這個概念雖然重要,但是很少會在通識教育課程中涉及到,更多的是一些圖學或者是工程學當中才會進行講解。本文主要是面向四元數,相比上一篇文章更加詳細的介紹和總結一下四元數的一些運演演算法則,還有基於四元數的插值法。
基本運算
說到四元數,很多人可能會覺得有點陌生,但是如果說複數,很多人就都有學習過。我們一般用\(z=x+iy\)這樣的形式去定義一個複數(Complex Number),其中\(x\)是實部,而\(y\)是虛部,\(i\)是虛數單位,並且有\(i^2=-1\)這樣的特性。並且對於一個虛數而言,如果取自然指數(運算規則為:\(e^{i\theta}=cos\theta+i\ sin\theta\)),還能夠得到一個很美的數學公式:\(e^{i\pi}=-1\),這就是非常著名的尤拉公式。
而四元數Quaternion這個概念的提出,更像是對複數的一個擴充套件,我們通常把四元數寫成這樣的形式:
\[q=s+ix+jy+kz
\]
其中\(s,x,y,z\)都是實數,並滿足這樣的一些運算規則:
\[i^2=j^2=k^2=ijk=-1\\
i\times j=k,j\times k=i,k\times i=j\\
j\times i=-k,k\times j=-i,i\times k=-j
\]
以上都是四元數的一些基本定義,接下來我們逐一看一下四元數的一些基本運算。
四元數加法
兩個四元數的加法就是將「實部虛部」對應位置做元素求和:
\[q_1+q_2=(s_1+ix_1+jy_1+kz_1)+(s_2+ix_2+jy_2+kz_2)=(s_1+s_2)+i(x_1+x_2)+j(y_1+y_2)+k(z_1+z_2)
\]
可以簡單證明,四元數的加法滿足交換律、結合律和分配律,這裡不過多展開介紹。
四元數縮放
在係數縮放這一點上,四元數與複數是一致的:
\[\lambda q=\lambda s+i\lambda x+j\lambda y+k\lambda z
\]
逐一對四元數中的各項元素進行縮放即可。
四元數乘法
四元數的乘法是所有元素之前都要運算一遍:
\[\begin{align*}
q_1q_2&=(s_1+ix_1+jy_1+kz_1)*(s_2+ix_2+jy_2+kz_2)\\
&=(s_1s_2-x_1x_2-y_1y_2-z_1z_2)\\
&\ +i(s_1x_2+s_2x_1+y_1z_2-y_2z_1)\\
&\ +j(s_1y_2+s_2y_1+x_2z_1-x_1z_2)\\
&\ +k(s_1z_2+s_2z_1+x_1y_2-x_2y_1)
\end{align*}
\]
這個運算過程是這樣的,我們令\(q=q_1q_2=s+ix+jy+kz\),那麼這個乘法運算最終組成\(s\)這個元素的,分別是\(s_1*s_2, (ix_1)*(ix_2), (iy_1)*(iy_2), (iz_1)*(iz_2)\)這些項,而\(i^2=j^2=k^2=-1\),因此最終得到\(s=(s_1s_2-x_1x_2-y_1y_2-z_1z_2)\)。但是直到這裡為止,我們所涉及到的元素乘法只是在「實部」和相同的「虛數單位」之間的運算,如果一旦涉及到不同的「虛數單位」之間的乘法運算,那就要自動轉化成向量叉乘,比如\(ij=ji=k\)。因此,我們要計算\(q\)中的\(z\)項的時候,只需要計算\(s_1z_2, s_2z_1, x_1y_2, x_2y_1\)這些項即可,同時注意符號的變換,那麼得到的最終的結果就是如上所示。
需要注意的是,四元數與複數的最大的一點不同,複數乘法是有交換律的,而四元數沒有
。舉個例子說,我們可以計算一下\(q_1,q_2\)的對易:
\[\begin{align*}
[q_1, q_2]&=q_1q_2-q_2q_1\\
&=(s_1s_2-x_1x_2-y_1y_2-z_1z_2)+i(s_1x_2+s_2x_1+y_1z_2-y_2z_1)+j(s_1y_2+s_2y_1+x_2z_1-x_1z_2)+k(s_1z_2+s_2z_1+x_1y_2-x_2y_1)-(s_2s_1-x_2x_1-y_2y_1-z_2z_1)-i(s_2x_1+s_1x_2+y_2z_1-y_1z_2)-j(s_2y_1+s_1y_2+x_1z_2-x_2z_1)-k(s_2z_1+s_1z_2+x_2y_1-x_1y_2)\\
&=2i(y_1z_2-y_2z_1)+2j(x_2z_1-x_1z_2)+2k(x_1y_2-x_2y_1)
\end{align*}
\]
那麼也就是說,這兩個四元數\(q_1,q_2\)之間是非對易的,也就是不可交換的。但是,四元數的運算是滿足結合律和分配率的
。
由於上面的這種四元數乘法展開,寫起來過於繁雜,我們考慮對其進行一定的簡化。如果我們假定2個純虛數(\(s=0\)):
\[a=ix_1+jy_1+kz_1\\
b=ix_2+jy_2+kz_2
\]
其實類似於這種形式的四元數,實際上就是三維空間中的向量,那麼這兩者的點積和叉積有:
\[a\cdot b=x_1x_2+y_1y_2+z_1z_2\\
a\times b=(y_1z_2-y_2z_1)i+(z_1x_2-z_2x_1)j+(x_1y_2-x_2y_1)k
\]
需要注意的是,這裡的叉積是向量叉積,跟四元數中的「虛數單位」相比,最大的一點不同就是:在向量叉積中,\(i\times i=0\),但是在四元數的乘法中,\(i\times i=-1\)(非常重要)。
那麼在有了以上的兩個公式之後,我們就可以對四元數的乘法表示做一個簡化:
\[q_1q_2=s_1s_2-a\cdot b+s_ab+s_ba+a\times b
\]
實四元數和純四元數
對於一個實四元數而言,就是取\(x=y=z=0\):
\[q_r=s
\]
對於一個純四元數而言,就是取\(s=0\):
\[q_i=ix+jy+kz
\]
四元數共軛
對四元數的所有「虛部」取負數,即是四元數的共軛:
\[q^*=s-ix-jy-kz
\]
單位四元數
四元數的模的定義跟複數是一致的:
\[|q|=\sqrt{s^2+x^2+y^2+z^2}=\sqrt{qq*}
\]
而單位四元數的定義即是模為1的四元數:
\[s^2+x^2+y^2+z^2=1
\]
如果給定的一個四元數不是單位四元數,那麼我們可以對其進行規範化:
\[q'=\frac{q}{\sqrt{s^2+x^2+y^2+z^2}}
\]
四元數的逆
對於一個單位四元數而言,因為有\(qq^*=1\),所以單位四元數的逆就是其共軛四元數。如果是對於更加一般的場景,我們可以這樣考慮:
\[q(q^{-1}*|q|^2)=|q|^2\\
qq^*=|q|^2\\
q^{-1}=\frac{q^*}{|q|^2}
\]
比較特殊地,對於單位四元數\(q^{-1}=q^*\)。
四元數的二元表示
類似於複數的二元形式,通常一個四元數也可以被表示成如下的二元形式:
\[q=s+v\hat{q}=[s,v\hat{q}]
\]
其中\(v=[x,y,z],\hat{q}=[i,j,k]\)。關於此處的乘法描述,其實有一定的不嚴謹性,因為它既不是點積,也不是叉積,也不是外積,而是普通的元素乘。這種元素乘的概念在計算機領域是很常用的,但是在數學上其實並不是很常用。在這種二元描述下,四元數的乘法形式會略有調整:
\[q_1q_2=[s_1s_2-(v_1\hat{q}_1)\cdot (v_2\hat{q}_2), s_1v_2\hat{q}_2+s_2v_1\hat{q}_1+(v_1\hat{q}_1)\times(v_2\hat{q}_2)]
\]
四元數點積
上面的章節中提到過四元數的普通乘法,但其實四元數也像普通的向量一樣可以進行點積運算:
\[q_1\cdot q_2=s_1s_2+v_1\cdot v_2
\]
這也是受益於四元數的二元表示,使得我們在書寫結果的時候可以更加的簡練。
四元數的指數
我們先來回顧一下複數\(z=x+iy\)的指數計算,根據泰勒展開公式\(f(x)=\sum_n\frac{f^{(n)}(x_0)}{n!}(x-x_0)^n\)(比較特殊地,\(e^x=\sum_{k=0}^\infty\frac{x^k}{k!}\))對\(e^z\)在\(y=0\)處的展開有:
\[\begin{align*}
e^{z}&=e^{x+iy}=e^xe^{iy}\\
&=e^x\left(
1+iy-\frac{1}{2!}y^2-\frac{i}{3!}y^3+\frac{1}{4!}y^4+\frac{i}{5!}y^5-\frac{1}{6!}y^6-\frac{i}{7!}y^7+...
\right)
\end{align*}
\]
對比一下常用的三角函數的泰勒展開式(相關證明見參考連結2):
\[sin\ x=x-\frac{1}{3!}x^3+\frac{1}{5!}x^5-\frac{1}{7!}x^7+...\\
cos\ x=1-\frac{1}{2!}x^2+\frac{1}{4!}x^4-\frac{1}{6!}x^6+...
\]
代入可得:
\[e^{z}=e^xe^{iy}
=e^x\left(
cos\ y+i\ sin\ y
\right)
\]
也即,對於一個純虛數\(i\theta\)而言,其指數為:\(e^{i\theta}=cos\theta+i\ sin\theta\)。那麼類似的,對於一個二元表示的四元數\(q=s+v\hat{q}\)有:
\[\begin{align*}
e^q&=e^{s+v\hat{q}}\\
&=e^s\left(
1+v\hat{q}-\frac{1}{2!}(v\hat{q})^2-\frac{1}{3!}(v\hat{q})^3+\frac{1}{4!}(v\hat{q})^4+\frac{1}{5!}(v\hat{q})^5-\frac{1}{6!}(v\hat{q})^6-\frac{1}{7!}(v\hat{q})^7+...
\right)
\end{align*}
\]
這裡有一點不同的是,我們計算四元數的冪次的時候需要謹慎,可以先手動計算一下:
\[\begin{align*}
(v\hat{q})^2&=0-(v\hat{q})\cdot (v\hat{q})+0+0+(v\hat{q})\times(v\hat{q})=-|v|^2\\
(v\hat{q})^3&=-|v|^2(v\hat{q})\\
(v\hat{q})^4&=|v|^4\\
(v\hat{q})^5&=|v|^4(v\hat{q})\\
(v\hat{q})^6&=-|v|^6\\
(v\hat{q})^7&=-|v|^6(v\hat{q})\\
&...
\end{align*}
\]
代入四元數的指數部分進行計算可得:
\[\begin{align*}
e^q&=e^{s+v\hat{q}}\\
&=e^s\left(
1+v\hat{q}-\frac{1}{2!}|v|^2-\frac{1}{3!}|v|^2(v\hat{q})+\frac{1}{4!}|v|^4+\frac{1}{5!}|v|^4(v\hat{q})-\frac{1}{6!}|v|^6-\frac{1}{7!}|v|^6(v\hat{q})+...
\right)\\
&=e^s\left(
cos|v|+\frac{v\hat{q}}{|v|}sin|v|
\right)
\end{align*}
\]
這就是四元數的指數運算。
四元數的指數表示
區分於上一個章節中的四元數的指數運算,這個章節我們是要用一個指數形式去表示任意給定的一個四元數。因為在上一個章節中我們發現,一個四元數的指數形式是另外一個四元數,因此,理論上說我們可以用一個指數形式來表示任意的一個四元數。我們首先還是參考一下複數的指數表示:
\[z=x+iy=\sqrt{x^2+y^2}\left(\frac{x}{\sqrt{x^2+y^2}}+i\frac{y}{\sqrt{x^2+y^2}}\right)=\sqrt{x^2+y^2}e^{i\frac{y}{|y|}\ arccos\left(\frac{x}{\sqrt{x^2+y^2}}\right)}
\]
類似地,一個四元數可以表示為:
\[q=s+v\hat{q}=\sqrt{s^2+|v|^2}\left(
\frac{s}{\sqrt{s^2+|v|^2}}+\frac{v\hat{q}}{|v|}\frac{|v|}{\sqrt{s^2+|v|^2}}
\right)=\sqrt{s^2+|v|^2}e^{\hat{q}\frac{v}{|v|}\ arccos\left(\frac{s}{\sqrt{s^2+|v|^2}}\right)}
\]
比較有意思的是,如果我們取\(q=s+ix+jy+kz\)中的\(y=0,z=0\)時,我們發現\(v=\pm|v|,\hat{q}=i\),這樣一來,四元數的指數表示形式就和複數的指數表示形式完全對應上了。
四元數的對數
在上一個章節中,如果我們把一個四元數表示成一個指數的形式,就會很大程度上方便我們去計算一個四元數\(q=s+v\hat{q}\)的對數:
\[\begin{align*}
log(q)&=log\left(\sqrt{s^2+|v|^2}e^{\hat{q}\frac{v}{|v|}\ arccos\left(\frac{s}{\sqrt{s^2+|v|^2}}\right)}\right)\\
&=log\left(\sqrt{s^2+|v|^2}\right)+\hat{q}\frac{v}{|v|}\ arccos\left(\frac{s}{\sqrt{s^2+|v|^2}}\right)
\end{align*}
\]
這樣就得到了四元數的對數的二元表示形式。
四元數的冪次
瞭解了四元數的指數和對數的計算模組之後,我們可以計算一個四元數的冪次。正是由於四元數的指數表示形式,使得我們可以將四元數的冪次簡單的轉化成乘法的表示形式:
\[q^t=\left[\sqrt{s^2+|v|^2}e^{\hat{q}\frac{v}{|v|}\ arccos\left(\frac{s}{\sqrt{s^2+|v|^2}}\right)}\right]^t=
\left(s^2+|v|^2\right)^{\frac{t}{2}}e^{\hat{q}\frac{vt}{|v|}\ arccos\left(\frac{s}{\sqrt{s^2+|v|^2}}\right)}
\]
那麼這就得到了四元數的冪次表達形式。
尤拉角旋轉四元數
在上一篇文章中我們提到過,每一個四元數其實都可以對應於三維空間的一個向量旋轉,一個四元數\(q\)作用在一個空間向量\(v\)上就會旋轉得到一個新的空間向量:
\[v'=qvq^*
\]
而如果給定了三維空間中的旋轉尤拉角,在四元數中就可以表示為相應的旋轉四元數。比如繞\(X\)軸旋轉\(\beta\)角所對應的四元數為:\(q=cos\frac{\beta}{2}+i\ sin\frac{\beta}{2}\),繞\(Y\)軸旋轉\(\alpha\)角所對應的四元數為:\(q=cos\frac{\alpha}{2}-j\ sin\frac{\alpha}{2}\),繞\(Z\)軸旋轉\(\gamma\)角所對應的四元數為:\(q=cos\frac{\gamma}{2}+k\ sin\frac{\gamma}{2}\)。而通常使用的\(ZXY\)順規可表示為:
\[q=\left(cos\frac{\alpha}{2}-j\ sin\frac{\alpha}{2}\right)\left(cos\frac{\beta}{2}+i\ sin\frac{\beta}{2}\right)\left(cos\frac{\gamma}{2}+k\ sin\frac{\gamma}{2}\right)
\]
關於更多的旋轉四元數的內容,可以閱讀一下參考連結3中的內容。
向量變換四元數
這個問題的定義是比較清晰的,如果給定空間中的兩個不同的向量,能否直接獲得這兩個向量之間變換的四元數呢?如果用公式來表示就是:已知\(\textbf{v}_1,\textbf{v}_2\)兩個空間向量,求\(q\)使得\(\textbf{v}_2=q\textbf{v}_1q^*\)。關於這個問題的求解,在參考連結3中也是有介紹的,這裡再簡單提一下計算方法:
\[\textbf{u}=\textbf{v}_1\times\textbf{v}_2\\
cos\theta=\frac{\textbf{v}_1\cdot\textbf{v}_2}{|\textbf{v}_1||\textbf{v}_2|}\\
q=cos\frac{\theta}{2}+i\ sin\frac{\theta}{2}\textbf{u}\cdot i+j\ sin\frac{\theta}{2}\textbf{u}\cdot j+k\ sin\frac{\theta}{2}\textbf{u}\cdot k
\]
這個演演算法的本質,其實就是先用向量叉乘找到旋轉軸,然後計算兩個向量之間的夾角,最後再使用四元數的繞旋轉軸旋轉指定角度的公式計算,就可以得到對應的空間向量變換的四元數。
總結概要
本文主要介紹四元數Quaternion的一些基本運演演算法則。四元數的概念,更像是複數的一個推廣,在圖學和工程學中有大量的應用,在蛋白質結構預測軟體AlphaFold和MEGA-Protein中都大量的使用了四元數的計算。而大部分的四元數的教材中寫的計演演算法則,經常把各類乘法混在一起使用,閱讀起來非常難受,因此只好自己總結一下四元數的相關運算。並且跟我們所熟悉的複數運算有一定的對比,更加容易去理解四元數的概念。
版權宣告
本文首發連結為:https://www.cnblogs.com/dechinphy/p/quaternion.html
作者ID:DechinPhy
更多原著文章請參考:https://www.cnblogs.com/dechinphy/
打賞專用連結:https://www.cnblogs.com/dechinphy/gallery/image/379634.html
騰訊雲專欄同步:https://cloud.tencent.com/developer/column/91958
CSDN同步連結:https://blog.csdn.net/baidu_37157624?spm=1008.2028.3001.5343
51CTO同步連結:https://blog.51cto.com/u_15561675
參考連結
- https://www.qiujiawei.com/understanding-quaternions/
- http://www.songho.ca/math/taylor/taylor_tri.html
- https://www.cnblogs.com/dechinphy/p/quaternion.html