1 #include "Painter.h"
2 
3 namespace Upp {
4 
GetScaleXY() const5 Pointf Xform2D::GetScaleXY() const
6 {
7 	return Pointf(sqrt(x.x * x.x + y.x * y.x), sqrt(x.y * x.y + y.y * y.y));
8 }
9 
GetScale() const10 double Xform2D::GetScale() const
11 {
12 	Pointf d = GetScaleXY();
13 	return Length(d) / M_SQRT2;
14 }
15 
Epsqual(double x,double y)16 inline bool Epsqual(double x, double y)
17 {
18 	return fabs(x - y) < 1e-10 * max(fabs(x), fabs(y));
19 }
20 
IsRegular() const21 bool Xform2D::IsRegular() const
22 {
23 	Pointf d = GetScaleXY();
24 	return Epsqual(d.x, d.y);
25 }
26 
GetClass() const27 byte Xform2D::GetClass() const
28 {
29 	if(x.y == 0 && y.x == 0) {
30 		if(t.x == 0 && t.y == 0)
31 			return XFORM_IDENTITY;
32 		else
33 			return XFORM_TRANSLATION;
34 		return Epsqual(x.x, y.x) ?  XFORM_REGULAR_SCALE : XFORM_SCALE;
35 	}
36 	return IsRegular() ? XFORM_REGULAR : XFORM_ANY;
37 }
38 
Xform2D()39 Xform2D::Xform2D()
40 {
41 	x.x = y.y = 1;
42 	x.y = y.x = t.x = t.y = 0;
43 }
44 
operator *(const Xform2D & a,const Xform2D & b)45 Xform2D operator*(const Xform2D& a, const Xform2D& b)
46 {
47 	Xform2D r;
48 	r.x.x = a.x.x * b.x.x + a.y.x * b.x.y;
49 	r.x.y = a.x.y * b.x.x + a.y.y * b.x.y;
50 	r.y.x = a.x.x * b.y.x + a.y.x * b.y.y;
51 	r.y.y = a.x.y * b.y.x + a.y.y * b.y.y;
52 	r.t.x = a.t.x * b.x.x + a.t.y * b.x.y + b.t.x;
53 	r.t.y = a.t.x * b.y.x + a.t.y * b.y.y + b.t.y;
54 	return r;
55 }
56 
Translation(double x,double y)57 Xform2D Xform2D::Translation(double x, double y)
58 {
59 	Xform2D m;
60 	m.t = Pointf(x, y);
61 	return m;
62 }
63 
Scale(double sx,double sy)64 Xform2D Xform2D::Scale(double sx, double sy)
65 {
66 	Xform2D m;
67 	m.x.x = sx;
68 	m.y.y = sy;
69 	return m;
70 }
71 
Scale(double scale)72 Xform2D Xform2D::Scale(double scale)
73 {
74 	return Scale(scale, scale);
75 }
76 
Rotation(double fi)77 Xform2D Xform2D::Rotation(double fi)
78 {
79 	double cosf = cos(fi);
80 	double sinf = sin(fi);
81 	Xform2D m;
82 	m.x.x = cosf;
83 	m.x.y = -sinf;
84 	m.y.x = sinf;
85 	m.y.y = cosf;
86 	m.t.x = m.t.y = 0;
87 	return m;
88 }
89 
Sheer(double fi)90 Xform2D Xform2D::Sheer(double fi)
91 {
92 	Xform2D m;
93 	m.x.x = m.y.y = 1;
94 	m.x.y = atan(fi);
95 	return m;
96 }
97 
Identity()98 Xform2D Xform2D::Identity()
99 {
100 	Xform2D m;
101 	return m;
102 }
103 
Map(Pointf s1,Pointf s2,Pointf s3)104 Xform2D Xform2D::Map(Pointf s1, Pointf s2, Pointf s3)
105 {
106 	Xform2D s;
107 	s.x.x = s1.x - s3.x;
108 	s.y.x = s1.y - s3.y;
109 	s.x.y = s2.x - s3.x;
110 	s.y.y = s2.y - s3.y;
111 	s.t = s3;
112 	return s;
113 }
114 
Map(Pointf s1,Pointf s2,Pointf s3,Pointf t1,Pointf t2,Pointf t3)115 Xform2D Xform2D::Map(Pointf s1, Pointf s2, Pointf s3, Pointf t1, Pointf t2, Pointf t3)
116 {
117 	return Inverse(Xform2D::Map(s1, s2, s3)) * Map(t1, t2, t3);
118 }
119 
Determinant(const Xform2D & m)120 double  Determinant(const Xform2D& m)
121 {
122 	return m.x.x * m.y.y - m.y.x * m.x.y;
123 }
124 
Inverse(const Xform2D & m)125 Xform2D Inverse(const Xform2D& m)
126 {
127 	Xform2D r;
128 	double det = Determinant(m);
129 	r.x = Pointf(m.y.y, -m.x.y) / det;
130 	r.y = Pointf(-m.y.x, m.x.x) / det;
131 	r.t.x = -m.t.x * r.x.x - m.t.y * r.x.y;
132 	r.t.y = -m.t.x * r.y.x - m.t.y * r.y.y;
133 	return r;
134 }
135 
136 }
137