OpenGL中的glLoadIdentity、glTranslatef、glRotatef原理【轉帖】

OpenGL中的glLoadIdentity、glTranslatef、glRotatef原理

 
單位矩陣  對角線上都是1,其餘元素皆爲0的矩陣。
在矩陣的乘法中,有一種矩陣起着特殊的作用,如同數的乘法中的1,我們稱這種矩陣爲單位矩陣.
它是個方陣,除左上角到右下角的對角線(稱爲主對角線)上的元素均爲1以外全都爲0.

OpenGL中的座標用齊次座標表示,即(x,y,z)表示成(x',y',z',h),其中x=x'/h; y=y'/h; z=z'/h. 通常h取1. 比如空間中的點(2,3,4),在OpenGL中將表示成(2,3,4,1). 齊次座標表示方式適合於矩陣運算,也很方便地表示了無窮遠的點,比如(1,0,0,0)就表示x軸上無窮遠的點,因爲1/0是無窮大,這裏約定0/0=0.

接着要說點矩陣(線性代數)的知識。OpenGL裏面的平移、旋轉、縮放等變換均是線性變換,用矩陣相乘來表示。以平移變換爲例,請見官方對glTranslatef函數的說明。假設有點(3,3,3),如果把該點沿x軸移動2單位,沿y軸移動3單位,沿z軸移動4單位,那麼該點會是(3+2, 3+3, 4+4) = (5,6,7). 用矩陣表示是:

2009-11-29 18-42-47.png

左邊的矩陣稱爲平移變換矩陣,若把2、3、4換成x、y、z,則用它乘以一個齊次座標表示的向量,就可以將該向量平移(x,y,z). 旋轉變換和縮放變換都像平移變換一樣可用一個矩陣來表示。這裏可以不用理會這些矩陣長什麼樣,只需清楚它們乘以一個齊次座標表示的向量,就可以使該向量發生需要的變換。

把平移變換矩陣記爲T(x,y,z),旋轉變換矩陣記爲R(x,y,z,s),表示繞向量(x,y,z)旋轉s角度;把向量記爲X。這裏只需要知道它們是矩陣就行了,現在要把一個點X,如(3,3,3,1),移動(2,2,2)單位,再繞y軸旋轉30度角,用矩陣表示即R(0,1,0,30)*T(2,2,2)*X,可以理解爲離X最近的矩陣最先作用。理解這個順序很重要,這樣,所有變換都可以用一串矩陣的相乘來表示,計算機裏面也確實是這麼做的。

介紹完基本的數學知識,下面說OpenGL的作用機制。OpenGL有個變換矩陣堆棧,堆棧就像子彈夾一樣,先進的後出。OpenGL中的每個向量,在被定義之後進入到OpenGL世界中,都必須先乘以這個變換矩陣堆棧的棧頂變換矩陣。如下圖所示:

2009-11-29 19-12-50.png

理解完上面的知識,再來理解glLoadIdentity、glTranslatef、glRotatef這些函數幹了什麼就容易多了。這些函數就是對這個堆棧的操作:

  • glTranslatef:將T(x,y,z)右乘與堆棧的棧頂變換矩陣。右乘的解釋,假設目前棧頂變換矩陣爲M,那麼就相當於把M修改爲M*T.
  • glRotatef :將R(x,y,z,s)右乘與堆棧的棧頂變換矩陣。
  • glLoadIdentity:將堆棧的棧頂變換矩陣設置成單位矩陣。
  • glPushMatrix:將堆棧的棧頂變換矩陣複製一份,然後Push到堆棧中。所謂Push,就像塞子彈一樣把一個矩陣壓入到堆棧中,此時,棧頂就是這個新的矩陣了,注意定義的向量都是和棧頂變換矩陣作用的。
  • glPopMatrix:將堆棧的棧頂變換矩陣Pop出來。

該講的講完了,下面出幾道題目練習下吧。

1、OpenGL代碼是:glLoadIdentity(); glTranslate3f(4,5,1); glRotate3f(0,1,0,90); glVertex3f(1,1,1); 請問此時棧頂變換矩陣是什麼?(1,1,1)這個點到了OpenGL世界中的點是什麼?

答:棧頂變換矩陣是T(4,5,1)*R(0,1,0,90),(1,1,1)到OpenGL世界中的座標是T(4,5,1)*R(0,1,0,90)*(1,1,1).

2、解釋爲什麼使用glPushMatrix和glPopMatrix的組合可以隔離這兩個函數中的變換,使之不影響後面的點?

答:glPushMatrix新壓入的變換矩陣是複製了原來的棧頂變換矩陣,所以它繼承了之前的變換,此後執行glTranslatef、glRotatef這些函數時,修改的是棧頂變換矩陣,在glPopMatrix之前的點都將受到棧頂變換矩陣的作用,之後用glPopMatrix,把棧頂變換矩陣Pop掉,此時的棧頂變換矩陣又還原成原來的那個棧頂變換矩陣。

3、爲什麼有時候glTranslate3f和glRotate3f能顛倒有時候又不能?

答:矩陣A乘以矩陣B未必等於矩陣B乘以矩陣A,當它們相等時,很多隻是巧合。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章