游戏开发中必备的数学知识(三)——矩阵的基本变换

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/DY_1024/article/details/84027006

基本变换

使用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。分别用于点数组和向量数组的变换。

猜你喜欢

转载自blog.csdn.net/DY_1024/article/details/84027006