欧拉角万向节锁问题
這兩天一直糾結在歐拉角的萬向節鎖問題上,查了很多資料,可是依舊沒有完全弄懂這個問題,引用《3D數學基礎:圖形與游戲開發》一書中的一句話,”如果您從來沒有遇到過萬向鎖情況,你可能會對此感到困惑,而且不幸的是,很難在本書中講清楚這個問題,你需要親身經歷才能明白。”,認為這個確實需要在以后的實踐過程中遇到這個問題時,才會理解地更加透徹.
雖然沒有完全弄明白,但還是有一點總結:
(1)萬向節鎖問題,和具體的旋轉順序相關,例如最常用的ZXY順序,在X軸旋轉為+-90°時,無論Z軸和Y軸的旋轉角度如何變化,物體將在某個維度上被鎖住這篇文章中第二部分手機旋轉的例子比較生動形象;如果此時X軸不是+-90°,那么在X軸不變的前提下,依舊可以通過選取適當的Z軸和Y軸旋轉值使物體指向三維空間中的任意方向.
(2)(1)中的鎖住并不是很多文章中所說的物體無法通過旋轉改變方向了,而是若要改變成某個方向,那么yaw-pitch-roll的角度會發生”突變”,如何理解這種突變呢?借助一個例子來,該例子來源于這篇文章,對于一個炮塔模型,假設地面上的一個炮塔有兩個旋轉軸:Y(對應于yaw)垂直于地面,使炮塔可以平行地面360°旋轉(12點方向為0°);X(對應于pitch)平行于地面,使得炮口可以繞著它上下90°旋轉(平行地面設為0°),這里我們省略roll旋轉角,因為roll是對炮口本身進行旋轉(炮口本身的旋轉對于這里的例子沒有太大意義,為了簡單,故省略),這里的X和Y已經足夠表示天空中的任意一點!
這時,一架敵機從3點鐘方向飛來,其在炮臺坐標系的坐標是XY-(10,-90),Y=-90°的原因是炮口初始對準的是12點方向,需要順時針旋轉90°(以逆時針為正)指向三點方向.飛機保持9點鐘的方向飛行,隨著飛機逐步向炮臺正上方飛來,X不斷增大,當飛機恰好飛到炮塔頂端時,即X=90°時(XY-(90,-90)),飛機突然向6點鐘方向飛行,且假設其飛至XY-(89, -180),我們發現,簡單地轉動X軸或者Y軸都無法使得炮口由正上方(89,-90)轉到飛機所在的方向,只有先將Y軸順時針轉動90°,再將X軸逆時針轉動1°,才能重新指向飛機的位置,我們發現,炮口相比于之前(10,-90)->(90,-90)的方向連續變化,現在卻發生了“突變”.那么這種突變的影響是,在飛機由(90,-90)->(89,-180)時,飛機是直線飛行,若炮口繼續保持勻速轉動,炮口方向在由(90,-90)->(89,-180)時,其過程可能是這樣的(90,-90)->(89.8,-108)->(89.6,-126)->(89.4, -144)->(89.2, -162)->(89, -180),如果在坐標系中畫出這些點并連接起來,就會發現其近似一根弧線,這樣,飛機是直線飛行,但炮口在這段時間內是曲線運動,結果就是這段時候內炮口會丟失目標!上述這個過程在做插值動畫時尤為明顯(插值過程就是上述的坐標變化過程),而萬向節鎖的真正問題也在于此!并不是上述鏈接中說的,炮口方向無法變化.
(3)雖然可以通過修改旋轉順序來改善萬向節鎖問題(例如Unity里采用的ZXY順序,就可以確保Y在0~360角度旋轉時都不會發生這個問題),但治標不治本,修改旋轉順序只能在某個旋轉角上避免出現萬向節鎖,可是其它角度依舊會有問題;實際上,”任何使用三個數來表達3D方位的系統,若能保證空間的唯一性,就都會遇到這個問題”.解決的辦法是,采用四元數,具體課搜索其它博客了解,在這多說一句,四元數理解起來相對歐拉角比較困難,但可以有效解決萬向節鎖的問題;
(4)歐拉角出現萬向節鎖的另一個原因是,別名!例如(2)中的炮臺,(90,-90)和(90,-180)實際上都是炮口豎直朝上,因此也導致了旋轉路徑發生偏移!
(5)萬向節死鎖會導致位置上連續變化 在數值表示上確是非連續的,給定的兩個關鍵幀之間無法平滑過渡.
實際上,自己對于萬向節鎖以及相關的問題還存在很多困惑,
(1)這篇文章中的數學證明過程無法理解,感覺作者的證明過程有點以結果來證明結果,特別是”Rb = Rr~*Ry*Rr 要得到繞 坐標系E在繞z軸旋轉r后的新系E’下的y軸旋轉β的旋轉矩陣為Rb,可以先應用Rr~這時可以視作在E下,然后使用E下的旋轉Ry繞舊的y軸旋轉,在應用Rr轉回到E’”這一段,完全不知所云!
(2)這篇文章里提及的靜態歐拉角和動態歐拉角;
(3)我在草稿上演示旋轉過程時,發現對于給定的角度(x1, y1,z1),分別繞X,Y,Z軸以一定的順序對指定的點或者線段進行旋轉時,最終的結果都是(2)中靜態歐拉角的結果,但看到的書籍和博客關于這個都是指動態歐拉角的結果,疑惑不解!
(4)物體坐標系和世界坐標系的軸發生重合,為何會導致萬向節鎖問題?
這些問題困擾了很久,這兩天一直在查資料,畫圖驗證,演算,依舊沒有完全弄明白,而且弄得心神疲憊,在此做記錄,希望以后實踐經歷豐富后,再逐步解決這些問題!
解決該問題過程中一些不錯的博客:
1.Unity 中的旋轉
2.【Unity技巧】四元數(Quaternion)和旋轉
3.游戲動畫中歐拉角與萬向鎖的理解
4.歐拉角與萬向節死鎖
5.萬向節死鎖問題
總結
- 上一篇: 【视频处理】嵌入式硬件编码(6818)进
- 下一篇: ALPS TCP新建配置——网络测试仪实