]> git.saurik.com Git - wxWidgets.git/blob - src/common/affinematrix2d.cpp
Fix background drawing in EVT_ERASE_BACKGROUND handler in erase sample.
[wxWidgets.git] / src / common / affinematrix2d.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: affinematrix2d.cpp
3 // Purpose: implementation of wxAffineMatrix2D
4 // Author: Based on wxTransformMatrix by Chris Breeze, Julian Smart
5 // Created: 2011-04-05
6 // Copyright: (c) wxWidgets team
7 // Licence: wxWindows licence
8 ///////////////////////////////////////////////////////////////////////////////
9
10 #include "wx/wxprec.h"
11
12 #ifdef __BORLANDC__
13 #pragma hdrstop
14 #endif
15
16 #if wxUSE_GEOMETRY
17
18 #include "wx/affinematrix2d.h"
19 #include "wx/math.h"
20
21 // sets the matrix to the respective values
22 void wxAffineMatrix2D::Set(const wxMatrix2D &mat2D, const wxPoint2DDouble &tr)
23 {
24 m_11 = mat2D.m_11;
25 m_12 = mat2D.m_12;
26 m_21 = mat2D.m_21;
27 m_22 = mat2D.m_22;
28 m_tx = tr.m_x;
29 m_ty = tr.m_y;
30 }
31
32 // gets the component valuess of the matrix
33 void wxAffineMatrix2D::Get(wxMatrix2D *mat2D, wxPoint2DDouble *tr) const
34 {
35 mat2D->m_11 = m_11;
36 mat2D->m_12 = m_12;
37 mat2D->m_21 = m_21;
38 mat2D->m_22 = m_22;
39
40 if ( tr )
41 {
42 tr->m_x = m_tx;
43 tr->m_y = m_ty;
44 }
45 }
46
47 // concatenates the matrix
48 // | t.m_11 t.m_12 0 | | m_11 m_12 0 |
49 // | t.m_21 t.m_22 0 | x | m_21 m_22 0 |
50 // | t.m_tx t.m_ty 1 | | m_tx m_ty 1 |
51 void wxAffineMatrix2D::Concat(const wxAffineMatrix2DBase &t)
52 {
53 wxMatrix2D mat;
54 wxPoint2DDouble tr;
55 t.Get(&mat, &tr);
56
57 m_tx += tr.m_x*m_11 + tr.m_y*m_21;
58 m_ty += tr.m_x*m_12 + tr.m_y*m_22;
59 wxDouble e11 = mat.m_11*m_11 + mat.m_12*m_21;
60 wxDouble e12 = mat.m_11*m_12 + mat.m_12*m_22;
61 wxDouble e21 = mat.m_21*m_11 + mat.m_22*m_21;
62 m_22 = mat.m_21*m_12 + mat.m_22*m_22;
63 m_11 = e11;
64 m_12 = e12;
65 m_21 = e21;
66 }
67
68 // makes this its inverse matrix.
69 // Invert
70 // | m_11 m_12 0 |
71 // | m_21 m_22 0 |
72 // | m_tx m_ty 1 |
73 bool wxAffineMatrix2D::Invert()
74 {
75 const wxDouble det = m_11*m_22 - m_12*m_21;
76
77 if ( !det )
78 return false;
79
80 wxDouble ex = (m_21*m_ty - m_22*m_tx) / det;
81 m_ty = (-m_11*m_ty + m_12*m_tx) / det;
82 m_tx = ex;
83 wxDouble e11 = m_22 / det;
84 m_12 = -m_12 / det;
85 m_21 = -m_21 / det;
86 m_22 = m_11 / det;
87 m_11 = e11;
88
89 return true;
90 }
91
92 // returns true if the elements of the transformation matrix are equal
93 bool wxAffineMatrix2D::IsEqual(const wxAffineMatrix2DBase& t) const
94 {
95 wxMatrix2D mat;
96 wxPoint2DDouble tr;
97 t.Get(&mat, &tr);
98
99 return m_11 == mat.m_11 && m_12 == mat.m_12 &&
100 m_21 == mat.m_21 && m_22 == mat.m_22 &&
101 m_tx == tr.m_x && m_ty == tr.m_y;
102 }
103
104 //
105 // transformations
106 //
107
108 // add the translation to this matrix
109 // | 1 0 0 | | m_11 m_12 0 |
110 // | 0 1 0 | x | m_21 m_22 0 |
111 // | dx dy 1 | | m_tx m_ty 1 |
112 void wxAffineMatrix2D::Translate(wxDouble dx, wxDouble dy)
113 {
114 m_tx += m_11 * dx + m_21 * dy;
115 m_ty += m_12 * dx + m_22 * dy;
116 }
117
118 // add the scale to this matrix
119 // | xScale 0 0 | | m_11 m_12 0 |
120 // | 0 yScale 0 | x | m_21 m_22 0 |
121 // | 0 0 1 | | m_tx m_ty 1 |
122 void wxAffineMatrix2D::Scale(wxDouble xScale, wxDouble yScale)
123 {
124 m_11 *= xScale;
125 m_12 *= xScale;
126 m_21 *= yScale;
127 m_22 *= yScale;
128 }
129
130 // add the rotation to this matrix (clockwise, radians)
131 // | cos sin 0 | | m_11 m_12 0 |
132 // | -sin cos 0 | x | m_21 m_22 0 |
133 // | 0 0 1 | | m_tx m_ty 1 |
134 void wxAffineMatrix2D::Rotate(wxDouble cRadians)
135 {
136 wxDouble c = cos(cRadians);
137 wxDouble s = sin(cRadians);
138
139 wxDouble e11 = c*m_11 + s*m_21;
140 wxDouble e12 = c*m_12 + s*m_22;
141 m_21 = c*m_21 - s*m_11;
142 m_22 = c*m_22 - s*m_12;
143 m_11 = e11;
144 m_12 = e12;
145 }
146
147 //
148 // apply the transforms
149 //
150
151 // applies that matrix to the point
152 // | m_11 m_12 0 |
153 // | src.m_x src._my 1 | x | m_21 m_22 0 |
154 // | m_tx m_ty 1 |
155 wxPoint2DDouble
156 wxAffineMatrix2D::DoTransformPoint(const wxPoint2DDouble& src) const
157 {
158 if ( IsIdentity() )
159 return src;
160
161 return wxPoint2DDouble(src.m_x * m_11 + src.m_y * m_21 + m_tx,
162 src.m_x * m_12 + src.m_y * m_22 + m_ty);
163 }
164
165 // applies the matrix except for translations
166 // | m_11 m_12 0 |
167 // | src.m_x src._my 0 | x | m_21 m_22 0 |
168 // | m_tx m_ty 1 |
169 wxPoint2DDouble
170 wxAffineMatrix2D::DoTransformDistance(const wxPoint2DDouble& src) const
171 {
172 if ( IsIdentity() )
173 return src;
174
175 return wxPoint2DDouble(src.m_x * m_11 + src.m_y * m_21,
176 src.m_x * m_12 + src.m_y * m_22);
177 }
178
179 bool wxAffineMatrix2D::IsIdentity() const
180 {
181 return m_11 == 1 && m_12 == 0 &&
182 m_21 == 0 && m_22 == 1 &&
183 m_tx == 0 && m_ty == 0;
184 }
185
186 #endif // wxUSE_GEOMETRY