www.pudn.com > CoordWarp_Source.zip > imcMatrix.cpp


// imcModel.cpp: implementation of the imcModel class. 
// 
////////////////////////////////////////////////////////////////////// 
 
#include "stdafx.h" 
 
#include  
 
#include "imcMatrix.h" 
 
 
#ifdef _DEBUG 
#undef THIS_FILE 
static char THIS_FILE[]=__FILE__; 
#define new DEBUG_NEW 
#endif 
 
 
 
imcVector imcVector::Min (imcVector v1, imcVector v2) 
{ 
	v1.x = min (v1.x, v2.x); 
	v1.y = min (v1.y, v2.y); 
//	v1.z = min (v1.z, v2.z); 
	return v1; 
} 
imcVector imcVector::Max (imcVector v1, imcVector v2) 
{ 
	v1.x = max (v1.x, v2.x); 
	v1.y = max (v1.y, v2.y); 
//	v1.z = max (v1.z, v2.z); 
	return v1; 
} 
 
void imcVector::operator+= (const imcVector &v) 
{ 
	x += v.x; 
	y += v.y; 
//	z += v.z; 
} 
void imcVector::operator-= (const imcVector &v) 
{ 
	x -= v.x; 
	y -= v.y; 
//	z -= v.z; 
} 
void imcVector::operator*= (const double &d) 
{ 
	x *= d; 
	y *= d; 
} 
void imcVector::operator/= (const double &d) 
{ 
	x /= d; 
	y /= d; 
} 
 
imcVector imcVector::operator-() const 
{ 
	return imcVector (-x, -y); //, -z); 
} 
 
imcVector imcVector::operator+(const imcVector &v) const 
{ 
	return imcVector (x + v.x, y + v.y); 
} 
imcVector imcVector::operator-(const imcVector &v) const 
{ 
	return imcVector (x - v.x, y - v.y); 
} 
imcVector imcVector::operator*(const double &d) const 
{ 
	return imcVector (x * d, y * d); 
} 
imcVector imcVector::operator/(const double &d) const 
{ 
	return imcVector (x / d, y / d); 
} 
 
bool imcVector::operator==( const imcVector& v ) const 
{ 
	return x == v.x && y == v.y; 
} 
bool imcVector::operator!=( const imcVector& v ) const 
{ 
	return x != v.x || y != v.y; 
} 
 
double imcVector::Magnitude () const 
{ 
	return sqrt (x*x + y*y); 
} 
 
bool imcVector::Normalise () 
{ 
	double m = Magnitude (); 
	if (m == 0.0) 
		return false; 
 
	x /= m; 
	y /= m; 
 
	return true; 
} 
imcVector imcVector::Transpose () const 
{ 
	imcVector v (y, x); 
	return v; 
} 
 
/////////////////////////////////////////////////////////////////////////////// 
 
void imcVectorTriple::operator+= (const imcVector &o) 
{ 
	v [0] += o; 
	v [1] += o; 
	v [2] += o; 
} 
void imcVectorTriple::operator-= (const imcVector &o) 
{ 
	v [0] -= o; 
	v [1] -= o; 
	v [2] -= o; 
} 
 
/////////////////////////////////////////////////////////////////////////////// 
 
imcMatrix::imcMatrix () 
{ 
	Identity (); 
} 
 
imcMatrix & imcMatrix::Identity () 
{ 
	for (int i = 0; i < 3; i++) 
	{ 
		for (int j = 0; j < 3; j++) 
		{ 
			m [i][j] = 0.0; 
		} 
	} 
	for (i = 0; i < 3; i++) 
		m [i][i] = 1.0; 
 
	return *this; 
} 
 
imcMatrix & imcMatrix::Translation (const imcVector &vIn) 
{ 
	return Translation (vIn.x, vIn.y); 
} 
 
imcMatrix & imcMatrix::Scaling (const imcVector &vIn) 
{ 
	return Scaling (vIn.x, vIn.y); 
} 
 
imcMatrix & imcMatrix::Translation (double x, double y) 
{ 
	Identity (); 
	m [2][0] = x; 
	m [2][1] = y; 
 
	return *this; 
} 
 
imcMatrix & imcMatrix::Scaling (double x, double y) 
{ 
	Identity (); 
	m [0][0] = x; 
	m [1][1] = y; 
 
	return *this; 
} 
 
imcMatrix & imcMatrix::Rotating (double dAngle) 
{ 
	Identity (); 
 
	m [0][0] =  cos (dAngle); 
	m [0][1] = -sin (dAngle); 
	m [1][0] =  sin (dAngle); 
	m [1][1] =  cos (dAngle); 
 
	return *this; 
} 
 
double	imcMatrix::Determinant () const 
{ 
	// If we have a translation element, our Determinant will be non valid. 
	if (m [2][0] != 0.0 || m [2][1] != 0.0 || m [2][2] != 1.0 || m [0][2] != 0.0 || m [1][2] != 0.0) 
		return 0.0; 
 
	return (m [0][0] * m [1][1]) - (m [1][0] * m [0][1]); 
 
/*	double D = 0.0; 
 
	D += m[0][0] * m[1][1] * m[2][2]; 
	D -= m[0][0] * m[2][1] * m[1][2]; 
	D += m[1][0] * m[2][1] * m[0][2]; 
	D -= m[1][0] * m[0][1] * m[2][2]; 
	D += m[2][0] * m[0][1] * m[1][2]; 
	D -= m[2][0] * m[1][1] * m[0][2]; 
 
	return D; 
*/ 
} 
 
imcMatrix imcMatrix::Inverse (double *Det) const 
{ 
	double D = Determinant (); 
	imcMatrix M; 
	if (Det) *Det = D; 
 
	if (D == 0.0) 
		return M; 
 
	// To be invertable, we can't have a translation element. Therefore, we must be a 2x2 at heart... 
	M.m [0][0] = m [1][1];	M.m [1][0] =-m [1][0]; 
	M.m [0][1] =-m [0][1];	M.m [1][1] = m [0][0]; 
 
	M.m [0][0] /= D;		M.m [1][0] /= D; 
	M.m [0][1] /= D;		M.m [1][1] /= D; 
 
	return M; 
 
/*	double D = Determinant (); 
	if (Det) *Det = D; 
 
	imcMatrix M; 
	if (D < 0.001 && D > -0.001) 
		return M; 
 
	int i,j; 
	for (i = 0; i < 3; i++) 
	{ 
		for (j = 0; j < 3; j++) 
		{ 
			M.m[i][j] = m[(i+1)%3][(j+1)%3] * m[(i+2)%3][(j+2)%3]; 
			M.m[i][j]-= m[(i+1)%3][(j+2)%3] * m[(i+2)%3][(j+1)%3]; 
			M.m[i][j]/= D; 
		} 
	} 
 
	return M; 
*/ 
} 
 
BOOL imcMatrix::WarpVectors (imcVectorTriple csFrom, imcVectorTriple csTo) 
{ 
	imcMatrix mFrom,mTo, mTransform; 
	imcVector v; 
	double Det; 
 
	// Do the unit vector to From coords matrix 
	v = csFrom.v [1] - csFrom.v [0]; 
	mFrom.m[0][0] = v.x; 
	mFrom.m[0][1] = v.y; 
	v = csFrom.v [2] - csFrom.v [0]; 
	mFrom.m[1][0] = v.x; 
	mFrom.m[1][1] = v.y; 
 
	// Do the unit vector to To coords matrix 
	v = csTo.v [1] - csTo.v [0]; 
	mTo.m[0][0] = v.x; 
	mTo.m[0][1] = v.y; 
	v = csTo.v [2] - csTo.v [0]; 
	mTo.m[1][0] = v.x; 
	mTo.m[1][1] = v.y; 
 
	// Invert the From matrix 
	mFrom = mFrom.Inverse (&Det); 
	if (Det == 0.0) // Fail to invert. 
		return FALSE; 
 
	v = mFrom * (csFrom.v [0] - csFrom.v [0]); 
	v = mTransform * v; 
	v = mTo * v; 
	v = mFrom * (csFrom.v [1] - csFrom.v [0]); 
	v = mTransform * v; 
	v = mTo * v; 
	v = mFrom * (csFrom.v [2] - csFrom.v [0]); 
	v = mTransform * v; 
	v = mTo * v; 
 
	// Merge the two into a tranform 
	mTransform = mTo * mFrom; 
 
	// Now do the translations 
	mFrom.Translation (-csFrom.v[0].x, -csFrom.v[0].y); 
	mTo.Translation (csTo.v[0].x, csTo.v[0].y); 
 
	// Combine it all 
	mTransform = mTransform * mFrom; 
	mTransform = mTo * mTransform; 
 
	*this = mTransform; 
	return TRUE; 
} 
 
/////////////////////////////////////////////////////////////////////////////// 
 
BOOL	imcMatrix::Transform (imcVector const *vFrom, imcVector *vTo, int n) const 
{ 
	for (int m = 0; m < n; m++) 
		vTo [m] = *this * vFrom [m]; 
	return TRUE; 
} 
 
BOOL	imcMatrix::Transform (CPoint *vFrom, CPoint *vTo, int n) const 
{ 
	for (int m = 0; m < n; m++) 
		vTo [m] = *this * (imcVector)vFrom [m]; 
	return TRUE; 
} 
BOOL	imcMatrix::Transform (CPoint *pt, int n) const 
{ 
	return Transform (pt, pt, n); 
} 
 
double		operator*(const imcVector &v1, const imcVector &v2) 
{ 
	return v1.x * v2.x + v1.y * v2.y; 
} 
 
imcMatrix	operator*(imcMatrix const &m1, imcMatrix const &m2) 
{ 
	imcMatrix m; 
 
	int i, j, k; 
 
	for (i = 0; i < 3; i++) 
	{ 
		for (j = 0; j < 3; j++) 
		{ 
			m.m [i][j] = 0.0; 
			for (k = 0; k < 3; k++) 
			{ 
				m.m [i][j] += m1.m [k][j] * m2.m [i][k]; 
			} 
		} 
	} 
 
	return m; 
} 
 
imcVector	operator*(const imcMatrix &m1, const imcVector &v2) 
{ 
	imcVector v; 
 
	v.x = m1.m[0][0]*v2.x + m1.m[1][0]*v2.y + m1.m[2][0]; 
	v.y = m1.m[0][1]*v2.x + m1.m[1][1]*v2.y + m1.m[2][1]; 
 
	return v; 
} 
 
CPoint		operator*(const imcMatrix &m1, CPoint p2) 
{ 
	m1.Transform (&p2, &p2, 1); 
	return p2; 
} 
 
CRect	operator*(const imcMatrix &m1, CRect r2) 
{ 
	m1.Transform ((CPoint *) &r2, (CPoint *) &r2, 2); 
	return r2; 
} 
 
bool imcMatrix::operator==( const imcMatrix& o ) const 
{ 
	int i, j; 
	for (i = 0; i < 3; i++) 
	{ 
		for (j = 0; j < 3; j++) 
			if (m [i][j] != o.m [i][j]) 
				return false; 
	} 
	return true; 
} 
bool imcMatrix::operator!=( const imcMatrix &o ) const 
{ 
	int i, j; 
	bool b = false; 
	for (i = 0; i < 3; i++) 
	{ 
		for (j = 0; j < 3; j++) 
			if (m [i][j] != o.m [i][j]) 
				b = true; 
	} 
	return b; 
} 
 
imcVector	operator*(const imcVector &v, double d) 
{ 
	imcVector o (v); 
	o.x *= d; 
	o.y *= d; 
	return o; 
} 
imcVector	operator*(double d, const imcVector &v) 
{ 
	imcVector o (v); 
	o.x *= d; 
	o.y *= d; 
	return o; 
} 
imcVector	operator/(const imcVector &v, double d) 
{ 
	imcVector o (v); 
	o.x /= d; 
	o.y /= d; 
	return o; 
}