1 | /****************************************************************************
|
---|
2 | **
|
---|
3 | ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
---|
4 | ** All rights reserved.
|
---|
5 | ** Contact: Nokia Corporation (qt-info@nokia.com)
|
---|
6 | **
|
---|
7 | ** This file is part of the QtGui module of the Qt Toolkit.
|
---|
8 | **
|
---|
9 | ** $QT_BEGIN_LICENSE:LGPL$
|
---|
10 | ** Commercial Usage
|
---|
11 | ** Licensees holding valid Qt Commercial licenses may use this file in
|
---|
12 | ** accordance with the Qt Commercial License Agreement provided with the
|
---|
13 | ** Software or, alternatively, in accordance with the terms contained in
|
---|
14 | ** a written agreement between you and Nokia.
|
---|
15 | **
|
---|
16 | ** GNU Lesser General Public License Usage
|
---|
17 | ** Alternatively, this file may be used under the terms of the GNU Lesser
|
---|
18 | ** General Public License version 2.1 as published by the Free Software
|
---|
19 | ** Foundation and appearing in the file LICENSE.LGPL included in the
|
---|
20 | ** packaging of this file. Please review the following information to
|
---|
21 | ** ensure the GNU Lesser General Public License version 2.1 requirements
|
---|
22 | ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
---|
23 | **
|
---|
24 | ** In addition, as a special exception, Nokia gives you certain additional
|
---|
25 | ** rights. These rights are described in the Nokia Qt LGPL Exception
|
---|
26 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
---|
27 | **
|
---|
28 | ** GNU General Public License Usage
|
---|
29 | ** Alternatively, this file may be used under the terms of the GNU
|
---|
30 | ** General Public License version 3.0 as published by the Free Software
|
---|
31 | ** Foundation and appearing in the file LICENSE.GPL included in the
|
---|
32 | ** packaging of this file. Please review the following information to
|
---|
33 | ** ensure the GNU General Public License version 3.0 requirements will be
|
---|
34 | ** met: http://www.gnu.org/copyleft/gpl.html.
|
---|
35 | **
|
---|
36 | ** If you have questions regarding the use of this file, please contact
|
---|
37 | ** Nokia at qt-info@nokia.com.
|
---|
38 | ** $QT_END_LICENSE$
|
---|
39 | **
|
---|
40 | ****************************************************************************/
|
---|
41 |
|
---|
42 | #include "qdatastream.h"
|
---|
43 | #include "qdebug.h"
|
---|
44 | #include "qmatrix.h"
|
---|
45 | #include "qregion.h"
|
---|
46 | #include "qpainterpath.h"
|
---|
47 | #include "qvariant.h"
|
---|
48 | #include <qmath.h>
|
---|
49 |
|
---|
50 | #include <limits.h>
|
---|
51 |
|
---|
52 | QT_BEGIN_NAMESPACE
|
---|
53 |
|
---|
54 | /*!
|
---|
55 | \class QMatrix
|
---|
56 | \brief The QMatrix class specifies 2D transformations of a
|
---|
57 | coordinate system.
|
---|
58 | \obsolete
|
---|
59 |
|
---|
60 | \ingroup painting
|
---|
61 |
|
---|
62 | A matrix specifies how to translate, scale, shear or rotate the
|
---|
63 | coordinate system, and is typically used when rendering graphics.
|
---|
64 | QMatrix, in contrast to QTransform, does not allow perspective
|
---|
65 | transformations. QTransform is the recommended transformation
|
---|
66 | class in Qt.
|
---|
67 |
|
---|
68 | A QMatrix object can be built using the setMatrix(), scale(),
|
---|
69 | rotate(), translate() and shear() functions. Alternatively, it
|
---|
70 | can be built by applying \l {QMatrix#Basic Matrix
|
---|
71 | Operations}{basic matrix operations}. The matrix can also be
|
---|
72 | defined when constructed, and it can be reset to the identity
|
---|
73 | matrix (the default) using the reset() function.
|
---|
74 |
|
---|
75 | The QMatrix class supports mapping of graphic primitives: A given
|
---|
76 | point, line, polygon, region, or painter path can be mapped to the
|
---|
77 | coordinate system defined by \e this matrix using the map()
|
---|
78 | function. In case of a rectangle, its coordinates can be
|
---|
79 | transformed using the mapRect() function. A rectangle can also be
|
---|
80 | transformed into a \e polygon (mapped to the coordinate system
|
---|
81 | defined by \e this matrix), using the mapToPolygon() function.
|
---|
82 |
|
---|
83 | QMatrix provides the isIdentity() function which returns true if
|
---|
84 | the matrix is the identity matrix, and the isInvertible() function
|
---|
85 | which returns true if the matrix is non-singular (i.e. AB = BA =
|
---|
86 | I). The inverted() function returns an inverted copy of \e this
|
---|
87 | matrix if it is invertible (otherwise it returns the identity
|
---|
88 | matrix). In addition, QMatrix provides the determinant() function
|
---|
89 | returning the matrix's determinant.
|
---|
90 |
|
---|
91 | Finally, the QMatrix class supports matrix multiplication, and
|
---|
92 | objects of the class can be streamed as well as compared.
|
---|
93 |
|
---|
94 | \tableofcontents
|
---|
95 |
|
---|
96 | \section1 Rendering Graphics
|
---|
97 |
|
---|
98 | When rendering graphics, the matrix defines the transformations
|
---|
99 | but the actual transformation is performed by the drawing routines
|
---|
100 | in QPainter.
|
---|
101 |
|
---|
102 | By default, QPainter operates on the associated device's own
|
---|
103 | coordinate system. The standard coordinate system of a
|
---|
104 | QPaintDevice has its origin located at the top-left position. The
|
---|
105 | \e x values increase to the right; \e y values increase
|
---|
106 | downward. For a complete description, see the \l {The Coordinate
|
---|
107 | System}{coordinate system} documentation.
|
---|
108 |
|
---|
109 | QPainter has functions to translate, scale, shear and rotate the
|
---|
110 | coordinate system without using a QMatrix. For example:
|
---|
111 |
|
---|
112 | \table 100%
|
---|
113 | \row
|
---|
114 | \o \inlineimage qmatrix-simpletransformation.png
|
---|
115 | \o
|
---|
116 | \snippet doc/src/snippets/matrix/matrix.cpp 0
|
---|
117 | \endtable
|
---|
118 |
|
---|
119 | Although these functions are very convenient, it can be more
|
---|
120 | efficient to build a QMatrix and call QPainter::setMatrix() if you
|
---|
121 | want to perform more than a single transform operation. For
|
---|
122 | example:
|
---|
123 |
|
---|
124 | \table 100%
|
---|
125 | \row
|
---|
126 | \o \inlineimage qmatrix-combinedtransformation.png
|
---|
127 | \o
|
---|
128 | \snippet doc/src/snippets/matrix/matrix.cpp 1
|
---|
129 | \endtable
|
---|
130 |
|
---|
131 | \section1 Basic Matrix Operations
|
---|
132 |
|
---|
133 | \image qmatrix-representation.png
|
---|
134 |
|
---|
135 | A QMatrix object contains a 3 x 3 matrix. The \c dx and \c dy
|
---|
136 | elements specify horizontal and vertical translation. The \c m11
|
---|
137 | and \c m22 elements specify horizontal and vertical scaling. And
|
---|
138 | finally, the \c m21 and \c m12 elements specify horizontal and
|
---|
139 | vertical \e shearing.
|
---|
140 |
|
---|
141 | QMatrix transforms a point in the plane to another point using the
|
---|
142 | following formulas:
|
---|
143 |
|
---|
144 | \snippet doc/src/snippets/code/src_gui_painting_qmatrix.cpp 0
|
---|
145 |
|
---|
146 | The point \e (x, y) is the original point, and \e (x', y') is the
|
---|
147 | transformed point. \e (x', y') can be transformed back to \e (x,
|
---|
148 | y) by performing the same operation on the inverted() matrix.
|
---|
149 |
|
---|
150 | The various matrix elements can be set when constructing the
|
---|
151 | matrix, or by using the setMatrix() function later on. They can also
|
---|
152 | be manipulated using the translate(), rotate(), scale() and
|
---|
153 | shear() convenience functions, The currently set values can be
|
---|
154 | retrieved using the m11(), m12(), m21(), m22(), dx() and dy()
|
---|
155 | functions.
|
---|
156 |
|
---|
157 | Translation is the simplest transformation. Setting \c dx and \c
|
---|
158 | dy will move the coordinate system \c dx units along the X axis
|
---|
159 | and \c dy units along the Y axis. Scaling can be done by setting
|
---|
160 | \c m11 and \c m22. For example, setting \c m11 to 2 and \c m22 to
|
---|
161 | 1.5 will double the height and increase the width by 50%. The
|
---|
162 | identity matrix has \c m11 and \c m22 set to 1 (all others are set
|
---|
163 | to 0) mapping a point to itself. Shearing is controlled by \c m12
|
---|
164 | and \c m21. Setting these elements to values different from zero
|
---|
165 | will twist the coordinate system. Rotation is achieved by
|
---|
166 | carefully setting both the shearing factors and the scaling
|
---|
167 | factors.
|
---|
168 |
|
---|
169 | Here's the combined transformations example using basic matrix
|
---|
170 | operations:
|
---|
171 |
|
---|
172 | \table 100%
|
---|
173 | \row
|
---|
174 | \o \inlineimage qmatrix-combinedtransformation.png
|
---|
175 | \o
|
---|
176 | \snippet doc/src/snippets/matrix/matrix.cpp 2
|
---|
177 | \endtable
|
---|
178 |
|
---|
179 | \sa QPainter, QTransform, {The Coordinate System},
|
---|
180 | {demos/affine}{Affine Transformations Demo}, {Transformations Example}
|
---|
181 | */
|
---|
182 |
|
---|
183 |
|
---|
184 | // some defines to inline some code
|
---|
185 | #define MAPDOUBLE(x, y, nx, ny) \
|
---|
186 | { \
|
---|
187 | qreal fx = x; \
|
---|
188 | qreal fy = y; \
|
---|
189 | nx = _m11*fx + _m21*fy + _dx; \
|
---|
190 | ny = _m12*fx + _m22*fy + _dy; \
|
---|
191 | }
|
---|
192 |
|
---|
193 | #define MAPINT(x, y, nx, ny) \
|
---|
194 | { \
|
---|
195 | qreal fx = x; \
|
---|
196 | qreal fy = y; \
|
---|
197 | nx = qRound(_m11*fx + _m21*fy + _dx); \
|
---|
198 | ny = qRound(_m12*fx + _m22*fy + _dy); \
|
---|
199 | }
|
---|
200 |
|
---|
201 | /*****************************************************************************
|
---|
202 | QMatrix member functions
|
---|
203 | *****************************************************************************/
|
---|
204 | /*!
|
---|
205 | \fn QMatrix::QMatrix(Qt::Initialization)
|
---|
206 | \internal
|
---|
207 | */
|
---|
208 |
|
---|
209 | /*!
|
---|
210 | Constructs an identity matrix.
|
---|
211 |
|
---|
212 | All elements are set to zero except \c m11 and \c m22 (specifying
|
---|
213 | the scale), which are set to 1.
|
---|
214 |
|
---|
215 | \sa reset()
|
---|
216 | */
|
---|
217 |
|
---|
218 | QMatrix::QMatrix()
|
---|
219 | : _m11(1.)
|
---|
220 | , _m12(0.)
|
---|
221 | , _m21(0.)
|
---|
222 | , _m22(1.)
|
---|
223 | , _dx(0.)
|
---|
224 | , _dy(0.)
|
---|
225 | {
|
---|
226 | }
|
---|
227 |
|
---|
228 | /*!
|
---|
229 | Constructs a matrix with the elements, \a m11, \a m12, \a m21, \a
|
---|
230 | m22, \a dx and \a dy.
|
---|
231 |
|
---|
232 | \sa setMatrix()
|
---|
233 | */
|
---|
234 |
|
---|
235 | QMatrix::QMatrix(qreal m11, qreal m12, qreal m21, qreal m22, qreal dx, qreal dy)
|
---|
236 | : _m11(m11)
|
---|
237 | , _m12(m12)
|
---|
238 | , _m21(m21)
|
---|
239 | , _m22(m22)
|
---|
240 | , _dx(dx)
|
---|
241 | , _dy(dy)
|
---|
242 | {
|
---|
243 | }
|
---|
244 |
|
---|
245 |
|
---|
246 | /*!
|
---|
247 | Constructs a matrix that is a copy of the given \a matrix.
|
---|
248 | */
|
---|
249 | QMatrix::QMatrix(const QMatrix &matrix)
|
---|
250 | : _m11(matrix._m11)
|
---|
251 | , _m12(matrix._m12)
|
---|
252 | , _m21(matrix._m21)
|
---|
253 | , _m22(matrix._m22)
|
---|
254 | , _dx(matrix._dx)
|
---|
255 | , _dy(matrix._dy)
|
---|
256 | {
|
---|
257 | }
|
---|
258 |
|
---|
259 | /*!
|
---|
260 | Sets the matrix elements to the specified values, \a m11, \a m12,
|
---|
261 | \a m21, \a m22, \a dx and \a dy.
|
---|
262 |
|
---|
263 | Note that this function replaces the previous values. QMatrix
|
---|
264 | provide the translate(), rotate(), scale() and shear() convenience
|
---|
265 | functions to manipulate the various matrix elements based on the
|
---|
266 | currently defined coordinate system.
|
---|
267 |
|
---|
268 | \sa QMatrix()
|
---|
269 | */
|
---|
270 |
|
---|
271 | void QMatrix::setMatrix(qreal m11, qreal m12, qreal m21, qreal m22, qreal dx, qreal dy)
|
---|
272 | {
|
---|
273 | _m11 = m11;
|
---|
274 | _m12 = m12;
|
---|
275 | _m21 = m21;
|
---|
276 | _m22 = m22;
|
---|
277 | _dx = dx;
|
---|
278 | _dy = dy;
|
---|
279 | }
|
---|
280 |
|
---|
281 |
|
---|
282 | /*!
|
---|
283 | \fn qreal QMatrix::m11() const
|
---|
284 |
|
---|
285 | Returns the horizontal scaling factor.
|
---|
286 |
|
---|
287 | \sa scale(), {QMatrix#Basic Matrix Operations}{Basic Matrix
|
---|
288 | Operations}
|
---|
289 | */
|
---|
290 |
|
---|
291 | /*!
|
---|
292 | \fn qreal QMatrix::m12() const
|
---|
293 |
|
---|
294 | Returns the vertical shearing factor.
|
---|
295 |
|
---|
296 | \sa shear(), {QMatrix#Basic Matrix Operations}{Basic Matrix
|
---|
297 | Operations}
|
---|
298 | */
|
---|
299 |
|
---|
300 | /*!
|
---|
301 | \fn qreal QMatrix::m21() const
|
---|
302 |
|
---|
303 | Returns the horizontal shearing factor.
|
---|
304 |
|
---|
305 | \sa shear(), {QMatrix#Basic Matrix Operations}{Basic Matrix
|
---|
306 | Operations}
|
---|
307 | */
|
---|
308 |
|
---|
309 | /*!
|
---|
310 | \fn qreal QMatrix::m22() const
|
---|
311 |
|
---|
312 | Returns the vertical scaling factor.
|
---|
313 |
|
---|
314 | \sa scale(), {QMatrix#Basic Matrix Operations}{Basic Matrix
|
---|
315 | Operations}
|
---|
316 | */
|
---|
317 |
|
---|
318 | /*!
|
---|
319 | \fn qreal QMatrix::dx() const
|
---|
320 |
|
---|
321 | Returns the horizontal translation factor.
|
---|
322 |
|
---|
323 | \sa translate(), {QMatrix#Basic Matrix Operations}{Basic Matrix
|
---|
324 | Operations}
|
---|
325 | */
|
---|
326 |
|
---|
327 | /*!
|
---|
328 | \fn qreal QMatrix::dy() const
|
---|
329 |
|
---|
330 | Returns the vertical translation factor.
|
---|
331 |
|
---|
332 | \sa translate(), {QMatrix#Basic Matrix Operations}{Basic Matrix
|
---|
333 | Operations}
|
---|
334 | */
|
---|
335 |
|
---|
336 |
|
---|
337 | /*!
|
---|
338 | Maps the given coordinates \a x and \a y into the coordinate
|
---|
339 | system defined by this matrix. The resulting values are put in *\a
|
---|
340 | tx and *\a ty, respectively.
|
---|
341 |
|
---|
342 | The coordinates are transformed using the following formulas:
|
---|
343 |
|
---|
344 | \snippet doc/src/snippets/code/src_gui_painting_qmatrix.cpp 1
|
---|
345 |
|
---|
346 | The point (x, y) is the original point, and (x', y') is the
|
---|
347 | transformed point.
|
---|
348 |
|
---|
349 | \sa {QMatrix#Basic Matrix Operations}{Basic Matrix Operations}
|
---|
350 | */
|
---|
351 |
|
---|
352 | void QMatrix::map(qreal x, qreal y, qreal *tx, qreal *ty) const
|
---|
353 | {
|
---|
354 | MAPDOUBLE(x, y, *tx, *ty);
|
---|
355 | }
|
---|
356 |
|
---|
357 |
|
---|
358 |
|
---|
359 | /*!
|
---|
360 | \overload
|
---|
361 |
|
---|
362 | Maps the given coordinates \a x and \a y into the coordinate
|
---|
363 | system defined by this matrix. The resulting values are put in *\a
|
---|
364 | tx and *\a ty, respectively. Note that the transformed coordinates
|
---|
365 | are rounded to the nearest integer.
|
---|
366 | */
|
---|
367 |
|
---|
368 | void QMatrix::map(int x, int y, int *tx, int *ty) const
|
---|
369 | {
|
---|
370 | MAPINT(x, y, *tx, *ty);
|
---|
371 | }
|
---|
372 |
|
---|
373 | QRect QMatrix::mapRect(const QRect &rect) const
|
---|
374 | {
|
---|
375 | QRect result;
|
---|
376 | if (_m12 == 0.0F && _m21 == 0.0F) {
|
---|
377 | int x = qRound(_m11*rect.x() + _dx);
|
---|
378 | int y = qRound(_m22*rect.y() + _dy);
|
---|
379 | int w = qRound(_m11*rect.width());
|
---|
380 | int h = qRound(_m22*rect.height());
|
---|
381 | if (w < 0) {
|
---|
382 | w = -w;
|
---|
383 | x -= w;
|
---|
384 | }
|
---|
385 | if (h < 0) {
|
---|
386 | h = -h;
|
---|
387 | y -= h;
|
---|
388 | }
|
---|
389 | result = QRect(x, y, w, h);
|
---|
390 | } else {
|
---|
391 | // see mapToPolygon for explanations of the algorithm.
|
---|
392 | qreal x0, y0;
|
---|
393 | qreal x, y;
|
---|
394 | MAPDOUBLE(rect.left(), rect.top(), x0, y0);
|
---|
395 | qreal xmin = x0;
|
---|
396 | qreal ymin = y0;
|
---|
397 | qreal xmax = x0;
|
---|
398 | qreal ymax = y0;
|
---|
399 | MAPDOUBLE(rect.right() + 1, rect.top(), x, y);
|
---|
400 | xmin = qMin(xmin, x);
|
---|
401 | ymin = qMin(ymin, y);
|
---|
402 | xmax = qMax(xmax, x);
|
---|
403 | ymax = qMax(ymax, y);
|
---|
404 | MAPDOUBLE(rect.right() + 1, rect.bottom() + 1, x, y);
|
---|
405 | xmin = qMin(xmin, x);
|
---|
406 | ymin = qMin(ymin, y);
|
---|
407 | xmax = qMax(xmax, x);
|
---|
408 | ymax = qMax(ymax, y);
|
---|
409 | MAPDOUBLE(rect.left(), rect.bottom() + 1, x, y);
|
---|
410 | xmin = qMin(xmin, x);
|
---|
411 | ymin = qMin(ymin, y);
|
---|
412 | xmax = qMax(xmax, x);
|
---|
413 | ymax = qMax(ymax, y);
|
---|
414 | result = QRect(qRound(xmin), qRound(ymin), qRound(xmax)-qRound(xmin), qRound(ymax)-qRound(ymin));
|
---|
415 | }
|
---|
416 | return result;
|
---|
417 | }
|
---|
418 |
|
---|
419 | /*!
|
---|
420 | \fn QRectF QMatrix::mapRect(const QRectF &rectangle) const
|
---|
421 |
|
---|
422 | Creates and returns a QRectF object that is a copy of the given \a
|
---|
423 | rectangle, mapped into the coordinate system defined by this
|
---|
424 | matrix.
|
---|
425 |
|
---|
426 | The rectangle's coordinates are transformed using the following
|
---|
427 | formulas:
|
---|
428 |
|
---|
429 | \snippet doc/src/snippets/code/src_gui_painting_qmatrix.cpp 2
|
---|
430 |
|
---|
431 | If rotation or shearing has been specified, this function returns
|
---|
432 | the \e bounding rectangle. To retrieve the exact region the given
|
---|
433 | \a rectangle maps to, use the mapToPolygon() function instead.
|
---|
434 |
|
---|
435 | \sa mapToPolygon(), {QMatrix#Basic Matrix Operations}{Basic Matrix
|
---|
436 | Operations}
|
---|
437 | */
|
---|
438 | QRectF QMatrix::mapRect(const QRectF &rect) const
|
---|
439 | {
|
---|
440 | QRectF result;
|
---|
441 | if (_m12 == 0.0F && _m21 == 0.0F) {
|
---|
442 | qreal x = _m11*rect.x() + _dx;
|
---|
443 | qreal y = _m22*rect.y() + _dy;
|
---|
444 | qreal w = _m11*rect.width();
|
---|
445 | qreal h = _m22*rect.height();
|
---|
446 | if (w < 0) {
|
---|
447 | w = -w;
|
---|
448 | x -= w;
|
---|
449 | }
|
---|
450 | if (h < 0) {
|
---|
451 | h = -h;
|
---|
452 | y -= h;
|
---|
453 | }
|
---|
454 | result = QRectF(x, y, w, h);
|
---|
455 | } else {
|
---|
456 | qreal x0, y0;
|
---|
457 | qreal x, y;
|
---|
458 | MAPDOUBLE(rect.x(), rect.y(), x0, y0);
|
---|
459 | qreal xmin = x0;
|
---|
460 | qreal ymin = y0;
|
---|
461 | qreal xmax = x0;
|
---|
462 | qreal ymax = y0;
|
---|
463 | MAPDOUBLE(rect.x() + rect.width(), rect.y(), x, y);
|
---|
464 | xmin = qMin(xmin, x);
|
---|
465 | ymin = qMin(ymin, y);
|
---|
466 | xmax = qMax(xmax, x);
|
---|
467 | ymax = qMax(ymax, y);
|
---|
468 | MAPDOUBLE(rect.x() + rect.width(), rect.y() + rect.height(), x, y);
|
---|
469 | xmin = qMin(xmin, x);
|
---|
470 | ymin = qMin(ymin, y);
|
---|
471 | xmax = qMax(xmax, x);
|
---|
472 | ymax = qMax(ymax, y);
|
---|
473 | MAPDOUBLE(rect.x(), rect.y() + rect.height(), x, y);
|
---|
474 | xmin = qMin(xmin, x);
|
---|
475 | ymin = qMin(ymin, y);
|
---|
476 | xmax = qMax(xmax, x);
|
---|
477 | ymax = qMax(ymax, y);
|
---|
478 | result = QRectF(xmin, ymin, xmax-xmin, ymax - ymin);
|
---|
479 | }
|
---|
480 | return result;
|
---|
481 | }
|
---|
482 |
|
---|
483 | /*!
|
---|
484 | \fn QRect QMatrix::mapRect(const QRect &rectangle) const
|
---|
485 | \overload
|
---|
486 |
|
---|
487 | Creates and returns a QRect object that is a copy of the given \a
|
---|
488 | rectangle, mapped into the coordinate system defined by this
|
---|
489 | matrix. Note that the transformed coordinates are rounded to the
|
---|
490 | nearest integer.
|
---|
491 | */
|
---|
492 |
|
---|
493 |
|
---|
494 | /*!
|
---|
495 | \fn QPoint operator*(const QPoint &point, const QMatrix &matrix)
|
---|
496 | \relates QMatrix
|
---|
497 |
|
---|
498 | This is the same as \a{matrix}.map(\a{point}).
|
---|
499 |
|
---|
500 | \sa QMatrix::map()
|
---|
501 | */
|
---|
502 |
|
---|
503 | QPoint QMatrix::map(const QPoint &p) const
|
---|
504 | {
|
---|
505 | qreal fx = p.x();
|
---|
506 | qreal fy = p.y();
|
---|
507 | return QPoint(qRound(_m11*fx + _m21*fy + _dx),
|
---|
508 | qRound(_m12*fx + _m22*fy + _dy));
|
---|
509 | }
|
---|
510 |
|
---|
511 | /*!
|
---|
512 | \fn QPointF operator*(const QPointF &point, const QMatrix &matrix)
|
---|
513 | \relates QMatrix
|
---|
514 |
|
---|
515 | Same as \a{matrix}.map(\a{point}).
|
---|
516 |
|
---|
517 | \sa QMatrix::map()
|
---|
518 | */
|
---|
519 |
|
---|
520 | /*!
|
---|
521 | \overload
|
---|
522 |
|
---|
523 | Creates and returns a QPointF object that is a copy of the given
|
---|
524 | \a point, mapped into the coordinate system defined by this
|
---|
525 | matrix.
|
---|
526 | */
|
---|
527 | QPointF QMatrix::map(const QPointF &point) const
|
---|
528 | {
|
---|
529 | qreal fx = point.x();
|
---|
530 | qreal fy = point.y();
|
---|
531 | return QPointF(_m11*fx + _m21*fy + _dx, _m12*fx + _m22*fy + _dy);
|
---|
532 | }
|
---|
533 |
|
---|
534 | /*!
|
---|
535 | \fn QPoint QMatrix::map(const QPoint &point) const
|
---|
536 | \overload
|
---|
537 |
|
---|
538 | Creates and returns a QPoint object that is a copy of the given \a
|
---|
539 | point, mapped into the coordinate system defined by this
|
---|
540 | matrix. Note that the transformed coordinates are rounded to the
|
---|
541 | nearest integer.
|
---|
542 | */
|
---|
543 |
|
---|
544 | /*!
|
---|
545 | \fn QLineF operator*(const QLineF &line, const QMatrix &matrix)
|
---|
546 | \relates QMatrix
|
---|
547 |
|
---|
548 | This is the same as \a{matrix}.map(\a{line}).
|
---|
549 |
|
---|
550 | \sa QMatrix::map()
|
---|
551 | */
|
---|
552 |
|
---|
553 | /*!
|
---|
554 | \fn QLine operator*(const QLine &line, const QMatrix &matrix)
|
---|
555 | \relates QMatrix
|
---|
556 |
|
---|
557 | This is the same as \a{matrix}.map(\a{line}).
|
---|
558 |
|
---|
559 | \sa QMatrix::map()
|
---|
560 | */
|
---|
561 |
|
---|
562 | /*!
|
---|
563 | \overload
|
---|
564 |
|
---|
565 | Creates and returns a QLineF object that is a copy of the given \a
|
---|
566 | line, mapped into the coordinate system defined by this matrix.
|
---|
567 | */
|
---|
568 | QLineF QMatrix::map(const QLineF &line) const
|
---|
569 | {
|
---|
570 | return QLineF(map(line.p1()), map(line.p2()));
|
---|
571 | }
|
---|
572 |
|
---|
573 | /*!
|
---|
574 | \overload
|
---|
575 |
|
---|
576 | Creates and returns a QLine object that is a copy of the given \a
|
---|
577 | line, mapped into the coordinate system defined by this matrix.
|
---|
578 | Note that the transformed coordinates are rounded to the nearest
|
---|
579 | integer.
|
---|
580 | */
|
---|
581 | QLine QMatrix::map(const QLine &line) const
|
---|
582 | {
|
---|
583 | return QLine(map(line.p1()), map(line.p2()));
|
---|
584 | }
|
---|
585 |
|
---|
586 | /*!
|
---|
587 | \fn QPolygonF operator *(const QPolygonF &polygon, const QMatrix &matrix)
|
---|
588 | \relates QMatrix
|
---|
589 |
|
---|
590 | This is the same as \a{matrix}.map(\a{polygon}).
|
---|
591 |
|
---|
592 | \sa QMatrix::map()
|
---|
593 | */
|
---|
594 |
|
---|
595 | /*!
|
---|
596 | \fn QPolygon operator*(const QPolygon &polygon, const QMatrix &matrix)
|
---|
597 | \relates QMatrix
|
---|
598 |
|
---|
599 | This is the same as \a{matrix}.map(\a{polygon}).
|
---|
600 |
|
---|
601 | \sa QMatrix::map()
|
---|
602 | */
|
---|
603 |
|
---|
604 | QPolygon QMatrix::map(const QPolygon &a) const
|
---|
605 | {
|
---|
606 | int size = a.size();
|
---|
607 | int i;
|
---|
608 | QPolygon p(size);
|
---|
609 | const QPoint *da = a.constData();
|
---|
610 | QPoint *dp = p.data();
|
---|
611 | for(i = 0; i < size; i++) {
|
---|
612 | MAPINT(da[i].x(), da[i].y(), dp[i].rx(), dp[i].ry());
|
---|
613 | }
|
---|
614 | return p;
|
---|
615 | }
|
---|
616 |
|
---|
617 | /*!
|
---|
618 | \fn QPolygonF QMatrix::map(const QPolygonF &polygon) const
|
---|
619 | \overload
|
---|
620 |
|
---|
621 | Creates and returns a QPolygonF object that is a copy of the given
|
---|
622 | \a polygon, mapped into the coordinate system defined by this
|
---|
623 | matrix.
|
---|
624 | */
|
---|
625 | QPolygonF QMatrix::map(const QPolygonF &a) const
|
---|
626 | {
|
---|
627 | int size = a.size();
|
---|
628 | int i;
|
---|
629 | QPolygonF p(size);
|
---|
630 | const QPointF *da = a.constData();
|
---|
631 | QPointF *dp = p.data();
|
---|
632 | for(i = 0; i < size; i++) {
|
---|
633 | MAPDOUBLE(da[i].xp, da[i].yp, dp[i].xp, dp[i].yp);
|
---|
634 | }
|
---|
635 | return p;
|
---|
636 | }
|
---|
637 |
|
---|
638 | /*!
|
---|
639 | \fn QPolygon QMatrix::map(const QPolygon &polygon) const
|
---|
640 | \overload
|
---|
641 |
|
---|
642 | Creates and returns a QPolygon object that is a copy of the given
|
---|
643 | \a polygon, mapped into the coordinate system defined by this
|
---|
644 | matrix. Note that the transformed coordinates are rounded to the
|
---|
645 | nearest integer.
|
---|
646 | */
|
---|
647 |
|
---|
648 | /*!
|
---|
649 | \fn QRegion operator*(const QRegion ®ion, const QMatrix &matrix)
|
---|
650 | \relates QMatrix
|
---|
651 |
|
---|
652 | This is the same as \a{matrix}.map(\a{region}).
|
---|
653 |
|
---|
654 | \sa QMatrix::map()
|
---|
655 | */
|
---|
656 |
|
---|
657 | extern QPainterPath qt_regionToPath(const QRegion ®ion);
|
---|
658 |
|
---|
659 | /*!
|
---|
660 | \fn QRegion QMatrix::map(const QRegion ®ion) const
|
---|
661 | \overload
|
---|
662 |
|
---|
663 | Creates and returns a QRegion object that is a copy of the given
|
---|
664 | \a region, mapped into the coordinate system defined by this matrix.
|
---|
665 |
|
---|
666 | Calling this method can be rather expensive if rotations or
|
---|
667 | shearing are used.
|
---|
668 | */
|
---|
669 | QRegion QMatrix::map(const QRegion &r) const
|
---|
670 | {
|
---|
671 | if (_m11 == 1.0 && _m22 == 1.0 && _m12 == 0.0 && _m21 == 0.0) { // translate or identity
|
---|
672 | if (_dx == 0.0 && _dy == 0.0) // Identity
|
---|
673 | return r;
|
---|
674 | QRegion copy(r);
|
---|
675 | copy.translate(qRound(_dx), qRound(_dy));
|
---|
676 | return copy;
|
---|
677 | }
|
---|
678 |
|
---|
679 | QPainterPath p = map(qt_regionToPath(r));
|
---|
680 | return p.toFillPolygon().toPolygon();
|
---|
681 | }
|
---|
682 |
|
---|
683 | /*!
|
---|
684 | \fn QPainterPath operator *(const QPainterPath &path, const QMatrix &matrix)
|
---|
685 | \relates QMatrix
|
---|
686 |
|
---|
687 | This is the same as \a{matrix}.map(\a{path}).
|
---|
688 |
|
---|
689 | \sa QMatrix::map()
|
---|
690 | */
|
---|
691 |
|
---|
692 | /*!
|
---|
693 | \overload
|
---|
694 |
|
---|
695 | Creates and returns a QPainterPath object that is a copy of the
|
---|
696 | given \a path, mapped into the coordinate system defined by this
|
---|
697 | matrix.
|
---|
698 | */
|
---|
699 | QPainterPath QMatrix::map(const QPainterPath &path) const
|
---|
700 | {
|
---|
701 | if (path.isEmpty())
|
---|
702 | return QPainterPath();
|
---|
703 |
|
---|
704 | QPainterPath copy = path;
|
---|
705 |
|
---|
706 | // Translate or identity
|
---|
707 | if (_m11 == 1.0 && _m22 == 1.0 && _m12 == 0.0 && _m21 == 0.0) {
|
---|
708 |
|
---|
709 | // Translate
|
---|
710 | if (_dx != 0.0 || _dy != 0.0) {
|
---|
711 | copy.detach();
|
---|
712 | for (int i=0; i<path.elementCount(); ++i) {
|
---|
713 | QPainterPath::Element &e = copy.d_ptr->elements[i];
|
---|
714 | e.x += _dx;
|
---|
715 | e.y += _dy;
|
---|
716 | }
|
---|
717 | }
|
---|
718 |
|
---|
719 | // Full xform
|
---|
720 | } else {
|
---|
721 | copy.detach();
|
---|
722 | for (int i=0; i<path.elementCount(); ++i) {
|
---|
723 | QPainterPath::Element &e = copy.d_ptr->elements[i];
|
---|
724 | qreal fx = e.x, fy = e.y;
|
---|
725 | e.x = _m11*fx + _m21*fy + _dx;
|
---|
726 | e.y = _m12*fx + _m22*fy + _dy;
|
---|
727 | }
|
---|
728 | }
|
---|
729 |
|
---|
730 | return copy;
|
---|
731 | }
|
---|
732 |
|
---|
733 | /*!
|
---|
734 | \fn QRegion QMatrix::mapToRegion(const QRect &rectangle) const
|
---|
735 |
|
---|
736 | Returns the transformed rectangle \a rectangle as a QRegion
|
---|
737 | object. A rectangle which has been rotated or sheared may result
|
---|
738 | in a non-rectangular region being returned.
|
---|
739 |
|
---|
740 | Use the mapToPolygon() or map() function instead.
|
---|
741 | */
|
---|
742 | #ifdef QT3_SUPPORT
|
---|
743 | QRegion QMatrix::mapToRegion(const QRect &rect) const
|
---|
744 | {
|
---|
745 | QRegion result;
|
---|
746 | if (isIdentity()) {
|
---|
747 | result = rect;
|
---|
748 | } else if (m12() == 0.0F && m21() == 0.0F) {
|
---|
749 | int x = qRound(m11()*rect.x() + dx());
|
---|
750 | int y = qRound(m22()*rect.y() + dy());
|
---|
751 | int w = qRound(m11()*rect.width());
|
---|
752 | int h = qRound(m22()*rect.height());
|
---|
753 | if (w < 0) {
|
---|
754 | w = -w;
|
---|
755 | x -= w - 1;
|
---|
756 | }
|
---|
757 | if (h < 0) {
|
---|
758 | h = -h;
|
---|
759 | y -= h - 1;
|
---|
760 | }
|
---|
761 | result = QRect(x, y, w, h);
|
---|
762 | } else {
|
---|
763 | result = QRegion(mapToPolygon(rect));
|
---|
764 | }
|
---|
765 | return result;
|
---|
766 |
|
---|
767 | }
|
---|
768 | #endif
|
---|
769 | /*!
|
---|
770 | \fn QPolygon QMatrix::mapToPolygon(const QRect &rectangle) const
|
---|
771 |
|
---|
772 | Creates and returns a QPolygon representation of the given \a
|
---|
773 | rectangle, mapped into the coordinate system defined by this
|
---|
774 | matrix.
|
---|
775 |
|
---|
776 | The rectangle's coordinates are transformed using the following
|
---|
777 | formulas:
|
---|
778 |
|
---|
779 | \snippet doc/src/snippets/code/src_gui_painting_qmatrix.cpp 3
|
---|
780 |
|
---|
781 | Polygons and rectangles behave slightly differently when
|
---|
782 | transformed (due to integer rounding), so
|
---|
783 | \c{matrix.map(QPolygon(rectangle))} is not always the same as
|
---|
784 | \c{matrix.mapToPolygon(rectangle)}.
|
---|
785 |
|
---|
786 | \sa mapRect(), {QMatrix#Basic Matrix Operations}{Basic Matrix
|
---|
787 | Operations}
|
---|
788 | */
|
---|
789 | QPolygon QMatrix::mapToPolygon(const QRect &rect) const
|
---|
790 | {
|
---|
791 | QPolygon a(4);
|
---|
792 | qreal x[4], y[4];
|
---|
793 | if (_m12 == 0.0F && _m21 == 0.0F) {
|
---|
794 | x[0] = _m11*rect.x() + _dx;
|
---|
795 | y[0] = _m22*rect.y() + _dy;
|
---|
796 | qreal w = _m11*rect.width();
|
---|
797 | qreal h = _m22*rect.height();
|
---|
798 | if (w < 0) {
|
---|
799 | w = -w;
|
---|
800 | x[0] -= w;
|
---|
801 | }
|
---|
802 | if (h < 0) {
|
---|
803 | h = -h;
|
---|
804 | y[0] -= h;
|
---|
805 | }
|
---|
806 | x[1] = x[0]+w;
|
---|
807 | x[2] = x[1];
|
---|
808 | x[3] = x[0];
|
---|
809 | y[1] = y[0];
|
---|
810 | y[2] = y[0]+h;
|
---|
811 | y[3] = y[2];
|
---|
812 | } else {
|
---|
813 | qreal right = rect.x() + rect.width();
|
---|
814 | qreal bottom = rect.y() + rect.height();
|
---|
815 | MAPDOUBLE(rect.x(), rect.y(), x[0], y[0]);
|
---|
816 | MAPDOUBLE(right, rect.y(), x[1], y[1]);
|
---|
817 | MAPDOUBLE(right, bottom, x[2], y[2]);
|
---|
818 | MAPDOUBLE(rect.x(), bottom, x[3], y[3]);
|
---|
819 | }
|
---|
820 | #if 0
|
---|
821 | int i;
|
---|
822 | for(i = 0; i< 4; i++)
|
---|
823 | qDebug("coords(%d) = (%f/%f) (%d/%d)", i, x[i], y[i], qRound(x[i]), qRound(y[i]));
|
---|
824 | qDebug("width=%f, height=%f", qSqrt((x[1]-x[0])*(x[1]-x[0]) + (y[1]-y[0])*(y[1]-y[0])),
|
---|
825 | qSqrt((x[0]-x[3])*(x[0]-x[3]) + (y[0]-y[3])*(y[0]-y[3])));
|
---|
826 | #endif
|
---|
827 | // all coordinates are correctly, tranform to a pointarray
|
---|
828 | // (rounding to the next integer)
|
---|
829 | a.setPoints(4, qRound(x[0]), qRound(y[0]),
|
---|
830 | qRound(x[1]), qRound(y[1]),
|
---|
831 | qRound(x[2]), qRound(y[2]),
|
---|
832 | qRound(x[3]), qRound(y[3]));
|
---|
833 | return a;
|
---|
834 | }
|
---|
835 |
|
---|
836 | /*!
|
---|
837 | Resets the matrix to an identity matrix, i.e. all elements are set
|
---|
838 | to zero, except \c m11 and \c m22 (specifying the scale) which are
|
---|
839 | set to 1.
|
---|
840 |
|
---|
841 | \sa QMatrix(), isIdentity(), {QMatrix#Basic Matrix
|
---|
842 | Operations}{Basic Matrix Operations}
|
---|
843 | */
|
---|
844 |
|
---|
845 | void QMatrix::reset()
|
---|
846 | {
|
---|
847 | _m11 = _m22 = 1.0;
|
---|
848 | _m12 = _m21 = _dx = _dy = 0.0;
|
---|
849 | }
|
---|
850 |
|
---|
851 | /*!
|
---|
852 | \fn bool QMatrix::isIdentity() const
|
---|
853 |
|
---|
854 | Returns true if the matrix is the identity matrix, otherwise
|
---|
855 | returns false.
|
---|
856 |
|
---|
857 | \sa reset()
|
---|
858 | */
|
---|
859 |
|
---|
860 | /*!
|
---|
861 | Moves the coordinate system \a dx along the x axis and \a dy along
|
---|
862 | the y axis, and returns a reference to the matrix.
|
---|
863 |
|
---|
864 | \sa setMatrix()
|
---|
865 | */
|
---|
866 |
|
---|
867 | QMatrix &QMatrix::translate(qreal dx, qreal dy)
|
---|
868 | {
|
---|
869 | _dx += dx*_m11 + dy*_m21;
|
---|
870 | _dy += dy*_m22 + dx*_m12;
|
---|
871 | return *this;
|
---|
872 | }
|
---|
873 |
|
---|
874 | /*!
|
---|
875 | \fn QMatrix &QMatrix::scale(qreal sx, qreal sy)
|
---|
876 |
|
---|
877 | Scales the coordinate system by \a sx horizontally and \a sy
|
---|
878 | vertically, and returns a reference to the matrix.
|
---|
879 |
|
---|
880 | \sa setMatrix()
|
---|
881 | */
|
---|
882 |
|
---|
883 | QMatrix &QMatrix::scale(qreal sx, qreal sy)
|
---|
884 | {
|
---|
885 | _m11 *= sx;
|
---|
886 | _m12 *= sx;
|
---|
887 | _m21 *= sy;
|
---|
888 | _m22 *= sy;
|
---|
889 | return *this;
|
---|
890 | }
|
---|
891 |
|
---|
892 | /*!
|
---|
893 | Shears the coordinate system by \a sh horizontally and \a sv
|
---|
894 | vertically, and returns a reference to the matrix.
|
---|
895 |
|
---|
896 | \sa setMatrix()
|
---|
897 | */
|
---|
898 |
|
---|
899 | QMatrix &QMatrix::shear(qreal sh, qreal sv)
|
---|
900 | {
|
---|
901 | qreal tm11 = sv*_m21;
|
---|
902 | qreal tm12 = sv*_m22;
|
---|
903 | qreal tm21 = sh*_m11;
|
---|
904 | qreal tm22 = sh*_m12;
|
---|
905 | _m11 += tm11;
|
---|
906 | _m12 += tm12;
|
---|
907 | _m21 += tm21;
|
---|
908 | _m22 += tm22;
|
---|
909 | return *this;
|
---|
910 | }
|
---|
911 |
|
---|
912 | const qreal deg2rad = qreal(0.017453292519943295769); // pi/180
|
---|
913 |
|
---|
914 | /*!
|
---|
915 | \fn QMatrix &QMatrix::rotate(qreal degrees)
|
---|
916 |
|
---|
917 | Rotates the coordinate system the given \a degrees
|
---|
918 | counterclockwise.
|
---|
919 |
|
---|
920 | Note that if you apply a QMatrix to a point defined in widget
|
---|
921 | coordinates, the direction of the rotation will be clockwise
|
---|
922 | because the y-axis points downwards.
|
---|
923 |
|
---|
924 | Returns a reference to the matrix.
|
---|
925 |
|
---|
926 | \sa setMatrix()
|
---|
927 | */
|
---|
928 |
|
---|
929 | QMatrix &QMatrix::rotate(qreal a)
|
---|
930 | {
|
---|
931 | qreal sina = 0;
|
---|
932 | qreal cosa = 0;
|
---|
933 | if (a == 90. || a == -270.)
|
---|
934 | sina = 1.;
|
---|
935 | else if (a == 270. || a == -90.)
|
---|
936 | sina = -1.;
|
---|
937 | else if (a == 180.)
|
---|
938 | cosa = -1.;
|
---|
939 | else{
|
---|
940 | qreal b = deg2rad*a; // convert to radians
|
---|
941 | sina = qSin(b); // fast and convenient
|
---|
942 | cosa = qCos(b);
|
---|
943 | }
|
---|
944 | qreal tm11 = cosa*_m11 + sina*_m21;
|
---|
945 | qreal tm12 = cosa*_m12 + sina*_m22;
|
---|
946 | qreal tm21 = -sina*_m11 + cosa*_m21;
|
---|
947 | qreal tm22 = -sina*_m12 + cosa*_m22;
|
---|
948 | _m11 = tm11; _m12 = tm12;
|
---|
949 | _m21 = tm21; _m22 = tm22;
|
---|
950 | return *this;
|
---|
951 | }
|
---|
952 |
|
---|
953 | /*!
|
---|
954 | \fn bool QMatrix::isInvertible() const
|
---|
955 |
|
---|
956 | Returns true if the matrix is invertible, otherwise returns false.
|
---|
957 |
|
---|
958 | \sa inverted()
|
---|
959 | */
|
---|
960 |
|
---|
961 | /*!
|
---|
962 | \obsolete
|
---|
963 | \fn qreal QMatrix::det() const
|
---|
964 |
|
---|
965 | Returns the matrix's determinant.
|
---|
966 |
|
---|
967 | \sa determinant()
|
---|
968 | */
|
---|
969 |
|
---|
970 | /*!
|
---|
971 | \since 4.6
|
---|
972 | \fn qreal QMatrix::determinant() const
|
---|
973 |
|
---|
974 | Returns the matrix's determinant.
|
---|
975 | */
|
---|
976 |
|
---|
977 | /*!
|
---|
978 | \fn QMatrix QMatrix::invert(bool *invertible) const
|
---|
979 |
|
---|
980 | Returns an inverted copy of this matrix.
|
---|
981 |
|
---|
982 | Use the inverted() function instead.
|
---|
983 | */
|
---|
984 |
|
---|
985 | /*!
|
---|
986 | Returns an inverted copy of this matrix.
|
---|
987 |
|
---|
988 | If the matrix is singular (not invertible), the returned matrix is
|
---|
989 | the identity matrix. If \a invertible is valid (i.e. not 0), its
|
---|
990 | value is set to true if the matrix is invertible, otherwise it is
|
---|
991 | set to false.
|
---|
992 |
|
---|
993 | \sa isInvertible()
|
---|
994 | */
|
---|
995 |
|
---|
996 | QMatrix QMatrix::inverted(bool *invertible) const
|
---|
997 | {
|
---|
998 | qreal dtr = determinant();
|
---|
999 | if (dtr == 0.0) {
|
---|
1000 | if (invertible)
|
---|
1001 | *invertible = false; // singular matrix
|
---|
1002 | return QMatrix(true);
|
---|
1003 | }
|
---|
1004 | else { // invertible matrix
|
---|
1005 | if (invertible)
|
---|
1006 | *invertible = true;
|
---|
1007 | qreal dinv = 1.0/dtr;
|
---|
1008 | return QMatrix((_m22*dinv), (-_m12*dinv),
|
---|
1009 | (-_m21*dinv), (_m11*dinv),
|
---|
1010 | ((_m21*_dy - _m22*_dx)*dinv),
|
---|
1011 | ((_m12*_dx - _m11*_dy)*dinv),
|
---|
1012 | true);
|
---|
1013 | }
|
---|
1014 | }
|
---|
1015 |
|
---|
1016 |
|
---|
1017 | /*!
|
---|
1018 | \fn bool QMatrix::operator==(const QMatrix &matrix) const
|
---|
1019 |
|
---|
1020 | Returns true if this matrix is equal to the given \a matrix,
|
---|
1021 | otherwise returns false.
|
---|
1022 | */
|
---|
1023 |
|
---|
1024 | bool QMatrix::operator==(const QMatrix &m) const
|
---|
1025 | {
|
---|
1026 | return _m11 == m._m11 &&
|
---|
1027 | _m12 == m._m12 &&
|
---|
1028 | _m21 == m._m21 &&
|
---|
1029 | _m22 == m._m22 &&
|
---|
1030 | _dx == m._dx &&
|
---|
1031 | _dy == m._dy;
|
---|
1032 | }
|
---|
1033 |
|
---|
1034 | /*!
|
---|
1035 | \fn bool QMatrix::operator!=(const QMatrix &matrix) const
|
---|
1036 |
|
---|
1037 | Returns true if this matrix is not equal to the given \a matrix,
|
---|
1038 | otherwise returns false.
|
---|
1039 | */
|
---|
1040 |
|
---|
1041 | bool QMatrix::operator!=(const QMatrix &m) const
|
---|
1042 | {
|
---|
1043 | return _m11 != m._m11 ||
|
---|
1044 | _m12 != m._m12 ||
|
---|
1045 | _m21 != m._m21 ||
|
---|
1046 | _m22 != m._m22 ||
|
---|
1047 | _dx != m._dx ||
|
---|
1048 | _dy != m._dy;
|
---|
1049 | }
|
---|
1050 |
|
---|
1051 | /*!
|
---|
1052 | \fn QMatrix &QMatrix::operator *=(const QMatrix &matrix)
|
---|
1053 | \overload
|
---|
1054 |
|
---|
1055 | Returns the result of multiplying this matrix by the given \a
|
---|
1056 | matrix.
|
---|
1057 | */
|
---|
1058 |
|
---|
1059 | QMatrix &QMatrix::operator *=(const QMatrix &m)
|
---|
1060 | {
|
---|
1061 | qreal tm11 = _m11*m._m11 + _m12*m._m21;
|
---|
1062 | qreal tm12 = _m11*m._m12 + _m12*m._m22;
|
---|
1063 | qreal tm21 = _m21*m._m11 + _m22*m._m21;
|
---|
1064 | qreal tm22 = _m21*m._m12 + _m22*m._m22;
|
---|
1065 |
|
---|
1066 | qreal tdx = _dx*m._m11 + _dy*m._m21 + m._dx;
|
---|
1067 | qreal tdy = _dx*m._m12 + _dy*m._m22 + m._dy;
|
---|
1068 |
|
---|
1069 | _m11 = tm11; _m12 = tm12;
|
---|
1070 | _m21 = tm21; _m22 = tm22;
|
---|
1071 | _dx = tdx; _dy = tdy;
|
---|
1072 | return *this;
|
---|
1073 | }
|
---|
1074 |
|
---|
1075 | /*!
|
---|
1076 | \fn QMatrix QMatrix::operator *(const QMatrix &matrix) const
|
---|
1077 |
|
---|
1078 | Returns the result of multiplying this matrix by the given \a
|
---|
1079 | matrix.
|
---|
1080 |
|
---|
1081 | Note that matrix multiplication is not commutative, i.e. a*b !=
|
---|
1082 | b*a.
|
---|
1083 | */
|
---|
1084 |
|
---|
1085 | QMatrix QMatrix::operator *(const QMatrix &m) const
|
---|
1086 | {
|
---|
1087 | qreal tm11 = _m11*m._m11 + _m12*m._m21;
|
---|
1088 | qreal tm12 = _m11*m._m12 + _m12*m._m22;
|
---|
1089 | qreal tm21 = _m21*m._m11 + _m22*m._m21;
|
---|
1090 | qreal tm22 = _m21*m._m12 + _m22*m._m22;
|
---|
1091 |
|
---|
1092 | qreal tdx = _dx*m._m11 + _dy*m._m21 + m._dx;
|
---|
1093 | qreal tdy = _dx*m._m12 + _dy*m._m22 + m._dy;
|
---|
1094 | return QMatrix(tm11, tm12, tm21, tm22, tdx, tdy, true);
|
---|
1095 | }
|
---|
1096 |
|
---|
1097 | /*!
|
---|
1098 | Assigns the given \a matrix's values to this matrix.
|
---|
1099 | */
|
---|
1100 | QMatrix &QMatrix::operator=(const QMatrix &matrix)
|
---|
1101 | {
|
---|
1102 | _m11 = matrix._m11;
|
---|
1103 | _m12 = matrix._m12;
|
---|
1104 | _m21 = matrix._m21;
|
---|
1105 | _m22 = matrix._m22;
|
---|
1106 | _dx = matrix._dx;
|
---|
1107 | _dy = matrix._dy;
|
---|
1108 | return *this;
|
---|
1109 | }
|
---|
1110 |
|
---|
1111 | /*!
|
---|
1112 | \since 4.2
|
---|
1113 |
|
---|
1114 | Returns the matrix as a QVariant.
|
---|
1115 | */
|
---|
1116 | QMatrix::operator QVariant() const
|
---|
1117 | {
|
---|
1118 | return QVariant(QVariant::Matrix, this);
|
---|
1119 | }
|
---|
1120 |
|
---|
1121 | Q_GUI_EXPORT QPainterPath operator *(const QPainterPath &p, const QMatrix &m)
|
---|
1122 | {
|
---|
1123 | return m.map(p);
|
---|
1124 | }
|
---|
1125 |
|
---|
1126 |
|
---|
1127 | /*****************************************************************************
|
---|
1128 | QMatrix stream functions
|
---|
1129 | *****************************************************************************/
|
---|
1130 | #ifndef QT_NO_DATASTREAM
|
---|
1131 | /*!
|
---|
1132 | \fn QDataStream &operator<<(QDataStream &stream, const QMatrix &matrix)
|
---|
1133 | \relates QMatrix
|
---|
1134 |
|
---|
1135 | Writes the given \a matrix to the given \a stream and returns a
|
---|
1136 | reference to the stream.
|
---|
1137 |
|
---|
1138 | \sa {Format of the QDataStream Operators}
|
---|
1139 | */
|
---|
1140 |
|
---|
1141 | QDataStream &operator<<(QDataStream &s, const QMatrix &m)
|
---|
1142 | {
|
---|
1143 | if (s.version() == 1) {
|
---|
1144 | s << (float)m.m11() << (float)m.m12() << (float)m.m21()
|
---|
1145 | << (float)m.m22() << (float)m.dx() << (float)m.dy();
|
---|
1146 | } else {
|
---|
1147 | s << double(m.m11())
|
---|
1148 | << double(m.m12())
|
---|
1149 | << double(m.m21())
|
---|
1150 | << double(m.m22())
|
---|
1151 | << double(m.dx())
|
---|
1152 | << double(m.dy());
|
---|
1153 | }
|
---|
1154 | return s;
|
---|
1155 | }
|
---|
1156 |
|
---|
1157 | /*!
|
---|
1158 | \fn QDataStream &operator>>(QDataStream &stream, QMatrix &matrix)
|
---|
1159 | \relates QMatrix
|
---|
1160 |
|
---|
1161 | Reads the given \a matrix from the given \a stream and returns a
|
---|
1162 | reference to the stream.
|
---|
1163 |
|
---|
1164 | \sa {Format of the QDataStream Operators}
|
---|
1165 | */
|
---|
1166 |
|
---|
1167 | QDataStream &operator>>(QDataStream &s, QMatrix &m)
|
---|
1168 | {
|
---|
1169 | if (s.version() == 1) {
|
---|
1170 | float m11, m12, m21, m22, dx, dy;
|
---|
1171 | s >> m11; s >> m12; s >> m21; s >> m22;
|
---|
1172 | s >> dx; s >> dy;
|
---|
1173 | m.setMatrix(m11, m12, m21, m22, dx, dy);
|
---|
1174 | }
|
---|
1175 | else {
|
---|
1176 | double m11, m12, m21, m22, dx, dy;
|
---|
1177 | s >> m11;
|
---|
1178 | s >> m12;
|
---|
1179 | s >> m21;
|
---|
1180 | s >> m22;
|
---|
1181 | s >> dx;
|
---|
1182 | s >> dy;
|
---|
1183 | m.setMatrix(m11, m12, m21, m22, dx, dy);
|
---|
1184 | }
|
---|
1185 | return s;
|
---|
1186 | }
|
---|
1187 | #endif // QT_NO_DATASTREAM
|
---|
1188 |
|
---|
1189 | #ifndef QT_NO_DEBUG_STREAM
|
---|
1190 | QDebug operator<<(QDebug dbg, const QMatrix &m)
|
---|
1191 | {
|
---|
1192 | dbg.nospace() << "QMatrix("
|
---|
1193 | << "11=" << m.m11()
|
---|
1194 | << " 12=" << m.m12()
|
---|
1195 | << " 21=" << m.m21()
|
---|
1196 | << " 22=" << m.m22()
|
---|
1197 | << " dx=" << m.dx()
|
---|
1198 | << " dy=" << m.dy()
|
---|
1199 | << ')';
|
---|
1200 | return dbg.space();
|
---|
1201 | }
|
---|
1202 | #endif
|
---|
1203 |
|
---|
1204 | /*!
|
---|
1205 | \fn QRect QMatrix::map(const QRect &rect) const
|
---|
1206 | \compat
|
---|
1207 |
|
---|
1208 | Creates and returns a QRect object that is a copy of the given
|
---|
1209 | rectangle, mapped into the coordinate system defined by this
|
---|
1210 | matrix.
|
---|
1211 |
|
---|
1212 | Use the mapRect() function instead.
|
---|
1213 | */
|
---|
1214 |
|
---|
1215 |
|
---|
1216 | /*!
|
---|
1217 | \fn bool qFuzzyCompare(const QMatrix& m1, const QMatrix& m2)
|
---|
1218 |
|
---|
1219 | \relates QMatrix
|
---|
1220 | \since 4.6
|
---|
1221 |
|
---|
1222 | \brief The qFuzzyCompare function is for comparing two matrices
|
---|
1223 | using a fuzziness factor.
|
---|
1224 |
|
---|
1225 | Returns true if \a m1 and \a m2 are equal, allowing for a small
|
---|
1226 | fuzziness factor for floating-point comparisons; false otherwise.
|
---|
1227 | */
|
---|
1228 |
|
---|
1229 | QT_END_NAMESPACE
|
---|