]>
Commit | Line | Data |
---|---|---|
1 | ///////////////////////////////////////////////////////////////////////////// | |
2 | // Name: wx/matrix.h | |
3 | // Purpose: wxTransformMatrix class. NOT YET USED | |
4 | // Author: Chris Breeze, Julian Smart | |
5 | // Modified by: Klaas Holwerda | |
6 | // Created: 01/02/97 | |
7 | // RCS-ID: $Id$ | |
8 | // Copyright: (c) Julian Smart, Chris Breeze | |
9 | // Licence: wxWindows licence | |
10 | ///////////////////////////////////////////////////////////////////////////// | |
11 | ||
12 | #ifndef _WX_MATRIXH__ | |
13 | #define _WX_MATRIXH__ | |
14 | ||
15 | //! headerfiles="matrix.h wx/object.h" | |
16 | #include "wx/object.h" | |
17 | #include "wx/math.h" | |
18 | ||
19 | //! codefiles="matrix.cpp" | |
20 | ||
21 | // A simple 3x3 matrix. This may be replaced by a more general matrix | |
22 | // class some day. | |
23 | // | |
24 | // Note: this is intended to be used in wxDC at some point to replace | |
25 | // the current system of scaling/translation. It is not yet used. | |
26 | ||
27 | //:definition | |
28 | // A 3x3 matrix to do 2D transformations. | |
29 | // It can be used to map data to window coordinates, | |
30 | // and also for manipulating your own data. | |
31 | // For example drawing a picture (composed of several primitives) | |
32 | // at a certain coordinate and angle within another parent picture. | |
33 | // At all times m_isIdentity is set if the matrix itself is an Identity matrix. | |
34 | // It is used where possible to optimize calculations. | |
35 | class WXDLLEXPORT wxTransformMatrix: public wxObject | |
36 | { | |
37 | public: | |
38 | wxTransformMatrix(void); | |
39 | wxTransformMatrix(const wxTransformMatrix& mat); | |
40 | ||
41 | //get the value in the matrix at col,row | |
42 | //rows are horizontal (second index of m_matrix member) | |
43 | //columns are vertical (first index of m_matrix member) | |
44 | double GetValue(int col, int row) const; | |
45 | ||
46 | //set the value in the matrix at col,row | |
47 | //rows are horizontal (second index of m_matrix member) | |
48 | //columns are vertical (first index of m_matrix member) | |
49 | void SetValue(int col, int row, double value); | |
50 | ||
51 | void operator = (const wxTransformMatrix& mat); | |
52 | bool operator == (const wxTransformMatrix& mat) const; | |
53 | bool operator != (const wxTransformMatrix& mat) const; | |
54 | ||
55 | //multiply every element by t | |
56 | wxTransformMatrix& operator*=(const double& t); | |
57 | //divide every element by t | |
58 | wxTransformMatrix& operator/=(const double& t); | |
59 | //add matrix m to this t | |
60 | wxTransformMatrix& operator+=(const wxTransformMatrix& m); | |
61 | //subtract matrix m from this | |
62 | wxTransformMatrix& operator-=(const wxTransformMatrix& m); | |
63 | //multiply matrix m with this | |
64 | wxTransformMatrix& operator*=(const wxTransformMatrix& m); | |
65 | ||
66 | // constant operators | |
67 | ||
68 | //multiply every element by t and return result | |
69 | wxTransformMatrix operator*(const double& t) const; | |
70 | //divide this matrix by t and return result | |
71 | wxTransformMatrix operator/(const double& t) const; | |
72 | //add matrix m to this and return result | |
73 | wxTransformMatrix operator+(const wxTransformMatrix& m) const; | |
74 | //subtract matrix m from this and return result | |
75 | wxTransformMatrix operator-(const wxTransformMatrix& m) const; | |
76 | //multiply this by matrix m and return result | |
77 | wxTransformMatrix operator*(const wxTransformMatrix& m) const; | |
78 | wxTransformMatrix operator-() const; | |
79 | ||
80 | //rows are horizontal (second index of m_matrix member) | |
81 | //columns are vertical (first index of m_matrix member) | |
82 | double& operator()(int col, int row); | |
83 | ||
84 | //rows are horizontal (second index of m_matrix member) | |
85 | //columns are vertical (first index of m_matrix member) | |
86 | double operator()(int col, int row) const; | |
87 | ||
88 | // Invert matrix | |
89 | bool Invert(void); | |
90 | ||
91 | // Make into identity matrix | |
92 | bool Identity(void); | |
93 | ||
94 | // Is the matrix the identity matrix? | |
95 | // Only returns a flag, which is set whenever an operation | |
96 | // is done. | |
97 | inline bool IsIdentity(void) const { return m_isIdentity; }; | |
98 | ||
99 | // This does an actual check. | |
100 | inline bool IsIdentity1(void) const ; | |
101 | ||
102 | //Scale by scale (isotropic scaling i.e. the same in x and y): | |
103 | //!ex: | |
104 | //!code: | scale 0 0 | | |
105 | //!code: matrix' = | 0 scale 0 | x matrix | |
106 | //!code: | 0 0 scale | | |
107 | bool Scale(double scale); | |
108 | ||
109 | //Scale with center point and x/y scale | |
110 | // | |
111 | //!ex: | |
112 | //!code: | xs 0 xc(1-xs) | | |
113 | //!code: matrix' = | 0 ys yc(1-ys) | x matrix | |
114 | //!code: | 0 0 1 | | |
115 | wxTransformMatrix& Scale(const double &xs, const double &ys,const double &xc, const double &yc); | |
116 | ||
117 | // mirror a matrix in x, y | |
118 | //!ex: | |
119 | //!code: | -1 0 0 | | |
120 | //!code: matrix' = | 0 -1 0 | x matrix | |
121 | //!code: | 0 0 1 | | |
122 | wxTransformMatrix& Mirror(bool x=true, bool y=false); | |
123 | // Translate by dx, dy: | |
124 | //!ex: | |
125 | //!code: | 1 0 dx | | |
126 | //!code: matrix' = | 0 1 dy | x matrix | |
127 | //!code: | 0 0 1 | | |
128 | bool Translate(double x, double y); | |
129 | ||
130 | // Rotate clockwise by the given number of degrees: | |
131 | //!ex: | |
132 | //!code: | cos sin 0 | | |
133 | //!code: matrix' = | -sin cos 0 | x matrix | |
134 | //!code: | 0 0 1 | | |
135 | bool Rotate(double angle); | |
136 | ||
137 | //Rotate counter clockwise with point of rotation | |
138 | // | |
139 | //!ex: | |
140 | //!code: | cos(r) -sin(r) x(1-cos(r))+y(sin(r)| | |
141 | //!code: matrix' = | sin(r) cos(r) y(1-cos(r))-x(sin(r)| x matrix | |
142 | //!code: | 0 0 1 | | |
143 | wxTransformMatrix& Rotate(const double &r, const double &x, const double &y); | |
144 | ||
145 | // Transform X value from logical to device | |
146 | inline double TransformX(double x) const; | |
147 | ||
148 | // Transform Y value from logical to device | |
149 | inline double TransformY(double y) const; | |
150 | ||
151 | // Transform a point from logical to device coordinates | |
152 | bool TransformPoint(double x, double y, double& tx, double& ty) const; | |
153 | ||
154 | // Transform a point from device to logical coordinates. | |
155 | // Example of use: | |
156 | // wxTransformMatrix mat = dc.GetTransformation(); | |
157 | // mat.Invert(); | |
158 | // mat.InverseTransformPoint(x, y, x1, y1); | |
159 | // OR (shorthand:) | |
160 | // dc.LogicalToDevice(x, y, x1, y1); | |
161 | // The latter is slightly less efficient if we're doing several | |
162 | // conversions, since the matrix is inverted several times. | |
163 | // N.B. 'this' matrix is the inverse at this point | |
164 | bool InverseTransformPoint(double x, double y, double& tx, double& ty) const; | |
165 | ||
166 | double Get_scaleX(); | |
167 | double Get_scaleY(); | |
168 | double GetRotation(); | |
169 | void SetRotation(double rotation); | |
170 | ||
171 | ||
172 | public: | |
173 | double m_matrix[3][3]; | |
174 | bool m_isIdentity; | |
175 | }; | |
176 | ||
177 | ||
178 | /* | |
179 | Chris Breeze reported, that | |
180 | some functions of wxTransformMatrix cannot work because it is not | |
181 | known if he matrix has been inverted. Be careful when using it. | |
182 | */ | |
183 | ||
184 | // Transform X value from logical to device | |
185 | // warning: this function can only be used for this purpose | |
186 | // because no rotation is involved when mapping logical to device coordinates | |
187 | // mirror and scaling for x and y will be part of the matrix | |
188 | // if you have a matrix that is rotated, eg a shape containing a matrix to place | |
189 | // it in the logical coordinate system, use TransformPoint | |
190 | inline double wxTransformMatrix::TransformX(double x) const | |
191 | { | |
192 | //normally like this, but since no rotation is involved (only mirror and scale) | |
193 | //we can do without Y -> m_matrix[1]{0] is -sin(rotation angle) and therefore zero | |
194 | //(x * m_matrix[0][0] + y * m_matrix[1][0] + m_matrix[2][0])) | |
195 | return (m_isIdentity ? x : (x * m_matrix[0][0] + m_matrix[2][0])); | |
196 | } | |
197 | ||
198 | // Transform Y value from logical to device | |
199 | // warning: this function can only be used for this purpose | |
200 | // because no rotation is involved when mapping logical to device coordinates | |
201 | // mirror and scaling for x and y will be part of the matrix | |
202 | // if you have a matrix that is rotated, eg a shape containing a matrix to place | |
203 | // it in the logical coordinate system, use TransformPoint | |
204 | inline double wxTransformMatrix::TransformY(double y) const | |
205 | { | |
206 | //normally like this, but since no rotation is involved (only mirror and scale) | |
207 | //we can do without X -> m_matrix[0]{1] is sin(rotation angle) and therefore zero | |
208 | //(x * m_matrix[0][1] + y * m_matrix[1][1] + m_matrix[2][1])) | |
209 | return (m_isIdentity ? y : (y * m_matrix[1][1] + m_matrix[2][1])); | |
210 | } | |
211 | ||
212 | ||
213 | // Is the matrix the identity matrix? | |
214 | // Each operation checks whether the result is still the identity matrix and sets a flag. | |
215 | inline bool wxTransformMatrix::IsIdentity1(void) const | |
216 | { | |
217 | return | |
218 | ( wxIsSameDouble(m_matrix[0][0], 1.0) && | |
219 | wxIsSameDouble(m_matrix[1][1], 1.0) && | |
220 | wxIsSameDouble(m_matrix[2][2], 1.0) && | |
221 | wxIsSameDouble(m_matrix[1][0], 0.0) && | |
222 | wxIsSameDouble(m_matrix[2][0], 0.0) && | |
223 | wxIsSameDouble(m_matrix[0][1], 0.0) && | |
224 | wxIsSameDouble(m_matrix[2][1], 0.0) && | |
225 | wxIsSameDouble(m_matrix[0][2], 0.0) && | |
226 | wxIsSameDouble(m_matrix[1][2], 0.0) ); | |
227 | } | |
228 | ||
229 | // Calculates the determinant of a 2 x 2 matrix | |
230 | inline double wxCalculateDet(double a11, double a21, double a12, double a22) | |
231 | { | |
232 | return a11 * a22 - a12 * a21; | |
233 | } | |
234 | ||
235 | #endif // _WX_MATRIXH__ |