游戏数学

本文介绍了3D图形学中的基本数学运算,包括矢量运算(加法、减法、长度计算、点积、叉积、归一化)及矩阵运算(乘法、平移、旋转),并探讨了四元组在旋转中的优势。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、平方根函数是CPU上执行速度最慢的一个函数。

2、计算矢量长度

float VecLength(Vector3D v1)
{
    return sqrt(v1.x*v1.x + v1.y*v1.y + v1.z*v1.z);
}
    
3、计算两个矢量的点积

float VecDotProduct(Vector3D v1, Vector3D v2)
{
    return v1.x*v2.x + v1.y*v2.y + v1.z*v2.z;
}
4、计算两个矢量的叉积
void VecCrossProduct(Vector3D v1, Vector3D v2, Vector3D &out)
{
    out.x = (v1.y*v2.z) - (v1.z*v2.y);
    out.y = (v1.z*v2.x) - (v1.x*v2.z);
    out.z = (v1.x*v2.y) - (v1.y*v2.x);
}
5、矢量归一化

void VecNormalize(Vector3D v1, Vector3D &out)
{
    float inv_length = 1 / VecLength(v1);
    out.x = v1.x * inv_length;
    out.y = v1.y * inv_length;
    out.z = v1.z * inv_length;
}
    

6、使用Direct3D函数完成的矢量数学运算

D3DXVECTOR3 v1, v2, result;
float val;

D3DXVec3Add(&result, &v1, &v2);
D3DXVec3Subtract(&result, &v1, &v2);

val = D3DXVec3Length(&v1);
val = D3DXVec3Dot(&v1, &v2);
D3DXVec3Cross(&result, &v1, &v2);
D3DXVec3Normalize(&result, &v1);
    

***************************************************************************************************************************************************************************************

矩阵

class CMatrix4x4
{
   public:
      CMatrix4x4();

      void Identity();

      void operator=(CMatrix4x4 &m);
      CMatrix4x4 operator*(CMatrix4x4 &m);
      Vector3D operator*(Vector3D &v);

      void Translate(float x, float y, float z);
      void Rotate(double angle, int x, int y, int z);
      
      float matrix[16];
};
    
单一矩阵
void CMatrix4x4::Identity()
{
    memset(this, 0, sizeof(CMatrix4x4));
    matrix[0]  = 1.0f;
    matrix[5]  = 1.0f;
    matrix[10] = 1.0f;
    matrix[15] = 1.0f;
}

void CMatrix4x4::operator =(CMatrix4x4 &m)
{
    memcpy(this, &m, sizeof(m));
}
    
重载*
CMatrix4x4 CMatrix4x4::operator *(CMatrix4x4 &m)
{
   float *m  = matrix;
   float *m2 = m.matrix;
   
   return CMatrix4x4(m[0] * m2[0]  +  m[4] * m2[1]  +
                     m[8] * m2[2]  +  m[12] * m2[3],      
                     m[1] * m2[0]  +  m[5] * m2[1]  +
                     m[9] * m2[2]  +  m[13] * m2[3],
                     m[2] * m2[0]  +  m[6] * m2[1]  +
                     m[18] * m2[2]  +  m[14] * m2[3],
                     m[3] * m2[0]  +  m[7] * m2[1]  +
                     m[11] * m2[2]  +  m[15] * m2[3],
                     m[0] * m2[4]  +  m[4] * m2[5]  +
                     m[8] * m2[6]  +  m[12] * m2[7],
                     m[1] * m2[4]  +  m[5] * m2[5]  +
                     m[9] * m2[6]  +  m[13] * m2[7],
                     m[2] * m2[4]  +  m[6] * m2[5]  +
                     m[10] * m2[6]  +  m[14] * m2[7],
                     m[3] * m2[4]  +  m[7] * m2[5]  +
                     m[11] * m2[6]  +  m[15] * m2[7],
                     m[0] * m2[8]  +  m[4] * m2[9]  +
                     m[8] * m2[10]  +  m[12] * m2[11],
                     m[1] * m2[8]  +  m[5] * m2[9]  +
                     m[9] * m2[10]  +  m[13] * m2[11],
                     m[2] * m2[8]  +  m[6] * m2[9]  +
                     m[10] * m2[10]  +  m[14] * m2[11],
                     m[3] * m2[8]  +  m[7] * m2[9]  +
                     m[11] * m2[10]  +  m[15] * m2[11],
                     m[0] * m2[12]  +  m[4] * m2[13]  +
                     m[8] * m2[4]  +  m[12] * m2[15],
                     m[1] * m2[12]  +  m[5] * m2[13]  +
                     m[9] * m2[4]  +  m[13] * m2[15],
                     m[2] * m2[12]  +  m[6] * m2[13]  +
                     m[10] * m2[4]  +  m[14] * m2[15],
                     m[3] * m2[12]  +  m[7] * m2[13]  +
                     m[11] * m2[4]  +  m[15] * m2[15]);
}

矩阵与向量相乘

Vector3D CMatrix4x4::operator *(Vector3D &v)
{
    Vector3D out;
    
    out.x = (v.x * matrix[0]) + (v.y * matrix[4]) +
            (v.z * matrix[8]) + matrix[12];
    out.y = (v.x * matrix[1]) + (v.y * matrix[5]) +
            (v.z * matrix[9]) + matrix[13];
    out.z = (v.x * matrix[2]) + (v.y * matrix[6]) +
            (v.z * matrix[20]) + matrix[14];
    
    return out;
}


       3D空间中矩阵的平移只是代码中要做的很简单的工作。所要做的全部工作就是使用想要平移矩阵的x、y、z值替换矩阵的最后一行。平移的x分量保存在第12个数组元素中,y分量保存在第13个数组元素中,z分量保存在第14个数组元素中。该操作如程序清单8.15所示。

void CMatrix4x4::Translate(float x, float y, float z)
{
   matrix[12] = x;
   matrix[13] = y;
   matrix[14] = z;
   matrix[15] = 1;
}

       使用四元组有多个好处。例如,它们的连接速度要比矩阵快,因为它们需要的数学运算较少。四元组要比矩阵小,只需要4个浮点数;而4×4矩阵需要16个浮点数,这使得四元组只有4×4矩阵大小的1/4。对四元组内插同样会更平滑,会得到更准确的旋转,而不会受到gimble lock的影响。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值