游戏开发论坛

 找回密码
 立即注册
搜索
查看: 2142|回复: 0

无限大小矩阵的设计.

[复制链接]

14

主题

131

帖子

136

积分

注册会员

Rank: 2

积分
136
发表于 2005-4-11 11:06:00 | 显示全部楼层 |阅读模式
  这一久在学习动力学,遇到一个很棘手的问题----接触力的计算,即为当一个物体的某一点与另一个问题的相对速度(VR = (V1 - V2) 点积 N)为0 ,或接近0是所受到的力,需要使用随意行 和 列的矩阵(我称它为 BIGMATRIX),而微软的DXSDK的数学库并没有提供大于 4X4的矩阵,所以决定自己写一个,经过一番努力,将其完成,现我把源代码贴出来,希望对大家以后遇到类似问题时有所帮助!
  BigMatrix为一个类, +=,-=,*=及 /=为BigMatrix的成员函数,并且重载,为内联函数,返回一个引用!而  +,-,*,/  为非成员函数,这几个运算符并没有重载,原因是由于C ++本身的缺陷,只能返回值,不能是指针或是引用(只是在重载函数的情况下,具体为什么请看有关c++书籍进行更多的了解)而返回值要调用拷贝构造函数,这样的效率是非常低下的,所以我在这里使用多一个包含返回值的函数,例如MatrixMultiply ,事实上微软在DXSDK的数学库中也确实是这样做的!!

  代码如下:
两个文件,一个是MATRIX.CPP,另一个是MATRIX.H.

/////////////////////////////////////////
//Matrix.cpp
//////////////////////////////////////////
#include "Matrix.h"

BigMatrix::BigMatrix(int iRow,int iColumn)
{
m_iRow = iRow;
m_iColumn = iColumn;

//现在定义一个 iRow X iColumn 大小的数组
m_f_pMatrix = new float *[iRow];
for(int i = 0;i < iRow;i ++)
m_f_pMatrix = new float [iColumn];

for(int i = 0;i < m_iRow;i ++)
{
for(int j = 0;j < m_iColumn;j ++)
{
m_f_pMatrix[j] = 0.0f;
}
}

//现在定义一个 iRow X iColumn 大小的数组
/*Matrix.resize(iRow);
for(int i = 0;i < iColumn;i ++)
Matrix.resize(iColumn);*/

}
BigMatrix::~BigMatrix(void)
{
for(int i = 0;i < m_iRow;i ++)
delete []m_f_pMatrix;
delete []m_f_pMatrix;
}
BigMatrix& BigMatrix:perator += (BigMatrix cM)
{
for(int i = 0;i <m_iRow;i ++)
{
for(int j = 0;j < m_iColumn;j ++)
{
m_f_pMatrix[j] += cM.m_f_pMatrix[j];
}
}
return *this;
}
BigMatrix& BigMatrix::operator -= (BigMatrix cM)
{
for(int i = 0;i <m_iRow;i ++)
{
for(int j = 0;j < m_iColumn;j ++)
{
m_f_pMatrix[j] -= cM.m_f_pMatrix[j];
}
}
return *this;
}
BigMatrix& BigMatrix::operator *= (float fMultiplicand)
{
for(int i = 0;i <m_iRow;i ++)
{
for(int j = 0;j < m_iColumn;j ++)
{
m_f_pMatrix[j] *= fMultiplicand;
}
}
return *this;
}
BigMatrix& BigMatrix::operator /= (float fMultiplicand)
{
for(int i = 0;i <m_iRow;i ++)
{
for(int j = 0;j < m_iColumn;j ++)
{
m_f_pMatrix[j] += fMultiplicand;
}
}
return *this;
}


BigMatrix* MatrixInverse(BigMatrix* pOut,const BigMatrix* pM)
{
float Pivot;
int iRow = pM->GetRow();//因为求逆时只能是方阵,只需行;

//建立一个ROW X ROW的单位矩阵,用来储存结果
float** f_pResult = new float* [iRow];
for(int i = 0;i <iRow;i ++)
f_pResult = new float [iRow];  ;

//初始化单位矩阵;
for(int i = 0;i < iRow;i ++)
{
for(int j = 0;j< iRow;j ++)
{
if(i == j)
f_pResult[j] = 1.0f;
else
f_pResult[j] = 0.0f;
}
}

//使主对角线的元为 1;
for(int i = 0;i < iRow;i ++)
{
Pivot = pM->m_f_pMatrix;
if(Pivot != 1)
{
for(int k = 0;k < iRow;k ++)
{
pM->m_f_pMatrix[k] /= Pivot;
f_pResult[k] /= Pivot;
}
}

for(int j = 0;j < iRow;j ++)
{
//以 i 变量为列,遍历除 i 行的所有行 (因为是方阵,所以 主对角线的元的 行 和 列是一样的)
Pivot = pM->m_f_pMatrix[j];
if(Pivot != 0 && j != i)
{
for(int k = 0;k < iRow;k ++)
{
pM->m_f_pMatrix[j][k] = pM->m_f_pMatrix[j][k] - pM->m_f_pMatrix[k] * Pivot;
f_pResult[j][k] = f_pResult[j][k] - f_pResult[k] * Pivot;
}
}
}
}
for(int i =0;i < iRow;i ++)
{
for(int j = 0;j < iRow;j ++)
{
pOut->m_f_pMatrix[j] = f_pResult[j];
}
}

for(int i = 0;i < iRow;i ++)
delete []f_pResult;
delete []f_pResult;

return pOut;
}

BigMatrix* MatrixTranspose(BigMatrix* pOut,const BigMatrix* pM)
{
float **f_pTemp = new float *[pM->GetColumn()];
for(int i = 0;i <pM->GetColumn();i ++)
f_pTemp = new float [pM->GetRow()];

for(int i = 0;i <pM->GetRow();i ++)
{
for(int j = 0;j < pM->GetColumn();j ++)
{
f_pTemp[j] = pM->m_f_pMatrix[j];
}
}

for(int i = 0;i <pM->GetRow();i ++)
{
for(int j = 0;j < pM->GetColumn();j ++)
{
pOut->m_f_pMatrix[j] = f_pTemp[j];
}
}

return pOut;
}


BigMatrix *MatrixAdd(BigMatrix *pOut,const BigMatrix *pM1,const BigMatrix *pM2)
{

for(int i = 0;i < pM1->GetRow();i ++)
{
for(int j = 0;j < pM1->GetColumn();j ++)
{
pOut->m_f_pMatrix[j] = pM1->m_f_pMatrix[j] + pM2->m_f_pMatrix[j];
}
}

return pOut;
}

BigMatrix *MatrixSubtract(BigMatrix *pOut,const BigMatrix *pM1,const BigMatrix *pM2)
{

for(int i = 0;i < pM1->GetRow();i ++)
{
for(int j = 0;j < pM1->GetColumn();j ++)
{
pOut->m_f_pMatrix[j] = pM1->m_f_pMatrix[j] - pM2->m_f_pMatrix[j];
}
}
return pOut;
}

BigMatrix *MatrixMultiply(BigMatrix *pOut,const BigMatrix *pM1,const BigMatrix *pM2)
{

for(int i = 0;i < pM1->GetRow();i ++)
{
for(int j = 0;j < pM2->GetColumn();j ++)
{
for(int k = 0;k <pM1->GetColumn();k ++)
{
pOut->m_f_pMatrix[j] += pM1->m_f_pMatrix[k] * pM2->m_f_pMatrix[k][j];

}

}
}

return pOut;
}



/////////////////////////////////////////////////////
//Matrix.h
///////////////////////////////////////////////////
#pragma once
#include<vector>
using namespace std;
class BigMatrix
{
public:

BigMatrix(int iRow,int iColumn);
~BigMatrix(void);
float **m_f_pMatrix;
/*vector <vector<int> > Matrix;*/
BigMatrix &operator += (BigMatrix cM);
BigMatrix &operator -= (BigMatrix cM);
BigMatrix &operator *= (float fMultiplicand);
BigMatrix &operator /= (float fMultiplicand);
inline int GetRow(void) const{return m_iRow;}
inline int GetColumn(void) const{return m_iColumn;}

private:

int m_iRow,m_iColumn;

};

BigMatrix *MatrixInverse(BigMatrix* pOut,const BigMatrix* pM);
BigMatrix *MatrixTranspose(BigMatrix* pOut,const BigMatrix* pM);
BigMatrix *MatrixAdd(BigMatrix *pOut,const BigMatrix *pM1,const BigMatrix *pM2);
BigMatrix *MatrixSubtract(BigMatrix *pOut,const BigMatrix *pM1,const BigMatrix *pM2);
BigMatrix *MatrixMultiply(BigMatrix *pOut,const BigMatrix *pM1,const BigMatrix *pM2);



执行演示结果:

sf_200541111639.jpg
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-12-25 06:22

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表