在使用opengl進行模型旋轉的時候乙個比較經典的問題就是萬向鎖,這是在使用opengl的旋轉函式時會面臨的問題。
glrotatef(rot,x,y,z);
這是opengl的旋轉函式,第乙個引數代表角度,其餘引數分別代表旋轉軸x,y,z。正常情況下,選擇繞乙個軸旋轉是沒有問題的,不管怎麼旋轉都是符合我們的預期的。但是當使用多個軸的時候就會出現問題,首先我們需要通過二維的座標來控制三維的旋轉,這就相當於我們少了一維座標,那麼第三維必須要通過一定的計算來得到旋轉的資訊。
在利用glrotate進行旋轉時,使用的是尤拉角,在旋轉的過程中座標軸也會跟隨旋轉,這樣在旋轉一定的角度後會失去乙個軸,其中的兩個軸會重疊,也就是其中的乙個方向會被鎖定,這樣當在二維空間拖動滑鼠時就會只有兩個軸有反應,自然也就會產生不符合我們預期的旋轉。
現在針對萬向鎖的一般解決方法是利用四元數,四元數是由乙個三維向量和乙個旋轉角組成(x,y,z,w),我的理解是四元數不像尤拉角單獨繞某個軸進行旋轉,四元數是利用乙個三維向量計算出乙個新的軸,然後繞這個軸來旋轉,並且四元數需要儲存舊的旋轉,以便在舊的旋轉的基礎上進行新的旋轉。
四元數利用乘法來表示旋轉
q1 * q2 =(w1*w2 - x1*x2 - y1*y2 - z1*z2) +
(w1*x2 + x1*w2 + y1*z2 - z1*y2) i +
(w1*y2 - x1*z2 + y1*w2 + z1*x2) j +
(w1*z2 + x1*y2 - y1*x2 + z1*w2) k
每一次新的四元數乘以舊的四元數得到4x4的矩陣,這個矩陣就是旋轉後的結果,不過要注意旋轉的順序,前乘與後乘順序是不同的的,pq代表先旋轉q後旋轉p。在opengl中也經常會遇到矩陣相乘先後的問題,不同的順序結果是不同的。
另外,四元數還有乙個優勢,是可以進行插值。
首先,我們在螢幕上移動的是乙個弦,也就是直線,因為螢幕是二維的。雖然我們的移動速度是相同的,但是角度的速度卻不是恆定的。所以為了讓角度恆定,我們會將直線移動對映到球面的弧度上,也就是進行球面插值。(arcball軌跡球就是非常經典的萬向鎖解決辦法,其中就用到了球面的對映相關的內容)
這樣通過四元數計算得到的矩陣就不存在萬向鎖問題了。
以上內容僅供總結記錄。
關於四元數更加詳細的內容可以參考以下。
徹底搞懂四元數
詳解萬向鎖
對於萬向鎖這個東西,很久都沒理解,找了很多資料,最後終於應該是被我明白,自我感覺很多教程沒有突出重點,或者我們沒有意識到他的重點在哪。發現的另外一篇比較易懂的則是 這篇部落格可以說是對後者的詳解,兩者可以參考。什麼是尤拉角?用一句話說,尤拉角就是物體繞座標系三個座標軸 x,y,z軸 的旋轉角度。1,...
OpenGL 02 尤拉角 萬向鎖 四元數
在learnopengl 學習,記錄一下學習筆記 目錄引用部落格尤拉角與旋轉矩陣的轉換關係 尤拉角就是我們日常生活中常用的表示旋轉的三維向量的乘積。在unity中,用zxy的順序來表示旋轉,即選旋轉z軸 x軸 y軸的方式來表示旋轉。在給出逆時針旋轉的角度為正時 與右手系旋轉方向相同的為旋轉正方向 繞...
對萬向鎖的理解
這周依然在繼續unity的學習,在開發過程中遇到了萬向鎖的問題。經過查詢資料對萬向鎖有了初步的理解。萬向鎖官方解釋 一旦選擇 90 作為pitch角,就會導致第一次旋轉和第三次旋轉等價,整個旋轉表示系統被限制在只能繞豎直軸旋轉,丟失了乙個表示維度。個人理解 在unity中有x軸 y軸 z軸,在它們在...