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