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