由正交矩陣構建的仿射變換矩陣求逆的快速算法


原文地址http://blog.csdn.net/i_dovelemon/article/details/45827953

齊次坐標

我們都知道,在3D圖形學中,所有的變換都可以划分為三種最基礎的變換方式,分別為:

    旋轉變換
    縮放變換
    平移變換

通過對這三種變換進行組合,就能夠實現任意的變換形式。

在3D坐標下,如果向量使用3D向量表示的話,對於這三種變換的處理方式如下:

    旋轉變換:乘法運算
    縮放變換:乘法運算
    平移變換:加法運算

也就是說,這三種變換的處理方式是不同的,旋轉和縮放變換能夠通過乘法實現,而平移需要通過加法來實現。 
所以圖形學的大師們,覺得這樣的計算方法十分的繁瑣,他們希望能夠使用一種統一的方式來對坐標進行變換。所以他們決定,將平移變換也使用乘法來統一這種計算方法。 
所以,就提出了齊次坐標的概念。 
齊次坐標,即使用N+1維的空間向量來表示N維的向量。通過這樣的方法就能夠使用乘法對平移變換也進行計算。 
而平移變換對向量是沒有用處的,只有對點才有用。所以就出現了齊次坐標(x,y,z,w),其中當w等於1的時候,表示的是點向量,0的時候,表示的就是普通向量。

仿射變換

在明白了齊次坐標之后,我們來看看什么是仿射變換。 
從學習3D以來,就經常聽到說3D圖形學里面的變換都是仿射變換。以前也查過這個概念,但是過不了多久就忘記了。主要就是因為沒有深刻的理解到這個概念的意義,所以就很容易遺忘掉它。直到今天遇到了問題,才深刻的理解仿射變換時什么樣的變換。 
仿射變換的定義如下:先進行線性變換,在進行平移變換的變換稱之為仿射變換。注意這個定義里面,具有先后關系,我就是忽略了這個先后關系才對很多變換,搞的迷迷糊糊的。 
在3D中,所謂的線性變換,指的就是旋轉變換和縮放變換這兩種。也就是說,我們在3D游戲開發中,使用的矩陣變換,實際上是一種仿射變換,它會先對向量進行旋轉和縮放(這兩種變換的先后順序,無關緊要),然后在對向量進行平移操作。 
這就是仿射變換的定義。一定要牢記,仿射變換時具有先后關系的兩種變換的聯合。

正交矩陣

在學校學習線性代數的時候,那時候還是很清楚什么是正交矩陣。但是拋去了課本,就忘記了什么是正交矩陣。依稀只記得好像是任意兩個行向量相乘的結果為0,也就是相互垂直的關系。今天也一直以這個定義來推導正交矩陣求逆運算的簡化步驟,發現總是得不出正確的結果。所以,就重新學習了下什么是正交矩陣。 
正交矩陣的定義:

a.矩陣中的任意兩個行向量的乘積為0b.矩陣中每一個行向量都是單位向量

沒有經過縮放的旋轉矩陣就是一個正交矩陣。

3D圖形中求逆的幾何意義

數學上對矩陣的求逆運算,在學習線性代數的時候,一直就不知道為毛搞這么一個東東。(這也體現了中國填鴨式教育,先交給你是這么做,至於為什么這么做,以后才知道)直到自己學習游戲開發,特別是進行3D變換的時候,才明白了。 
在3D中,變換都是通過矩陣來實現的。比如一個矩陣的功能是先讓某個向量旋轉A角度,在平移B距離。那么這個矩陣的逆矩陣的效果就應該是先讓向量平移-B距離,然后在旋轉-A角度。也就是說,矩陣和它的逆矩陣對向量進行的變換效果是相反的過程。

矩陣乘法

在學習3D游戲編程的過程中,經常會遇到一個問題,在解決某種變換的時候,網上給出這個變換的矩陣總是有兩種不同的格式,他們互為轉置。我以前一直不明白怎么回事。直到自己在學習OpenGL(先學DirectX)之后,才明白原來是兩個標准3D API對於向量的定義方式不同導致的。 
當我們講解某個變換的時候,作者大多使用自己熟悉的方式來進行講解。熟悉DirectX的人,會使用行向量的方式對矩陣進行描述,熟悉OpenGL的人,會使用列向量的方式對矩陣進行描述。所以就會導致出現兩個相互為轉置的矩陣出現。 
比如說,在DX中,一個向量實際上是這樣的:[x,y,z,w] 
它在進行矩陣乘法的時候,是這樣的:[x,y,z,w] * M (右乘矩陣的方式) 

而對於OpenGL來說,它的向量表示是這樣的: 

[x, 
y, 
z, 
w] 

它在進行矩陣乘法的時候,是這樣的: 
M * transpose[x,y,z,w] (左乘矩陣的方式)

所以,這就導致了理解上的偏差。初學者最好弄明白這些基礎的概念。

正交矩陣求逆

前面講了一大堆,就是為了得出怎么樣快速的求出一個正交矩陣的逆矩陣出來。

這里統一使用OpenGL的矩陣表示方法。 
假如有一個矩陣: 
[m00 m01 m02 m03] 
[m10 m11 m12 m13] 
[m20 m21 m22 m23] 
[0 0 0 1]

在3D中這個矩陣有兩個不同的部分構成,

一個是: 
[m00 m01 m02] 
[m10 m11 m12] 
[m20 m21 m22] 
的旋轉矩陣R(由於是正交矩陣,這里就只能是未進行縮放的單位向量的正交旋轉矩陣)

另外一個就是: 
[1 0 0 m03] 
[0 1 0 m13] 
[0 0 1 m23] 
[0 0 0 1] 
的平移矩陣 
這兩個部分構成。

也就是可以簡化為如下的矩陣表示:

[R T] * V 
[0 0 0 1]

前面說過,要想求一個矩陣的逆矩陣,就是構造一個具有相反效果的矩陣即可,那么上面的矩陣是一個仿射矩陣,它是先進行R旋轉,然后在進行T平移操作,所以它的逆操作就應該是: 
先平移-T,然后在旋轉-R

所以得出下面的矩陣: 
[Transpose_R] * [Transpose_T
[0 0 0 1] [0 0 0 1]

由於R是正交矩陣,正交矩陣有一個特性: 
正交矩陣的逆矩陣等於轉置矩陣 
所以就能夠很直觀的得出正交矩陣構成的仿射矩陣的逆矩陣了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM