四元數
定義
【四元數的視覺化】 https://www.bilibili.com/video/BV1SW411y7W1/?share_source=copy_web&vd_source=ac806c24de13bf5f509bf105a8578e24
最左側實數稱為標量部分,右側\(ijk\)虛部稱為向量vector
用四元數來描述矩陣相乘
\(q_1\cdot q_2 = (\frac{q_1}{\lVert q_1\rVert})\lVert q_1 \rVert\cdot q_2\)
\(q_1\cdot q_2\)會將\(q_2\)的大小拉伸到\(q_1\)的大小(上市括號外的內容),然後施加一個特殊的四維旋轉(上式括號內的內容)
四維超球投影到三維空間,在單位球內的是\([-1,1]^4\),超出\([-1,1]^4\)的點投影到了單位球外,延申至無窮遠
投影過程可參考二維到一維、三維到二維的球極投影
四元數在三維點上的應用
【四元數和三維轉動,可互動的探索式影片(請看連結)】 https://www.bilibili.com/video/BV1Lt411U7og/?share_source=copy_web&vd_source=ac806c24de13bf5f509bf105a8578e24
當想繞某個軸旋轉某個角度時,首先用一個單位向量(\(ijk\)經過歸一化,三者平方和為\(1\))定義這個軸,對於三維向量,其實部為\(0\),\(xyz\)作為\(ijk\)的係數
之後,若想旋轉的角度是\(\theta\),則使用半形\(\theta/2\)的餘弦值作為實部,正弦值乘以四元數向量
如:\(q=(\cos(40^{\circ}/2)+\sin(40^{\circ}/2)(0.67i-0.67j-0.33k))\)
如果想對一點\(p\)應用這個旋轉,只需\(p'=q\cdot p\cdot q^{-1}\)即可,就能得到旋轉後的座標\(p'\),\(p'\)是一個四元數,其實部為0,\(ijk\)向量係數即為旋轉後的三維座標
為什麼是\(q\cdotp\cdot q^{-1}而不是q\cdot p\)?
\(q\)的本質是一個空間變換,旋轉變換是其中一環,旋轉*縮放=空間變換
四元數有一個性質是可逆的
那麼(旋轉*縮放)p / 縮放 = 旋轉*p?
然而這樣做是不行的,因為空間變換\(q\)必定包含旋轉和縮放
於是可以用到左右手螺旋定則
\(q\)左乘\(p\)或右乘\(p\),只會影響旋轉的方向,不會影響縮放的方向
而\(q\cdot p\)和\(q^{-1}\cdot p\)的異同在於二者旋轉一樣縮放相反
於是可以透過\(q\cdot p\cdot q^{-1}\),左乘\(q\)和右乘\(q^{-1}\)分別完成半個\(\theta\)角度的旋轉,而\(q\)與\(q^{-1}\)又剛好抵消掉了縮放
四元數插值
要在兩個四元數之間進行球面線性插值(Spherical Linear Interpolation), Slerp()。球面線性插值可在球面表面大圓的弧線上做勻速率運動,因此對於旋轉插值有兩個期望的性質
- 旋轉插值路徑使得扭矩最小化:兩個旋轉之間的路徑是旋轉空間中所能得到的最短路徑
- 插值有很頂角速度:動畫引數\(t\)的變化量和所得旋轉的變換了的關係在插值過程中是恆定的,換句話說,在插值範圍內,插值速度是恆定的
Shoemake(1985)提出的公式
PBRT中的公式
以一種更直觀的方式理解
考慮在2D平面下的兩個單位圓上的向量\(v_0\)和\(v_1\),二者夾角為\(\theta\),想要計算二者之間角度為\(\theta'\)的插值向量,可以尋找正交於\(v_0\)的向量\(v_\bot\),再應用三角恆等式\(v'=v_0\cos\theta'+v_\bot\sin\theta'\)
那麼要計算\(q'\),首先要在四元數空間種計算一個正交座標系,一個軸為\(q_1\),另一個是於\(q_1\)正交的四元數\(q_\bot\),這樣兩軸就構成張開\(q_1\)和\(q_2\)的基
可以透過將\(q_2\)投影到\(q_1\),再由\(q_2\)減去這一部分得到\(q_\bot\)
\(q_\bot=q_2-(q_1\cdot q_2)q_1\)
那麼插值四元數為\(q'=q_1\cos(\theta t)+\hat q_\bot\sin(\theta t)\)
要注意的點
在插值時應檢查兩個四元數是否幾乎平行
-
二者幾乎平行,則按順序對四元數分量用普通的線性插值以避免數值不穩定
-
否則,按\(q_\bot=q_2-(q_1\cdot q_2)q_1\)
\(q'=q_1\cos(\theta t)+\hat q_\bot\sin(\theta t)\)
插值計算四元數