]>
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: 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 | } |