三維座標要建乙個4 4的矩陣 平移 旋轉 縮放

2021-09-30 20:43:32 字數 3427 閱讀 1792

移植不知道三維物體的旋轉平移縮放和矩陣的關係。找到這篇文章借鑑一下。

**:我們應該怎麼平移乙個三維空間中的點呢?答案很簡單,我們只需要對這個點的座標中的每個分量(x,y,z)和對應軸上的平移距離相加即可。 

例如,點p1(x1,y1,z1)在x軸y軸以及z軸上分別平移δx,δy,δz到新的點p2(x2,y2,z2),那麼我們只需在座標對應的分量上加上這些增量就可以確定點p2的座標了。

x2 = x1 + δx 

y2 = y1 + δy 

z2 = z1 + δz

很簡單是嗎?那麼接下來再讓我們來看一看另一種變換:旋轉。

旋轉相比較平移來說,會略顯複雜一些。因為我們需要指明以下幾個方面來描述乙個旋** 

旋轉軸 

旋轉方向 

旋轉角度

在這裡,我們假設點p需要繞z軸順時針旋轉β度。

x1 = l·sinα 

y1 = l·cosα

由於是繞z軸旋轉,因此z座標不變,因此此處不考慮。 

同樣根據三角函式公式,我們可以繼續計算出p2的具體座標: 

x2 = l·sin(α + β) 

y2 = l·cos(α + β)

再讓我們回憶一下中學時代的幾何數學的內容,對青春的回憶又把我們帶回了課堂上老師聲嘶力竭向我們傳授的內容——兩角和與差: 

cos(α+β)=cosα·cosβ-sinα·sinβcos(α-β)=cosα·cosβ+sinα·sinβsin(α+β)=sinα·cosβ+cosα·sinβsin(α-β)=sinα·cosβ-cosα·sinβ

回憶起老師傳授給我們的知識之後,接下來結合p1的座標表示形式我們就可以把p2的座標換乙個表示形式了。 

x2 = l·(sinα·cosβ+cosα·sinβ) = cosβ·x1 + sinβ·y1 

y2 = l·(cosα·cosβ-sinα·sinβ) = cosβ·y1 - sinβ·x1 

z2 = z1

因此,在已知p1點座標以及旋轉角度β的情況下,我們就可以根據以上公式分別求出p2點座標的各個分量。如果再結合上一小節中平移乙個點的公式來看,我們可以發現似乎並不需要矩陣,而僅僅通過兩組表示式就能實現座標的變換。但是……

當然,從理論上講我們的確可以只通過數學公式就能實現變換,但實際的情況卻是在變換十分複雜時,直接使用數學表示式來進行運算也是相當繁複的。因此,在現實中常常使用矩陣(由m × n個標量組成的長方形陣列)來表示諸如平移、旋轉以及縮放等線性變換。而另乙個更有趣的事實是,當兩個變換矩陣a和b的積為p=ab時,則變換矩陣p相當於a和b所代表的變換。舉乙個例子,若a為旋轉矩陣,b為平移矩陣,則矩陣p就能夠實現旋轉和平移變換。不過需要注意的是,矩陣乘法不符合交換律,因此ab和ba並不相等。說了這麼多,我們似乎還是沒有回答為什麼三維空間需要乙個4×4矩陣來實現變換呢?下面我們就帶著這個問題,分別看看3×3矩陣和4×4矩陣的使用吧。

首先,我們先來看乙個矩陣乘以乙個三維向量的算式:

x2 = a·x1 + b·y1 + c·z1 

y2 = d·x1 + e·y1 + f·z1 

z2 = g·x1 + h·y1 + i·z1

為了將矩陣等式和之前小節的數學表示式聯絡起來,下面我們就將旋轉表示式和該矩陣等式做乙個對比。 

x2 = a·x1 + b·y1 + c·z1x2 = cosβ·x1 + sinβ·y1 

y2 = d·x1 + e·y1 + f·z1y2 = cosβ·y1 - sinβ·x1 

z2 = g·x1 + h·y1 + i·z1z2 = z1

通過對比x2,我們可以發現a=cosβ,b=sinβ,c=0;對比y2,也可以發現d=-sinβ,e=cosβ,f=0;最後對比z2,可以確定g=0,h=0,i=1;將這個結果帶入到之前的矩陣中,我們的等式就可以變成下面這個樣子:

我們已經通過乙個3×3矩陣搞定了旋轉變換,顯然如果這個3×3矩陣真的是完美的解決變換的方案的話,那麼它顯然也必須要適合於其他的變換,例如平移。但是它到底能否滿足平移的需求呢?下面我們還是通過對比矩陣等式和數學表示式的方式,來尋找答案。 

x2 = a·x1 + b·y1 + c·z1x2 = x1 + δx 

y2 = d·x1 + e·y1 + f·z1y2 = y1 + δy 

z2 = g·x1 + h·y1 + i·z1z2 = z1 + δz

通過對比,我們發現平移和旋轉之間很有趣的乙個區別,那就是平移的表示式中帶有常量δx,而無論是旋轉的表示式還是矩陣等式中都不存在這樣乙個常量能夠與之對應。那麼問題就來,我們沒有辦法使用3×3的矩陣來表示平移。這個問題該如何解決呢?答案其實很簡單,那就是使用4×4矩陣來實現。但是隨之而來的乙個問題就是如何讓乙個三維座標和乙個4×4的矩陣相乘呢?

為了解決三維向量和4×4矩陣相乘的問題,我們機智的為三維向量新增了第四個分量,這樣之前的三維向量(x,y,z)就變成了四維的(x,y,z,w),這樣由4個分量組成的向量便被稱為齊次座標。需要說明的是,齊次座標(x,y,z,w)等價於三維座標(x/w,y/w,z/w),因此只要w分量的值是1,那麼這個齊次座標就可以被當作三維座標來使用,而且所表示的座標就是以x,y,z這3個值為座標值的點。因此,為了和4×4矩陣相乘,我們的p1點座標就變成了(x1,y1,z1,1)。而矩陣等式也變成了下面這個樣子:

x2 = a·x1 + b·y1 + c·z1 + dx2 = x1 + δx 

y2 = e·x1 + f·y1 + g·z1 + hy2 = y1 + δy 

z2 = i·x1 + j·y1 + k·z1 + lz2 = z1 + δz 

1 = m·x1 + n·y1 + o·z1 + p

通過對比x2,我們可以發現a=1,b=0,c=0,d=δx;對比y2,也可以發現e=0,f=1,g=0,h=δy;再對比z2,可以確定i=0,j=0,k=1,l=δz;最後還可以根據表示式求出m=0,n=0,o=0,p=1;這樣,我們就求出了我們的4×4的平移矩陣:

寫到這裡,不知各位是否還記得之前在介紹矩陣乘法的時候我有提到過兩個變換矩陣a和b的積p=ab,相當於a和b所代表的變換。事實上在遊戲程式設計中,常常需要把一連串的變換預先通過計算成為單一矩陣,所以就不能即存在3×3的矩陣又存在4×4的矩陣。而將3×3矩陣拓展成4×4矩陣還是相對更加容易的。這樣,就通過乙個4×4矩陣整合了平移矩陣、旋轉矩陣。

三維座標和矩陣的關係

三維座標是空間中的點,常用 x,y,z 表示。但是在三維引擎中常用齊次座標來表示,進行平移 旋轉 縮放的變換。齊次座標是將乙個 n 維的向量用 n 1 維來表示,這樣可以很好的區分點和向量。比如說 x,y,z,w w 等於1,則,表示是乙個點,如果w 0,則表示是乙個向量。我們將三維座標引入到四位的...

建立乙個三維陣列

題目 建立乙個三維陣列,4 4 4個元素,數字隨機生成,找出每行最大的數,每面最大的數,以及整個陣列中最大的數的位址,具體實現如下 cpp view plain copy include include include void printmaxvalbyindex int pdata 4 4 in...

建立乙個三維陣列

題目 建立乙個三維陣列,4 4 4個元素,數字隨機生成,找出每行最大的數,每面最大的數,以及整個陣列中最大的數的位址,具體實現如下 include include include void printmaxvalbyindex int pdata 4 4 int nrows int planmaxv...