#ifndef _mat2_h #define _mat2_h // #include #ifndef _real_h # include "real.h" #endif #ifndef _vec2_h # include "vec2.h" #endif // // Member: r11 r12 tx // r21 r22 ty // 0 0 1 // // Move: 1 0 tx Scale: sx 0 0 Rotate: cosa -sina 0 // 0 1 ty 0 sy 0 sina cosa 0 // 0 0 1 0 0 1 0 0 1 // // ShearX: 1 a 0 ShearY: 1 0 0 // 0 1 0 b 1 0 // 0 0 1 0 0 1 // // Multiplikation: C = A * B // cr11 = ar11*br11 + ar12*br21; // cr21 = ar21*br11 + ar22*br21; // cr12 = ar11*br12 + ar12*br22; // cr22 = ar21*br12 + ar22*br22; // ctx = ar11*btx + ar12*bty + atx; // cty = ar21*btx + ar22*bty + aty; // // inverse Matrix: // detA = r11*r22 - r12*r21 // // -1 r22/detA -r12/detA // A = -r21/detA r11/detA // tx = (r12*ty-r22*tx)/detA // ty = (r21*tx-r11*ty)/detA // // Punktumrechnung: // p2 = A * p1 // x2 = x1*r11 + y1*r12 + tx; // y2 = x1*r21 + y1*r22 + ty; // // -1 // p1 = A * p2; // x1 = ( x2*r22 - y2*r21)/detA - tx; // y1 = (-x2*r12 + y2*r11)/detA - ty; // // ------------------------------------------------------------------------- class Mat2 { public: // // Konstruktoren // Mat2() { r11=r22=1.0; r12=r21= tx=ty= 0.0; } Mat2( const Mat2 &m ) { r11=m.r11; r12=m.r12; r21=m.r21; r22=m.r22; tx=m.tx; ty=m.ty; } Mat2(const Real &ir11, const Real &ir12, const Real &itx, const Real &ir21, const Real &ir22, const Real &ity ) { r11=ir11; r12=ir12; r21=ir21; r22=ir22; tx=itx; ty=ity; } // // Methoden zum Anwenden einer Transformation. // Die der Transformation entsprechende Matrix wird von links!! // in die aktuelle Matrix hineinmultipliziert. // Mat2 &Reset(); Mat2 &Move(const Real &dx, const Real &dy); Mat2 &Move(const Vec2 &p); Mat2 &MoveX(const Real &dx); Mat2 &MoveY(const Real &dy); Mat2 &Scale(const Real &sx, const Real &sy); Mat2 &Scale(const Real &s); Mat2 &ScaleX(const Real &sx); Mat2 &ScaleY(const Real &sy); Mat2 &ScaleAt(const Real &px, const Real &py,const Real &sx, const Real &sy); Mat2 &ScaleAt(const Vec2 &p,const Real &sx, const Real &sy); Mat2 &ScaleAt(const Real &px, const Real &py,const Real &s); Mat2 &ScaleAt(const Vec2 &p,const Real &s); Mat2 &Rotate(const Real &a); Mat2 &RotateAt(const Real &px, const Real &py,const Real &a); Mat2 &RotateAt(const Vec2 &p,const Real &a); Mat2 &RotateDeg(const Real &a); Mat2 &RotateDegAt(const Real &px, const Real &py,const Real &a); Mat2 &RotateDegAt(const Vec2 &p,const Real &a); Mat2 &ShearX(const Real& a); Mat2 &ShearY(const Real& b); Mat2 &Shear(const Real& a, const Real& b); int IsRotated() const { return r12 || r21; } // // Zuweisungsoperator // const Mat2& operator=(const Mat2 &m) { r11=m.r11; r12=m.r12; r21=m.r21; r22=m.r22; tx=m.tx; ty=m.ty; return *this; } // // Operatoren // const Mat2 &operator*=(const Mat2 &m); Mat2 operator*(const Mat2 &m) const { Mat2 help(*this); return help*=m; } void Invert(Mat2 *m) const; Mat2 operator!() const { Mat2 m; Invert( &m ); return m; } Vec2 operator*(const Vec2 &p) const { return Vec2( r11*p.X() + r12*p.Y() + tx, r21*p.X() + r22*p.Y() + ty ); } // // Zugriff auf Koeffizienten // void Split( Real *sh, Real *sx, Real *sy, Real *angle, Real *mx, Real *my ) const; protected: Real r11, r12, tx; Real r21, r22, ty; }; inline Mat2 &Mat2::Reset() { r11=r22=1.0; r12=r21= tx=ty= 0.0; return *this; } inline Mat2 &Mat2::Move(const Real &dx, const Real &dy) { tx+=dx; ty+=dy; return *this; } inline Mat2 &Mat2::Move(const Vec2 &p) { tx+=p.X(); ty+=p.Y(); return *this; } inline Mat2 &Mat2::MoveX(const Real &dx) { tx+=dx; return *this; } inline Mat2 &Mat2::MoveY(const Real &dy) { ty+=dy; return *this; } inline Mat2 &Mat2::Scale(const Real &sx, const Real &sy) { r11*=sx; r21*=sy; r12*=sx; r22*=sy; tx*=sx; ty*=sy; return *this; } inline Mat2 &Mat2::Scale(const Real &s) { return Scale(s,s); } inline Mat2 &Mat2::ScaleX(const Real &sx) { r11*=sx; r12*=sx; tx*=sx; return *this; } inline Mat2 &Mat2::ScaleY(const Real &sy) { r21*=sy; r22*=sy; ty*=sy; return *this; } inline Mat2 &Mat2::ScaleAt(const Real &px, const Real &py,const Real &sx, const Real &sy) { return Move(-px,-py).Scale(sx,sy).Move(px,py); } inline Mat2 &Mat2::ScaleAt(const Vec2 &p,const Real &sx, const Real &sy) { return Move(-p).Scale(sx,sy).Move(p); } inline Mat2 &Mat2::ScaleAt(const Real &px, const Real &py,const Real &s) { return Move(-px,-py).Scale(s).Move(px,py); } inline Mat2 &Mat2::ScaleAt(const Vec2 &p,const Real &s) { return Move(-p).Scale(s).Move(p); } inline Mat2 &Mat2::Rotate(const Real &a) { Mat2 help(*this); r11 = r22 = cos(a); r12 = -( r21 = sin(a) ); tx = ty = 0.0; operator*=(help); return *this; } inline Mat2 &Mat2::RotateDeg(const Real &a) { return Rotate(a/Real(180/M_PI)); } inline Mat2 &Mat2::RotateAt(const Real &px, const Real &py,const Real &a) { return Move(-px,-py).Rotate(a).Move(px,py); } inline Mat2 &Mat2::RotateDegAt(const Real &px, const Real &py,const Real &a) { return Move(-px,-py).Rotate(a/Real(180/M_PI)).Move(px,py); } inline Mat2 &Mat2::RotateAt(const Vec2 &p,const Real &a) { return Move(-p).Rotate(a).Move(p); } inline Mat2 &Mat2::RotateDegAt(const Vec2 &p,const Real &a) { return Move(-p).Rotate(a/Real(180/M_PI)).Move(p); } inline Mat2 &Mat2::ShearX(const Real& a) { r11+=a*r21; r12+=a*r22; tx+=a*ty; return *this; } inline Mat2 &Mat2::ShearY(const Real& b) { r21+=b*r11; r22+=b*r12; ty+=b*tx; return *this; } inline Mat2 &Mat2::Shear(const Real& a, const Real& b) { return ShearX(a).ShearY(b); } #endif /* __Mat2_H */