1. 程式人生 > >遊戲開發中必備的數學知識(三)——矩陣的基本變換

遊戲開發中必備的數學知識(三)——矩陣的基本變換

基本變換

使用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。分別用於點陣列和向量陣列的變換。