矩阵类型及其操作

在Direct3D中,顶点坐标变换通常是借助于矩阵实现的,因此下面首先介绍在Direct3D中提供的各种矩阵类型和相关的矩阵运算函数。

 

1、D3DMATRIX矩阵类型

D3DMATRIX是Direct3D中最简单的矩阵类型,其定义如下:

typedef struct _D3DMATRIX {
union {
struct {
float _11, _12, _13, _14;
float _21, _22, _23, _24;
float _31, _32, _33, _34;
float _41, _42, _43, _44;
        };
float m[4][4];
};
} D3DMATRIX;

显然,D3DMATIX中存放的是一个4x4的二维浮点数组,可以通过_ij的格式访问该数组中的每个元素,i表示该元素的行数,j表示该元素的列数。例如,_34表示第三行、第四列的元素。

 

2、D3DXMATRIX矩阵类型

该类型矩阵定义如下:

#ifdef __cplusplus
typedef struct D3DXMATRIX : public D3DMATRIX
{
public:
D3DXMATRIX() {};
D3DXMATRIX( CONST FLOAT * );
D3DXMATRIX( CONST D3DMATRIX& );
D3DXMATRIX( CONST D3DXFLOAT16 * );
D3DXMATRIX( FLOAT _11, FLOAT _12, FLOAT _13, FLOAT _14,
FLOAT _21, FLOAT _22, FLOAT _23, FLOAT _24,
FLOAT _31, FLOAT _32, FLOAT _33, FLOAT _34,
FLOAT _41, FLOAT _42, FLOAT _43, FLOAT _44 );
    // access grants
FLOAT& operator () ( UINT Row, UINT Col );
FLOAT operator () ( UINT Row, UINT Col ) const;
    // casting operators
operator FLOAT* ();
operator CONST FLOAT* () const;
    // assignment operators
D3DXMATRIX& operator *= ( CONST D3DXMATRIX& );
D3DXMATRIX& operator += ( CONST D3DXMATRIX& );
D3DXMATRIX& operator -= ( CONST D3DXMATRIX& );
D3DXMATRIX& operator *= ( FLOAT );
D3DXMATRIX& operator /= ( FLOAT );
    // unary operators
D3DXMATRIX operator + () const;
D3DXMATRIX operator - () const;
    // binary operators
D3DXMATRIX operator * ( CONST D3DXMATRIX& ) const;
D3DXMATRIX operator + ( CONST D3DXMATRIX& ) const;
D3DXMATRIX operator - ( CONST D3DXMATRIX& ) const;
D3DXMATRIX operator * ( FLOAT ) const;
D3DXMATRIX operator / ( FLOAT ) const;
    friend D3DXMATRIX operator * ( FLOAT, CONST D3DXMATRIX& );
    BOOL operator == ( CONST D3DXMATRIX& ) const;
BOOL operator != ( CONST D3DXMATRIX& ) const;
} D3DXMATRIX, *LPD3DXMATRIX;
#else //!__cplusplus
typedef struct _D3DMATRIX D3DXMATRIX, *LPD3DXMATRIX;
#endif //!__cplusplus

 

3、D3DXMATRIXA16矩阵类型

D3DXMATRIXA16称为16字节对齐矩阵(16-byte aligned matrix),它是从矩阵D3DXMATRIX中继承而来的,其定义如下:

typedef D3DX_ALIGN16 _D3DXMATRIXA16 D3DXMATRIXA16, *LPD3DXMATRIXA16;

//---------------------------------------------------------------------------
// Aligned Matrices
//
// This class helps keep matrices 16-byte aligned as preferred by P4 cpus.
// It aligns matrices on the stack and on the heap or in global scope.
// It does this using __declspec(align(16)) which works on VC7 and on VC 6
// with the processor pack. Unfortunately there is no way to detect the
// latter so this is turned on only on VC7. On other compilers this is the
// the same as D3DXMATRIX.
//
// Using this class on a compiler that does not actually do the alignment
// can be dangerous since it will not expose bugs that ignore alignment.
// E.g if an object of this class in inside a struct or class, and some code
// memcopys data in it assuming tight packing. This could break on a compiler
// that eventually start aligning the matrix.
//---------------------------------------------------------------------------
#ifdef __cplusplus
typedef struct _D3DXMATRIXA16 : public D3DXMATRIX
{
_D3DXMATRIXA16() {}
_D3DXMATRIXA16( CONST FLOAT * );
_D3DXMATRIXA16( CONST D3DMATRIX& );
_D3DXMATRIXA16( CONST D3DXFLOAT16 * );
_D3DXMATRIXA16( FLOAT _11, FLOAT _12, FLOAT _13, FLOAT _14,
FLOAT _21, FLOAT _22, FLOAT _23, FLOAT _24,
FLOAT _31, FLOAT _32, FLOAT _33, FLOAT _34,
FLOAT _41, FLOAT _42, FLOAT _43, FLOAT _44 );
    // new operators
void* operator new ( size_t );
void* operator new[] ( size_t );
    // delete operators
void operator delete ( void* ); // These are NOT virtual; Do not
void operator delete[] ( void* ); // cast to D3DXMATRIX and delete.
    // assignment operators
_D3DXMATRIXA16& operator = ( CONST D3DXMATRIX& );
} _D3DXMATRIXA16;
#else //!__cplusplus
typedef D3DXMATRIX _D3DXMATRIXA16;
#endif //!__cplusplus

当使用了Intel Pentium 4运行一个D3DX数学函数时,16字节对齐矩阵D3DXMATRIXA16为完成相应操作进行了优化。当使用VC++.net或使用安装了processor pack的VC6++时,将开启字节对齐功能。但不幸的是,编译器无法探测到是否安装了processor pack,所以字节对齐仅仅只对VC++.net默认开启。对于其他编译器,16字节对齐矩阵D3DXMATRIXA16将被当作D3DXMATRIX进行操作。

经过扩展后的结构体D3DXMATRIX和D3DXMATRIXA16对许多运算符进行了重载,所以可以直接进行转换运算、赋值运算以及多种一元、二元运算,大大方便了矩阵类型变量的运算。

 

4、常见的矩阵运算函数

因为矩阵的运算相对比较复杂,所以Direct3D提供了一组矩阵运算函数,例如,通过函数D3DXMatrixTranslation()构造一个平移矩阵;通过函数D3DXMatrixRotationX()、D3DXMatrixRotationY()和D3DXMatrixRotationZ()构造绕x、y和z轴转动一定角度的矩阵;通过函数D3DXMatrixScaling()构造一个缩放矩阵;通过函数D3DXMatrxiIdentity()将一个矩阵单位化;通过函数D3DXMatrixMultiply()计算两个矩阵的积;通过函数D3DXMatrixInverse()求原矩阵的逆矩阵;通过函数D3DXMatrixTranspose()计算原矩阵的转置矩阵。

 

D3DXMatrixRotationY 函数


创建绕着Y轴旋转矩阵。

定义:

D3DXMATRIX *WINAPI D3DXMatrixRotationY(      



    D3DXMATRIX *pOut,
    FLOAT Angle
);

参数:

pOut

[in, out] 指向D3DXMATRIX 结构的操作结果矩阵。

Angle

[in] 绕着Y轴旋转的角度(单位是弧度)。角度计算方法是当朝着旋转轴的原点看去时,顺时针方向为正值。

返回值:

指向D3DXMATRIX 结构的绕着Y轴旋转矩阵。

说明:

函数返回值跟pOut 参数返回值是一样的。这样可以让函数D3DXMatrixRotationY作为其它函数的参数使用。

函数信息:

 

Header

d3dx9math.h

Import library

d3dx9.lib

Minimum operating systems

Windows 98

相关函数:

D3DXMatrixRotationAxis, D3DXMatrixRotationQuaternion, D3DXMatrixRotationX, D3DXMatrixRotationYawPitchRoll, D3DXMatrixRotationZ

认识矩阵, 譬如这是一个 2*3 (2 行 3 列) 的矩阵: ┏    ┓ ┃3 1 4 ┃ ┃2 5 0 ┃ ┗    ┛ 矩阵相加的例子: ┏  ┓  ┏  ┓  ┏  ┓ ┃1 0┃  ┃2 4┃  ┃3 4┃ ┃0 2┃ + ┃1 5┃ = ┃1 7┃ ┃1 3┃  ┃0 6┃  ┃1 9┃ ┗  ┛  ┗  ┛  ┗  ┛ 在 GDI+ 中应用的矩阵运算是 "相乘". 矩阵相乘有个前提: 就是第一个矩阵的 "列数" 要和第二个矩阵的 "行数" 一致. 譬如: 矩阵 A*B 要乘以 矩阵 M*N, 要求 B = M. GDI+ 中用到的 GP矩阵 是 3*3 的, 颜色矩阵(ColorMatrix) 是 5*5 的, 都符合这个条件. 矩阵 A*B 与 M*N 相乘后会得到一个 A*N 的新矩阵; 譬如一个 "2 行 3 列" 的矩阵与 "3 行 2 列" 的矩阵相乘, 会得到一个 "2 行 2 列" 的新矩阵. 从下面例子中可以看出相乘的方法: ┏    ┓  ┏   ┓  ┏               ┓  ┏    ┓ ┃1 2 3 ┃  ┃7  8 ┃  ┃1*7+2*9+3*11  1*8+2*10+3*12┃  ┃58  64┃ ┃    ┃ * ┃9 10 ┃ = ┃               ┃ = ┃    ┃ ┃4 5 6 ┃  ┃11 12 ┃  ┃4*7+5*9+6*11  4*8+5*10+6*12┃  ┃130 154┃ ┗    ┛  ┗   ┛  ┗               ┛  ┗    ┛ 因为 GDI+ 是二维的, GP矩阵 的第 3 列一直是 0, 0, 1, 但为了相乘运算也必须有这个位置. 它们看起来是下面的样子: ┏      ┓  ┏      ┓ ┃1  0  0┃  ┃1  0  0┃ ┃0  1  0┃ or┃0  1  0┃ ┃2  3  1┃  ┃4  5  1┃ ┗      ┛  ┗      ┛ 假如让上面两个矩阵相乘, 下面分别用 "手动运算" 与 "GDI+的函数运算" 对照下结果. 手动运算: ┏      ┓  ┏      ┓  ┏                     ┓  ┏      ┓ ┃1  0  0┃  ┃1  0  0┃  ┃1*1+0*0+0*4  1*0+0*1+0*5  1*0+0*0+0*1┃  ┃1  0  0┃ ┃0  1  0┃ * ┃0  1  0┃ = ┃0*1+1*0+0*4  0*0+1*1+0*5  0*0+1*0+0*1┃ = ┃0  1  0┃ ┃2  3  1┃  ┃4  5  1┃  ┃2*1+3*0+1*4  2*0+3*1+1*5  2*0+3*0+1*1┃  ┃6  8  1┃ ┗      ┛  ┗      ┛  ┗                     ┛  ┗      ┛ 一个 GP矩阵 的默认值(或者说单位矩阵)是: ┏      ┓ ┃1  0  0┃ ┃0  1  0┃ ┃0  0  1┃ ┗      ┛ //对角线上是 1, 其他都是 0; 这个默认值可通过 矩阵.重置 方法获取. 根据各个位置的功能, GDI+ 给各位置命名如下(第三列没有意义也没有命名): ┏        ┓ ┃M11  M12  0┃ ┃M21  M22  0┃ ┃DX   DY   1┃ ┗        ┛
资源介绍:认识矩阵, 譬如这是一个 2*3 (2 行 3 列) 的矩阵:┏    ┓ ┃3 1 4 ┃ ┃2 5 0 ┃ ┗    ┛   矩阵相加的例子:┏  ┓  ┏  ┓  ┏  ┓ ┃1 0┃  ┃2 4┃  ┃3 4┃ ┃0 2┃  ┃1 5┃ = ┃1 7┃ ┃1 3┃  ┃0 6┃  ┃1 9┃ ┗  ┛  ┗  ┛  ┗  ┛   在 GDI 中应用的矩阵运算是 "相乘".  矩阵相乘有个前提: 就是第一个矩阵的 "列数" 要和第二个矩阵的 "行数" 一致.  譬如: 矩阵 A*B 要乘以 矩阵 M*N, 要求 B = M.  GDI 中用到的 GP矩阵 是 3*3 的, 颜色矩阵(ColorMatrix) 是 5*5 的, 都符合这个条件.  矩阵 A*B 与 M*N 相乘后会得到一个 A*N 的新矩阵;   譬如一个 "2 行 3 列" 的矩阵与 "3 行 2 列" 的矩阵相乘, 会得到一个 "2 行 2 列" 的新矩阵.  从下面例子中可以看出相乘的方法:┏    ┓  ┏   ┓  ┏               ┓  ┏    ┓ ┃1 2 3 ┃  ┃7  8 ┃  ┃1*7 2*9 3*11  1*8 2*10 3*12┃  ┃58  64┃ ┃    ┃ * ┃9 10 ┃ = ┃               ┃ = ┃    ┃ ┃4 5 6 ┃  ┃11 12 ┃  ┃4*7 5*9 6*11  4*8 5*10 6*12┃  ┃130 154┃ ┗    ┛  ┗   ┛  ┗               ┛  ┗    ┛   因为 GDI 是二维的, GP矩阵 的第 3 列一直是 0, 0, 1, 但为了相乘运算也必须有这个位置.  它们看起来是下面的样子:┏      ┓  ┏      ┓ ┃1  0  0┃  ┃1  0  0┃ ┃0  1  0┃ or┃0  1  0┃ ┃2  3  1┃  ┃4  5  1┃ ┗      ┛  ┗      ┛   假如让上面两个矩阵相乘, 下面分别用 "手动运算" 与 "GDI 的函数运算" 对照下结果.  手动运算:┏      ┓  ┏      ┓  ┏                     ┓  ┏      ┓ ┃1  0  0┃  ┃1  0  0┃  ┃1*1 0*0 0*4  1*0 0*1 0*5  1*0 0*0 0*1┃  ┃1  0  0┃ ┃0  1  0┃ * ┃0  1  0┃ = ┃0*1 1*0 0*4  0*0 1*1 0*5  0*0 1*0 0*1┃ = ┃0  1  0┃ ┃2  3  1┃  ┃4  5  1┃  ┃2*1 3*0 1*4  2*0 3*1 1*5  2*0 3*0 1*1┃  ┃6  8  1┃ ┗      ┛  ┗      ┛  ┗                     ┛  ┗      ┛   一个 GP矩阵 的默认值(或者说单位矩阵)是:┏      ┓ ┃1  0  0┃ ┃0  1  0┃ ┃0  0  1┃ ┗      ┛ //对角线上是 1, 其他都是 0; 这个默认值可通过 矩阵.重置 方法获取.   根据各个位置的功能, GDI 给各位置命名如下(第三列没有意义也没有命名):┏        ┓ ┃M11  M12  0┃ ┃M21  M22  0┃ ┃DX   DY   1┃ ┗        ┛ 资源作者:
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值