遊戲開發中必備的數學知識(三)——矩陣的基本變換
基本變換
使用Direct3D程式設計的時候,我們使用4×4的矩陣表示一個變換。其思路如下:
設定一個4×4的矩陣中元素的值,使其表示某一個具體變換,然後我們將某一點的座標或者某向量的分量放入一個1×4的行向量v中,乘積vX就是成為了一個新的經過變換的向量v。
此時,我們之所以使用4×4的矩陣,,是因為這種特定維數的矩陣有能力表示我們所需要的所有變換,3×3的矩陣似乎更適合3D變化,但是例如:平移、透視投影以及反射都無法使用3×3的矩陣來描述。
還有就是我們之前使用的都是點以及向量都是3D的,為什麼我們要使用1×4的向量?因為我們需要將向量和4×4的矩陣相乘,為了使得乘積有意義,我們即必須將3D向量擴充套件到4D。
此時問題來了:我們如何使用3D的點或者向量表示4D中的點或者向量?
答案:當我們將1×3的點放入到1×4的向量中去的時候:將w分量置為1
當我們將1×3的向量放入到1×4的向量中的時候:將w分量置為0
例如:點P(P1,P2,P3)=======》P[P1,P2,P3,1]
向量P(V1,V2,V3)=======》P[V1,V2,V3,0]
我們將擴充套件後的4D向量稱之為齊次向量,因為齊次向量既可以表示點,又可以表示向量,所以注意區分。
當我們的W分量!=0且!=1的時候,我們稱這個向量處於齊次空間。
我們將齊次空間中的向量映射回3D空間的辦法,就是讓齊次向量的每一個分量都去除以w分量:
進行3D程式設計的時候,如果涉及到透視投影,就需要將向量由齊次空間投射到3D空間。
平移矩陣
要想將向量(x,y,z,1)沿x軸平移Px個單位,沿y軸平移Py個單位或者沿Z軸平移Pz個單位,我們只需將向量和如下矩陣相乘:
得到的結果就是將向量平移Px,或者Py,或者Pz個座標。
用於建立平移矩陣的D3DX函式為:
D3DXMATRIX* D3DXMatrixTranslation( D3DXMATRIX* pOut, //Result FLOAT x, //要平移的數量單位x FLOAT y, //要平移的數量單位y FLOAT z, //要平移的數量單位z )
旋轉矩陣
我們可以使用如下3個舉著將向量分別繞著x,y,z軸旋轉λ角度。
注意:當沿著旋轉軸指向原點的方向觀察的時候,角度是按照順時針方向度量的。
和下面的矩陣相乘,是將向量沿著X軸旋轉λ:
用於建立繞X軸旋轉矩陣的D3DX函式為:
D3DXMATRIX* D3DXMatrixRotationX(
D3DXMATRIX* pOut, //Result
FLOAT Angle //Angle
)
和下面的矩陣相乘,是將向量沿著Y軸旋轉λ:
用於建立繞Y軸旋轉矩陣的D3DX函式為:
D3DXMATRIX *D3DXMatrixRotationY(
D3DXMATRIX *pOut, //Result
FLOAT Angle //Angle
)
和下面的矩陣相乘,是將向量沿著Z軸旋轉λ:
用於建立Z軸旋轉矩陣的D3DX函式為:
D3DXMATRIX *D3DXMatrixRotationZ(
D3DXMATRIX *pOut, //Result
FLOAT Angle //Angle
)
比例變換矩陣
如果想讓一個向量沿著x,y,z軸放大Qx,Qy,Qz倍,則領該向量和如下矩陣相乘:
建立比例矩陣的D3DX函式為:
D3DXMATRIX* D3DXMatrixTranslation(
D3DXMATRIX* pOut, //Result
FLOAT x, //沿x軸縮放的比例
FLOAT y, //沿y軸縮放的比例
FLOAT z, //沿z軸縮放的比例
)
如果將比例矩陣的各個因子取倒數,就得到該矩陣的逆矩陣。
幾何變換的組合
在3D圖形學中,我們經常要對某一個向量依次進行:縮放,旋轉,平移等操作,每操作一次,我們都要生成一個對應的矩陣,但是這樣在實際的開發過程中,效率會很低,因為當我們面對的如果是一個向量集合的時候,生成矩陣會拉低我們的效率。所以我們會將變換組合起來,組合成一個融合縮放,旋轉,平移為一體的一個全功能矩陣,然後將該矩陣和我們要變換的向量相乘,來得到我們需要的變換之後的向量。節省了很多向量和矩陣相乘的開銷。
向量變換的一些函式
D3DX庫分別提供瞭如下兩個函式用於點和向量的變換。
D3DXVecTransformCoord()函式對點進行變換,並假定向量的第四個分量為1;
D3DXVecTransformNormal()函式對向量進行變換,並假定向量的第四個分量為0;
D3DXVECTOR3 *D3DXVecTransformCoord(
D3DXVECTOR3 *pOut, //Result
CONST D3DXVECTOR3* pV, //轉換的點
CONST D3DXMATRIX* pM //轉換的矩陣
)
D3DXMATRIX T(...); //初始化轉換矩陣
D3DXVECTOR3 p(...); //初始化一個點
D3DXVec3TransformCoord(&p,&p,&T); //平移一個點
D3DXVECTOR3 *D3DXVecTransformNormal(
D3DXVECTOR3 *pOut, //Result
CONST D3DXVECTOR3* pV, //轉換的向量
CONST D3DXMATRIX* pM //轉換的矩陣
)
D3DXMATRIX T(...); //初始化轉換矩陣
D3DXVECTOR3 p(...); //初始化向量
D3DXVec3TransformCoord(&p,&p,&T); //平移一個向量
D3DX庫裡面還提供了函式D3DXVec3TransformCoordArray和D3DXVec3TransformNormalArray。分別用於點陣列和向量陣列的變換。