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