DirectX12 3D 游戏开发与实战第三章内容

变换

学习目标

  1. 理解如何使用矩阵表示线性变换和仿射变换
  2. 学习对几何体进行缩放、旋转和平移的坐标变换
  3. 根据矩阵之间的乘法运算性质,将多个变换矩阵合并为一个单独的净变换矩阵
  4. 找寻不同坐标系之间的坐标转换方法,并利用矩阵来表示此坐标变换
  5. 熟悉DirectXMath库中专门为构建变换矩阵所提供的相关函数

3.1线性变换

3.1.1定义

如果有一个函数t可以使

t(u + v) = t(u) + t(v)
t(ku) = tk(u)

成立,则函数t称为线性函数,也称为线性变换。其中u和v为3D向量,k为标量。(非3D向量也可以作为线性变换的输入和输出,不过在3D图形学中我们一般讨论3D向量的线性变换)

3.1.2矩阵表示法(重点)

略()

3.1.3缩放

缩放(比例变换)是指改变物体的大小,我们一般把缩放定义

S(x,y,z) = (s1x,s2y,s3z)

s1,s2,s3分别代表S的三个分量

此变换将相对于当前坐标系中的原点,令向量在x,y,z轴上分别以系数s1,s2,s3进行缩放,S是一种线性变换,这里不做证明

  • 关于缩放变换 S的矩阵表示

S(i) = (s11,s20,s3*0);

S(j) = (s10,s21,s3*0);

S(k) = (s10,s20,s3*1);

所以缩放矩阵S的矩阵表示为

{
    s1,0,0,
    0,s2,0,
    0,0,s3
}

例子:如果要将一个正方形在x轴上缩小0.5,在y轴上方法2.0倍,在z轴上保持不变,可以采用缩放矩阵S

{
    0.5,0,0,
    0,2,0,
    0,0,0
}

将该矩阵S分别与正方形的最小点坐标、正方形的最大点坐标相乘即可

3.1.4旋转

本节将用数学的方式来描述向量v绕轴n以角theta进行旋转,我们首先会将向量v分解为两部分,一部分平行于n,另一部分正交于n,在旋转的过程中,平行于n的部分是保持不变的,所以我们只需要考虑正交于n的部分。

推导过程:略

旋转变换也是一种线性变换,所以也可以转换为矩阵表示。旋转变换的矩阵表示为:

{
    c+(1-c)x^2  (1-c)xy + sz    (1-c)xz-sy
    (1-c)xy-sz  c+(1-c)y^2      (1-c)yz+sx
    (1-c)xz+sy  (1-c)yz-sx      c+(1-c)z^2
}

其中x,y,z表示旋转轴n的(x,y,z),s和c分别表示sin(theta)和cos(theta)

例子:略

3.2仿射变换

3.2.1齐次坐标

在下一节中我们可以看到,仿射变换是由一个线性变换和一个平移变换组合而成的,对于向量而言,平移操作使没有意义的,因为向量只描述大小的方向,和位置无关。所以,平移操作只能应用于点(即位置向量)。在采用齐次坐标所提供的表示机制中,我们可以方便地对点和向量进行统一的处理,在齐次坐标中,坐标将被扩充为四元组,第四个坐标的值将根据被描述对象是点还是向量而定,具体来说

  1. (x,y,z,0)表示向量
  2. (x,y,z,1)表示点

3.2.2仿射变换的定义及其矩阵表示

线性变换并不能表示出我们需要的所有变换,因此我们需要把它扩充为一种称为仿射变换的映射范围更广的函数类,仿射变换为一个线性变换+一个平移向量即

a(u) = t(u) + b

也可以用矩阵表示法表示:

{
    A1  A2  A3  0
    A4  A5  A6  0
    A7  A8  A9  0
    Bx  By  Bz  1
}

其中An为线性变换的矩阵表示,Bx,By,Bz为平移向量b

3.2.3平移

恒等变换是一种直接返回其输入参数的线性变换,即t(u) = u;不难看出,线性变换t的矩阵表示为单位矩阵。现将平移变换定义为仿射变换,其中的线性变换即是一种恒等变换,所以平移变换的仿射公式为

t(u) = uI + b = u + b

其中I为单位矩阵。

平移变换的矩阵表达为:

{
    1   0   0   0
    0   1   0   0
    0   0   1   0
    Bx  By  Bz  1
}

其中Bx,By,Bz分别为平移向量b的各分量

3.2.4缩放和旋转的仿射矩阵

将缩放矩阵和旋转矩阵扩充为4x4矩阵,即将每一个行向量的w值设为0,同时加上平移向量b(0,0,0,1)即可

仿射变换矩阵的几何意义

变换的复合(变换的组合)

问题:假设有一个缩放矩阵S,旋转矩阵R,平移矩阵T,现在有一个由8个顶点构成的立方体,现想将这3中变换相继应用到正方体的每一个顶点上,则可以

((Vi S) R) T        //其中Vi为正方体的每一个顶点

由于矩阵乘法满足结合律,所以可以令矩阵C = SRT;即提前将这3中变换封装成一个净变换矩阵,这样便于我们操作,同时也可以提高性能

3.4坐标变换(坐标系变换)

  • 在后续的学习中,我们要面对不同的标架来转换点或向量的坐标,我们把不同标架间的转换称之为坐标变换

  • 在坐标变换的过程中,几何体本身并没有发生变换,坐标变换改变的只是物体的参考系。相比之下,我们可以认为缩放,旋转,平移这些操作才使几何体发生了实质性的改变

  • 在计算机图形学中,我们会用到许多不同的坐标系,因此需要了解他们之间相互转换的方法,由于位置是点的属性,与向量无关,所以点和向量的坐标转换时不同的,下面我们会分开来介绍。

3.4.1向量的坐标变换

思考:其中有一向量p分别位于标架1和标架2中,设向量p在标架1中的坐标为P1 = (x,y,z);那如何求得向量p在标架2中的对应坐标?

解答过程:略(主要应用平移的方法)

答案:P2 = xu + yv + zw

u,v,w分别表示指向标架1中x轴,y轴和z轴正方向上的单位向量(在标架2中进行表示)

3.4.2点的坐标变换

点与向量的坐标变换有点不一样,因为位置是点的一个重要属性,因而不能把向量和点混为一谈,也不能简单的把向量平移的方法应用到点上

解答过程:略

转换公式:P2 = xu + yv + zw + Q

u,v,w分别表示指向标架1中x轴,y轴和z轴正方向上的单位向量(在标架2中进行表示),Q表示标架1中的原点在标架2中的坐标

3.4.3坐标变换的矩阵表示

在上两节中,我们已经介绍了向量和点的坐标变换

(x',y',z') = xu + yv + zw           //对于向量而言
(x',y',z') = xu + yv + zw + Q       //对于点而言

如果使用齐次坐标,可以将上面的两个公式合并成一个公式,即:

(x',y',z',w) = xu + yv + zw + Q

在上面的坐标变换公式中,如果w = 0;则表示向量,w = 1则表示点,这样便可以只记忆一条公式了。上述公式的矩阵表示为:

{
    u1  u2  u3  0
    v1  v2  v3  0
    w1  w2  w3  0
    Q1  Q2  Q3  1
}

此矩阵称为坐标变换矩阵或标架变换矩阵

3.4.4坐标变换矩阵及其结合律

问题:假设有3个标架,分别为1、2、3,且已知三个标架的标架变换矩阵分别为A、B、C,在标架1中有一个向量的坐标为P,如果想要求出此向量在标架3中对应的坐标,则可以

(PB)C = p';

但是这样的计算效率不高,因为矩阵的乘法满足结合律,所以我们可以令H = BC;然后可以使用PH = P';便可以完成变换

3.4.5坐标变换矩阵及其逆矩阵

3.5变换矩阵与坐标变换矩阵

在前面的小结中,我们强调了“使几何体本身发生改变”的变换(缩放,旋转和平移)和坐标变换的区分,不过,在本节中,我们将证明:从数学角度上来看,两者是等价的。

证明过程:略

3.6DirectXMath库提供的变换函数

本节我们将对DirectXMath库中和变换相关的函数进行总结,以便以以后进行参考。

//构建一个缩放矩阵
XMMATRIX XM_CALLCONV XMMatrixScaling(
    float ScaleX,       //缩放系数
    float ScaleY,       //缩放系数
    flaot ScaleZ        //缩放系数
)
//用一个3D向量中的分量来构建一个缩放矩阵
XMMATRIX XM_CALLCONV XMMatrixScalingFromVector(
    FXMVECTOR Scale;    //缩放系数(Sx,Sy,Sz)
);
//构建一个绕x轴旋转的旋转矩阵
XMMATRIX XM_CALLCONV XMMatrixRotationX(
    float Angle         //以顺时间方向旋转Angle弧度
);
//构建一个绕y轴旋转的旋转矩阵
XMMATRIX XM_CALLCONV XMMatrixRotationY(
    float Angle         //以顺时间方向旋转Angle弧度
);
//构建一个绕z轴旋转的旋转矩阵
XMMATRIX XM_CALLCONV XMMatrixRotationZ(
    float Angle         //以顺时间方向旋转Angle弧度
);
//构建一个绕任意轴旋转的矩阵
XMMATRIX XM_CALLCONV XMMatrixRotationAxis(
    FXMVECTOR Axis,     //旋转轴n
    float Angle         //沿n轴正方向看,以顺时针方向按弧度Angle进行旋转
);
//构建一个平移矩阵
XMMATRIX XM_CALLCONV XMMatrixTranslation(
    float OffsetX,      //平移系数 
    float OffsetY,      //平移系数
    float OffsetZ       //平移系数
);
//用一个3D向量中的分量来构建平移矩阵
XMMATRIX XM_CALLCONV XMMatrixTranslationFromVector(
    FXMVECTOR Offset    //平移系数(Sx,Sy,Sz)
);
//计算向量和矩阵的乘积VM,此函数默认w = 1;即针对点计算
XMVECTOR XM_CALLCONV XMVector3TransformCoord(
    FXMVECTOR V,        //输入向量V
    CXMMATRIX M         //输入矩阵M
);
//计算向量和矩阵的乘积VM,此函数默认w = 0;即针对向量计算
XMVECTOR XM_CALLCONV XMVector3TransformNormal(
    FXMVECTOR V,        //输入向量V
    CXMMATRIX M         //输入矩阵M
);

小结

1、缩放、平移和旋转这3种基础操作的变换矩阵分别为:

S = 
{
    Sx  0   0   0
    0   Sy  0   0
    0   0   Sz  0
    0   0   0   1
};

T = 
{
    1   0   0   0
    0   1   0   0
    0   0   1   0
    b1  b2  b3  1
};

R = 
{
    c+(1-c)x^2  (1-c)xy + sz    (1-c)xz-sy
    (1-c)xy-sz  c+(1-c)y^2      (1-c)yz+sx
    (1-c)xz+sy  (1-c)yz-sx      c+(1-c)z^2
}

2、在使用齐次坐标表示变换时,我们用1 x 4齐次坐标来描述点和向量。当把第四个分量w设置为0时,则表示向量,w = 1时,则表示点。这样可以使平移操作只应用于点,而不会影响向量

3、如果一个矩阵中所用的行向量都是单位长度而且两两正交,则该矩阵称为正交矩阵,正交矩阵的逆矩阵和转置矩阵相等,正交矩阵对应的逆矩阵很容易计算。所有的旋转矩阵都是正交矩阵

4、由于矩阵的乘法运算满足结合律,所以我们一般把若干种变换矩阵合并为一个矩阵,这样可以提高运算效率

5、设Q,u,v,w分别表示标架1中的原点,x轴,y轴,z轴相对于标架2的坐标,如果一个向量p在标架1中的对应坐标为(x,y,z),则该向量相对于标架2的坐标为

p' = xu + yv + zw;              //针对向量
p' = xu + yv + zw + Q;          //针对点(位置向量)

6、由于矩阵的乘法运算满足结合律,所以对于多个标架之间的转换,我们可以把多个标架变换矩阵合并成一个矩阵,可以提高运算效率

7、如果矩阵A可以将坐标从标架1映射到标架2中,那么A的逆矩阵可以把坐标从标架2映射到标架1中

转载于:https://www.cnblogs.com/yaya12138/p/11458617.html

你可能感兴趣的:(DirectX12 3D 游戏开发与实战第三章内容)