DirectX9:先导篇 数学基础

一.左手系坐标和右手系坐标

左手系坐标和右手系坐标的X轴和Y轴都是分别指向右边和上边的,唯一的区别在于手指中指指向的方向,一个是朝着屏幕,一个是朝着我们自己.

 

二.向量

点是三维空间中的一个坐标,它的值是参照原点绝对的

向量是表示方向和大小的三个分量,与位置距离无关,它是相对于参考点的

 

1.向量的表示

(1)3D向量
1
2
3
4
5
6
7
8
9
10
// 向量结构体
  
#ifndef D3DVECTOR_DEFINED
typedef struct _D3DVECTOR {
    float x;
    float y;
    float z;
} D3DVECTOR;
#define D3DVECTOR_DEFINED
#endif

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
// 向量类
  
#ifdef __cplusplus
typedef struct D3DXVECTOR3 : public D3DVECTOR
{
public:
    D3DXVECTOR3() {};
    D3DXVECTOR3( CONST FLOAT * );
    D3DXVECTOR3( CONST D3DVECTOR& );
    D3DXVECTOR3( CONST D3DXFLOAT16 * );
    D3DXVECTOR3( FLOAT x,FLOAT y,FLOAT z );
  
    //casting
    operator FLOAT* ();
    operator CONST FLOAT* () const;
  
    D3DXVECTOR3& operator += ( CONST D3DXVECTOR3& );
    D3DXVECTOR3& operator -= ( CONST D3DXVECTOR3& );
    D3DXVECTOR3& operator *= ( FLOAT );
    D3DXVECTOR3& operator /= ( FLOAT );
  
    D3DXVECTOR3 operator + () const;
    D3DXVECTOR3 operator - () const;
  
    D3DXVECTOR3 operator + ( CONST D3DXVECTOR3& ) const;
    D3DXVECTOR3 operator - ( CONST D3DXVECTOR3& ) const;
    D3DXVECTOR3 operator * ( FLOAT ) const;
    D3DXVECTOR3 operator / ( FLOAT ) const;
  
    friend D3DXVECTOR3 operator * ( FLOAT, CONST struct D3DXVECTOR3& );
  
    BOOL operator == ( CONST D3DXVECTOR3& ) const;
    BOOL operator != ( CONST D3DXVECTOR3& ) const;
  
} D3DXVECTOR3, *LPD3DXVECTOR3;
  
#else
typedef struct _D3DVECTOR D3DXVECTOR3, *LPD3DXVECTOR3;
#endif

 

(2)2D向量

 

(3)4D向量

 

2.向量判断

1
2
3
4
5
6
7
8
9
10
11
12
D3DXVECTOR u(1.0f,0.0f,1.0f);
D3DXVECTOR v(0.0f,1,0f,0.0f);
  
if(u==v)
  
if(u!=v)
  
// 比较浮点数,相差很小精度
bool Equals(float lhs,float rhs)
{
    return fabs(lhs - rhs) < EPSILON ? true : false;
}

 

3.计算向量的长度

|| u ||表示向量u的长度,计算向量u = (1,2,3)和v = (1,1)的长度

 

 

 

(1)D3DXVec3Length()
1
2
3
4
5
6
FLOAT D3DXVec3Length(
    CONST D3DXVECTOR3* pV;
);
  
D3DXVECTOR3 v(1.0f, 2.0f, 3.0f);
float magnitude = D3DXVec3Length( &v );  //相当于sqrt(),求模得14

 

4.向量的规范化

向量的规范化就是让向量的模变为1,即变为单位向量

将向量u=(1,2,3) 和v = (1,1)规范化

 

 

 

(1)D3DXVec3Normalize()
1
2
3
4
D3DXVECTOR3 *D3DXVec3Normalize(
    D3DXVECTOR3* pOut;
    CONST D3DXVECTOR3* pV;
);

 

5.向量的加减

向量的加减必须在两个向量的向量维数一致下进行

坐标轴意义:向量的加减其实就是根据原点对向量做两次平移的操作

 

1
2
3
4
5
6
D3DXVECTOR3 u(2.0f, 0.0f, 1.0f);
D3DXVECTOR3 v(0.0f, -1.0f, 5.0f);
  
// (2.0 + 0.0, 0.0 + (-1.0), 1.0 + 5.0)
  
D3DXVECTOR3 sum = u + v;  // = (2.0f, -1.0f, 6.0f)

 

 

1
2
3
4
D3DXVECTOR3 u(2.0f, 0.0f, 1.0f);
D3DXVECTOR3 v(0.0f, -1.0f, 5.0f);
  
D3DXVECTOR3 difference = u - v;    // = (2.0f, 1.0f, -4.0f)

 

6.向量的数乘

标量可以与向量相乘,

坐标轴意义:该运算是对向量进行缩放

 

 

1
2
D3DXVECTOR3 u(1.0f, 1.0f, -1.0f);
D3DXVECTOR3 scaledVec = u * 10.0f;  // =(10.0f, 10.0f, -10.0f)

 

7.向量的点乘

点乘就是两个向量的乘积

u * v = | u | | v | cosθ  表示两个向量的点乘是它们的模和夹角的余弦之和

 

(1)D3DXVec3Dot()
1
2
3
4
5
6
D3DXVECTOR3 u(1.0f, -1.0f, 0.0f);
D3DXVECTOR3 v(3.0f, 2.0f, 1.0f);
  
// (1.0*3.0)+(-1.0f*2.0f)+(0.0*1.0)
  
float dot = D3DXVec3Dot( &u, &v );  // =1.0

 

8.向量的叉乘

点乘求出的是一个标量

叉乘求出的是另一个向量,这一个向量垂直于另外两个向量

 

(1)D3DXVec3Cross()

D3DXVECTOR3* D3DXVec3Cross(

    D3DXVECTOR3* pOut,

    CONST D3DXVECTOR3* pV1,

    CONST D3DXVECTOR3* pV2

);

 

9.点和向量变换

D3DXVECTOR3* D3DXVec3TransformCoord(

    D3DXVECTOR3* pOut,

    CONST D3DXVECTOR3* pV,

    CONST D3DXMATRIX* pM

);

 

D3DXVECTOR3* WINAPI D3DXVec3TransformNormal(

    D3DXVECTOR3* pOut,

    CONST D3DXVECTOR3* pV,

    CONST D3DXMATRIX* pM

);

 

三.矩阵

 

 

1.矩阵的表示

在D3DX中表示4*4的矩阵,因为3*3的矩阵不能实现所有变换,比如平移 投影 反射等

1*4的矩阵表示行向量

 

 (1)D3DMATRIX结构体

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;

 

(2)D3DXMATRIX类

typedef struct D3DXMATRIX : public D3DMATRIX {
public:
    D3DXMATRIX() {};
    D3DXMATRIX( CONST FLOAT* );
    D3DXMATRIX( CONST D3DMATRIX& );
    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 );
 
    FLOAT& operator () ( UINT Row, UINT Col );
    FLOAT& operator () ( UINT Row, UINT Col ) const;
 
    operator FLOAT* ();
    operator cONST FLOAT* () const;
 
    D3DXMATRIX& operator *= ( CONST D3DXMATRIX& );
    D3DXMATRIX& operator += ( CONST D3DXMATRIX& );
    D3DXMATRIX& operator -= ( CONST D3DXMATRIX& );
    D3DXMATRIX& operator *= ( FLOAT );
    D3DXMATRIX& operator /= ( FLOAT );
 
    D3DXMATRIX operator + () const;
    D3DXMATRIX operator - () const;
   
    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;
 

 

2.矩阵相加减

两个矩阵的维数相同时才能把它们相加减

 

3.矩阵数乘

 

4.矩阵相乘

A的列数必须等于B的行数才能矩阵相乘

 

 

5.单位矩阵

单位矩阵除了对角(斜对角线)以外所有成员都是0

单位矩阵乘以任何矩阵都不会改变矩阵,相当于1

 

(1)D3DXMatrixIdentity()

D3DXMATRIX* D3DXMatrixIdentity(

    D3DXMATRIX* pout

);

 

1
2
D3DXMATRIX M;
D3DXMatrixIdentity(&M);

 

6.逆矩阵

矩阵之中并没有除法运算

只有方矩阵(正方形矩阵)才能求逆

矩阵和它的逆矩阵相乘得到单位矩阵

 

(1) D3DXMatrixInverse()

D3DXMATRIX* D3DXMatrixInverse(

    D3DXMATRIX* pOut,

    FLOAT* pDeterminant,

    CONST D3DXMATRIX* pM

);

 

7.转置矩阵

矩阵的转置就是相互交换矩阵的行和列

 

(1)D3DXMatrixTranspose()

D3DXMATRIX* D3DXMatrixTranspose(

    D3DXMATRIX* pOut,

    CONST D3DXMATRIX* pM

);

 

1
2
3
D3DXMATRIX A(...);
D3DXMATRIX B;
D3DXMatrixTranspose(&B, &A);

 

五.基本变换

1.平移矩阵

通过以下的矩阵相乘把向量(x,y,z,1)沿着x轴移动Px个单位,沿着y轴移动Py个单位,沿着z轴移动Pz个单位

向量多加一个维度,1表示可以变换,0表示禁止变换

(1)D3DXMatrixTranslation()

D3DXMATRIX* D3DXMatrixTranslation(

    D3DXMATRIX* pOut,

    FLOAT x,

    FLOAT y,

    FLOAT z

);

 

2.旋转矩阵

角度是顺时针的方向

 

(1)沿X轴旋转

 

 D3DXMATRIX* D3DXMatrixRotationX(

    D3DXMATRIX* pOut,

    FLOAT Angle

);

 

(2)沿Y轴旋转

 

 

D3DXMATRIX* D3DXMatrixRotationY(

    D3DXMATRIX* pOut,

    FLOAT Angle

);

 

(3)沿Z轴旋转

 

D3DXMATRIX* D3DXMatrixRotationZ(

    D3DXMATRIX* pOut,

    FLOAT Angle

);

 

3.缩放矩阵

通过以下的矩阵相乘把向量沿X轴缩放Qx个单位,沿Y轴缩放Qy个单位,沿Z轴缩放Qz个单位

 

 

(1)D3DXMatrixScaling()

D3DXMATRIX* D3DXMatrixScaling(

    D3DXMATRIX* pOut,

    FLOAT sx,

    FLOAT sy,

    FLOAT sz

);

 

posted @   言午丶  阅读(556)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示