缺點:尤拉旋轉
缺點:四元數旋轉
缺點:四元數和尤拉角
基礎知識=(
(x,y
,z)sinθ2
, cosθ2
) 來執行乙個旋轉。具體來說,如果我們想要把空間的乙個點p繞著單位向量軸u = (x, y, z)表示的旋轉軸旋轉θ角度,我們首先把點p擴充套件到四元數空間,即四元數p = (p, 0)。那麼,旋轉後新的點對應的四元數(當然這個計算而得的四元數的實部為0,虛部係數就是新的座標)為:′=
qpq−
1=(cosθ2
, (x,y
,z)sinθ2
),q−1
=q∗n
(q),由於u是單位向量,因此n(
q)=1,即q−1
=q∗。右邊表示式包含了四元數乘法。相關的定義如下:1q
2=(v
1→×v
2→+w
1v2→
+w2v
1→,w
1w2−
v1→⋅
v2→)
共軛四元數:q∗=
(−v⃗
,w)四元數的模:
n(q) = √(x^2 + y^2 + z^2 +w^2),即四元數到原點的距離
四元數的逆:q−1
=q∗n
(q)k
∗=kv
∗,以此證明w與v、k在同一平面內,且與v夾角為θ。′=
qpq−
1的值。建議大家一定要在紙上計算一邊,這樣才能加深印象,連筆都懶得動的人還是不要往下看了。最後的結果p` = ((1, 0, -1), 0),即旋轉後的頂點位置是(1, 0, -1)。
:每一次旋轉實際上需要兩個四元數的參與,即q和q*;
所有用於旋轉的四元數都是單位四元數,即它們的模是1;
除非你對四元數非常了解,那麼不要直接對它們進行賦值
。如果你不想知道原理,只想在unity裡找到對應的函式來進行四元數變換,那麼你可以使用這兩個函式:quaternion
.euler
和quaternion
.eulerangles
。它們基本可以滿足絕大多數的四元數旋轉變換。
和其他型別的轉換:=
((x,
y,z)
sinθ
2, cosθ2
):y = sin(y/2)cos(z/2)cos(x/2)+cos(y/2)sin(z/2)sin(x/2)
z = cos(y/2)sin(z/2)cos(x/2)-sin(y/2)cos(z/2)sin(x/2)
w = cos(y/2)cos(z/2)cos(x/2)-sin(y/2)sin(z/2)sin(x/2)
q = ((x, y, z), w)
:euler to quaternion
2. quaternion to euler
3. angleaxis to quaternion
4. quaternion to angleaxis
四元數的插值
四元數的建立
.angleaxis(float angle, vector3 axis)
,它可以返回乙個繞軸線axis旋轉angle角度的四元數變換。我們可以乙個vector3和它進行左乘,就將得到旋轉後的vector3。在unity裡只需要用乙個「 * 」操作符就可以進行四元數對向量的變換操作,相當於我們上述講到的p′=
qpq−
1操作。如果我們想要進行多個旋轉變換,只需要左乘其他四元數變換即可。例如下面這樣:
vector3 newvector = quaternion.angleaxis(90, vector3.up) * quaternion.lookrotation(somedirection) * somevector;
例如,如果我們需要對旋轉進行插值,我們可以首先使用
quaternion
.eulerangles
來得到尤拉角度,然後使用
mathf.clamp
對其進行插值運算。
最後更新quaternion
.eulerangles或者使用quaternion.euler(yourangles)來建立乙個新的四元數。
又例如,如果你想要組合旋轉,比如讓人物的腦袋向下看或者旋轉身體,兩種方法其實都可以,但一旦這些旋轉不是以世界座標軸為旋轉軸,比如人物扭動脖子向下看等,那麼四元數是乙個更合適的選擇。unity還提供了transform.forward, transform.right and transform.up 這些非常有用的軸,這些軸可以和quaternion.angleaxis組合起來,來建立非常有用的旋轉組合。例如,下面的**讓物體執行低頭的動作:
transform.rotation = quaternion.angleaxis(degrees, transform.right) * transform.rotation;
補充:尤拉旋轉
尤拉旋轉是怎麼運作的
),有兩種座標系可以選擇:
繞座標系e下的z軸旋轉α,繞座標系e在繞z軸旋轉α後的新座標系e'下的y軸旋轉β,繞座標系e'在繞y軸旋轉β後的新座標系e''下的x軸旋轉r, 即在旋轉時,把座標系一起轉動;
transform.rotate(new vector3(0, 30, 90));
原模型的方向和執行結果如下:
// first case
transform.rotate(new vector3(0, 30, 0));
transform.rotate(new vector3(0, 0, 90));
// second case
// transform.rotate(new vector3(0, 0, 90));
// transform.rotate(new vector3(0, 30, 0));
兩種情況的結果分別是:
.rotate
(new
vector3(0
, 30
, 90
));是和第一種情況中的**是一樣的結果,即先旋轉y、再旋轉z。進一步實驗,我們會發現transform
.rotate
(new
vector3(30
, 90
, -40
));的結果是和transform
.rotate
(new
vector3(0
, 90, 0
));transform
.rotate
(new
vector3(30
, 0, 0
));transform
.rotate
(new
vector3(0
, 0, -40
));的結果一樣的。你會問了,文件中不是明明說了旋轉順序是z、x、y嗎?怎麼現在完全反過來了呢?原因就是我們之前說的兩種座標系的選擇。在一次呼叫transform
.rotate
的過程中,座標軸是不隨每次單個座標軸的旋轉而旋轉的。而在呼叫
transform
.rotate
後,這個旋轉座標系才會變化。也就是說,transform
.rotate
(new
vector3(30
, 90
, -40
));執行時使用的是第一種情況,而transform
.rotate
(new
vector3(0
, 90, 0
));transform
.rotate
(new
vector3(30
, 0, 0
));transform
.rotate
(new
vector3(0
, 0, -40
));每一句則是分別使用了上一句執行後的座標系,即第二種座標系情況。因此,我們看起來順序好像是完全是反了,但結果是一樣的。
數學模型
萬向節鎖
transform.rotate(new vector3(0, 0, 40));
transform.rotate(new vector3(0, 90, 0));
transform.rotate(new vector3(80, 0, 0));
我們只需要固定中間一句**,即使y軸的旋轉角度始終為90°,那麼你會發現無論你怎麼調整第一句和最後一句中的x或z值,它會像乙個鐘錶的表針一樣總是在同乙個平面上運動。
數學解釋
來自為知筆記(wiz)
Unity中四元數quaternion的學習筆記
筆記來自 遊戲引擎架構 jason gregory著 第二版,4.4四元數,page144。3 3矩陣可以表示三位中的任何旋轉,但是他又三個問題。1.9個浮點型表述只有三個自由度的旋轉顯得多餘。2.矩陣乘法過於複雜對於計算機來說,我們需要運算更快的旋轉方法。3.不能平滑插值。如此,我們有quater...
Ogre中的四元數Quaternion類
四元數最早是為了擴充套件複數應用而產生與發展起來的。然而,人們發現四元數也可以應用在計算機圖形學上,作為表現旋轉的可選擇方法之一。普通的複數形式可以寫成 xi y 其中x 是虛部,y是實部。不可思議的是 i的平方等於 1,那個 1的平方根就像你應該知道的那樣,其並不存在。因此取名叫 虛數 假如xi ...
四元數和方向
三維計算中,經常需要計算方向,假定三維座標係為右手系,z向上,y向前,x 向右。通常的作法是,getlookat,獲取eye和target,來計算dir dir target eye 除此,可以使用四元數來計算 ogre vector3 dir mnode getorientation ogre v...