四元數(Quaternion)和旋轉 尤拉角

2022-06-07 03:00:10 字數 4314 閱讀 6337

缺點:尤拉旋轉

缺點:四元數旋轉

缺點:四元數和尤拉角

基礎知識=(

(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...