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; }