1 
2 #ifndef _mat2_h
3 #define _mat2_h
4 
5 // #include <math.h>
6 #ifndef _real_h
7 #	include "real.h"
8 #endif
9 #ifndef _vec2_h
10 #	include "vec2.h"
11 #endif
12 
13 //
14 // Member:  r11 r12 tx
15 //          r21 r22 ty
16 //           0   0   1
17 //
18 // Move:    1  0 tx   Scale:  sx  0  0   Rotate:  cosa -sina  0
19 //          0  1 ty            0 sy  0            sina  cosa  0
20 //          0  0  1            0  0  1             0     0    1
21 //
22 // ShearX:  1  a  0   ShearY:  1  0  0
23 //          0  1  0            b  1  0
24 //          0  0  1            0  0  1
25 //
26 // Multiplikation:   C = A * B
27 //          cr11 = ar11*br11 + ar12*br21;
28 //          cr21 = ar21*br11 + ar22*br21;
29 //          cr12 = ar11*br12 + ar12*br22;
30 //          cr22 = ar21*br12 + ar22*br22;
31 //          ctx  = ar11*btx  + ar12*bty  + atx;
32 //          cty  = ar21*btx  + ar22*bty  + aty;
33 //
34 // inverse Matrix:
35 //          detA = r11*r22 - r12*r21
36 //
37 //           -1    r22/detA  -r12/detA
38 //          A  =  -r21/detA   r11/detA
39 //          tx =  (r12*ty-r22*tx)/detA
40 //          ty =  (r21*tx-r11*ty)/detA
41 //
42 // Punktumrechnung:
43 //                   p2 = A * p1
44 //          x2 = x1*r11 + y1*r12 + tx;
45 //          y2 = x1*r21 + y1*r22 + ty;
46 //
47 //                         -1
48 //                   p1 = A  * p2;
49 //          x1 = ( x2*r22 - y2*r21)/detA - tx;
50 //          y1 = (-x2*r12 + y2*r11)/detA - ty;
51 //
52 // -------------------------------------------------------------------------
53 
54 class Mat2
55 {
56 
57    public:
58 		//
59 		// Konstruktoren
60 		//
Mat2()61       Mat2()
62 			{ r11=r22=1.0; r12=r21= tx=ty= 0.0; }
Mat2(const Mat2 & m)63       Mat2( const Mat2 &m )
64 			{ 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)65       Mat2(const Real &ir11, const Real &ir12, const Real &itx,
66 					const Real &ir21, const Real &ir22, const Real &ity )
67 			{ r11=ir11; r12=ir12; r21=ir21; r22=ir22; tx=itx; ty=ity; }
68 		//
69 		// Methoden zum Anwenden einer Transformation.
70 		// Die der Transformation entsprechende Matrix wird von links!!
71 		// in die aktuelle Matrix hineinmultipliziert.
72 		//
73       Mat2 &Reset();
74 
75       Mat2 &Move(const Real &dx, const Real &dy);
76       Mat2 &Move(const Vec2 &p);
77       Mat2 &MoveX(const Real &dx);
78       Mat2 &MoveY(const Real &dy);
79 
80       Mat2 &Scale(const Real &sx, const Real &sy);
81       Mat2 &Scale(const Real &s);
82       Mat2 &ScaleX(const Real &sx);
83       Mat2 &ScaleY(const Real &sy);
84       Mat2 &ScaleAt(const Real &px, const Real &py,const Real &sx, const Real &sy);
85       Mat2 &ScaleAt(const Vec2 &p,const Real &sx, const Real &sy);
86       Mat2 &ScaleAt(const Real &px, const Real &py,const Real &s);
87       Mat2 &ScaleAt(const Vec2 &p,const Real &s);
88 
89       Mat2 &Rotate(const Real &a);
90       Mat2 &RotateAt(const Real &px, const Real &py,const Real &a);
91       Mat2 &RotateAt(const Vec2 &p,const Real &a);
92 
93       Mat2 &RotateDeg(const Real &a);
94       Mat2 &RotateDegAt(const Real &px, const Real &py,const Real &a);
95       Mat2 &RotateDegAt(const Vec2 &p,const Real &a);
96 
97       Mat2 &ShearX(const Real& a);
98       Mat2 &ShearY(const Real& b);
99       Mat2 &Shear(const Real& a, const Real& b);
100 
IsRotated()101       int IsRotated() const { return r12 || r21; }
102 
103 		//
104 		// Zuweisungsoperator
105 		//
106       const Mat2& operator=(const Mat2 &m)
107 			{	r11=m.r11; r12=m.r12; r21=m.r21; r22=m.r22; tx=m.tx; ty=m.ty;
108 				return *this; }
109 
110 		//
111 		// Operatoren
112 		//
113       const Mat2 &operator*=(const Mat2 &m);
114       Mat2 operator*(const Mat2 &m) const
115 			{
116 				Mat2 help(*this);
117 				return help*=m;
118 			}
119       void Invert(Mat2 *m) const;
120       Mat2 operator!() const
121 			{	Mat2	m;
122 				Invert( &m );
123 				return m;
124 			}
125 
126       Vec2 operator*(const Vec2 &p) const {
127 			return Vec2( r11*p.X() + r12*p.Y() + tx, r21*p.X() + r22*p.Y() + ty );
128 		}
129 
130 		//
131 		// Zugriff auf Koeffizienten
132 		//
133       void Split( Real *sh, Real *sx, Real *sy, Real *angle, Real *mx, Real *my ) const;
134 
135    protected:
136 
137       Real	r11, r12, tx;
138       Real	r21, r22, ty;
139 
140 };
141 
142 
Reset()143 inline Mat2 &Mat2::Reset()
144 			{ r11=r22=1.0; r12=r21= tx=ty= 0.0; return *this; }
Move(const Real & dx,const Real & dy)145 inline Mat2 &Mat2::Move(const Real &dx, const Real &dy)
146 			{ tx+=dx; ty+=dy; return *this; }
Move(const Vec2 & p)147 inline Mat2 &Mat2::Move(const Vec2 &p)
148 			{ tx+=p.X(); ty+=p.Y(); return *this; }
MoveX(const Real & dx)149 inline Mat2 &Mat2::MoveX(const Real &dx)
150 			{ tx+=dx; return *this; }
MoveY(const Real & dy)151 inline Mat2 &Mat2::MoveY(const Real &dy)
152 			{ ty+=dy; return *this; }
Scale(const Real & sx,const Real & sy)153 inline Mat2 &Mat2::Scale(const Real &sx, const Real &sy)
154 			{ r11*=sx; r21*=sy; r12*=sx; r22*=sy; tx*=sx; ty*=sy; return *this; }
Scale(const Real & s)155 inline Mat2 &Mat2::Scale(const Real &s)
156 			{ return Scale(s,s); }
ScaleX(const Real & sx)157 inline Mat2 &Mat2::ScaleX(const Real &sx)
158 			{ r11*=sx; r12*=sx; tx*=sx; return *this; }
ScaleY(const Real & sy)159 inline Mat2 &Mat2::ScaleY(const Real &sy)
160 			{ r21*=sy; r22*=sy; ty*=sy; return *this; }
ScaleAt(const Real & px,const Real & py,const Real & sx,const Real & sy)161 inline Mat2 &Mat2::ScaleAt(const Real &px, const Real &py,const Real &sx, const Real &sy)
162 			{ return Move(-px,-py).Scale(sx,sy).Move(px,py); }
ScaleAt(const Vec2 & p,const Real & sx,const Real & sy)163 inline Mat2 &Mat2::ScaleAt(const Vec2 &p,const Real &sx, const Real &sy)
164 			{ return Move(-p).Scale(sx,sy).Move(p); }
ScaleAt(const Real & px,const Real & py,const Real & s)165 inline Mat2 &Mat2::ScaleAt(const Real &px, const Real &py,const Real &s)
166 			{ return Move(-px,-py).Scale(s).Move(px,py); }
ScaleAt(const Vec2 & p,const Real & s)167 inline Mat2 &Mat2::ScaleAt(const Vec2 &p,const Real &s)
168 			{ return Move(-p).Scale(s).Move(p); }
Rotate(const Real & a)169 inline Mat2 &Mat2::Rotate(const Real &a)
170 			{	Mat2 help(*this);
171 				r11 =    r22 = cos(a);
172 				r12 = -( r21 = sin(a) );
173 				tx  = ty = 0.0;
174 				operator*=(help);
175 				return *this;
176 			}
RotateDeg(const Real & a)177 inline Mat2 &Mat2::RotateDeg(const Real &a)
178 			{ return Rotate(a/Real(180/M_PI)); }
RotateAt(const Real & px,const Real & py,const Real & a)179 inline Mat2 &Mat2::RotateAt(const Real &px, const Real &py,const Real &a)
180 			{ return Move(-px,-py).Rotate(a).Move(px,py); }
RotateDegAt(const Real & px,const Real & py,const Real & a)181 inline Mat2 &Mat2::RotateDegAt(const Real &px, const Real &py,const Real &a)
182 			{ return Move(-px,-py).Rotate(a/Real(180/M_PI)).Move(px,py); }
RotateAt(const Vec2 & p,const Real & a)183 inline Mat2 &Mat2::RotateAt(const Vec2 &p,const Real &a)
184 			{ return Move(-p).Rotate(a).Move(p); }
RotateDegAt(const Vec2 & p,const Real & a)185 inline Mat2 &Mat2::RotateDegAt(const Vec2 &p,const Real &a)
186 			{ return Move(-p).Rotate(a/Real(180/M_PI)).Move(p); }
ShearX(const Real & a)187 inline Mat2 &Mat2::ShearX(const Real& a)
188 			{ r11+=a*r21; r12+=a*r22; tx+=a*ty; return *this; }
ShearY(const Real & b)189 inline Mat2 &Mat2::ShearY(const Real& b)
190 			{ r21+=b*r11; r22+=b*r12; ty+=b*tx; return *this; }
Shear(const Real & a,const Real & b)191 inline Mat2 &Mat2::Shear(const Real& a, const Real& b)
192 			{ return ShearX(a).ShearY(b); }
193 
194 #endif    /* __Mat2_H */
195 
196