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