zoukankan      html  css  js  c++  java
  • 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来分别变换一个点数组和向量数组。

  • 相关阅读:
    Chrome浏览器网页截全屏算法以及实现
    去除scons构建动态库的前缀lib
    Javascript的继承
    win7 VS2008 ffmpeg release 版本崩溃 0x00905a4d 处未处理的异常
    shell脚本获取随机数random
    iOS navigationbar添加实现
    TableView中改变Button按钮状态
    将TableView的中的Label和Cell行数绑定
    build diff: /../Podfile.lock: No such file or directory
    initramfs-tools ... update-initramfs: Generating /boot/initrd.img-3.14-kali1-amd64 mktemp: failed to create directory via template `/var/tmp/mki
  • 原文地址:https://www.cnblogs.com/flying_bat/p/1108356.html
Copyright © 2011-2022 走看看