#include <matrix.h>
Inheritance diagram for Matrix:
Public Member Functions | |
Matrix () | |
Default initialisation - sets up the identity matrix. | |
Matrix (const FIXED16 &, const FIXED16 &) | |
Default initialisation - sets up the scale matrix. | |
Matrix (const ANGLE &theta) | |
Default initialisation - sets up the rotation matrix. | |
Matrix (const Coord &) | |
Default initialisation - Sets up a translate matrix. | |
Matrix (const Coord &, const ANGLE &) | |
Creates a Matrix transform object that will perform a rotation about the given point by the given number of degrees. | |
Matrix (const INT32, const INT32) | |
Default initialisation - Sets up a translate matrix. | |
Matrix (const FIXED16 &, const FIXED16 &, const FIXED16 &, const FIXED16 &, const INT32, const INT32) | |
Initialise a while matrix. | |
Matrix (const DocRect &, const DocRect &) | |
Matrix constructor taking two document rectangles. Creates a matrix which can be used to transform coordinates within the source rectangle into coordinates in the second rectangle. | |
void | transform (Coord *) const |
Transforms a single point. | |
void | transform (Coord[], UINT32 count) const |
Transforms a list of points. | |
void | transform (Coord[], const Coord[], UINT32) const |
Transforms a list of points. | |
void | translate (const INT32 TransX, const INT32 TransY) |
QUICKLY add a translation to a matrix! | |
BOOL | TransformBounds (DocRect *pRect) const |
Given a rect, find its bounds when transformed. | |
BOOL | Decompose (FIXED16 *pScale=NULL, FIXED16 *pAspect=NULL, ANGLE *pRotation=NULL, ANGLE *pShear=NULL, Coord *pTranslate=NULL, FIXED16 *pScaleY=NULL) |
Decompose a matrix into its component transforms. | |
BOOL | Compose (FIXED16 Scale=1.0, FIXED16 Aspect=1.0, ANGLE Rotation=0, ANGLE Shear=0, Coord Translation=Coord(0, 0)) |
Compose a matrix from its components. | |
BOOL | IsRotation (const double epsilon=0.0) const |
Determine whether this matrix is a rotation matrix or not. | |
BOOL | IsReflection (const double epsilon=0.0) const |
Determine whether this matrix is a reflection matrix or not. | |
BOOL | IsTranslation (const double epsilon=0.0) const |
Examine this matrix and determin whether it is a translation matrix or not. This function is needed as within the code there are areas where complex matricees are built which are really translation matricees. The function will return immediately with TRUE if the matrix type is Translation otherwise the function will actually check the matrix values for translation type See also: IsRotation(), IsReflection(). | |
BOOL | IsIdentity () const |
Support function for IsIsometric Determines whether two values are near enough to each other to be considered equal. Notes: This is a templated function with <class t>="">Determines whether or not this matrix is an identity matrix. Used by the MOA interface, XMOAFhMtx::FHIMtxIsUnity. | |
Matrix & | operator= (const Matrix &) |
Matrix assignment. | |
BOOL | operator== (const Matrix &) const |
Test for Matrix equality. | |
Matrix & | operator *= (const Matrix &) |
optimized *= operator for matrices Note: e,f are not optimised as MatrixCalc() has different round from explicit operations however, it does have optimisations for 0 an 1 | |
Matrix | Inverse () const |
Inverts the 'this' matrix and returns the result. 'this' matrix is not effected. | |
void | GetComponents (FIXED16 *, INT32 *) const |
Allows code to get to the elements in the matrix without having to be a friend of the class. Should be used very sparingly indeed. | |
void | GetTranslation (DocCoord &) const |
void | GetTranslation (INT32 &, INT32 &) const |
void | SetTranslation (const DocCoord &) |
void | SetTranslation (const INT32 &, const INT32 &) |
double | Trace () const |
double | Det () const |
void | RatioMatrix (const double ratio) |
Matrix | Interpolate (const Matrix &op, const double ratio) const |
Interpolate between this and another matrix. | |
Matrix | PostRotate (DocCoord dcCentre, const ANGLE &Angle) const |
Allows you to transform an object, then rotate it about some point relative to its original self, which has now been transformed. | |
Static Public Member Functions | |
static Matrix | CreateTransMatrix (const Coord &dcTrans) |
Factory method - maps directly onto the translation Matrix constructor. | |
static Matrix | CreateScaleMatrix (const double &xScale, const double &yScale) |
Factory method - maps directly onto the scaling Matrix constructor. | |
static Matrix | CreateScaleMatrix (const double &ScaleFactor) |
Factory method - maps directly onto the scaling Matrix constructor. | |
static Matrix | CreateShearMatrix (const double &ShearAngle) |
Factory method - maps directly onto the 'complex' Matrix constructor. | |
static Matrix | CreateRotateMatrix (const double &RotateAngle) |
Factory method - maps directly onto the rotation Matrix constructor. | |
Public Attributes | |
TransformType | Type |
ANGLE | Angle |
Private Attributes | |
FIXED16 | a |
FIXED16 | b |
FIXED16 | c |
FIXED16 | d |
INT32 | e |
INT32 | f |
Friends | |
class | OSRenderRegion |
class | XMatrix |
Matrix | operator * (const Matrix &, const Matrix &) |
Matrix multiplication. |
Definition at line 170 of file matrix.h.
|
Default initialisation - sets up the identity matrix.
Definition at line 133 of file matrix.cpp. 00134 { 00135 a = (FIXED16)1; 00136 b = (FIXED16)0; 00137 c = (FIXED16)0; 00138 d = (FIXED16)1; 00139 e = 0; 00140 f = 0; 00141 00142 Type = TRANS_IDENTITY; 00143 Angle = (ANGLE)0; 00144 }
|
|
Default initialisation - sets up the scale matrix.
Definition at line 164 of file matrix.cpp. 00165 { 00166 a = xScale; 00167 b = (FIXED16)0; 00168 c = (FIXED16)0; 00169 d = yScale; 00170 e = 0; 00171 f = 0; 00172 00173 Type = TRANS_SCALE; 00174 Angle = (ANGLE)0; 00175 }
|
|
Default initialisation - sets up the rotation matrix.
Definition at line 195 of file matrix.cpp. 00196 { 00197 #if 0 00198 a = b = c = d = theta; 00199 00200 a.Cos(); 00201 b.Sin(); 00202 c = -(c.Sin()); 00203 d.Cos(); 00204 #else 00205 00206 double thetaradians = TORADIANS(theta.MakeDouble()); 00207 FIXED16 costheta = cos(thetaradians); 00208 FIXED16 sintheta = sin(thetaradians); 00209 00210 a = d = costheta; 00211 b = sintheta; 00212 c = -sintheta; 00213 #endif 00214 00215 e = 0; 00216 f = 0; 00217 00218 Type = TRANS_ROTATION; 00219 Angle = theta; 00220 }
|
|
Default initialisation - Sets up a translate matrix.
Definition at line 240 of file matrix.cpp. 00241 { 00242 a = (FIXED16)1; 00243 b = (FIXED16)0; 00244 c = (FIXED16)0; 00245 d = (FIXED16)1; 00246 e = disp.x; 00247 f = disp.y; 00248 00249 Type = TRANS_TRANSLATION; 00250 Angle = (ANGLE)0; 00251 }
|
|
Creates a Matrix transform object that will perform a rotation about the given point by the given number of degrees.
Definition at line 1031 of file matrix.cpp. 01032 { 01033 // need to translate the centre of rotation to the origin 01034 *this = Matrix(-CentreOfRotation.x, -CentreOfRotation.y); 01035 01036 // rotate about the origin 01037 *this *= Matrix(Rotation); 01038 01039 // translate back to the centre of rotation 01040 this->translate(CentreOfRotation.x, CentreOfRotation.y); 01041 01042 Type = TRANS_COMPLEX; 01043 Angle = (ANGLE)0; 01044 }
|
|
Default initialisation - Sets up a translate matrix.
Definition at line 272 of file matrix.cpp. 00273 { 00274 a = (FIXED16)1; 00275 b = (FIXED16)0; 00276 c = (FIXED16)0; 00277 d = (FIXED16)1; 00278 e = x; 00279 f = y; 00280 00281 Type = TRANS_TRANSLATION; 00282 Angle = (ANGLE)0; 00283 }
|
|
Initialise a while matrix.
Definition at line 305 of file matrix.cpp. 00312 { 00313 a = ca; 00314 b = cb; 00315 c = cc; 00316 d = cd; 00317 e = ce; 00318 f = cf; 00319 00320 Type = TRANS_COMPLEX; 00321 Angle = (ANGLE)0; 00322 }
|
|
Matrix constructor taking two document rectangles. Creates a matrix which can be used to transform coordinates within the source rectangle into coordinates in the second rectangle.
Definition at line 341 of file matrix.cpp. 00342 { 00343 double Sx0 = Source.lo.x; 00344 double Sy0 = Source.lo.y; 00345 double Sx1 = Source.hi.x; 00346 double Sy1 = Source.hi.y; 00347 double Dx0 = Destin.lo.x; 00348 double Dy0 = Destin.lo.y; 00349 double Dx1 = Destin.hi.x; 00350 double Dy1 = Destin.hi.y; 00351 double t0,t1; 00352 00353 (Sx1==Sx0) ? t0=1 : t0=(Dx1-Dx0)/(Sx1-Sx0); 00354 (Sy1==Sy0) ? t1=1 : t1=(Dy1-Dy0)/(Sy1-Sy0); 00355 00356 a = (FIXED16)t0; 00357 b = (FIXED16)0; 00358 c = (FIXED16)0; 00359 d = (FIXED16)t1; 00360 e = (INT32)(Dx0-Sx0*t0); 00361 f = (INT32)(Dy0-Sy0*t1); 00362 00363 Type = TRANS_COMPLEX; 00364 Angle = (ANGLE)0; 00365 }
|
|
Compose a matrix from its components.
Definition at line 970 of file matrix.cpp. 00971 { 00972 // do scale, aspect and shear 00973 FIXED16 AbsScale = (Scale<0) ? -Scale : Scale; 00974 *this=Matrix(AbsScale*Aspect,0,Scale*tan(Shear.MakeDouble()),Scale,0,0); 00975 00976 // do rotate 00977 *this*=Matrix((Rotation*180)/PI); // god damned amatuers using degrees! 00978 00979 // translate 00980 this->translate(Translation.x,Translation.y); 00981 00982 return TRUE; 00983 }
|
|
Factory method - maps directly onto the rotation Matrix constructor.
Definition at line 1381 of file matrix.cpp.
|
|
Factory method - maps directly onto the scaling Matrix constructor.
Definition at line 1337 of file matrix.cpp. 01338 { 01339 return Matrix(FIXED16(ScaleFactor), FIXED16(ScaleFactor)); 01340 }
|
|
Factory method - maps directly onto the scaling Matrix constructor.
Definition at line 1319 of file matrix.cpp.
|
|
Factory method - maps directly onto the 'complex' Matrix constructor.
Definition at line 1355 of file matrix.cpp. 01356 { 01357 FIXED16 one = FIXED16(1); 01358 FIXED16 zero = FIXED16(0); 01359 FIXED16 shear = FIXED16(tan(ShearAngle)); 01360 return Matrix( one, zero, 01361 shear, one, 01362 0, 0 ); 01363 }
|
|
Factory method - maps directly onto the translation Matrix constructor.
Definition at line 1300 of file matrix.cpp. 01301 { 01302 return Matrix(dcTrans); 01303 }
|
|
Decompose a matrix into its component transforms.
Definition at line 897 of file matrix.cpp. 00899 { 00900 // unit square decomposition of matrix ... 00901 // A={a,c}, B={b,d}, Q=angle between vectors (ie PI/2-shear angle)! 00902 // |A|=sqrt(aa+cc) 00903 // |B|=sqrt(bb+dd) 00904 // AxB=|A||B|sinQ=ad-bc=(new area of unit square) 00905 // A.B=|A||B|cosQ=ab+cd 00906 // so ... 00907 // ScaleX = |A| 00908 // ScaleY = |B| 00909 // Scale = ScaleY*cos(PI/2-Q) = ScaleY*sinQ = AxB/|A| 00910 // AbsScale = abs(Scale) // effectively remove any mirror 00911 // Aspect = ScaleX/abs(Scale) 00912 // Shear = PI/2-Q = PI/2-acos((A.B)/(|A||B|)) 00913 // Rotate = RotateX = atan2(c,a) 00914 00915 double a=this->a.MakeDouble(); 00916 double b=this->c.MakeDouble(); // 'cos I think of coords as column vectors not rows! 00917 double c=this->b.MakeDouble(); 00918 double d=this->d.MakeDouble(); 00919 00920 // get cross product (determinant), modulus (length) of A and scale 00921 double AxB = a*d-b*c; 00922 double ModA = sqrt(a*a+c*c); 00923 double ModB = sqrt(b*b+d*d); 00924 double Scale = AxB/ModA; 00925 00926 // set output values where required 00927 if (pTranslate) *pTranslate = Coord(this->e,this->f); 00928 if (pScale) *pScale = Scale; 00929 if (pAspect) 00930 if (Scale==0) 00931 *pAspect = (FIXED16)1; 00932 else 00933 *pAspect = ModA/fabs(Scale); 00934 if (pRotation) *pRotation = (ANGLE)atan2(c,a); 00935 if (pShear) 00936 { 00937 double AdotB = a*b+c*d; 00938 *pShear = (ANGLE)(PI/2-acos(AdotB/(ModB*ModA))); 00939 } 00940 if (pScaleY) *pScaleY = ModB; 00941 00942 // TRACE( _T("\n")); 00943 // TRACE( _T("Scale = %f\n"),Scale); 00944 // TRACE( _T("Aspect = %f\n"),ModA/fabs(Scale)); 00945 // TRACE( _T("Rotate = %f\n"),atan2(c,a)/PI*180); 00946 // double AdotB = a*b+c*d; 00947 // double ModB = sqrt(b*b+d*d); 00948 // TRACE( _T("Shear = %f\n"),(PI/2-acos(AdotB/(ModB*ModA)))/PI*180); 00949 00950 return TRUE; 00951 }
|
|
Definition at line 1418 of file matrix.cpp. 01419 { 01420 return ( (a.MakeDouble() * d.MakeDouble()) - (b.MakeDouble() * c.MakeDouble()) ); 01421 }
|
|
Allows code to get to the elements in the matrix without having to be a friend of the class. Should be used very sparingly indeed.
Definition at line 802 of file matrix.cpp. 00803 { 00804 if (abcd) 00805 { 00806 abcd[0] = a; 00807 abcd[1] = b; 00808 abcd[2] = c; 00809 abcd[3] = d; 00810 } 00811 00812 if (ef) 00813 { 00814 ef[0] = e; 00815 ef[1] = f; 00816 } 00817 }
|
|
Definition at line 854 of file matrix.cpp.
|
|
Definition at line 848 of file matrix.cpp.
|
|
Interpolate between this and another matrix.
Definition at line 1466 of file matrix.cpp. 01467 { 01468 // Essential: 0 <= ratio <= 1. 01469 01470 if (ratio < 0 || ratio > 1 || Type == TRANS_ROTATION || op.Type == TRANS_ROTATION) 01471 { 01472 ERROR3("Interpolate() requires 0 <= ratio <= 1 and no rotation matrices."); 01473 return Matrix(); 01474 } 01475 01476 else if (ratio == 0) 01477 return *this; 01478 01479 else if (ratio == 1) 01480 return op; 01481 01482 else 01483 { 01484 const FIXED16 f16Ratio (ratio); 01485 const FIXED16 f16InvRatio (1 - ratio); 01486 01487 Matrix temp; 01488 01489 temp.a = a * f16InvRatio + op.a * f16Ratio; 01490 temp.b = b * f16InvRatio + op.b * f16Ratio; 01491 temp.c = c * f16InvRatio + op.c * f16Ratio; 01492 temp.d = d * f16InvRatio + op.d * f16Ratio; 01493 01494 temp.e = e * (INT32)((1 - ratio) + op.e * ratio); 01495 temp.f = f * (INT32)((1 - ratio) + op.f * ratio); 01496 01497 temp.Type = TRANS_COMPLEX; 01498 temp.Angle = 0; 01499 01500 return temp; 01501 } 01502 }
|
|
Inverts the 'this' matrix and returns the result. 'this' matrix is not effected.
Definition at line 659 of file matrix.cpp. 00660 { 00661 Matrix Temp; 00662 00663 // Inverting a general matrix is quite an expensive operation, so we will try and 00664 // avoid having to do all the maths (esp as it can fail - some matrices do not have 00665 // an inverse! eg Scale by a factor of zero) 00666 00667 switch ( Type ) 00668 { 00669 case TRANS_IDENTITY: 00670 // Inverse is the same as this 00671 ENSURE(a==FIXED16(1), "Matrix inconsistency!"); 00672 ENSURE(b==FIXED16(0), "Matrix inconsistency!"); 00673 ENSURE(c==FIXED16(0), "Matrix inconsistency!"); 00674 ENSURE(d==FIXED16(1), "Matrix inconsistency!"); 00675 ENSURE(e==0, "Matrix inconsistency!"); 00676 ENSURE(f==0, "Matrix inconsistency!"); 00677 00678 return Temp; 00679 break; 00680 00681 case TRANS_TRANSLATION : 00682 // Translation matrix - The inverse of this requires negating the x and y 00683 // components of the translation 00684 ENSURE(a==FIXED16(1), "Matrix inconsistency!"); 00685 ENSURE(b==FIXED16(0), "Matrix inconsistency!"); 00686 ENSURE(c==FIXED16(0), "Matrix inconsistency!"); 00687 ENSURE(d==FIXED16(1), "Matrix inconsistency!"); 00688 00689 Temp.a = this->a; 00690 Temp.b = this->b; 00691 Temp.c = this->c; 00692 Temp.d = this->d; 00693 Temp.e = -this->e; 00694 Temp.f = -this->f; 00695 Temp.Type = this->Type; 00696 Temp.Angle = this->Angle; 00697 break; 00698 00699 case TRANS_ROTATION: 00700 // The inverse of a rotation matrix is the Transpose of this matrix 00701 // ie components b and c are swapped 00702 ENSURE(e==0, "Matrix inconsistency!"); 00703 ENSURE(f==0, "Matrix inconsistency!"); 00704 00705 Temp.a = this->a; 00706 Temp.b = this->c; 00707 Temp.c = this->b; 00708 Temp.d = this->d; 00709 Temp.e = this->e; 00710 Temp.f = this->f; 00711 Temp.Type = this->Type; 00712 Temp.Angle = -this->Angle; 00713 break; 00714 00715 case TRANS_SCALE: 00716 // This can fail if one of the scale factors is 0. This will cause an ENSURE to fail 00717 // The inverse of a scale involves finding the inverse of the scale factors 00718 // ENSURE( this->a != 0, "Matrix Inversion failed - X scale factor was zero!" ); 00719 // ENSURE( this->d != 0, "Matrix Inversion failed - Y scale factor was zero!" ); 00720 if ((this->a==0) || (this->d==0)) 00721 { 00722 TRACE( _T("Matrix Inversion failed!\n")); 00723 // There is no inversion of this matrix 00724 // return the identity matrix 00725 return Temp; 00726 } 00727 ENSURE(e==0, "Matrix inconsistency!"); 00728 ENSURE(f==0, "Matrix inconsistency!"); 00729 00730 Temp.a = 1/this->a; 00731 Temp.b = this->b; 00732 Temp.c = this->c; 00733 Temp.d = 1/this->d; 00734 Temp.e = this->e; 00735 Temp.f = this->f; 00736 Temp.Type = this->Type; 00737 Temp.Angle = this->Angle; 00738 break; 00739 00740 case TRANS_SHEAR: 00741 case TRANS_COMPLEX: 00742 default: 00743 // This is the general case. It may be possible for this to fail. 00744 // I got the general idea for this from Graphics Gems page 766. 00745 // It did take 4 pages of c code in there, but it was a slightly 00746 // more complex solution. 00747 00748 // Find the determinent of the Adjoint matrix - Luckily we can calculate 00749 // this before we calculate the Adjoint matrix as we know that the 00750 // right hand edge of the matrix is 0 0 1 00751 double Det = a.MakeDouble()*d.MakeDouble() - b.MakeDouble()*c.MakeDouble(); 00752 00753 if (Det==0.0) 00754 { 00755 // There is no inversion of this matrix 00756 // return the identity matrix 00757 // ENSURE( FALSE, "Matrix Inversion Failed - Tried to Invert a non-invertable matrix" ); 00758 TRACE( _T("Matrix Inversion failed!\n")); 00759 return Temp; 00760 } 00761 00762 // this section calculates the inverse of the matrix. As it takes into 00763 // account that our 3x3 matrix always has 0,0,1 down its right hand side 00764 // it has been greatly simplified. The operations combine the calculation 00765 // of the adjoint matrix and scaling it by the Determinent with a matrix 00766 // transpose (the inverse is the transpose of the adjoint scaled by the 00767 // determinent) 00768 Temp.a = (FIXED16)(d.MakeDouble() / Det); 00769 Temp.b = (FIXED16)(-b.MakeDouble() / Det); 00770 Temp.c = (FIXED16)(-c.MakeDouble() / Det); 00771 Temp.d = (FIXED16)(a.MakeDouble() / Det); 00772 Temp.e = (INT32)( ((c.MakeDouble()*f)-(e*d.MakeDouble()))/Det ); 00773 Temp.f = (INT32)( -(((a.MakeDouble()*f) - (e*b.MakeDouble()))/Det)); 00774 Temp.Type = TRANS_COMPLEX; 00775 Temp.Angle = 0; 00776 00777 break; 00778 } 00779 00780 // return the inverted matrix back 00781 return Temp; 00782 }
|
|
Support function for IsIsometric Determines whether two values are near enough to each other to be considered equal. Notes: This is a templated function with <class t>="">Determines whether or not this matrix is an identity matrix. Used by the MOA interface, XMOAFhMtx::FHIMtxIsUnity.
Definition at line 1253 of file matrix.cpp. 01254 { 01255 BOOL bIsIdentity = FALSE; 01256 01257 if (Type == TRANS_IDENTITY) 01258 { 01259 bIsIdentity = TRUE; 01260 } 01261 01262 if (Type != TRANS_IDENTITY) // && epsilon == 0.0) 01263 { 01264 const FIXED16 c0 = FIXED16(0); 01265 const FIXED16 c1 = FIXED16(1); 01266 01267 bIsIdentity = ( (a == c1) && (b == c0) && (c == c0) && (d == c1) && 01268 (e == 0) && (f == 0)); 01269 } 01270 /* 01271 if (Type != TRANS_IDENTITY && epsilon != 0.0) 01272 { 01273 const double ca = a.MakeDouble(); 01274 const double cb = b.MakeDouble(); 01275 const double cc = c.MakeDouble(); 01276 const double cd = d.MakeDouble(); 01277 const double ce = e.MakeDouble(); 01278 const double cf = f.MakeDouble(); 01279 01280 bIsIdentity = ( IsNear(ca, 1.0, epsilon) && IsNear(cb, 1.0, epsilon) && 01281 IsNear(cc, 1.0, epsilon) && IsNear(cd, 1.0, epsilon) && 01282 IsNear(ce, 1.0, epsilon) && IsNear(cf, 1.0, epsilon)) 01283 }*/ 01284 return bIsIdentity; 01285 }
|
|
Determine whether this matrix is a reflection matrix or not.
Feel free to modify this method to test for all reflections, but first make sure you won't break any code which uses it (at time of writing, you're ok). See also: IsTranslation(), IsRotation(). Definition at line 1179 of file matrix.cpp. 01180 { 01181 // A Camelot matrix of the form: (a c) , is an x- or y- reflection if: 01182 // (b d) 01183 // 1. b = c = 0. 01184 // 2. a = -d. 01185 // 3. |a| = 1. 01186 01187 if (epsilon == 0.0) 01188 { 01189 if (b == c && c == FIXED16(0) && 01190 a == -d && 01191 (a == FIXED16(1) || a == FIXED16(-1)) ) 01192 return TRUE; 01193 } 01194 01195 else 01196 { 01197 double c0,c1,c2,c3; 01198 01199 c0 = a.MakeDouble(); 01200 c1 = b.MakeDouble(); 01201 c2 = c.MakeDouble(); 01202 c3 = d.MakeDouble(); 01203 01204 if (fabs(c1) < epsilon && fabs(c2) < epsilon && 01205 fabs(c0 + c3) < epsilon && 01206 (fabs(c0 - 1.0) < epsilon || fabs(c0 + 1.0) < epsilon) ) 01207 return TRUE; 01208 } 01209 01210 return FALSE; 01211 }
|
|
Determine whether this matrix is a rotation matrix or not.
Definition at line 1108 of file matrix.cpp. 01109 { 01110 if (Type == TRANS_ROTATION) 01111 return TRUE; 01112 01113 // Note: Camelot matrices swap the b & c components, so the form is: 01114 // 01115 // (a c) , instead of the more familiar (a b) . 01116 // (b d) (c d) 01117 // 01118 // So tests for rotation are: 01119 // 1. a = d 01120 // 2. b = -c 01121 // 3. |(a b)| = |(c d)| = 1. 01122 01123 if (epsilon == 0.0) 01124 { 01125 if (a == d && b == -c) 01126 { 01127 FIXED16 aa = (a * a); 01128 FIXED16 bb = (b * b); 01129 FIXED16 ab = aa + bb; 01130 if (ab == FIXED16(1)) 01131 return TRUE; 01132 } 01133 } 01134 01135 else 01136 { 01137 double c0,c1,c2,c3; 01138 01139 c0 = a.MakeDouble(); 01140 c1 = b.MakeDouble(); 01141 c2 = c.MakeDouble(); 01142 c3 = d.MakeDouble(); 01143 01144 if (fabs(c0 - c3) < epsilon && fabs(c1 + c2) < epsilon) 01145 { 01146 double ab = (c0 * c0) + (c1 * c1); 01147 if (fabs(ab - 1.0) < epsilon) 01148 return TRUE; 01149 } 01150 } 01151 01152 return FALSE; 01153 }
|
|
Examine this matrix and determin whether it is a translation matrix or not. This function is needed as within the code there are areas where complex matricees are built which are really translation matricees. The function will return immediately with TRUE if the matrix type is Translation otherwise the function will actually check the matrix values for translation type See also: IsRotation(), IsReflection().
Definition at line 1065 of file matrix.cpp. 01066 { 01067 if (Type==TRANS_TRANSLATION) 01068 return TRUE; 01069 01070 if (epsilon==0.0) 01071 { 01072 FIXED16 c0,c1,c2,c3; 01073 c0 = (FIXED16)1; 01074 c1 = (FIXED16)0; 01075 c2 = (FIXED16)0; 01076 c3 = (FIXED16)1; 01077 return ((a==c0) && (b==c1) && (c==c2) && (d==c3)); 01078 } 01079 01080 double c0,c1,c2,c3; 01081 01082 c0=a.MakeDouble(); 01083 c1=b.MakeDouble(); 01084 c2=c.MakeDouble(); 01085 c3=d.MakeDouble(); 01086 01087 return ( (fabs(c0-1.0)<epsilon) && (fabs(c1-0.0)<epsilon) && (fabs(c2-0.0)<epsilon) && (fabs(c3-1.0)<epsilon) ); 01088 }
|
|
optimized *= operator for matrices Note: e,f are not optimised as MatrixCalc() has different round from explicit operations however, it does have optimisations for 0 an 1
Definition at line 604 of file matrix.cpp. 00605 { 00606 if (op.b==0 && op.c==0) 00607 { 00608 // it's just an x or y scaling ... 00609 if (op.a!=1) 00610 { 00611 a *= op.a; 00612 c *= op.a; 00613 } 00614 if (op.d!=1) 00615 { 00616 b *= op.d; 00617 d *= op.d; 00618 } 00619 } 00620 else 00621 { 00622 // it's the complex case ... 00623 FIXED16 t; 00624 t = a*op.a + b*op.c; 00625 b = a*op.b + b*op.d; 00626 a = t; 00627 t = c*op.a + d*op.c; 00628 d = c*op.b + d*op.d; 00629 c = t; 00630 } 00631 00632 // either case requires these bits 00633 INT32 u; 00634 u = MatrixCalc(op.a, e, op.c, f) + op.e; 00635 f = MatrixCalc(op.b, e, op.d, f) + op.f; 00636 e = u; 00637 00638 Type = TRANS_COMPLEX; 00639 Angle = (ANGLE)0; 00640 00641 return *this; 00642 }
|
|
Matrix assignment.
Definition at line 537 of file matrix.cpp. 00538 { 00539 this->a = rhs.a; 00540 this->b = rhs.b; 00541 this->c = rhs.c; 00542 this->d = rhs.d; 00543 this->e = rhs.e; 00544 this->f = rhs.f; 00545 00546 this->Type = rhs.Type; 00547 this->Angle = rhs.Angle; 00548 00549 return *this; 00550 }
|
|
Test for Matrix equality.
Definition at line 564 of file matrix.cpp. 00565 { 00566 return (a == rhs.a && b == rhs.b && c == rhs.c && d == rhs.d && 00567 e == rhs.e && f == rhs.f); 00568 }
|
|
Allows you to transform an object, then rotate it about some point relative to its original self, which has now been transformed.
Definition at line 1528 of file matrix.cpp.
|
|
You should get CGS to change this routine if needs be .... This routine cannot be used to ratio a rotation matrix. This is because the elements in a rotation matrix are cos & sin of the quantity which must be interpolated (the angle), and these are non-linear functions. Definition at line 1443 of file matrix.cpp. 01444 { 01445 static Matrix Identity; 01446 *this = Identity.Interpolate(*this, ratio); 01447 }
|
|
Definition at line 869 of file matrix.cpp. 00870 { 00871 e = xlate; 00872 f = ylate; 00873 00874 if (Type!=TRANS_TRANSLATION) 00875 Type = TRANS_COMPLEX; 00876 }
|
|
Definition at line 860 of file matrix.cpp. 00861 { 00862 e = coord.x; 00863 f = coord.y; 00864 00865 if (Type!=TRANS_TRANSLATION) 00866 Type = TRANS_COMPLEX; 00867 }
|
|
Definition at line 1400 of file matrix.cpp. 01401 { 01402 return (a.MakeDouble() + d.MakeDouble()); 01403 }
|
|
Transforms a list of points.
Definition at line 450 of file matrix.cpp. 00451 { 00452 if ( Type == TRANS_TRANSLATION ) 00453 { 00454 for (UINT32 i = 0; i < count; i++) 00455 { 00456 pts[i].x = input[i].x + e; 00457 pts[i].y = input[i].y + f; 00458 } 00459 } 00460 else 00461 { 00462 #ifdef OLD_MATRIX_TRANSFORMATIONS 00463 for (UINT32 i = 0; i < count; i++) 00464 { 00465 pts[i].x = MatrixCalc(a, input[i].x, c, input[i].y); 00466 pts[i].x += e; 00467 pts[i].y = MatrixCalc(b, input[i].x, d, input[i].y); 00468 pts[i].y += f; 00469 } 00470 #else 00471 // We use GDraw to transform the path 00472 // Alex asserts it is unimportant to switch contexts here as path transformations are not context 00473 // dependent; thus we call GDraw directly 00474 00475 GMATRIX gmat; 00476 gmat.AX = a.GetShifted16(); 00477 gmat.AY = b.GetShifted16(); 00478 gmat.BX = c.GetShifted16(); 00479 gmat.BY = d.GetShifted16(); 00480 gmat.CX.SetHighLow(e>>16, e<<16); 00481 gmat.CY.SetHighLow(f>>16, f<<16); 00482 // Alex promises we don't need a context to do this op 00483 // XaDrawOld_TransformPath( (LPPOINT)input, (LPPOINT)pts, count, &gmat ); 00484 GRenderRegion::GetStaticDrawContext()->TransformPath( (LPPOINT)input, (LPPOINT)pts, count, &gmat ); 00485 #endif 00486 } 00487 }
|
|
Transforms a list of points.
Definition at line 390 of file matrix.cpp. 00391 { 00392 if ( Type == TRANS_TRANSLATION ) 00393 { 00394 for (UINT32 i = 0; i < count; i++) 00395 { 00396 pts[i].x += e; 00397 pts[i].y += f; 00398 } 00399 } 00400 else 00401 { 00402 #ifdef OLD_MATRIX_TRANSFORMATIONS 00403 INT32 tx; // Holds INPUT value of pts[i].x for use in second MatrixCalc 00404 00405 for (UINT32 i = 0; i < count; i++) 00406 { 00407 tx = pts[i].x; 00408 pts[i].x = MatrixCalc(a, tx, c, pts[i].y) + e; 00409 pts[i].y = MatrixCalc(b, tx, d, pts[i].y) + f; 00410 } 00411 #else 00412 // We use GDraw to transform the path 00413 // Alex asserts it is unimportant to switch contexts here as path transformations are not context 00414 // dependent; thus we call GDraw directly 00415 00416 GMATRIX gmat; 00417 gmat.AX = a.GetShifted16(); 00418 gmat.AY = b.GetShifted16(); 00419 gmat.BX = c.GetShifted16(); 00420 gmat.BY = d.GetShifted16(); 00421 gmat.CX.SetHighLow(e>>16, e<<16); 00422 gmat.CY.SetHighLow(f>>16, f<<16); 00423 // Alex promises we don't need a context to do this op 00424 // XaDrawOld_TransformPath( (LPPOINT)pts, (LPPOINT)pts, count, &gmat ); 00425 GRenderRegion::GetStaticDrawContext()->TransformPath( (LPPOINT)pts, (LPPOINT)pts, count, &gmat ); 00426 #endif 00427 } 00428 00429 }
|
|
Transforms a single point.
Definition at line 507 of file matrix.cpp. 00508 { 00509 INT32 tx; // Holds INPUT value of pt.x for use in second MatrixCalc! 00510 00511 if ( Type == TRANS_TRANSLATION ) 00512 { 00513 pt->x += e; 00514 pt->y += f; 00515 } 00516 else 00517 { 00518 tx = pt->x; 00519 pt->x = MatrixCalc(a, tx, c, pt->y) + e; 00520 pt->y = MatrixCalc(b, tx, d, pt->y) + f; 00521 } 00522 }
|
|
Given a rect, find its bounds when transformed.
Definition at line 997 of file matrix.cpp. 00998 { 00999 ERROR2IF(pRect==NULL,FALSE,"Matrix::Transform() - pRect==NULL"); 01000 01001 static DocCoord coords[4]; 01002 coords[0] = pRect->lo; 01003 coords[1] = DocCoord(pRect->hi.x,pRect->lo.y); 01004 coords[2] = pRect->hi; 01005 coords[3] = DocCoord(pRect->lo.x,pRect->hi.y); 01006 01007 this->transform((Coord*)&coords,4); 01008 01009 *pRect = DocRect(coords[0],coords[0]); 01010 pRect->IncludePoint(coords[1]); 01011 pRect->IncludePoint(coords[2]); 01012 pRect->IncludePoint(coords[3]); 01013 01014 return TRUE; 01015 }
|
|
QUICKLY add a translation to a matrix!
Definition at line 841 of file matrix.cpp.
|
|
Matrix multiplication.
Definition at line 581 of file matrix.cpp. 00582 { 00583 static Matrix t; 00584 00585 t = op1; 00586 t *= op2; // no point in duplicating code, just call *= operator 00587 00588 return t; 00589 }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|