|
发表于 2004-9-2 08:38:00
|
显示全部楼层
Re:转载矩阵运算代码
//----------------------------------------------------------------------------
template <int N, class Real>
Matrix<N,Real> Matrix<N,Real>::Transpose () const
{
Matrix<N,Real> kTranspose;
for (int iRow = 0; iRow < N; iRow++)
{
for (int iCol = 0; iCol < N; iCol++)
kTranspose.m_afEntry[I(iRow,iCol)] = m_afEntry[I(iCol,iRow)];
}
return kTranspose;
}
//----------------------------------------------------------------------------
template <int N, class Real>
Matrix<N,Real> Matrix<N,Real>::TransposeTimes (const Matrix& rkM) const
{
// P = A^T*B, P[r][c] = sum_m A[m][r]*B[m][c]
Matrix<N,Real> kProd;
for (int iRow = 0; iRow < N; iRow++)
{
for (int iCol = 0; iCol < N; iCol++)
{
int i = I(iRow,iCol);
kProd.m_afEntry = (Real)0.0;
for (int iMid = 0; iMid < N; iMid++)
{
kProd.m_afEntry +=
m_afEntry[I(iMid,iRow)]*rkM.m_afEntry[I(iMid,iCol)];
}
}
}
return kProd;
}
//----------------------------------------------------------------------------
template <int N, class Real>
Matrix<N,Real> Matrix<N,Real>::TimesTranspose (const Matrix& rkM) const
{
// P = A*B^T, P[r][c] = sum_m A[r][m]*B[c][m]
Matrix<N,Real> kProd;
for (int iRow = 0; iRow < N; iRow++)
{
for (int iCol = 0; iCol < N; iCol++)
{
int i = I(iRow,iCol);
kProd.m_afEntry = (Real)0.0;
for (int iMid = 0; iMid < N; iMid++)
{
kProd.m_afEntry +=
m_afEntry[I(iRow,iMid)]*rkM.m_afEntry[I(iCol,iRow)];
}
}
}
return kProd;
}
//----------------------------------------------------------------------------
template <int N, class Real>
Vector<N,Real> Matrix<N,Real>: perator* (const Vector<N,Real>& rkV) const
{
Vector<N,Real> kProd;
for (int iRow = 0; iRow < N; iRow++)
{
kProd[iRow] = (Real)0.0;
for (int iCol = 0; iCol < N; iCol++)
kProd[iRow] += m_afEntry[I(iRow,iCol)]*rkV[iCol];
}
return kProd;
}
//----------------------------------------------------------------------------
template <int N, class Real>
Vector<N,Real> operator* (const Vector<N,Real>& rkV,
const Matrix<N,Real>& rkM)
{
Vector<N,Real> kProd;
const Real* afMEntry = rkM;
Real* afPEntry = kProd;
for (int iCol = 0; iCol < N; iCol++)
{
afPEntry[iCol] = (Real)0.0;
for (int iRow = 0; iRow < N; iRow++)
afPEntry[iCol] += rkV[iRow]*afMEntry[iCol + N*iRow];
}
return kProd;
}
//----------------------------------------------------------------------------
template <int N, class Real>
Real Matrix<N,Real>: Form (const Vector<N,Real>& rkU,
const Vector<N,Real>& rkV) const
{
return rkU.Dot((*this)*rkV);
}
//----------------------------------------------------------------------------
template <int N, class Real>
int Matrix<N,Real>::I (int iRow, int iCol)
{
assert( 0 <= iRow && iRow < N && 0 <= iCol && iCol < N );
return iCol + N*iRow;
}
//----------------------------------------------------------------------------
// Magic Software, Inc.
// http://www.magic-software.com
// http://www.wild-magic.com
// Copyright (c) 2004. All Rights Reserved
//
// The Wild Magic Library (WML) source code is supplied under the terms of
// the license agreement http://www.magic-software.com/License/WildMagic.pdf
// and may not be copied or disclosed except in accordance with the terms of
// that agreement.
#ifndef WMLMATRIX4_H
#define WMLMATRIX4_H
#include "WmlMatrix.h"
#include "WmlVector4.h"
namespace Wml
{
template <class Real>
class WML_ITEM Matrix4 : public Matrix<4,Real>
{
public:
// construction
Matrix4 ();
Matrix4 (const Matrix4& rkM);
Matrix4 (const Matrix<4,Real>& rkM);
// input Mrc is in row r, column c.
Matrix4 (Real fM00, Real fM01, Real fM02, Real fM03,
Real fM10, Real fM11, Real fM12, Real fM13,
Real fM20, Real fM21, Real fM22, Real fM23,
Real fM30, Real fM31, Real fM32, Real fM33);
// Create a matrix from an array of numbers. The input array is
// interpreted based on the Boolean input as
// true: entry[0..15]={m00,m01,m02,m03,m10,m11,m12,m13,m20,m21,m22,
// m23,m30,m31,m32,m33} [row major]
// false: entry[0..15]={m00,m10,m20,m30,m01,m11,m21,m31,m02,m12,m22,
// m32,m03,m13,m23,m33} [col major]
Matrix4 (const Real afEntry[16], bool bRowMajor);
// assignment
Matrix4& operator= (const Matrix4& rkM);
Matrix4& operator= (const Matrix<4,Real>& rkM);
// matrix operations
Matrix4 Inverse () const;
Matrix4 Adjoint () const;
Real Determinant () const;
// special matrices
static const Matrix4 ZERO;
static const Matrix4 IDENTITY;
};
typedef Matrix4<float> Matrix4f;
typedef Matrix4<double> Matrix4d;
}
#endif
// Magic Software, Inc.
// http://www.magic-software.com
// http://www.wild-magic.com
// Copyright (c) 2004. All Rights Reserved
//
// The Wild Magic Library (WML) source code is supplied under the terms of
// the license agreement http://www.magic-software.com/License/WildMagic.pdf
// and may not be copied or disclosed except in accordance with the terms of
// that agreement.
#include "WmlMatrix4.h"
namespace Wml
{
#include "WmlMatrix.inl"
}
using namespace Wml;
//----------------------------------------------------------------------------
template <class Real>
Matrix4<Real>::Matrix4 ()
{
// the matrix is uninitialized
}
//----------------------------------------------------------------------------
template <class Real>
Matrix4<Real>::Matrix4 (const Matrix4& rkM)
{
memcpy(m_afEntry,rkM.m_afEntry,16*sizeof(Real));
}
//----------------------------------------------------------------------------
template <class Real>
Matrix4<Real>::Matrix4 (const Matrix<4,Real>& rkM)
{
memcpy(m_afEntry,(const Real*)rkM,16*sizeof(Real));
}
//----------------------------------------------------------------------------
template <class Real>
Matrix4<Real>& Matrix4<Real>::operator= (const Matrix4& rkM)
{
memcpy(m_afEntry,rkM.m_afEntry,16*sizeof(Real));
return *this;
}
//----------------------------------------------------------------------------
template <class Real>
Matrix4<Real>& Matrix4<Real>::operator= (const Matrix<4,Real>& rkM)
{
memcpy(m_afEntry,(const Real*)rkM,16*sizeof(Real));
return *this;
}
//----------------------------------------------------------------------------
template <class Real>
Matrix4<Real>::Matrix4 (Real fM00, Real fM01, Real fM02, Real fM03,
Real fM10, Real fM11, Real fM12, Real fM13, Real fM20, Real fM21,
Real fM22, Real fM23, Real fM30, Real fM31, Real fM32, Real fM33)
{
m_afEntry[ 0] = fM00;
m_afEntry[ 1] = fM01;
m_afEntry[ 2] = fM02;
m_afEntry[ 3] = fM03;
m_afEntry[ 4] = fM10;
m_afEntry[ 5] = fM11;
m_afEntry[ 6] = fM12;
m_afEntry[ 7] = fM13;
m_afEntry[ 8] = fM20;
m_afEntry[ 9] = fM21;
m_afEntry[10] = fM22;
m_afEntry[11] = fM23;
m_afEntry[12] = fM30;
m_afEntry[13] = fM31;
m_afEntry[14] = fM32;
m_afEntry[15] = fM33;
}
//----------------------------------------------------------------------------
template <class Real>
Matrix4<Real>::Matrix4 (const Real afEntry[16], bool bRowMajor)
{
if ( bRowMajor )
{
memcpy(m_afEntry,afEntry,16*sizeof(Real));
}
else
{
m_afEntry[ 0] = afEntry[ 0];
m_afEntry[ 1] = afEntry[ 4];
m_afEntry[ 2] = afEntry[ 8];
m_afEntry[ 3] = afEntry[12];
m_afEntry[ 4] = afEntry[ 1];
m_afEntry[ 5] = afEntry[ 5];
m_afEntry[ 6] = afEntry[ 9];
m_afEntry[ 7] = afEntry[13];
m_afEntry[ 8] = afEntry[ 2];
m_afEntry[ 9] = afEntry[ 6];
m_afEntry[10] = afEntry[10];
m_afEntry[11] = afEntry[14];
m_afEntry[12] = afEntry[ 3];
m_afEntry[13] = afEntry[ 7];
m_afEntry[14] = afEntry[11];
m_afEntry[15] = afEntry[15];
}
}
//----------------------------------------------------------------------------
template <class Real>
Matrix4<Real> Matrix4<Real>::Inverse () const
{
Real fA0 = m_afEntry[ 0]*m_afEntry[ 5] - m_afEntry[ 1]*m_afEntry[ 4];
Real fA1 = m_afEntry[ 0]*m_afEntry[ 6] - m_afEntry[ 2]*m_afEntry[ 4];
Real fA2 = m_afEntry[ 0]*m_afEntry[ 7] - m_afEntry[ 3]*m_afEntry[ 4];
Real fA3 = m_afEntry[ 1]*m_afEntry[ 6] - m_afEntry[ 2]*m_afEntry[ 5];
Real fA4 = m_afEntry[ 1]*m_afEntry[ 7] - m_afEntry[ 3]*m_afEntry[ 5];
Real fA5 = m_afEntry[ 2]*m_afEntry[ 7] - m_afEntry[ 3]*m_afEntry[ 6];
Real fB0 = m_afEntry[ 8]*m_afEntry[13] - m_afEntry[ 9]*m_afEntry[12];
Real fB1 = m_afEntry[ 8]*m_afEntry[14] - m_afEntry[10]*m_afEntry[12];
Real fB2 = m_afEntry[ 8]*m_afEntry[15] - m_afEntry[11]*m_afEntry[12];
Real fB3 = m_afEntry[ 9]*m_afEntry[14] - m_afEntry[10]*m_afEntry[13];
Real fB4 = m_afEntry[ 9]*m_afEntry[15] - m_afEntry[11]*m_afEntry[13];
Real fB5 = m_afEntry[10]*m_afEntry[15] - m_afEntry[11]*m_afEntry[14];
Real fDet = fA0*fB5-fA1*fB4+fA2*fB3+fA3*fB2-fA4*fB1+fA5*fB0;
if ( Math<Real>::FAbs(fDet) <= Math<Real>::EPSILON )
return Matrix4::ZERO;
Matrix4 kInv;
kInv[0][0] = + m_afEntry[ 5]*fB5 - m_afEntry[ 6]*fB4 + m_afEntry[ 7]*fB3;
kInv[1][0] = - m_afEntry[ 4]*fB5 + m_afEntry[ 6]*fB2 - m_afEntry[ 7]*fB1;
kInv[2][0] = + m_afEntry[ 4]*fB4 - m_afEntry[ 5]*fB2 + m_afEntry[ 7]*fB0;
kInv[3][0] = - m_afEntry[ 4]*fB3 + m_afEntry[ 5]*fB1 - m_afEntry[ 6]*fB0;
kInv[0][1] = - m_afEntry[ 1]*fB5 + m_afEntry[ 2]*fB4 - m_afEntry[ 3]*fB3;
kInv[1][1] = + m_afEntry[ 0]*fB5 - m_afEntry[ 2]*fB2 + m_afEntry[ 3]*fB1;
kInv[2][1] = - m_afEntry[ 0]*fB4 + m_afEntry[ 1]*fB2 - m_afEntry[ 3]*fB0;
kInv[3][1] = + m_afEntry[ 0]*fB3 - m_afEntry[ 1]*fB1 + m_afEntry[ 2]*fB0;
kInv[0][2] = + m_afEntry[13]*fA5 - m_afEntry[14]*fA4 + m_afEntry[15]*fA3;
kInv[1][2] = - m_afEntry[12]*fA5 + m_afEntry[14]*fA2 - m_afEntry[15]*fA1;
kInv[2][2] = + m_afEntry[12]*fA4 - m_afEntry[13]*fA2 + m_afEntry[15]*fA0;
kInv[3][2] = - m_afEntry[12]*fA3 + m_afEntry[13]*fA1 - m_afEntry[14]*fA0;
kInv[0][3] = - m_afEntry[ 9]*fA5 + m_afEntry[10]*fA4 - m_afEntry[11]*fA3;
kInv[1][3] = + m_afEntry[ 8]*fA5 - m_afEntry[10]*fA2 + m_afEntry[11]*fA1;
kInv[2][3] = - m_afEntry[ 8]*fA4 + m_afEntry[ 9]*fA2 - m_afEntry[11]*fA0;
kInv[3][3] = + m_afEntry[ 8]*fA3 - m_afEntry[ 9]*fA1 + m_afEntry[10]*fA0;
Real fInvDet = ((Real)1.0)/fDet;
for (int iRow = 0; iRow < 4; iRow++)
{
for (int iCol = 0; iCol < 4; iCol++)
kInv[iRow][iCol] *= fInvDet;
}
return kInv;
}
//----------------------------------------------------------------------------
template <class Real>
Matrix4<Real> Matrix4<Real>::Adjoint () const
{
Real fA0 = m_afEntry[ 0]*m_afEntry[ 5] - m_afEntry[ 1]*m_afEntry[ 4];
Real fA1 = m_afEntry[ 0]*m_afEntry[ 6] - m_afEntry[ 2]*m_afEntry[ 4];
Real fA2 = m_afEntry[ 0]*m_afEntry[ 7] - m_afEntry[ 3]*m_afEntry[ 4];
Real fA3 = m_afEntry[ 1]*m_afEntry[ 6] - m_afEntry[ 2]*m_afEntry[ 5];
Real fA4 = m_afEntry[ 1]*m_afEntry[ 7] - m_afEntry[ 3]*m_afEntry[ 5];
Real fA5 = m_afEntry[ 2]*m_afEntry[ 7] - m_afEntry[ 3]*m_afEntry[ 6];
Real fB0 = m_afEntry[ 8]*m_afEntry[13] - m_afEntry[ 9]*m_afEntry[12];
Real fB1 = m_afEntry[ 8]*m_afEntry[14] - m_afEntry[10]*m_afEntry[12];
Real fB2 = m_afEntry[ 8]*m_afEntry[15] - m_afEntry[11]*m_afEntry[12];
Real fB3 = m_afEntry[ 9]*m_afEntry[14] - m_afEntry[10]*m_afEntry[13];
Real fB4 = m_afEntry[ 9]*m_afEntry[15] - m_afEntry[11]*m_afEntry[13];
Real fB5 = m_afEntry[10]*m_afEntry[15] - m_afEntry[11]*m_afEntry[14];
Matrix4 kAdj;
kAdj[0][0] = + m_afEntry[ 5]*fB5 - m_afEntry[ 6]*fB4 + m_afEntry[ 7]*fB3;
kAdj[1][0] = - m_afEntry[ 4]*fB5 + m_afEntry[ 6]*fB2 - m_afEntry[ 7]*fB1;
kAdj[2][0] = + m_afEntry[ 4]*fB4 - m_afEntry[ 5]*fB2 + m_afEntry[ 7]*fB0;
kAdj[3][0] = - m_afEntry[ 4]*fB3 + m_afEntry[ 5]*fB1 - m_afEntry[ 6]*fB0;
kAdj[0][1] = - m_afEntry[ 1]*fB5 + m_afEntry[ 2]*fB4 - m_afEntry[ 3]*fB3;
kAdj[1][1] = + m_afEntry[ 0]*fB5 - m_afEntry[ 2]*fB2 + m_afEntry[ 3]*fB1;
kAdj[2][1] = - m_afEntry[ 0]*fB4 + m_afEntry[ 1]*fB2 - m_afEntry[ 3]*fB0;
kAdj[3][1] = + m_afEntry[ 0]*fB3 - m_afEntry[ 1]*fB1 + m_afEntry[ 2]*fB0;
kAdj[0][2] = + m_afEntry[13]*fA5 - m_afEntry[14]*fA4 + m_afEntry[15]*fA3;
kAdj[1][2] = - m_afEntry[12]*fA5 + m_afEntry[14]*fA2 - m_afEntry[15]*fA1;
kAdj[2][2] = + m_afEntry[12]*fA4 - m_afEntry[13]*fA2 + m_afEntry[15]*fA0;
kAdj[3][2] = - m_afEntry[12]*fA3 + m_afEntry[13]*fA1 - m_afEntry[14]*fA0;
kAdj[0][3] = - m_afEntry[ 9]*fA5 + m_afEntry[10]*fA4 - m_afEntry[11]*fA3;
kAdj[1][3] = + m_afEntry[ 8]*fA5 - m_afEntry[10]*fA2 + m_afEntry[11]*fA1;
kAdj[2][3] = - m_afEntry[ 8]*fA4 + m_afEntry[ 9]*fA2 - m_afEntry[11]*fA0;
kAdj[3][3] = + m_afEntry[ 8]*fA3 - m_afEntry[ 9]*fA1 + m_afEntry[10]*fA0;
return kAdj;
}
//----------------------------------------------------------------------------
template <class Real>
Real Matrix4<Real>: eterminant () const
{
Real fA0 = m_afEntry[ 0]*m_afEntry[ 5] - m_afEntry[ 1]*m_afEntry[ 4];
Real fA1 = m_afEntry[ 0]*m_afEntry[ 6] - m_afEntry[ 2]*m_afEntry[ 4];
Real fA2 = m_afEntry[ 0]*m_afEntry[ 7] - m_afEntry[ 3]*m_afEntry[ 4];
Real fA3 = m_afEntry[ 1]*m_afEntry[ 6] - m_afEntry[ 2]*m_afEntry[ 5];
Real fA4 = m_afEntry[ 1]*m_afEntry[ 7] - m_afEntry[ 3]*m_afEntry[ 5];
Real fA5 = m_afEntry[ 2]*m_afEntry[ 7] - m_afEntry[ 3]*m_afEntry[ 6];
Real fB0 = m_afEntry[ 8]*m_afEntry[13] - m_afEntry[ 9]*m_afEntry[12];
Real fB1 = m_afEntry[ 8]*m_afEntry[14] - m_afEntry[10]*m_afEntry[12];
Real fB2 = m_afEntry[ 8]*m_afEntry[15] - m_afEntry[11]*m_afEntry[12];
Real fB3 = m_afEntry[ 9]*m_afEntry[14] - m_afEntry[10]*m_afEntry[13];
Real fB4 = m_afEntry[ 9]*m_afEntry[15] - m_afEntry[11]*m_afEntry[13];
Real fB5 = m_afEntry[10]*m_afEntry[15] - m_afEntry[11]*m_afEntry[14];
Real fDet = fA0*fB5-fA1*fB4+fA2*fB3+fA3*fB2-fA4*fB1+fA5*fB0;
return fDet;
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
// explicit instantiation
//----------------------------------------------------------------------------
namespace Wml
{
#ifdef WML_INSTANTIATE_BEFORE
template class WML_ITEM Matrix<4,float>;
#ifdef WML_USING_VC6
template WML_ITEM Matrix<4,float> operator* (float,
const Matrix<4,float>&);
template WML_ITEM Vector<4,float> operator*
(const Vector<4,float>&, const Matrix<4,float>&);
#else
template WML_ITEM Matrix<4,float> operator*<4,float> (float,
const Matrix<4,float>&);
template WML_ITEM Vector<4,float> operator*<4,float>
(const Vector<4,float>&, const Matrix<4,float>&);
#endif
template<> const Matrix4<float> Matrix4<float>::ZERO(
0.0f,0.0f,0.0f,0.0f,
0.0f,0.0f,0.0f,0.0f,
0.0f,0.0f,0.0f,0.0f,
0.0f,0.0f,0.0f,0.0f);
template<> const Matrix4<float> Matrix4<float>::IDENTITY(
1.0f,0.0f,0.0f,0.0f,
0.0f,1.0f,0.0f,0.0f,
0.0f,0.0f,1.0f,0.0f,
0.0f,0.0f,0.0f,1.0f);
template class WML_ITEM Matrix4<float>;
template class WML_ITEM Matrix<4,double>;
#ifdef WML_USING_VC6
template WML_ITEM Matrix<4,double> operator* (double,
const Matrix<4,double>&);
template WML_ITEM Vector<4,double> operator*
(const Vector<4,double>&, const Matrix<4,double>&);
#else
template WML_ITEM Matrix<4,double> operator*<4,double> (double,
const Matrix<4,double>&);
template WML_ITEM Vector<4,double> operator*<4,double>
(const Vector<4,double>&, const Matrix<4,double>&);
#endif
template<> const Matrix4<double> Matrix4<double>::ZERO(
0.0,0.0,0.0,0.0,
0.0,0.0,0.0,0.0,
0.0,0.0,0.0,0.0,
0.0,0.0,0.0,0.0);
template<> const Matrix4<double> Matrix4<double>::IDENTITY(
1.0,0.0,0.0,0.0,
0.0,1.0,0.0,0.0,
0.0,0.0,1.0,0.0,
0.0,0.0,0.0,1.0);
template class WML_ITEM Matrix4<double>;
#else
template class WML_ITEM Matrix<4,float>;
#ifdef WML_USING_VC6
template WML_ITEM Matrix<4,float> operator* (float,
const Matrix<4,float>&);
template WML_ITEM Vector<4,float> operator*
(const Vector<4,float>&, const Matrix<4,float>&);
#else
template WML_ITEM Matrix<4,float> operator*<4,float> (float,
const Matrix<4,float>&);
template WML_ITEM Vector<4,float> operator*<4,float>
(const Vector<4,float>&, const Matrix<4,float>&);
#endif
template class WML_ITEM Matrix4<float>;
template<> const Matrix4<float> Matrix4<float>::ZERO(
0.0f,0.0f,0.0f,0.0f,
0.0f,0.0f,0.0f,0.0f,
0.0f,0.0f,0.0f,0.0f,
0.0f,0.0f,0.0f,0.0f);
template<> const Matrix4<float> Matrix4<float>::IDENTITY(
1.0f,0.0f,0.0f,0.0f,
0.0f,1.0f,0.0f,0.0f,
0.0f,0.0f,1.0f,0.0f,
0.0f,0.0f,0.0f,1.0f);
template class WML_ITEM Matrix<4,double>;
#ifdef WML_USING_VC6
template WML_ITEM Matrix<4,double> operator* (double,
const Matrix<4,double>&);
template WML_ITEM Vector<4,double> operator*
(const Vector<4,double>&, const Matrix<4,double>&);
#else
template WML_ITEM Matrix<4,double> operator*<4,double> (double,
const Matrix<4,double>&);
template WML_ITEM Vector<4,double> operator*<4,double>
(const Vector<4,double>&, const Matrix<4,double>&);
#endif
template class WML_ITEM Matrix4<double>;
template<> const Matrix4<double> Matrix4<double>::ZERO(
0.0,0.0,0.0,0.0,
0.0,0.0,0.0,0.0,
0.0,0.0,0.0,0.0,
0.0,0.0,0.0,0.0);
template<> const Matrix4<double> Matrix4<double>::IDENTITY(
1.0,0.0,0.0,0.0,
0.0,1.0,0.0,0.0,
0.0,0.0,1.0,0.0,
0.0,0.0,0.0,1.0);
#endif
}
//----------------------------------------------------------------------------
|
|