D3D编程必备的数学知识(4)

基本变换

当用Direct3D编程时,我们使用4×4矩阵来进行矩阵变换。用它的原因是:我们设置一个4×4矩阵X是为了更精确的描述矩阵变换。同样我们设置一个相匹配的点或者把向量的分量放置到一个1×4的行矩阵V中。VX的乘积返回一个新的向量V’。例如:让X沿着x轴平移10个单位同时V = [2, 6, –3, 1],乘积VX = V’= [12, 6, –3, 1]。

有一些东西需要阐明。我们使用4×4矩阵是因为这样的大小能表现我们需要的所有变换。最初看来一个3×3的好象更适合3D。然而这里有很多种我们喜欢用的变换是不能用一个3×3的矩阵来表示的,比如平移、投影、反射。我们使用向量-矩阵相乘来工作,因此我们至少要通过一个矩阵乘法来完成相应的变化。增大到4×4的矩阵后,它允许我们用一个矩阵描述更多的变换,并且向量-矩阵乘法是可行的。

我们说过把一个相匹配的点或者一个向量的成员放置到一个1×4的行矩阵中。但是点和向量是3D的!为什么我们要用一个1×4的行矩阵呢?我们必需把3D点/向量增大为4D的单行矩阵,是为了符合向量与矩阵的乘法定义,而1×3的单行矩阵和4×4的矩阵相乘是不允许的。

那么,我们怎么使用第四个成员(我们用w来表示)呢?当我们把一个点放置到一个1×4的行矩阵中时,我们设置w为1。允许对点进行适当的平移。因为向量和位置无关,所以向量的平移没有被定义,如果试图这样做会返回一个无意义的向量。为了防止对向量进行平移,当在把一个向量放置到一个1×4行矩阵中时我们把w设置为0。例如:

把点p = (p1, p2, p3)放置到一个单行矩阵中就象这样:

[p1, p2, p3, 1]

同样把向量v = (v1, v2, v3) 放置到一个单行矩阵中就象这样:

[v1, v2, v3, 0]

注意:我们设置w = 1是为了让点可以被恰当的移动,同样我们设置w = 0是为了防止向量被平移。当我们检查矩阵实际平移时这是一个非常清晰的模型。

有时一个矩阵变换时我们改变向量成员w的值,即w≠0 且 w≠1。考虑下边例子:

矩阵平移

矩阵旋转

旋转矩阵R的逆矩阵等于它的转置矩阵:RT= R-1。这样的矩阵我们说它们是正交矩阵的。

矩阵缩放

综合变换

       常常我们要对一个向量进行一系列的变换。比如,我们可能先缩放一个向量,然后旋转它,最后把它平移到指定的位置。

例如:先把向量p = [5, 0, 0, 1] 在所有轴上缩小为原来的1/5,然后沿着y轴旋转π/4,最后把它在x轴上移动1个单位,在y轴上移动2个单位,在z轴上移动3个单位。

解答:注意我们必须完成缩放,沿y轴旋转,以及移动。我们设缩放、旋转、移动的变换矩阵分别是S, Ry, T,如下:

我们能用矩阵乘法把几个变换矩阵转换成一个矩阵,它是非常有益的矩阵。比如,重新考虑这部分开始的例子。通过使用矩阵相乘把3个变换矩阵合成一个矩阵。注意我们必须按实际应用的顺序来进行矩阵相乘。

联合变换有提高效率的能力。假如我们需要对一组数量巨大的向量(在3D图形任务中是很普遍的)进行同样的缩放,旋转以及移动变换。替换这一系列的变换,即就象等式(5)中对每一个向量的做法,我们能把所有3个变换转换到一个矩阵中,即就象在等式(6)中的做法。这样我们只需要对每一个向量进行一次乘法就可以实现3种变换。这就减少了大量的向量-矩阵乘法操作。

一些向量变换函数

D3DX库分别提供了下边两个对点和向量的变换函数。D3DXVec3TransformCoord函数变换点同时设置向量第4个成员为1(用于变换点向量)。D3DXVec3TransformNormal函数变换向量并且设置第4个成员为0(用于变换方向向量)。

D3DXVECTOR3 *D3DXVec3TransformCoord(

              D3DXVECTOR3* pOut, // 返回的点向量

              CONST D3DXVECTOR3* pV, // 点向量

              CONST D3DXMATRIX* pM // 变换矩阵

);

D3DXMATRIX T(...); // 初始化矩阵

D3DXVECTOR3 p(...); // 初始化点

D3DXVec3TransformCoord( &p, &p, &T); // 变换一个点

D3DXVECTOR3 *WINAPI D3DXVec3TransformNormal(

              D3DXVECTOR3 *pOut, //返回的方向向量

              CONST D3DXVECTOR3 *pV, // 方向向量

              CONST D3DXMATRIX *pM //变换矩阵

);

D3DXMATRIX T(...); // 初始化变换矩阵

D3DXVECTOR3 v(...); // 初始化方向向量

D3DXVec3TransformNormal( &v, &v, &T); // 变换方向向量

注意:D3DX库也提供D3DXVec3TransformCoordArray和D3DXVec3TransformNormalArray来分别变换一个点数组和向量数组。

posted @ 2008-03-16 13:20  至尊王者  阅读(1294)  评论(0编辑  收藏  举报