Qt 4.8
qmatrix4x4.h
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #ifndef QMATRIX4X4_H
43 #define QMATRIX4X4_H
44 
45 #include <QtGui/qvector3d.h>
46 #include <QtGui/qvector4d.h>
47 #include <QtGui/qquaternion.h>
48 #include <QtGui/qgenericmatrix.h>
49 #include <QtCore/qrect.h>
50 
52 
54 
55 QT_MODULE(Gui)
56 
57 #ifndef QT_NO_MATRIX4X4
58 
59 class QMatrix;
60 class QTransform;
61 class QVariant;
62 
64 {
65 public:
66  inline QMatrix4x4() { setToIdentity(); }
67  explicit QMatrix4x4(const qreal *values);
68  inline QMatrix4x4(qreal m11, qreal m12, qreal m13, qreal m14,
69  qreal m21, qreal m22, qreal m23, qreal m24,
70  qreal m31, qreal m32, qreal m33, qreal m34,
71  qreal m41, qreal m42, qreal m43, qreal m44);
72 
73  template <int N, int M>
74  explicit QMatrix4x4(const QGenericMatrix<N, M, qreal>& matrix);
75 
76  QMatrix4x4(const qreal *values, int cols, int rows);
77  QMatrix4x4(const QTransform& transform);
78  QMatrix4x4(const QMatrix& matrix);
79 
80  inline const qreal& operator()(int row, int column) const;
81  inline qreal& operator()(int row, int column);
82 
83  inline QVector4D column(int index) const;
84  inline void setColumn(int index, const QVector4D& value);
85 
86  inline QVector4D row(int index) const;
87  inline void setRow(int index, const QVector4D& value);
88 
89  inline bool isIdentity() const;
90  inline void setToIdentity();
91 
92  inline void fill(qreal value);
93 
94  qreal determinant() const;
95  QMatrix4x4 inverted(bool *invertible = 0) const;
96  QMatrix4x4 transposed() const;
97  QMatrix3x3 normalMatrix() const;
98 
99  inline QMatrix4x4& operator+=(const QMatrix4x4& other);
100  inline QMatrix4x4& operator-=(const QMatrix4x4& other);
101  inline QMatrix4x4& operator*=(const QMatrix4x4& other);
102  inline QMatrix4x4& operator*=(qreal factor);
103  QMatrix4x4& operator/=(qreal divisor);
104  inline bool operator==(const QMatrix4x4& other) const;
105  inline bool operator!=(const QMatrix4x4& other) const;
106 
107  friend QMatrix4x4 operator+(const QMatrix4x4& m1, const QMatrix4x4& m2);
108  friend QMatrix4x4 operator-(const QMatrix4x4& m1, const QMatrix4x4& m2);
109  friend QMatrix4x4 operator*(const QMatrix4x4& m1, const QMatrix4x4& m2);
110 #ifndef QT_NO_VECTOR3D
111  friend QVector3D operator*(const QMatrix4x4& matrix, const QVector3D& vector);
112  friend QVector3D operator*(const QVector3D& vector, const QMatrix4x4& matrix);
113 #endif
114 #ifndef QT_NO_VECTOR4D
115  friend QVector4D operator*(const QVector4D& vector, const QMatrix4x4& matrix);
116  friend QVector4D operator*(const QMatrix4x4& matrix, const QVector4D& vector);
117 #endif
118  friend QPoint operator*(const QPoint& point, const QMatrix4x4& matrix);
119  friend QPointF operator*(const QPointF& point, const QMatrix4x4& matrix);
120  friend QMatrix4x4 operator-(const QMatrix4x4& matrix);
121  friend QPoint operator*(const QMatrix4x4& matrix, const QPoint& point);
122  friend QPointF operator*(const QMatrix4x4& matrix, const QPointF& point);
123  friend QMatrix4x4 operator*(qreal factor, const QMatrix4x4& matrix);
124  friend QMatrix4x4 operator*(const QMatrix4x4& matrix, qreal factor);
125  friend Q_GUI_EXPORT QMatrix4x4 operator/(const QMatrix4x4& matrix, qreal divisor);
126 
127  friend inline bool qFuzzyCompare(const QMatrix4x4& m1, const QMatrix4x4& m2);
128 
129 #ifndef QT_NO_VECTOR3D
130  void scale(const QVector3D& vector);
131  void translate(const QVector3D& vector);
132  void rotate(qreal angle, const QVector3D& vector);
133 #endif
134  void scale(qreal x, qreal y);
135  void scale(qreal x, qreal y, qreal z);
136  void scale(qreal factor);
137  void translate(qreal x, qreal y);
138  void translate(qreal x, qreal y, qreal z);
139  void rotate(qreal angle, qreal x, qreal y, qreal z = 0.0f);
140 #ifndef QT_NO_QUATERNION
141  void rotate(const QQuaternion& quaternion);
142 #endif
143 
144  void ortho(const QRect& rect);
145  void ortho(const QRectF& rect);
146  void ortho(qreal left, qreal right, qreal bottom, qreal top, qreal nearPlane, qreal farPlane);
147  void frustum(qreal left, qreal right, qreal bottom, qreal top, qreal nearPlane, qreal farPlane);
148  void perspective(qreal angle, qreal aspect, qreal nearPlane, qreal farPlane);
149 #ifndef QT_NO_VECTOR3D
150  void lookAt(const QVector3D& eye, const QVector3D& center, const QVector3D& up);
151 #endif
152  void flipCoordinates();
153 
154  void copyDataTo(qreal *values) const;
155 
156  QMatrix toAffine() const;
157  QTransform toTransform() const;
158  QTransform toTransform(qreal distanceToPlane) const;
159 
160  QPoint map(const QPoint& point) const;
161  QPointF map(const QPointF& point) const;
162 #ifndef QT_NO_VECTOR3D
163  QVector3D map(const QVector3D& point) const;
164  QVector3D mapVector(const QVector3D& vector) const;
165 #endif
166 #ifndef QT_NO_VECTOR4D
167  QVector4D map(const QVector4D& point) const;
168 #endif
169  QRect mapRect(const QRect& rect) const;
170  QRectF mapRect(const QRectF& rect) const;
171 
172  template <int N, int M>
173  QGenericMatrix<N, M, qreal> toGenericMatrix() const;
174 
175  inline qreal *data();
176  inline const qreal *data() const { return *m; }
177  inline const qreal *constData() const { return *m; }
178 
179  void optimize();
180 
181  operator QVariant() const;
182 
183 #ifndef QT_NO_DEBUG_STREAM
184  friend Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QMatrix4x4 &m);
185 #endif
186 
187 private:
188  qreal m[4][4]; // Column-major order to match OpenGL.
189  int flagBits; // Flag bits from the enum below.
190 
191  enum {
192  Identity = 0x0001, // Identity matrix
193  General = 0x0002, // General matrix, unknown contents
194  Translation = 0x0004, // Contains a simple translation
195  Scale = 0x0008, // Contains a simple scale
196  Rotation = 0x0010 // Contains a simple rotation
197  };
198 
199  // Construct without initializing identity matrix.
200  QMatrix4x4(int) { flagBits = General; }
201 
202  QMatrix4x4 orthonormalInverse() const;
203 
204  void projectedRotate(qreal angle, qreal x, qreal y, qreal z);
205 
206  friend class QGraphicsRotation;
207 };
208 
210 
212  (qreal m11, qreal m12, qreal m13, qreal m14,
213  qreal m21, qreal m22, qreal m23, qreal m24,
214  qreal m31, qreal m32, qreal m33, qreal m34,
215  qreal m41, qreal m42, qreal m43, qreal m44)
216 {
217  m[0][0] = m11; m[0][1] = m21; m[0][2] = m31; m[0][3] = m41;
218  m[1][0] = m12; m[1][1] = m22; m[1][2] = m32; m[1][3] = m42;
219  m[2][0] = m13; m[2][1] = m23; m[2][2] = m33; m[2][3] = m43;
220  m[3][0] = m14; m[3][1] = m24; m[3][2] = m34; m[3][3] = m44;
221  flagBits = General;
222 }
223 
224 template <int N, int M>
227 {
228  const qreal *values = matrix.constData();
229  for (int matrixCol = 0; matrixCol < 4; ++matrixCol) {
230  for (int matrixRow = 0; matrixRow < 4; ++matrixRow) {
231  if (matrixCol < N && matrixRow < M)
232  m[matrixCol][matrixRow] = values[matrixCol * M + matrixRow];
233  else if (matrixCol == matrixRow)
234  m[matrixCol][matrixRow] = 1.0f;
235  else
236  m[matrixCol][matrixRow] = 0.0f;
237  }
238  }
239  flagBits = General;
240 }
241 
242 template <int N, int M>
244 {
246  qreal *values = result.data();
247  for (int matrixCol = 0; matrixCol < N; ++matrixCol) {
248  for (int matrixRow = 0; matrixRow < M; ++matrixRow) {
249  if (matrixCol < 4 && matrixRow < 4)
250  values[matrixCol * M + matrixRow] = m[matrixCol][matrixRow];
251  else if (matrixCol == matrixRow)
252  values[matrixCol * M + matrixRow] = 1.0f;
253  else
254  values[matrixCol * M + matrixRow] = 0.0f;
255  }
256  }
257  return result;
258 }
259 
260 inline const qreal& QMatrix4x4::operator()(int aRow, int aColumn) const
261 {
262  Q_ASSERT(aRow >= 0 && aRow < 4 && aColumn >= 0 && aColumn < 4);
263  return m[aColumn][aRow];
264 }
265 
266 inline qreal& QMatrix4x4::operator()(int aRow, int aColumn)
267 {
268  Q_ASSERT(aRow >= 0 && aRow < 4 && aColumn >= 0 && aColumn < 4);
269  flagBits = General;
270  return m[aColumn][aRow];
271 }
272 
274 {
275  Q_ASSERT(index >= 0 && index < 4);
276  return QVector4D(m[index][0], m[index][1], m[index][2], m[index][3]);
277 }
278 
279 inline void QMatrix4x4::setColumn(int index, const QVector4D& value)
280 {
281  Q_ASSERT(index >= 0 && index < 4);
282  m[index][0] = value.x();
283  m[index][1] = value.y();
284  m[index][2] = value.z();
285  m[index][3] = value.w();
286  flagBits = General;
287 }
288 
289 inline QVector4D QMatrix4x4::row(int index) const
290 {
291  Q_ASSERT(index >= 0 && index < 4);
292  return QVector4D(m[0][index], m[1][index], m[2][index], m[3][index]);
293 }
294 
295 inline void QMatrix4x4::setRow(int index, const QVector4D& value)
296 {
297  Q_ASSERT(index >= 0 && index < 4);
298  m[0][index] = value.x();
299  m[1][index] = value.y();
300  m[2][index] = value.z();
301  m[3][index] = value.w();
302  flagBits = General;
303 }
304 
305 Q_GUI_EXPORT QMatrix4x4 operator/(const QMatrix4x4& matrix, qreal divisor);
306 
307 inline bool QMatrix4x4::isIdentity() const
308 {
309  if (flagBits == Identity)
310  return true;
311  if (m[0][0] != 1.0f || m[0][1] != 0.0f || m[0][2] != 0.0f)
312  return false;
313  if (m[0][3] != 0.0f || m[1][0] != 0.0f || m[1][1] != 1.0f)
314  return false;
315  if (m[1][2] != 0.0f || m[1][3] != 0.0f || m[2][0] != 0.0f)
316  return false;
317  if (m[2][1] != 0.0f || m[2][2] != 1.0f || m[2][3] != 0.0f)
318  return false;
319  if (m[3][0] != 0.0f || m[3][1] != 0.0f || m[3][2] != 0.0f)
320  return false;
321  return (m[3][3] == 1.0f);
322 }
323 
325 {
326  m[0][0] = 1.0f;
327  m[0][1] = 0.0f;
328  m[0][2] = 0.0f;
329  m[0][3] = 0.0f;
330  m[1][0] = 0.0f;
331  m[1][1] = 1.0f;
332  m[1][2] = 0.0f;
333  m[1][3] = 0.0f;
334  m[2][0] = 0.0f;
335  m[2][1] = 0.0f;
336  m[2][2] = 1.0f;
337  m[2][3] = 0.0f;
338  m[3][0] = 0.0f;
339  m[3][1] = 0.0f;
340  m[3][2] = 0.0f;
341  m[3][3] = 1.0f;
342  flagBits = Identity;
343 }
344 
345 inline void QMatrix4x4::fill(qreal value)
346 {
347  m[0][0] = value;
348  m[0][1] = value;
349  m[0][2] = value;
350  m[0][3] = value;
351  m[1][0] = value;
352  m[1][1] = value;
353  m[1][2] = value;
354  m[1][3] = value;
355  m[2][0] = value;
356  m[2][1] = value;
357  m[2][2] = value;
358  m[2][3] = value;
359  m[3][0] = value;
360  m[3][1] = value;
361  m[3][2] = value;
362  m[3][3] = value;
363  flagBits = General;
364 }
365 
367 {
368  m[0][0] += other.m[0][0];
369  m[0][1] += other.m[0][1];
370  m[0][2] += other.m[0][2];
371  m[0][3] += other.m[0][3];
372  m[1][0] += other.m[1][0];
373  m[1][1] += other.m[1][1];
374  m[1][2] += other.m[1][2];
375  m[1][3] += other.m[1][3];
376  m[2][0] += other.m[2][0];
377  m[2][1] += other.m[2][1];
378  m[2][2] += other.m[2][2];
379  m[2][3] += other.m[2][3];
380  m[3][0] += other.m[3][0];
381  m[3][1] += other.m[3][1];
382  m[3][2] += other.m[3][2];
383  m[3][3] += other.m[3][3];
384  flagBits = General;
385  return *this;
386 }
387 
389 {
390  m[0][0] -= other.m[0][0];
391  m[0][1] -= other.m[0][1];
392  m[0][2] -= other.m[0][2];
393  m[0][3] -= other.m[0][3];
394  m[1][0] -= other.m[1][0];
395  m[1][1] -= other.m[1][1];
396  m[1][2] -= other.m[1][2];
397  m[1][3] -= other.m[1][3];
398  m[2][0] -= other.m[2][0];
399  m[2][1] -= other.m[2][1];
400  m[2][2] -= other.m[2][2];
401  m[2][3] -= other.m[2][3];
402  m[3][0] -= other.m[3][0];
403  m[3][1] -= other.m[3][1];
404  m[3][2] -= other.m[3][2];
405  m[3][3] -= other.m[3][3];
406  flagBits = General;
407  return *this;
408 }
409 
411 {
412  if (flagBits == Identity) {
413  *this = other;
414  return *this;
415  } else if (other.flagBits == Identity) {
416  return *this;
417  } else {
418  *this = *this * other;
419  return *this;
420  }
421 }
422 
424 {
425  m[0][0] *= factor;
426  m[0][1] *= factor;
427  m[0][2] *= factor;
428  m[0][3] *= factor;
429  m[1][0] *= factor;
430  m[1][1] *= factor;
431  m[1][2] *= factor;
432  m[1][3] *= factor;
433  m[2][0] *= factor;
434  m[2][1] *= factor;
435  m[2][2] *= factor;
436  m[2][3] *= factor;
437  m[3][0] *= factor;
438  m[3][1] *= factor;
439  m[3][2] *= factor;
440  m[3][3] *= factor;
441  flagBits = General;
442  return *this;
443 }
444 
445 inline bool QMatrix4x4::operator==(const QMatrix4x4& other) const
446 {
447  return m[0][0] == other.m[0][0] &&
448  m[0][1] == other.m[0][1] &&
449  m[0][2] == other.m[0][2] &&
450  m[0][3] == other.m[0][3] &&
451  m[1][0] == other.m[1][0] &&
452  m[1][1] == other.m[1][1] &&
453  m[1][2] == other.m[1][2] &&
454  m[1][3] == other.m[1][3] &&
455  m[2][0] == other.m[2][0] &&
456  m[2][1] == other.m[2][1] &&
457  m[2][2] == other.m[2][2] &&
458  m[2][3] == other.m[2][3] &&
459  m[3][0] == other.m[3][0] &&
460  m[3][1] == other.m[3][1] &&
461  m[3][2] == other.m[3][2] &&
462  m[3][3] == other.m[3][3];
463 }
464 
465 inline bool QMatrix4x4::operator!=(const QMatrix4x4& other) const
466 {
467  return m[0][0] != other.m[0][0] ||
468  m[0][1] != other.m[0][1] ||
469  m[0][2] != other.m[0][2] ||
470  m[0][3] != other.m[0][3] ||
471  m[1][0] != other.m[1][0] ||
472  m[1][1] != other.m[1][1] ||
473  m[1][2] != other.m[1][2] ||
474  m[1][3] != other.m[1][3] ||
475  m[2][0] != other.m[2][0] ||
476  m[2][1] != other.m[2][1] ||
477  m[2][2] != other.m[2][2] ||
478  m[2][3] != other.m[2][3] ||
479  m[3][0] != other.m[3][0] ||
480  m[3][1] != other.m[3][1] ||
481  m[3][2] != other.m[3][2] ||
482  m[3][3] != other.m[3][3];
483 }
484 
485 inline QMatrix4x4 operator+(const QMatrix4x4& m1, const QMatrix4x4& m2)
486 {
487  QMatrix4x4 m(1);
488  m.m[0][0] = m1.m[0][0] + m2.m[0][0];
489  m.m[0][1] = m1.m[0][1] + m2.m[0][1];
490  m.m[0][2] = m1.m[0][2] + m2.m[0][2];
491  m.m[0][3] = m1.m[0][3] + m2.m[0][3];
492  m.m[1][0] = m1.m[1][0] + m2.m[1][0];
493  m.m[1][1] = m1.m[1][1] + m2.m[1][1];
494  m.m[1][2] = m1.m[1][2] + m2.m[1][2];
495  m.m[1][3] = m1.m[1][3] + m2.m[1][3];
496  m.m[2][0] = m1.m[2][0] + m2.m[2][0];
497  m.m[2][1] = m1.m[2][1] + m2.m[2][1];
498  m.m[2][2] = m1.m[2][2] + m2.m[2][2];
499  m.m[2][3] = m1.m[2][3] + m2.m[2][3];
500  m.m[3][0] = m1.m[3][0] + m2.m[3][0];
501  m.m[3][1] = m1.m[3][1] + m2.m[3][1];
502  m.m[3][2] = m1.m[3][2] + m2.m[3][2];
503  m.m[3][3] = m1.m[3][3] + m2.m[3][3];
504  return m;
505 }
506 
507 inline QMatrix4x4 operator-(const QMatrix4x4& m1, const QMatrix4x4& m2)
508 {
509  QMatrix4x4 m(1);
510  m.m[0][0] = m1.m[0][0] - m2.m[0][0];
511  m.m[0][1] = m1.m[0][1] - m2.m[0][1];
512  m.m[0][2] = m1.m[0][2] - m2.m[0][2];
513  m.m[0][3] = m1.m[0][3] - m2.m[0][3];
514  m.m[1][0] = m1.m[1][0] - m2.m[1][0];
515  m.m[1][1] = m1.m[1][1] - m2.m[1][1];
516  m.m[1][2] = m1.m[1][2] - m2.m[1][2];
517  m.m[1][3] = m1.m[1][3] - m2.m[1][3];
518  m.m[2][0] = m1.m[2][0] - m2.m[2][0];
519  m.m[2][1] = m1.m[2][1] - m2.m[2][1];
520  m.m[2][2] = m1.m[2][2] - m2.m[2][2];
521  m.m[2][3] = m1.m[2][3] - m2.m[2][3];
522  m.m[3][0] = m1.m[3][0] - m2.m[3][0];
523  m.m[3][1] = m1.m[3][1] - m2.m[3][1];
524  m.m[3][2] = m1.m[3][2] - m2.m[3][2];
525  m.m[3][3] = m1.m[3][3] - m2.m[3][3];
526  return m;
527 }
528 
529 inline QMatrix4x4 operator*(const QMatrix4x4& m1, const QMatrix4x4& m2)
530 {
531  if (m1.flagBits == QMatrix4x4::Identity)
532  return m2;
533  else if (m2.flagBits == QMatrix4x4::Identity)
534  return m1;
535 
536  QMatrix4x4 m(1);
537  m.m[0][0] = m1.m[0][0] * m2.m[0][0] +
538  m1.m[1][0] * m2.m[0][1] +
539  m1.m[2][0] * m2.m[0][2] +
540  m1.m[3][0] * m2.m[0][3];
541  m.m[0][1] = m1.m[0][1] * m2.m[0][0] +
542  m1.m[1][1] * m2.m[0][1] +
543  m1.m[2][1] * m2.m[0][2] +
544  m1.m[3][1] * m2.m[0][3];
545  m.m[0][2] = m1.m[0][2] * m2.m[0][0] +
546  m1.m[1][2] * m2.m[0][1] +
547  m1.m[2][2] * m2.m[0][2] +
548  m1.m[3][2] * m2.m[0][3];
549  m.m[0][3] = m1.m[0][3] * m2.m[0][0] +
550  m1.m[1][3] * m2.m[0][1] +
551  m1.m[2][3] * m2.m[0][2] +
552  m1.m[3][3] * m2.m[0][3];
553  m.m[1][0] = m1.m[0][0] * m2.m[1][0] +
554  m1.m[1][0] * m2.m[1][1] +
555  m1.m[2][0] * m2.m[1][2] +
556  m1.m[3][0] * m2.m[1][3];
557  m.m[1][1] = m1.m[0][1] * m2.m[1][0] +
558  m1.m[1][1] * m2.m[1][1] +
559  m1.m[2][1] * m2.m[1][2] +
560  m1.m[3][1] * m2.m[1][3];
561  m.m[1][2] = m1.m[0][2] * m2.m[1][0] +
562  m1.m[1][2] * m2.m[1][1] +
563  m1.m[2][2] * m2.m[1][2] +
564  m1.m[3][2] * m2.m[1][3];
565  m.m[1][3] = m1.m[0][3] * m2.m[1][0] +
566  m1.m[1][3] * m2.m[1][1] +
567  m1.m[2][3] * m2.m[1][2] +
568  m1.m[3][3] * m2.m[1][3];
569  m.m[2][0] = m1.m[0][0] * m2.m[2][0] +
570  m1.m[1][0] * m2.m[2][1] +
571  m1.m[2][0] * m2.m[2][2] +
572  m1.m[3][0] * m2.m[2][3];
573  m.m[2][1] = m1.m[0][1] * m2.m[2][0] +
574  m1.m[1][1] * m2.m[2][1] +
575  m1.m[2][1] * m2.m[2][2] +
576  m1.m[3][1] * m2.m[2][3];
577  m.m[2][2] = m1.m[0][2] * m2.m[2][0] +
578  m1.m[1][2] * m2.m[2][1] +
579  m1.m[2][2] * m2.m[2][2] +
580  m1.m[3][2] * m2.m[2][3];
581  m.m[2][3] = m1.m[0][3] * m2.m[2][0] +
582  m1.m[1][3] * m2.m[2][1] +
583  m1.m[2][3] * m2.m[2][2] +
584  m1.m[3][3] * m2.m[2][3];
585  m.m[3][0] = m1.m[0][0] * m2.m[3][0] +
586  m1.m[1][0] * m2.m[3][1] +
587  m1.m[2][0] * m2.m[3][2] +
588  m1.m[3][0] * m2.m[3][3];
589  m.m[3][1] = m1.m[0][1] * m2.m[3][0] +
590  m1.m[1][1] * m2.m[3][1] +
591  m1.m[2][1] * m2.m[3][2] +
592  m1.m[3][1] * m2.m[3][3];
593  m.m[3][2] = m1.m[0][2] * m2.m[3][0] +
594  m1.m[1][2] * m2.m[3][1] +
595  m1.m[2][2] * m2.m[3][2] +
596  m1.m[3][2] * m2.m[3][3];
597  m.m[3][3] = m1.m[0][3] * m2.m[3][0] +
598  m1.m[1][3] * m2.m[3][1] +
599  m1.m[2][3] * m2.m[3][2] +
600  m1.m[3][3] * m2.m[3][3];
601  return m;
602 }
603 
604 #ifndef QT_NO_VECTOR3D
605 
606 inline QVector3D operator*(const QVector3D& vector, const QMatrix4x4& matrix)
607 {
608  qreal x, y, z, w;
609  x = vector.x() * matrix.m[0][0] +
610  vector.y() * matrix.m[0][1] +
611  vector.z() * matrix.m[0][2] +
612  matrix.m[0][3];
613  y = vector.x() * matrix.m[1][0] +
614  vector.y() * matrix.m[1][1] +
615  vector.z() * matrix.m[1][2] +
616  matrix.m[1][3];
617  z = vector.x() * matrix.m[2][0] +
618  vector.y() * matrix.m[2][1] +
619  vector.z() * matrix.m[2][2] +
620  matrix.m[2][3];
621  w = vector.x() * matrix.m[3][0] +
622  vector.y() * matrix.m[3][1] +
623  vector.z() * matrix.m[3][2] +
624  matrix.m[3][3];
625  if (w == 1.0f)
626  return QVector3D(x, y, z);
627  else
628  return QVector3D(x / w, y / w, z / w);
629 }
630 
631 inline QVector3D operator*(const QMatrix4x4& matrix, const QVector3D& vector)
632 {
633  qreal x, y, z, w;
634  if (matrix.flagBits == QMatrix4x4::Identity) {
635  return vector;
636  } else if (matrix.flagBits == QMatrix4x4::Translation) {
637  return QVector3D(vector.x() + matrix.m[3][0],
638  vector.y() + matrix.m[3][1],
639  vector.z() + matrix.m[3][2]);
640  } else if (matrix.flagBits ==
642  return QVector3D(vector.x() * matrix.m[0][0] + matrix.m[3][0],
643  vector.y() * matrix.m[1][1] + matrix.m[3][1],
644  vector.z() * matrix.m[2][2] + matrix.m[3][2]);
645  } else if (matrix.flagBits == QMatrix4x4::Scale) {
646  return QVector3D(vector.x() * matrix.m[0][0],
647  vector.y() * matrix.m[1][1],
648  vector.z() * matrix.m[2][2]);
649  } else {
650  x = vector.x() * matrix.m[0][0] +
651  vector.y() * matrix.m[1][0] +
652  vector.z() * matrix.m[2][0] +
653  matrix.m[3][0];
654  y = vector.x() * matrix.m[0][1] +
655  vector.y() * matrix.m[1][1] +
656  vector.z() * matrix.m[2][1] +
657  matrix.m[3][1];
658  z = vector.x() * matrix.m[0][2] +
659  vector.y() * matrix.m[1][2] +
660  vector.z() * matrix.m[2][2] +
661  matrix.m[3][2];
662  w = vector.x() * matrix.m[0][3] +
663  vector.y() * matrix.m[1][3] +
664  vector.z() * matrix.m[2][3] +
665  matrix.m[3][3];
666  if (w == 1.0f)
667  return QVector3D(x, y, z);
668  else
669  return QVector3D(x / w, y / w, z / w);
670  }
671 }
672 
673 #endif
674 
675 #ifndef QT_NO_VECTOR4D
676 
677 inline QVector4D operator*(const QVector4D& vector, const QMatrix4x4& matrix)
678 {
679  qreal x, y, z, w;
680  x = vector.x() * matrix.m[0][0] +
681  vector.y() * matrix.m[0][1] +
682  vector.z() * matrix.m[0][2] +
683  vector.w() * matrix.m[0][3];
684  y = vector.x() * matrix.m[1][0] +
685  vector.y() * matrix.m[1][1] +
686  vector.z() * matrix.m[1][2] +
687  vector.w() * matrix.m[1][3];
688  z = vector.x() * matrix.m[2][0] +
689  vector.y() * matrix.m[2][1] +
690  vector.z() * matrix.m[2][2] +
691  vector.w() * matrix.m[2][3];
692  w = vector.x() * matrix.m[3][0] +
693  vector.y() * matrix.m[3][1] +
694  vector.z() * matrix.m[3][2] +
695  vector.w() * matrix.m[3][3];
696  return QVector4D(x, y, z, w);
697 }
698 
699 inline QVector4D operator*(const QMatrix4x4& matrix, const QVector4D& vector)
700 {
701  qreal x, y, z, w;
702  x = vector.x() * matrix.m[0][0] +
703  vector.y() * matrix.m[1][0] +
704  vector.z() * matrix.m[2][0] +
705  vector.w() * matrix.m[3][0];
706  y = vector.x() * matrix.m[0][1] +
707  vector.y() * matrix.m[1][1] +
708  vector.z() * matrix.m[2][1] +
709  vector.w() * matrix.m[3][1];
710  z = vector.x() * matrix.m[0][2] +
711  vector.y() * matrix.m[1][2] +
712  vector.z() * matrix.m[2][2] +
713  vector.w() * matrix.m[3][2];
714  w = vector.x() * matrix.m[0][3] +
715  vector.y() * matrix.m[1][3] +
716  vector.z() * matrix.m[2][3] +
717  vector.w() * matrix.m[3][3];
718  return QVector4D(x, y, z, w);
719 }
720 
721 #endif
722 
723 inline QPoint operator*(const QPoint& point, const QMatrix4x4& matrix)
724 {
725  qreal xin, yin;
726  qreal x, y, w;
727  xin = point.x();
728  yin = point.y();
729  x = xin * matrix.m[0][0] +
730  yin * matrix.m[0][1] +
731  matrix.m[0][3];
732  y = xin * matrix.m[1][0] +
733  yin * matrix.m[1][1] +
734  matrix.m[1][3];
735  w = xin * matrix.m[3][0] +
736  yin * matrix.m[3][1] +
737  matrix.m[3][3];
738  if (w == 1.0f)
739  return QPoint(qRound(x), qRound(y));
740  else
741  return QPoint(qRound(x / w), qRound(y / w));
742 }
743 
744 inline QPointF operator*(const QPointF& point, const QMatrix4x4& matrix)
745 {
746  qreal xin, yin;
747  qreal x, y, w;
748  xin = point.x();
749  yin = point.y();
750  x = xin * matrix.m[0][0] +
751  yin * matrix.m[0][1] +
752  matrix.m[0][3];
753  y = xin * matrix.m[1][0] +
754  yin * matrix.m[1][1] +
755  matrix.m[1][3];
756  w = xin * matrix.m[3][0] +
757  yin * matrix.m[3][1] +
758  matrix.m[3][3];
759  if (w == 1.0f) {
760  return QPointF(qreal(x), qreal(y));
761  } else {
762  return QPointF(qreal(x / w), qreal(y / w));
763  }
764 }
765 
766 inline QPoint operator*(const QMatrix4x4& matrix, const QPoint& point)
767 {
768  qreal xin, yin;
769  qreal x, y, w;
770  xin = point.x();
771  yin = point.y();
772  if (matrix.flagBits == QMatrix4x4::Identity) {
773  return point;
774  } else if (matrix.flagBits == QMatrix4x4::Translation) {
775  return QPoint(qRound(xin + matrix.m[3][0]),
776  qRound(yin + matrix.m[3][1]));
777  } else if (matrix.flagBits ==
779  return QPoint(qRound(xin * matrix.m[0][0] + matrix.m[3][0]),
780  qRound(yin * matrix.m[1][1] + matrix.m[3][1]));
781  } else if (matrix.flagBits == QMatrix4x4::Scale) {
782  return QPoint(qRound(xin * matrix.m[0][0]),
783  qRound(yin * matrix.m[1][1]));
784  } else {
785  x = xin * matrix.m[0][0] +
786  yin * matrix.m[1][0] +
787  matrix.m[3][0];
788  y = xin * matrix.m[0][1] +
789  yin * matrix.m[1][1] +
790  matrix.m[3][1];
791  w = xin * matrix.m[0][3] +
792  yin * matrix.m[1][3] +
793  matrix.m[3][3];
794  if (w == 1.0f)
795  return QPoint(qRound(x), qRound(y));
796  else
797  return QPoint(qRound(x / w), qRound(y / w));
798  }
799 }
800 
801 inline QPointF operator*(const QMatrix4x4& matrix, const QPointF& point)
802 {
803  qreal xin, yin;
804  qreal x, y, w;
805  xin = point.x();
806  yin = point.y();
807  if (matrix.flagBits == QMatrix4x4::Identity) {
808  return point;
809  } else if (matrix.flagBits == QMatrix4x4::Translation) {
810  return QPointF(xin + matrix.m[3][0],
811  yin + matrix.m[3][1]);
812  } else if (matrix.flagBits ==
814  return QPointF(xin * matrix.m[0][0] + matrix.m[3][0],
815  yin * matrix.m[1][1] + matrix.m[3][1]);
816  } else if (matrix.flagBits == QMatrix4x4::Scale) {
817  return QPointF(xin * matrix.m[0][0],
818  yin * matrix.m[1][1]);
819  } else {
820  x = xin * matrix.m[0][0] +
821  yin * matrix.m[1][0] +
822  matrix.m[3][0];
823  y = xin * matrix.m[0][1] +
824  yin * matrix.m[1][1] +
825  matrix.m[3][1];
826  w = xin * matrix.m[0][3] +
827  yin * matrix.m[1][3] +
828  matrix.m[3][3];
829  if (w == 1.0f) {
830  return QPointF(qreal(x), qreal(y));
831  } else {
832  return QPointF(qreal(x / w), qreal(y / w));
833  }
834  }
835 }
836 
837 inline QMatrix4x4 operator-(const QMatrix4x4& matrix)
838 {
839  QMatrix4x4 m(1);
840  m.m[0][0] = -matrix.m[0][0];
841  m.m[0][1] = -matrix.m[0][1];
842  m.m[0][2] = -matrix.m[0][2];
843  m.m[0][3] = -matrix.m[0][3];
844  m.m[1][0] = -matrix.m[1][0];
845  m.m[1][1] = -matrix.m[1][1];
846  m.m[1][2] = -matrix.m[1][2];
847  m.m[1][3] = -matrix.m[1][3];
848  m.m[2][0] = -matrix.m[2][0];
849  m.m[2][1] = -matrix.m[2][1];
850  m.m[2][2] = -matrix.m[2][2];
851  m.m[2][3] = -matrix.m[2][3];
852  m.m[3][0] = -matrix.m[3][0];
853  m.m[3][1] = -matrix.m[3][1];
854  m.m[3][2] = -matrix.m[3][2];
855  m.m[3][3] = -matrix.m[3][3];
856  return m;
857 }
858 
859 inline QMatrix4x4 operator*(qreal factor, const QMatrix4x4& matrix)
860 {
861  QMatrix4x4 m(1);
862  m.m[0][0] = matrix.m[0][0] * factor;
863  m.m[0][1] = matrix.m[0][1] * factor;
864  m.m[0][2] = matrix.m[0][2] * factor;
865  m.m[0][3] = matrix.m[0][3] * factor;
866  m.m[1][0] = matrix.m[1][0] * factor;
867  m.m[1][1] = matrix.m[1][1] * factor;
868  m.m[1][2] = matrix.m[1][2] * factor;
869  m.m[1][3] = matrix.m[1][3] * factor;
870  m.m[2][0] = matrix.m[2][0] * factor;
871  m.m[2][1] = matrix.m[2][1] * factor;
872  m.m[2][2] = matrix.m[2][2] * factor;
873  m.m[2][3] = matrix.m[2][3] * factor;
874  m.m[3][0] = matrix.m[3][0] * factor;
875  m.m[3][1] = matrix.m[3][1] * factor;
876  m.m[3][2] = matrix.m[3][2] * factor;
877  m.m[3][3] = matrix.m[3][3] * factor;
878  return m;
879 }
880 
881 inline QMatrix4x4 operator*(const QMatrix4x4& matrix, qreal factor)
882 {
883  QMatrix4x4 m(1);
884  m.m[0][0] = matrix.m[0][0] * factor;
885  m.m[0][1] = matrix.m[0][1] * factor;
886  m.m[0][2] = matrix.m[0][2] * factor;
887  m.m[0][3] = matrix.m[0][3] * factor;
888  m.m[1][0] = matrix.m[1][0] * factor;
889  m.m[1][1] = matrix.m[1][1] * factor;
890  m.m[1][2] = matrix.m[1][2] * factor;
891  m.m[1][3] = matrix.m[1][3] * factor;
892  m.m[2][0] = matrix.m[2][0] * factor;
893  m.m[2][1] = matrix.m[2][1] * factor;
894  m.m[2][2] = matrix.m[2][2] * factor;
895  m.m[2][3] = matrix.m[2][3] * factor;
896  m.m[3][0] = matrix.m[3][0] * factor;
897  m.m[3][1] = matrix.m[3][1] * factor;
898  m.m[3][2] = matrix.m[3][2] * factor;
899  m.m[3][3] = matrix.m[3][3] * factor;
900  return m;
901 }
902 
903 inline bool qFuzzyCompare(const QMatrix4x4& m1, const QMatrix4x4& m2)
904 {
905  return qFuzzyCompare(m1.m[0][0], m2.m[0][0]) &&
906  qFuzzyCompare(m1.m[0][1], m2.m[0][1]) &&
907  qFuzzyCompare(m1.m[0][2], m2.m[0][2]) &&
908  qFuzzyCompare(m1.m[0][3], m2.m[0][3]) &&
909  qFuzzyCompare(m1.m[1][0], m2.m[1][0]) &&
910  qFuzzyCompare(m1.m[1][1], m2.m[1][1]) &&
911  qFuzzyCompare(m1.m[1][2], m2.m[1][2]) &&
912  qFuzzyCompare(m1.m[1][3], m2.m[1][3]) &&
913  qFuzzyCompare(m1.m[2][0], m2.m[2][0]) &&
914  qFuzzyCompare(m1.m[2][1], m2.m[2][1]) &&
915  qFuzzyCompare(m1.m[2][2], m2.m[2][2]) &&
916  qFuzzyCompare(m1.m[2][3], m2.m[2][3]) &&
917  qFuzzyCompare(m1.m[3][0], m2.m[3][0]) &&
918  qFuzzyCompare(m1.m[3][1], m2.m[3][1]) &&
919  qFuzzyCompare(m1.m[3][2], m2.m[3][2]) &&
920  qFuzzyCompare(m1.m[3][3], m2.m[3][3]);
921 }
922 
923 inline QPoint QMatrix4x4::map(const QPoint& point) const
924 {
925  return *this * point;
926 }
927 
928 inline QPointF QMatrix4x4::map(const QPointF& point) const
929 {
930  return *this * point;
931 }
932 
933 #ifndef QT_NO_VECTOR3D
934 
935 inline QVector3D QMatrix4x4::map(const QVector3D& point) const
936 {
937  return *this * point;
938 }
939 
940 inline QVector3D QMatrix4x4::mapVector(const QVector3D& vector) const
941 {
942  if (flagBits == Identity || flagBits == Translation) {
943  return vector;
944  } else if (flagBits == Scale || flagBits == (Translation | Scale)) {
945  return QVector3D(vector.x() * m[0][0],
946  vector.y() * m[1][1],
947  vector.z() * m[2][2]);
948  } else {
949  return QVector3D(vector.x() * m[0][0] +
950  vector.y() * m[1][0] +
951  vector.z() * m[2][0],
952  vector.x() * m[0][1] +
953  vector.y() * m[1][1] +
954  vector.z() * m[2][1],
955  vector.x() * m[0][2] +
956  vector.y() * m[1][2] +
957  vector.z() * m[2][2]);
958  }
959 }
960 
961 #endif
962 
963 #ifndef QT_NO_VECTOR4D
964 
965 inline QVector4D QMatrix4x4::map(const QVector4D& point) const
966 {
967  return *this * point;
968 }
969 
970 #endif
971 
973 {
974  // We have to assume that the caller will modify the matrix elements,
975  // so we flip it over to "General" mode.
976  flagBits = General;
977  return *m;
978 }
979 
980 #ifndef QT_NO_DEBUG_STREAM
982 #endif
983 
984 #ifndef QT_NO_DATASTREAM
987 #endif
988 
989 #ifdef QT_DEPRECATED
990 template <int N, int M>
992 {
993  return QMatrix4x4(matrix.constData(), N, M);
994 }
995 
996 template <int N, int M>
998 {
1000  const qreal *m = matrix.constData();
1001  qreal *values = result.data();
1002  for (int col = 0; col < N; ++col) {
1003  for (int row = 0; row < M; ++row) {
1004  if (col < 4 && row < 4)
1005  values[col * M + row] = m[col * 4 + row];
1006  else if (col == row)
1007  values[col * M + row] = 1.0f;
1008  else
1009  values[col * M + row] = 0.0f;
1010  }
1011  }
1012  return result;
1013 }
1014 #endif
1015 
1016 #endif
1017 
1019 
1021 
1022 #endif
The QVariant class acts like a union for the most common Qt data types.
Definition: qvariant.h:92
const T * constData() const
Returns a constant pointer to the raw data of this matrix.
The QDebug class provides an output stream for debugging information.
Definition: qdebug.h:62
T * data()
Returns a pointer to the raw data of this matrix.
int flagBits
Definition: qmatrix4x4.h:189
The QVector3D class represents a vector or vertex in 3D space.
Definition: qvector3d.h:60
double qreal
Definition: qglobal.h:1193
QT_DEPRECATED QMatrix4x4 qGenericMatrixToMatrix4x4(const QGenericMatrix< N, M, qreal > &matrix)
Definition: qmatrix4x4.h:991
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
QMatrix4x4(int)
Definition: qmatrix4x4.h:200
The QGenericMatrix class is a template class that represents a NxM transformation matrix with N colum...
#define QT_MODULE(x)
Definition: qglobal.h:2783
QMatrix4x4()
Constructs an identity matrix.
Definition: qmatrix4x4.h:66
#define QT_BEGIN_HEADER
Definition: qglobal.h:136
The QMatrix class specifies 2D transformations of a coordinate system.
Definition: qmatrix.h:61
bool qFuzzyCompare(const QMatrix4x4 &m1, const QMatrix4x4 &m2)
Definition: qmatrix4x4.h:903
The Rotation object provides a way to rotate an Item.
#define Q_GUI_EXPORT
Definition: qglobal.h:1450
qreal w() const
Returns the w coordinate of this point.
Definition: qvector4d.h:161
The QVector4D class represents a vector or vertex in 4D space.
Definition: qvector4d.h:60
The QPointF class defines a point in the plane using floating point precision.
Definition: qpoint.h:214
void setRow(int index, const QVector4D &value)
Sets the elements of row index to the components of value.
Definition: qmatrix4x4.h:295
qreal * data()
Returns a pointer to the raw data of this matrix.
Definition: qmatrix4x4.h:972
const qreal & operator()(int row, int column) const
Returns a constant reference to the element at position (row, column) in this matrix.
Definition: qmatrix4x4.h:260
bool operator!=(QBool b1, bool b2)
Definition: qglobal.h:2026
QT_DEPRECATED QGenericMatrix< N, M, qreal > qGenericMatrixFromMatrix4x4(const QMatrix4x4 &matrix)
Definition: qmatrix4x4.h:997
qreal x() const
Returns the x coordinate of this point.
Definition: qvector3d.h:161
QPoint map(const QPoint &point) const
Maps point by multiplying this matrix by point.
Definition: qmatrix4x4.h:923
QGenericMatrix< N, M, qreal > toGenericMatrix() const
Constructs a NxM generic matrix from the left-most N columns and top-most M rows of this 4x4 matrix...
Definition: qmatrix4x4.h:243
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
Q_CORE_EXPORT QTextStream & right(QTextStream &s)
qreal x() const
Returns the x-coordinate of this point.
Definition: qpoint.h:282
Q_DECLARE_TYPEINFO(QMatrix4x4, Q_MOVABLE_TYPE)
void setColumn(int index, const QVector4D &value)
Sets the elements of column index to the components of value.
Definition: qmatrix4x4.h:279
#define M(row, col)
QVector4D column(int index) const
Returns the elements of column index as a 4D vector.
Definition: qmatrix4x4.h:273
QMatrix4x4 & operator+=(const QMatrix4x4 &other)
Adds the contents of other to this matrix.
Definition: qmatrix4x4.h:366
QFuture< void > map(Sequence &sequence, MapFunction function)
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
The QRectF class defines a rectangle in the plane using floating point precision. ...
Definition: qrect.h:511
QMatrix4x4 & operator-=(const QMatrix4x4 &other)
Subtracts the contents of other from this matrix.
Definition: qmatrix4x4.h:388
bool operator==(const QMatrix4x4 &other) const
Returns true if this matrix is identical to other; false otherwise.
Definition: qmatrix4x4.h:445
qreal x() const
Returns the x coordinate of this point.
Definition: qvector4d.h:158
Q_GUI_EXPORT QMatrix4x4 operator/(const QMatrix4x4 &matrix, qreal divisor)
void setToIdentity()
Sets this matrix to the identity.
Definition: qmatrix4x4.h:324
QMatrix4x4 operator+(const QMatrix4x4 &m1, const QMatrix4x4 &m2)
Definition: qmatrix4x4.h:485
QVector4D row(int index) const
Returns the elements of row index as a 4D vector.
Definition: qmatrix4x4.h:289
The QMatrix4x4 class represents a 4x4 transformation matrix in 3D space.
Definition: qmatrix4x4.h:63
#define Q_INLINE_TEMPLATE
Definition: qglobal.h:1713
static const char * data(const QByteArray &arr)
void fill(qreal value)
Fills all elements of this matrx with value.
Definition: qmatrix4x4.h:345
quint16 values[128]
const qreal * constData() const
Returns a constant pointer to the raw data of this matrix.
Definition: qmatrix4x4.h:177
qreal z() const
Returns the z coordinate of this point.
Definition: qvector3d.h:163
const qreal * data() const
Returns a constant pointer to the raw data of this matrix.
Definition: qmatrix4x4.h:176
QVector3D mapVector(const QVector3D &vector) const
Maps vector by multiplying the top 3x3 portion of this matrix by vector.
Definition: qmatrix4x4.h:940
qreal m[4][4]
Definition: qmatrix4x4.h:188
Q_CORE_EXPORT QTextStream & center(QTextStream &s)
bool operator!=(const QMatrix4x4 &other) const
Returns true if this matrix is not identical to other; false otherwise.
Definition: qmatrix4x4.h:465
qreal angle(const QPointF &p1, const QPointF &p2)
Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QMatrix4x4 &m)
The Scale element provides a way to scale an Item.
Q_GUI_EXPORT QDataStream & operator>>(QDataStream &, QMatrix4x4 &)
The QPoint class defines a point in the plane using integer precision.
Definition: qpoint.h:53
qreal y() const
Returns the y coordinate of this point.
Definition: qvector3d.h:162
QMatrix4x4 operator-(const QMatrix4x4 &m1, const QMatrix4x4 &m2)
Definition: qmatrix4x4.h:507
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:58
The QQuaternion class represents a quaternion consisting of a vector and scalar.
Definition: qquaternion.h:59
int y() const
Returns the y coordinate of this point.
Definition: qpoint.h:131
qreal y() const
Returns the y-coordinate of this point.
Definition: qpoint.h:287
quint16 index
QMatrix4x4 operator*(const QMatrix4x4 &m1, const QMatrix4x4 &m2)
Definition: qmatrix4x4.h:529
#define QT_DEPRECATED
Definition: qglobal.h:1094
The QGraphicsRotation class provides a rotation transformation around a given axis.
The QDataStream class provides serialization of binary data to a QIODevice.
Definition: qdatastream.h:71
int x() const
Returns the x coordinate of this point.
Definition: qpoint.h:128
timeval & operator+=(timeval &t1, const timeval &t2)
Definition: qcore_unix_p.h:120
QMatrix4x4 & operator*=(const QMatrix4x4 &other)
Multiplies the contents of other by this matrix.
Definition: qmatrix4x4.h:410
qreal z() const
Returns the z coordinate of this point.
Definition: qvector4d.h:160
Q_CORE_EXPORT QTextStream & left(QTextStream &s)
#define QT_END_HEADER
Definition: qglobal.h:137
bool operator==(QBool b1, bool b2)
Definition: qglobal.h:2023
qreal y() const
Returns the y coordinate of this point.
Definition: qvector4d.h:159
Q_DECL_CONSTEXPR int qRound(qreal d)
Definition: qglobal.h:1203
bool isIdentity() const
Returns true if this matrix is the identity; false otherwise.
Definition: qmatrix4x4.h:307
The QTransform class specifies 2D transformations of a coordinate system.
Definition: qtransform.h:65