推導正交投影變換

原文來自CSDN http://blog.csdn.net/popy007/article/details/4126809

-潘宏

-2009.4.20 

-本人水平有限,疏忽錯誤在所難免,還請各位數學高手、編程高手不吝賜教

-email: [email protected]

 

    之前我們在《深入探索透視投影變換》以及《深入探索透視投影變換(續)》中研究了OpenGLD3D以及M3G的透視投影變換的原理以及生成方法。這些方法在當前的主流圖形API中得到了普遍使用。但關於投影應用,還有一類經常使用的投影方式需要我們深入理解——正交投影,我們在本篇文章裏面研究它(這裏假設讀者已經看過前兩篇文章,並理解了絕大多數的理論,因爲正交投影比透視投影的推導關係簡單得多,因此我們的推導會非常得快,如果讀者有任何的不解,請參考前兩篇文章或者通過email聯繫我)。

在具體研究之前我覺得有必要把平面投影的分類簡單介紹一下,目的是爲了讓大家有一個總體的認識,從而更好的理解這個知識體系。請看下圖:

 

      

平面投影分爲平行投影和透視投影兩種類型,後者我們在前兩篇文章中介紹了。平行投影則是具有矩形觀察體的投影方式(透視投影則是視錐觀察體),它不會根據物體離視點的遠近縮放物體(透視投影則會)。平行投影可以分成側投影和正交投影兩種類型。這兩種類型如何區分呢?我們繼續看圖吧:

上圖中,v是投影平面,n是它的法線。p和q是平面外兩點,p’和q’分別是它們在平面上的投影點。q的投影方向向量爲Q =單位化(q’-q),而p的投影方向向量爲P = 單位化(p’-p),其中Q不平行於n而P平行於n,則q的投影叫做側投影,而p的投影叫做正交投影。正交投影是我們今天的研究對象。

實際上上面對平面投影的分類還可以繼續向下細分,比如透視投影可以分爲一滅點、二滅點以及三滅點透視投影。側投影則可以繼續分爲散點側投、斜二軸側投等等。而正交投影則可以分成軸側投影以及多視點正交投影等等。如果讀者對此感興趣,可以參考相關的圖形學教程。

接下來我們研究正交投影。分別介紹OpenGL、D3D以及M3G的。我們的環境約定(左右手座標系、行列向量乘法、CVV範圍)仍然尊重相應API自己的設置。

OpenGL正交投影變換

    下圖是OpenGL的右手座標系中觀察空間的情形,我們看到的是正交投影的矩形觀察體,原點是相機位置,n是近裁剪平面到相機平面的距離,f是遠裁剪平面到相機平面的距離。p是觀察體中的一個點,p’是它投影之後的點。

投影之後我們有關係:

因爲是正交投影,沒有統一的投影射線目標點,因此投影之後的x和y不會變,而z則永遠地變成了-n,跑到了投影平面上(我們讓投影平面和近裁剪平面重合),它已經沒用了,則我們用這個沒用的信息保存z(爲了之後片元操作的時候用),寫爲:

從而在z方向上構建 CVV,使得當z在近裁剪平面的時候,az+b=-1,而z在遠裁剪平面的時候az+b=1(OpenGL的CVV的z範圍是[-1,1],我已經說了三遍了,如果讀者感到迷惑不解,強烈建議把前兩篇文章理解)。我們算出a和b

然後我們就通過當前的結果反推正交投影矩陣版本一

 

 

接着把x和y建立成CVV情形(簡單的線性插值)

 

 

反推正交投影矩陣版本二(最終版本)

 

 

 

則右邊的那個矩陣就是OpenGL的正交投影矩陣,它可以通過glOrtho創建出來。如果你讀過並理解了之前兩篇文章,你會覺得我的推導越來越簡潔利落了:)OpenGL的解決了,下面是D3D的。

D3D正交投影變換

    下圖是D3D左手座標系中觀察空間的情形。因爲是左手座標系,因此近裁剪平面在z = n平面,而遠裁剪平面在z = f平面。

 

投影之後,有                                                                                                    

 

用第三個沒用的信息保存z,寫爲

 

使得(D3D的CVV的z範圍是[0, 1])

反推正交投影矩陣版本一

對x和y進行CVV線性插值

 

 

分兩種情況討論(如果讀者對此不清楚,請參考第二篇文章《深入探索透視投影變換(續)》):

(1)       投影平面居中,銷掉兩邊的1/2,然後反推正交投影矩陣

 

 

後面那個矩陣就是相應正交投影矩陣,這個也是D3DXMatrixOrthoLH方法所使用的情況。

 

(2)       一般情況,投影平面不一定居中,直接通過投影結果反推正交投影矩陣

 

 

後面那個矩陣就是相應的正交投影矩陣,這個也是D3DXMatrixOrthoOffCenterLH方法所使用的情況。好了,D3D的也介紹完畢,接下來是M3G的。

 

M3G正交投影變換

M3G是對OpenGL的封裝,因此環境和OpenGL的相同,我們從對x和y的插值來看

 

 

M3G只使用居中的投影平面,因此可以銷掉兩邊的1/2,得到

 

 

接着反推出正交投影矩陣

 

 

最後那個矩陣就是M3G的正交投影矩陣,也就是Camera.setParallel所使用的形式。

結束語

以上介紹了三個API所使用的正交投影矩陣的生成方法,三者的正交投影矩陣依然可以通過視野(FOV)以及投影平面的寬高比(Aspect Ratio)來設置,這裏請讀者自行推導,可以參考第二篇文章《深入探索透視投影變換(續)》。

正交投影矩陣和透視投影矩陣一樣可以有無窮多個,但原理相同,不同的只是環境。目前正交投影在3D引擎中有着和透視投影同樣的地位,它至少是3D用戶界面系統的基礎。因此,有必要清晰地理解正交投影矩陣和透視投影矩陣的原理,如此才能夠真正創建、修改、使用好圖形引擎。


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