]>
Commit | Line | Data |
---|---|---|
c801d85f KB |
1 | ///////////////////////////////////////////////////////////////////////////// |
2 | // Name: matrix.h | |
3 | // Purpose: wxTransformMatrix class. NOT YET USED | |
555526fb RR |
4 | //! Author: Chris Breeze, Julian Smart |
5 | // Modified by: Klaas Holwerda | |
c801d85f KB |
6 | // Created: 01/02/97 |
7 | // RCS-ID: $Id$ | |
8 | // Copyright: (c) Julian Smart and Markus Holzem | |
555526fb | 9 | // Licence: wxWindows licence |
c801d85f KB |
10 | ///////////////////////////////////////////////////////////////////////////// |
11 | ||
34138703 JS |
12 | #ifndef _WX_MATRIXH__ |
13 | #define _WX_MATRIXH__ | |
c801d85f KB |
14 | |
15 | #ifdef __GNUG__ | |
16 | #pragma interface "matrix.h" | |
17 | #endif | |
18 | ||
555526fb | 19 | //! headerfiles="matrix.h wx/object.h" |
c801d85f KB |
20 | #include "wx/object.h" |
21 | ||
555526fb RR |
22 | //! codefiles="matrix.cpp" |
23 | ||
c801d85f KB |
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 | ||
555526fb RR |
30 | //:defenition |
31 | // A 3x3 matrix to do 2D transformations. | |
32 | // It can be used to map data to window coordinates. | |
33 | // But 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. | |
c801d85f KB |
38 | class WXDLLEXPORT wxTransformMatrix: public wxObject |
39 | { | |
40 | public: | |
555526fb RR |
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 | | |
3bdb7232 DW |
125 | #if defined(__WXPM__) |
126 | wxTransformMatrix& Mirror(bool x=TRUE, bool y=FALSE); | |
127 | #else | |
555526fb | 128 | wxTransformMatrix& Mirror(bool x=true, bool y=false); |
3bdb7232 | 129 | #endif |
555526fb RR |
130 | // Translate by dx, dy: |
131 | //!ex: | |
132 | //!code: | 1 0 dx | | |
133 | //!code: matrix' = | 0 1 dy | x matrix | |
134 | //!code: | 0 0 1 | | |
135 | bool Translate(double x, double y); | |
136 | ||
137 | // Rotate clockwise by the given number of degrees: | |
138 | //!ex: | |
139 | //!code: | cos sin 0 | | |
140 | //!code: matrix' = | -sin cos 0 | x matrix | |
141 | //!code: | 0 0 1 | | |
142 | bool Rotate(double angle); | |
143 | ||
144 | //Rotate counter clockwise with point of rotation | |
145 | // | |
146 | //!ex: | |
147 | //!code: | cos(r) -sin(r) x(1-cos(r))+y(sin(r)| | |
148 | //!code: matrix' = | sin(r) cos(r) y(1-cos(r))-x(sin(r)| x matrix | |
149 | //!code: | 0 0 1 | | |
150 | wxTransformMatrix& Rotate(const double &r, const double &x, const double &y); | |
151 | ||
152 | // Transform X value from logical to device | |
153 | inline double TransformX(double x) const; | |
154 | ||
155 | // Transform Y value from logical to device | |
156 | inline double TransformY(double y) const; | |
157 | ||
158 | // Transform a point from logical to device coordinates | |
159 | bool TransformPoint(double x, double y, double& tx, double& ty) const; | |
160 | ||
161 | // Transform a point from device to logical coordinates. | |
162 | // Example of use: | |
163 | // wxTransformMatrix mat = dc.GetTransformation(); | |
164 | // mat.Invert(); | |
165 | // mat.InverseTransformPoint(x, y, x1, y1); | |
166 | // OR (shorthand:) | |
167 | // dc.LogicalToDevice(x, y, x1, y1); | |
168 | // The latter is slightly less efficient if we're doing several | |
169 | // conversions, since the matrix is inverted several times. | |
170 | // N.B. 'this' matrix is the inverse at this point | |
171 | bool InverseTransformPoint(double x, double y, double& tx, double& ty) const; | |
172 | ||
173 | double Get_scaleX(); | |
174 | double Get_scaleY(); | |
175 | double GetRotation(); | |
176 | void SetRotation(double rotation); | |
c801d85f | 177 | |
c801d85f KB |
178 | |
179 | public: | |
555526fb RR |
180 | double m_matrix[3][3]; |
181 | bool m_isIdentity; | |
c801d85f KB |
182 | }; |
183 | ||
46dc76ba RR |
184 | |
185 | /* | |
555526fb | 186 | Chris Breeze reported, that |
46dc76ba RR |
187 | some functions of wxTransformMatrix cannot work because it is not |
188 | known if he matrix has been inverted. Be careful when using it. | |
555526fb | 189 | */ |
46dc76ba | 190 | |
c801d85f | 191 | // Transform X value from logical to device |
555526fb RR |
192 | // warning: this function can only be used for this purpose |
193 | // because no rotation is involved when mapping logical to device coordinates | |
194 | // mirror and scaling for x and y will be part of the matrix | |
195 | // if you have a matrix that is rotated, eg a shape containing a matrix to place | |
196 | // it in the logical coordinate system, use TransformPoint | |
c801d85f KB |
197 | inline double wxTransformMatrix::TransformX(double x) const |
198 | { | |
555526fb RR |
199 | //normally like this, but since no rotation is involved (only mirror and scale) |
200 | //we can do without Y -> m_matrix[1]{0] is -sin(rotation angle) and therefore zero | |
201 | //(x * m_matrix[0][0] + y * m_matrix[1][0] + m_matrix[2][0])) | |
202 | return (m_isIdentity ? x : (x * m_matrix[0][0] + m_matrix[2][0])); | |
c801d85f KB |
203 | } |
204 | ||
205 | // Transform Y value from logical to device | |
555526fb RR |
206 | // warning: this function can only be used for this purpose |
207 | // because no rotation is involved when mapping logical to device coordinates | |
208 | // mirror and scaling for x and y will be part of the matrix | |
209 | // if you have a matrix that is rotated, eg a shape containing a matrix to place | |
210 | // it in the logical coordinate system, use TransformPoint | |
c801d85f KB |
211 | inline double wxTransformMatrix::TransformY(double y) const |
212 | { | |
555526fb RR |
213 | //normally like this, but since no rotation is involved (only mirror and scale) |
214 | //we can do without X -> m_matrix[0]{1] is sin(rotation angle) and therefore zero | |
215 | //(x * m_matrix[0][1] + y * m_matrix[1][1] + m_matrix[2][1])) | |
216 | return (m_isIdentity ? y : (y * m_matrix[1][1] + m_matrix[2][1])); | |
c801d85f | 217 | } |
555526fb | 218 | |
c801d85f KB |
219 | |
220 | // Is the matrix the identity matrix? | |
555526fb | 221 | // Each operation checks whether the result is still the identity matrix and sets a flag. |
c801d85f KB |
222 | inline bool wxTransformMatrix::IsIdentity1(void) const |
223 | { | |
555526fb RR |
224 | return |
225 | (m_matrix[0][0] == 1.0 && | |
226 | m_matrix[1][1] == 1.0 && | |
227 | m_matrix[2][2] == 1.0 && | |
228 | m_matrix[1][0] == 0.0 && | |
229 | m_matrix[2][0] == 0.0 && | |
230 | m_matrix[0][1] == 0.0 && | |
231 | m_matrix[2][1] == 0.0 && | |
232 | m_matrix[0][2] == 0.0 && | |
233 | m_matrix[1][2] == 0.0) ; | |
c801d85f KB |
234 | } |
235 | ||
236 | // Calculates the determinant of a 2 x 2 matrix | |
237 | inline double wxCalculateDet(double a11, double a21, double a12, double a22) | |
238 | { | |
555526fb | 239 | return a11 * a22 - a12 * a21; |
c801d85f KB |
240 | } |
241 | ||
242 | #endif | |
555526fb | 243 | // _WX_MATRIXH__ |