,如下圖一,把灰色箭頭想象成是一架飛機,紅,綠藍三個圈看作是三個外圍控制器,外圈帶動所有里圈運動,里圈的運動不影響外圈。
1,首先,繞Y軸旋轉(旋轉綠圈),來確定前進的方向。這時紅圈與藍圈都跟着旋轉。
2,然后,繞x軸旋轉(旋轉紅圈),讓飛機仰視或俯視。這時藍圈跟着一起旋轉,綠圈不動。
3,最后,繞z軸旋轉(旋轉藍圈),讓飛機左右傾斜。這時只有藍圈在轉,紅綠圈不動。
經過這三個步驟,我們可以把飛機調整到任意想要的角度。這也是FPS相機中常用的 yaw, pitch, row三個操作。
在步驟2中,若旋轉紅圈過程中,恰巧旋轉到了圖二所示狀態,然后進行步驟3時會發現,旋轉藍圈與綠圈效果一樣。
也就是這種狀態下,旋轉Y或Z軸效果一樣了,都只能使飛機左右傾斜,而不能再俯視或仰視(它只能頭朝天),這下壞了,飛機操作失靈了,只能向上直沖。這就所謂的萬向節死鎖,gimbal lock.
可見,歐拉角旋轉使用的是物體的局部坐標系,旋轉過程是對局部坐標的三個軸X,Y,Z分別進行的旋轉。
【所謂的死鎖,僅是在一個操作單元,即XYZ組成的任意一個次序中出現了無法控制的現象,如上面飛機失靈的情況,我們可以繼續操作X軸(紅圈)來調整飛機的仰視和俯視,這時飛機又可以回到水平飛行的正常軌道上來了】
【但是,對於使用歐拉角旋轉的程序,沒有人會去專門寫邏輯來判斷是否發生了萬向節死鎖,D3D底層API更不會去管,因此我們的程序就會出BUG]
yaw 是左右看,pitch是俯視或仰視,roll就是左右傾斜。
如果我們寫了一個FPS的飛機控制程序,當發生上面的死鎖時,調用pitch就與調用roll一樣了,當發現飛機朝上飛時,於是調用pitch想調整機頭朝下,結果卻發現飛機只是左右傾斜而機頭仍然朝上直飛!出BUG了。
參考:http://www.cnitblog.com/luckydmz/archive/2010/09/07/68674.html
按上述方法在U3D編輯器中可以試驗出萬向節死鎖,如下圖,物體先繞X軸旋轉90度后,再去調節Y軸和Z軸的旋轉角時,發現物體只能繞Z軸旋轉了,調節Y軸的旋轉值時物體還是在繞Z軸轉,死鎖了。
歐拉旋轉的計算可以有許多次序,每種次序得到的結果都不一樣,U3D為YXZ次序,如果不按此次序來旋轉,你就會看不懂它的表現
死鎖的的情況是與歐拉旋轉的計算次序有關的。如YXZ次序時,只要繞X軸的旋轉為90度,不管繞Y,Z旋轉多少,都是死鎖;XYZ次序時,只要繞Y的旋轉為90度,不管繞X,Z的旋轉是多少,都是死鎖;其它類推,死鎖取決於中間次序的那個軸。
如上面U3D中的試驗,當我們先給rotation的Y設置90度,再調節X和Z的旋轉值時,只要X不為90度就無死鎖,這說明U3D在計算歐拉角時使用的計算順序正是上面的YXZ順序。
PS,歐拉角並不是個特殊算法的產物,它和矩陣旋轉本質相同,就是說利用矩陣來實現旋轉也會有死鎖,參考下面的這篇文章: