www.pudn.com > cad3d.zip > 3DMatrix.h


// Matrix.h: interface for the C3DMatrix class. 
// 
////////////////////////////////////////////////////////////////////// 
 
#if !defined(AFX_3DMATRIX_H__2BA53B06_5FF2_11D4_9525_FB525FE16108__INCLUDED_) 
#define AFX_3DMATRIX_H__2BA53B06_5FF2_11D4_9525_FB525FE16108__INCLUDED_ 
 
#if _MSC_VER > 1000 
#pragma once 
#endif // _MSC_VER > 1000 
 
#include  
#include    
 
#include "Check.h" 
#include "3DMath/3DPoint.h" 
#include "3DMath/3DVector.h" 
 
class MATH3D_API C3DMatrix 
{ 
public: 
	enum InitMatrix0Enum { InitUndefined, InitNull, InitUnit}; 
	enum InitMatrix1Enum { InitTransposed, InitInverted}; 
	enum InitMatrix3Enum { InitPlaneProject, InitHouseholder, InitMainPivot}; 
	enum InitMatrix4Enum { InitRows, InitCols}; 
 
protected: 
	 
	math_real		m_dMt[16]; 
 
public: 
 
	C3DMatrix(); 
	C3DMatrix(const C3DMatrix& rOther); 
	C3DMatrix(const math_real* pOther); 
	C3DMatrix(const C3DPoint& rVec, const C3DPoint& rCoVec); 
	C3DMatrix(InitMatrix0Enum eInitMatrix); 
	C3DMatrix(InitMatrix3Enum eInitMatrix, const C3DPoint& rVec); 
	C3DMatrix(InitMatrix1Enum eInitMatrix, const C3DMatrix& rOther); 
	C3DMatrix(InitMatrix4Enum eInitMatrix, const C3DPoint& rVec0, const C3DPoint& rVec1, const C3DPoint& rVec2, const C3DPoint& rVec3); 
	 
	std::string	Dump(bool showMessage = true) const; 
 
	C3DPoint	GetRow(int i) const 
	{ 
		CHECK( 0 <= i && i <= 3); 
		return C3DPoint (m_dMt[i],m_dMt[i+4], m_dMt[i+8],m_dMt[i+12]); 
	} 
 
	C3DPoint	GetCol(int j) const 
	{ 
		CHECK( 0 <= j && j <= 3); 
		return C3DPoint(m_dMt + (j<<2)); 
	} 
 
	C3DPoint	GetMainPivot() const 
	{ 
		return C3DPoint((*this)(0,0), (*this)(1,1), (*this)(2,2), (*this)(3,3)); 
	} 
 
	void		SetRow(const int i, const math_real* row); 
	void		SetCol(const int j, const math_real* col); 
	void		SetMainPivot(const C3DPoint& rPt) 
	{ 
		(*this)(0,0) = rPt(0); 
		(*this)(1,1) = rPt(1); 
		(*this)(2,2) = rPt(2); 
		(*this)(3,3) = rPt(3); 
	} 
	 
	void		SetMainPivot(math_real dX = 0, math_real dY = 0, math_real dZ = 0, math_real dW = 1) 
	{ 
		(*this)(0,0) = dX; 
		(*this)(1,1) = dY; 
		(*this)(2,2) = dZ; 
		(*this)(3,3) = dW; 
	} 
 
	void		MultCol(const int j, const math_real k); 
	void		MultRow(const int i, const math_real k); 
	math_real	SumMainPivot() const; 
	math_real	MulMainPivot() const; 
 
	math_real	GetTrace() const 
	{ 
		return SumMainPivot(); 
	} 
 
	void		SwapRows(const int i1, const int i2); 
	void		SwapCols(const int j1, const int j2); 
 
	C3DMatrix	operator * (const C3DMatrix& a) const; 
	C3DMatrix	operator + (const C3DMatrix& a) const; 
	C3DMatrix	operator - (const C3DMatrix& a) const; 
	C3DMatrix	operator * (math_real dK) const; 
	C3DMatrix	operator / (math_real dK) const; 
	C3DMatrix&	operator *= (const C3DMatrix& a); //right mult 
	C3DMatrix&	operator += (const C3DMatrix& a);  
	C3DMatrix&	operator -= (const C3DMatrix& a);  
	C3DPoint	operator * (const C3DPoint& a) const; 
	math_real&	operator ()(const int i, const int j); 
	math_real	operator ()(const int i, const int j) const; 
				operator math_real*() { return m_dMt; } 
				operator const math_real*() const { return m_dMt; } 
 
	C3DMatrix&	operator *= (math_real k);  
	C3DMatrix&	operator /= (math_real k);  
 
	math_real	Det() const; 
	bool		Invert(); 
	void		Identity(); 
	void		Zero(); 
	void		Transpose(); 
	void		Tensor(const C3DPoint& rVec, const C3DPoint& rCoVec); 
	void		PlaneProject(const C3DPoint& rNormal); 
	void		Householder(const C3DPoint& rNormal); 
	bool		IsSingular() const; 
}; 
 
inline	C3DMatrix::C3DMatrix(const C3DMatrix& rOther) 
{ 
	memcpy(m_dMt,rOther.m_dMt,16*sizeof(math_real)); 
} 
 
inline	C3DMatrix::C3DMatrix(const math_real* pOther) 
{ 
	memcpy(m_dMt,pOther,16*sizeof(math_real)); 
} 
 
inline	math_real C3DMatrix::SumMainPivot() const 
{ 
	return m_dMt[0] + m_dMt[5] + m_dMt[10] + m_dMt[15]; 
} 
 
inline	math_real		C3DMatrix::MulMainPivot() const 
{ 
	return m_dMt[0] * m_dMt[5] * m_dMt[10] * m_dMt[15]; 
} 
 
 
inline	void C3DMatrix::SetRow(const int i, const math_real* row) 
{ 
	CHECK( 0 <= i && i <= 3); 
 
	m_dMt[i]	= row[0]; 
	m_dMt[i+4]	= row[1]; 
	m_dMt[i+8]	= row[2]; 
	m_dMt[i+12]	= row[3]; 
} 
 
inline	void C3DMatrix::SetCol(const int j, const math_real* col) 
{ 
	CHECK( 0 <= j && j <= 3); 
 
	memcpy(m_dMt + (j<<2), col, 4*sizeof(math_real)); 
} 
 
inline	void C3DMatrix::SwapRows(const int i1, const int i2) 
{ 
	CHECK( 0 <= i1 && i1 <= 3); 
	CHECK( 0 <= i2 && i2 <= 3); 
 
	const C3DPoint temp(GetRow(i1)); 
	m_dMt[i1]	= m_dMt[i2]; 
	m_dMt[i1+4]	= m_dMt[i2+4]; 
	m_dMt[i1+8]	= m_dMt[i2+8]; 
	m_dMt[i1+12]= m_dMt[i2+12]; 
 
	SetRow(i2,temp); 
} 
 
inline	void		C3DMatrix::SwapCols(const int j1, const int j2) 
{ 
	CHECK( 0 <= j1 && j1 <= 3); 
	CHECK( 0 <= j2 && j2 <= 3); 
 
	const C3DPoint temp(GetCol(j1)); 
	SetCol(j1,m_dMt + j2*4); 
	SetCol(j2,temp); 
} 
 
inline	void C3DMatrix::MultCol(const int j, const math_real k) 
{ 
	CHECK( 0 <= j && j <= 3); 
 
	register math_real* dCol = m_dMt + (j<<2); 
	dCol[0] *= k;	 
	dCol[1] *= k;	 
	dCol[2] *= k;	 
	dCol[3] *= k;	 
} 
 
inline	void C3DMatrix::MultRow(const int i, const math_real k) 
{ 
	m_dMt[i] *= k; 
	m_dMt[i+4] *= k; 
	m_dMt[i+8] *= k; 
	m_dMt[i+12] *= k; 
} 
 
inline	math_real& C3DMatrix::operator ()(const int i, const int j)  
{ 
	CHECK( 0 <= i && i <= 3); 
	CHECK( 0 <= j && j <= 3); 
//	return m_dMt[(i<<2) + j];//rows linear in memory 
	return m_dMt[(j<<2) + i];//columns linear in memory 
} 
 
 
inline math_real C3DMatrix::operator ()(const int i, const int j) const 
{ 
	CHECK( 0 <= i && i <= 3); 
	CHECK( 0 <= j && j <= 3); 
//	return m_dMt[(i<<2) + j];//rows linear in memory 
	return m_dMt[(j<<2) + i];//columns linear in memory 
} 
 
 
#endif // !defined(AFX_3DMATRIX_H__2BA53B06_5FF2_11D4_9525_FB525FE16108__INCLUDED_)