]>
Commit | Line | Data |
---|---|---|
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 |