Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qdoublematrix4x4_p.h
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5#ifndef QDOUBLEMATRIX4X4_H
6#define QDOUBLEMATRIX4X4_H
7
8//
9// W A R N I N G
10// -------------
11//
12// This file is not part of the Qt API. It exists purely as an
13// implementation detail. This header file may change from version to
14// version without notice, or even be removed.
15//
16// We mean it.
17//
18
19#include <QtPositioning/private/qpositioningglobal_p.h>
20#include <QtPositioning/private/qdoublevector3d_p.h>
21#include <QtCore/QDebug>
22#include <QtCore/qmetatype.h>
23#include <QtCore/QRectF>
24
26
27/*
28 * This class is a copy/paste/replace of QMatrix4x4
29 * No algorithm has been changed.
30 * Some methods have been removed.
31 */
32
34{
35public:
36 inline QDoubleMatrix4x4() { setToIdentity(); }
37 explicit QDoubleMatrix4x4(Qt::Initialization) : flagBits(General) {}
38 explicit QDoubleMatrix4x4(const double *values);
39 inline QDoubleMatrix4x4(double m11, double m12, double m13, double m14,
40 double m21, double m22, double m23, double m24,
41 double m31, double m32, double m33, double m34,
42 double m41, double m42, double m43, double m44);
43
44 QDoubleMatrix4x4(const double *values, int cols, int rows);
45
46 inline const double& operator()(int row, int column) const;
47 inline double& operator()(int row, int column);
48
49 inline bool isAffine() const;
50
51 inline bool isIdentity() const;
52 inline void setToIdentity();
53
54 inline void fill(double value);
55
56 double determinant() const;
57 QDoubleMatrix4x4 inverted(bool *invertible = nullptr) const;
58 QDoubleMatrix4x4 transposed() const;
59
60 inline QDoubleMatrix4x4& operator+=(const QDoubleMatrix4x4& other);
61 inline QDoubleMatrix4x4& operator-=(const QDoubleMatrix4x4& other);
62 inline QDoubleMatrix4x4& operator*=(const QDoubleMatrix4x4& other);
63 inline QDoubleMatrix4x4& operator*=(double factor);
64 QDoubleMatrix4x4& operator/=(double divisor);
65 inline bool operator==(const QDoubleMatrix4x4& other) const;
66 inline bool operator!=(const QDoubleMatrix4x4& other) const;
67
68 friend QDoubleMatrix4x4 operator+(const QDoubleMatrix4x4& m1, const QDoubleMatrix4x4& m2);
69 friend QDoubleMatrix4x4 operator-(const QDoubleMatrix4x4& m1, const QDoubleMatrix4x4& m2);
70 friend QDoubleMatrix4x4 operator*(const QDoubleMatrix4x4& m1, const QDoubleMatrix4x4& m2);
71
72 friend QDoubleVector3D operator*(const QDoubleMatrix4x4& matrix, const QDoubleVector3D& vector);
73 friend QDoubleVector3D operator*(const QDoubleVector3D& vector, const QDoubleMatrix4x4& matrix);
74
75 friend QPoint operator*(const QPoint& point, const QDoubleMatrix4x4& matrix);
76 friend QPointF operator*(const QPointF& point, const QDoubleMatrix4x4& matrix);
77 friend QDoubleMatrix4x4 operator-(const QDoubleMatrix4x4& matrix);
78 friend QPoint operator*(const QDoubleMatrix4x4& matrix, const QPoint& point);
79 friend QPointF operator*(const QDoubleMatrix4x4& matrix, const QPointF& point);
80 friend QDoubleMatrix4x4 operator*(double factor, const QDoubleMatrix4x4& matrix);
81 friend QDoubleMatrix4x4 operator*(const QDoubleMatrix4x4& matrix, double factor);
82 friend Q_POSITIONING_EXPORT QDoubleMatrix4x4 operator/(const QDoubleMatrix4x4& matrix, double divisor);
83
84 friend inline bool qFuzzyCompare(const QDoubleMatrix4x4& m1, const QDoubleMatrix4x4& m2);
85
86
87 void scale(const QDoubleVector3D& vector);
88 void translate(const QDoubleVector3D& vector);
89 void rotate(double angle, const QDoubleVector3D& vector);
90
91 void scale(double x, double y);
92 void scale(double x, double y, double z);
93 void scale(double factor);
94 void translate(double x, double y);
95 void translate(double x, double y, double z);
96 void rotate(double angle, double x, double y, double z = 0.0f);
97
98 void ortho(const QRect& rect);
99 void ortho(const QRectF& rect);
100 void ortho(double left, double right, double bottom, double top, double nearPlane, double farPlane);
101 void frustum(double left, double right, double bottom, double top, double nearPlane, double farPlane);
102 void perspective(double verticalAngle, double aspectRatio, double nearPlane, double farPlane);
103
104 void lookAt(const QDoubleVector3D& eye, const QDoubleVector3D& center, const QDoubleVector3D& up);
105
106 void viewport(const QRectF &rect);
107 void viewport(double left, double bottom, double width, double height, double nearPlane = 0.0f, double farPlane = 1.0f);
108 void flipCoordinates();
109
110 void copyDataTo(double *values) const;
111
112 QPoint map(const QPoint& point) const;
113 QPointF map(const QPointF& point) const;
114
115 QDoubleVector3D map(const QDoubleVector3D& point) const;
116 QDoubleVector3D mapVector(const QDoubleVector3D& vector) const;
117
118 QRect mapRect(const QRect& rect) const;
119 QRectF mapRect(const QRectF& rect) const;
120
121 inline double *data();
122 inline const double *data() const { return *m; }
123 inline const double *constData() const { return *m; }
124
125 void optimize();
126
127#ifndef QT_NO_DEBUG_STREAM
128 friend Q_POSITIONING_EXPORT QDebug operator<<(QDebug dbg, const QDoubleMatrix4x4 &m);
129#endif
130
131private:
132 double m[4][4]; // Column-major order to match OpenGL.
133 int flagBits; // Flag bits from the enum below.
134
135 // When matrices are multiplied, the flag bits are or-ed together.
136 enum {
137 Identity = 0x0000, // Identity matrix
138 Translation = 0x0001, // Contains a translation
139 Scale = 0x0002, // Contains a scale
140 Rotation2D = 0x0004, // Contains a rotation about the Z axis
141 Rotation = 0x0008, // Contains an arbitrary rotation
142 Perspective = 0x0010, // Last row is different from (0, 0, 0, 1)
143 General = 0x001f // General matrix, unknown contents
144 };
145
146 // Construct without initializing identity matrix.
147 explicit QDoubleMatrix4x4(int) { }
148
149 QDoubleMatrix4x4 orthonormalInverse() const;
150
151 void projectedRotate(double angle, double x, double y, double z,
152 double distanceToPlane = 1024.0);
153};
154
155Q_DECLARE_TYPEINFO(QDoubleMatrix4x4, Q_RELOCATABLE_TYPE);
156
157inline QDoubleMatrix4x4::QDoubleMatrix4x4
158 (double m11, double m12, double m13, double m14,
159 double m21, double m22, double m23, double m24,
160 double m31, double m32, double m33, double m34,
161 double m41, double m42, double m43, double m44)
162{
163 m[0][0] = m11; m[0][1] = m21; m[0][2] = m31; m[0][3] = m41;
164 m[1][0] = m12; m[1][1] = m22; m[1][2] = m32; m[1][3] = m42;
165 m[2][0] = m13; m[2][1] = m23; m[2][2] = m33; m[2][3] = m43;
166 m[3][0] = m14; m[3][1] = m24; m[3][2] = m34; m[3][3] = m44;
167 flagBits = General;
168}
169
170inline const double& QDoubleMatrix4x4::operator()(int aRow, int aColumn) const
171{
172 Q_ASSERT(aRow >= 0 && aRow < 4 && aColumn >= 0 && aColumn < 4);
173 return m[aColumn][aRow];
174}
175
176inline double& QDoubleMatrix4x4::operator()(int aRow, int aColumn)
177{
178 Q_ASSERT(aRow >= 0 && aRow < 4 && aColumn >= 0 && aColumn < 4);
179 flagBits = General;
180 return m[aColumn][aRow];
181}
182
183Q_POSITIONING_EXPORT QDoubleMatrix4x4 operator/(const QDoubleMatrix4x4& matrix, double divisor);
184
185inline bool QDoubleMatrix4x4::isAffine() const
186{
187 return m[0][3] == 0.0f && m[1][3] == 0.0f && m[2][3] == 0.0f && m[3][3] == 1.0f;
188}
189
190inline bool QDoubleMatrix4x4::isIdentity() const
191{
192 if (flagBits == Identity)
193 return true;
194 if (m[0][0] != 1.0f || m[0][1] != 0.0f || m[0][2] != 0.0f)
195 return false;
196 if (m[0][3] != 0.0f || m[1][0] != 0.0f || m[1][1] != 1.0f)
197 return false;
198 if (m[1][2] != 0.0f || m[1][3] != 0.0f || m[2][0] != 0.0f)
199 return false;
200 if (m[2][1] != 0.0f || m[2][2] != 1.0f || m[2][3] != 0.0f)
201 return false;
202 if (m[3][0] != 0.0f || m[3][1] != 0.0f || m[3][2] != 0.0f)
203 return false;
204 return (m[3][3] == 1.0f);
205}
206
207inline void QDoubleMatrix4x4::setToIdentity()
208{
209 m[0][0] = 1.0f;
210 m[0][1] = 0.0f;
211 m[0][2] = 0.0f;
212 m[0][3] = 0.0f;
213 m[1][0] = 0.0f;
214 m[1][1] = 1.0f;
215 m[1][2] = 0.0f;
216 m[1][3] = 0.0f;
217 m[2][0] = 0.0f;
218 m[2][1] = 0.0f;
219 m[2][2] = 1.0f;
220 m[2][3] = 0.0f;
221 m[3][0] = 0.0f;
222 m[3][1] = 0.0f;
223 m[3][2] = 0.0f;
224 m[3][3] = 1.0f;
225 flagBits = Identity;
226}
227
228inline void QDoubleMatrix4x4::fill(double value)
229{
230 m[0][0] = value;
231 m[0][1] = value;
232 m[0][2] = value;
233 m[0][3] = value;
234 m[1][0] = value;
235 m[1][1] = value;
236 m[1][2] = value;
237 m[1][3] = value;
238 m[2][0] = value;
239 m[2][1] = value;
240 m[2][2] = value;
241 m[2][3] = value;
242 m[3][0] = value;
243 m[3][1] = value;
244 m[3][2] = value;
245 m[3][3] = value;
246 flagBits = General;
247}
248
249inline QDoubleMatrix4x4& QDoubleMatrix4x4::operator+=(const QDoubleMatrix4x4& other)
250{
251 m[0][0] += other.m[0][0];
252 m[0][1] += other.m[0][1];
253 m[0][2] += other.m[0][2];
254 m[0][3] += other.m[0][3];
255 m[1][0] += other.m[1][0];
256 m[1][1] += other.m[1][1];
257 m[1][2] += other.m[1][2];
258 m[1][3] += other.m[1][3];
259 m[2][0] += other.m[2][0];
260 m[2][1] += other.m[2][1];
261 m[2][2] += other.m[2][2];
262 m[2][3] += other.m[2][3];
263 m[3][0] += other.m[3][0];
264 m[3][1] += other.m[3][1];
265 m[3][2] += other.m[3][2];
266 m[3][3] += other.m[3][3];
267 flagBits = General;
268 return *this;
269}
270
271inline QDoubleMatrix4x4& QDoubleMatrix4x4::operator-=(const QDoubleMatrix4x4& other)
272{
273 m[0][0] -= other.m[0][0];
274 m[0][1] -= other.m[0][1];
275 m[0][2] -= other.m[0][2];
276 m[0][3] -= other.m[0][3];
277 m[1][0] -= other.m[1][0];
278 m[1][1] -= other.m[1][1];
279 m[1][2] -= other.m[1][2];
280 m[1][3] -= other.m[1][3];
281 m[2][0] -= other.m[2][0];
282 m[2][1] -= other.m[2][1];
283 m[2][2] -= other.m[2][2];
284 m[2][3] -= other.m[2][3];
285 m[3][0] -= other.m[3][0];
286 m[3][1] -= other.m[3][1];
287 m[3][2] -= other.m[3][2];
288 m[3][3] -= other.m[3][3];
289 flagBits = General;
290 return *this;
291}
292
293inline QDoubleMatrix4x4& QDoubleMatrix4x4::operator*=(const QDoubleMatrix4x4& other)
294{
295 flagBits |= other.flagBits;
296
297 if (flagBits < Rotation2D) {
298 m[3][0] += m[0][0] * other.m[3][0];
299 m[3][1] += m[1][1] * other.m[3][1];
300 m[3][2] += m[2][2] * other.m[3][2];
301
302 m[0][0] *= other.m[0][0];
303 m[1][1] *= other.m[1][1];
304 m[2][2] *= other.m[2][2];
305 return *this;
306 }
307
308 double m0, m1, m2;
309 m0 = m[0][0] * other.m[0][0]
310 + m[1][0] * other.m[0][1]
311 + m[2][0] * other.m[0][2]
312 + m[3][0] * other.m[0][3];
313 m1 = m[0][0] * other.m[1][0]
314 + m[1][0] * other.m[1][1]
315 + m[2][0] * other.m[1][2]
316 + m[3][0] * other.m[1][3];
317 m2 = m[0][0] * other.m[2][0]
318 + m[1][0] * other.m[2][1]
319 + m[2][0] * other.m[2][2]
320 + m[3][0] * other.m[2][3];
321 m[3][0] = m[0][0] * other.m[3][0]
322 + m[1][0] * other.m[3][1]
323 + m[2][0] * other.m[3][2]
324 + m[3][0] * other.m[3][3];
325 m[0][0] = m0;
326 m[1][0] = m1;
327 m[2][0] = m2;
328
329 m0 = m[0][1] * other.m[0][0]
330 + m[1][1] * other.m[0][1]
331 + m[2][1] * other.m[0][2]
332 + m[3][1] * other.m[0][3];
333 m1 = m[0][1] * other.m[1][0]
334 + m[1][1] * other.m[1][1]
335 + m[2][1] * other.m[1][2]
336 + m[3][1] * other.m[1][3];
337 m2 = m[0][1] * other.m[2][0]
338 + m[1][1] * other.m[2][1]
339 + m[2][1] * other.m[2][2]
340 + m[3][1] * other.m[2][3];
341 m[3][1] = m[0][1] * other.m[3][0]
342 + m[1][1] * other.m[3][1]
343 + m[2][1] * other.m[3][2]
344 + m[3][1] * other.m[3][3];
345 m[0][1] = m0;
346 m[1][1] = m1;
347 m[2][1] = m2;
348
349 m0 = m[0][2] * other.m[0][0]
350 + m[1][2] * other.m[0][1]
351 + m[2][2] * other.m[0][2]
352 + m[3][2] * other.m[0][3];
353 m1 = m[0][2] * other.m[1][0]
354 + m[1][2] * other.m[1][1]
355 + m[2][2] * other.m[1][2]
356 + m[3][2] * other.m[1][3];
357 m2 = m[0][2] * other.m[2][0]
358 + m[1][2] * other.m[2][1]
359 + m[2][2] * other.m[2][2]
360 + m[3][2] * other.m[2][3];
361 m[3][2] = m[0][2] * other.m[3][0]
362 + m[1][2] * other.m[3][1]
363 + m[2][2] * other.m[3][2]
364 + m[3][2] * other.m[3][3];
365 m[0][2] = m0;
366 m[1][2] = m1;
367 m[2][2] = m2;
368
369 m0 = m[0][3] * other.m[0][0]
370 + m[1][3] * other.m[0][1]
371 + m[2][3] * other.m[0][2]
372 + m[3][3] * other.m[0][3];
373 m1 = m[0][3] * other.m[1][0]
374 + m[1][3] * other.m[1][1]
375 + m[2][3] * other.m[1][2]
376 + m[3][3] * other.m[1][3];
377 m2 = m[0][3] * other.m[2][0]
378 + m[1][3] * other.m[2][1]
379 + m[2][3] * other.m[2][2]
380 + m[3][3] * other.m[2][3];
381 m[3][3] = m[0][3] * other.m[3][0]
382 + m[1][3] * other.m[3][1]
383 + m[2][3] * other.m[3][2]
384 + m[3][3] * other.m[3][3];
385 m[0][3] = m0;
386 m[1][3] = m1;
387 m[2][3] = m2;
388 return *this;
389}
390
391inline QDoubleMatrix4x4& QDoubleMatrix4x4::operator*=(double factor)
392{
393 m[0][0] *= factor;
394 m[0][1] *= factor;
395 m[0][2] *= factor;
396 m[0][3] *= factor;
397 m[1][0] *= factor;
398 m[1][1] *= factor;
399 m[1][2] *= factor;
400 m[1][3] *= factor;
401 m[2][0] *= factor;
402 m[2][1] *= factor;
403 m[2][2] *= factor;
404 m[2][3] *= factor;
405 m[3][0] *= factor;
406 m[3][1] *= factor;
407 m[3][2] *= factor;
408 m[3][3] *= factor;
409 flagBits = General;
410 return *this;
411}
412
413inline bool QDoubleMatrix4x4::operator==(const QDoubleMatrix4x4& other) const
414{
415 return m[0][0] == other.m[0][0] &&
416 m[0][1] == other.m[0][1] &&
417 m[0][2] == other.m[0][2] &&
418 m[0][3] == other.m[0][3] &&
419 m[1][0] == other.m[1][0] &&
420 m[1][1] == other.m[1][1] &&
421 m[1][2] == other.m[1][2] &&
422 m[1][3] == other.m[1][3] &&
423 m[2][0] == other.m[2][0] &&
424 m[2][1] == other.m[2][1] &&
425 m[2][2] == other.m[2][2] &&
426 m[2][3] == other.m[2][3] &&
427 m[3][0] == other.m[3][0] &&
428 m[3][1] == other.m[3][1] &&
429 m[3][2] == other.m[3][2] &&
430 m[3][3] == other.m[3][3];
431}
432
433inline bool QDoubleMatrix4x4::operator!=(const QDoubleMatrix4x4& other) const
434{
435 return m[0][0] != other.m[0][0] ||
436 m[0][1] != other.m[0][1] ||
437 m[0][2] != other.m[0][2] ||
438 m[0][3] != other.m[0][3] ||
439 m[1][0] != other.m[1][0] ||
440 m[1][1] != other.m[1][1] ||
441 m[1][2] != other.m[1][2] ||
442 m[1][3] != other.m[1][3] ||
443 m[2][0] != other.m[2][0] ||
444 m[2][1] != other.m[2][1] ||
445 m[2][2] != other.m[2][2] ||
446 m[2][3] != other.m[2][3] ||
447 m[3][0] != other.m[3][0] ||
448 m[3][1] != other.m[3][1] ||
449 m[3][2] != other.m[3][2] ||
450 m[3][3] != other.m[3][3];
451}
452
453inline QDoubleMatrix4x4 operator+(const QDoubleMatrix4x4& m1, const QDoubleMatrix4x4& m2)
454{
455 QDoubleMatrix4x4 m(1);
456 m.m[0][0] = m1.m[0][0] + m2.m[0][0];
457 m.m[0][1] = m1.m[0][1] + m2.m[0][1];
458 m.m[0][2] = m1.m[0][2] + m2.m[0][2];
459 m.m[0][3] = m1.m[0][3] + m2.m[0][3];
460 m.m[1][0] = m1.m[1][0] + m2.m[1][0];
461 m.m[1][1] = m1.m[1][1] + m2.m[1][1];
462 m.m[1][2] = m1.m[1][2] + m2.m[1][2];
463 m.m[1][3] = m1.m[1][3] + m2.m[1][3];
464 m.m[2][0] = m1.m[2][0] + m2.m[2][0];
465 m.m[2][1] = m1.m[2][1] + m2.m[2][1];
466 m.m[2][2] = m1.m[2][2] + m2.m[2][2];
467 m.m[2][3] = m1.m[2][3] + m2.m[2][3];
468 m.m[3][0] = m1.m[3][0] + m2.m[3][0];
469 m.m[3][1] = m1.m[3][1] + m2.m[3][1];
470 m.m[3][2] = m1.m[3][2] + m2.m[3][2];
471 m.m[3][3] = m1.m[3][3] + m2.m[3][3];
472 m.flagBits = QDoubleMatrix4x4::General;
473 return m;
474}
475
476inline QDoubleMatrix4x4 operator-(const QDoubleMatrix4x4& m1, const QDoubleMatrix4x4& m2)
477{
478 QDoubleMatrix4x4 m(1);
479 m.m[0][0] = m1.m[0][0] - m2.m[0][0];
480 m.m[0][1] = m1.m[0][1] - m2.m[0][1];
481 m.m[0][2] = m1.m[0][2] - m2.m[0][2];
482 m.m[0][3] = m1.m[0][3] - m2.m[0][3];
483 m.m[1][0] = m1.m[1][0] - m2.m[1][0];
484 m.m[1][1] = m1.m[1][1] - m2.m[1][1];
485 m.m[1][2] = m1.m[1][2] - m2.m[1][2];
486 m.m[1][3] = m1.m[1][3] - m2.m[1][3];
487 m.m[2][0] = m1.m[2][0] - m2.m[2][0];
488 m.m[2][1] = m1.m[2][1] - m2.m[2][1];
489 m.m[2][2] = m1.m[2][2] - m2.m[2][2];
490 m.m[2][3] = m1.m[2][3] - m2.m[2][3];
491 m.m[3][0] = m1.m[3][0] - m2.m[3][0];
492 m.m[3][1] = m1.m[3][1] - m2.m[3][1];
493 m.m[3][2] = m1.m[3][2] - m2.m[3][2];
494 m.m[3][3] = m1.m[3][3] - m2.m[3][3];
495 m.flagBits = QDoubleMatrix4x4::General;
496 return m;
497}
498
499inline QDoubleMatrix4x4 operator*(const QDoubleMatrix4x4& m1, const QDoubleMatrix4x4& m2)
500{
501 int flagBits = m1.flagBits | m2.flagBits;
502 if (flagBits < QDoubleMatrix4x4::Rotation2D) {
503 QDoubleMatrix4x4 m = m1;
504 m.m[3][0] += m.m[0][0] * m2.m[3][0];
505 m.m[3][1] += m.m[1][1] * m2.m[3][1];
506 m.m[3][2] += m.m[2][2] * m2.m[3][2];
507
508 m.m[0][0] *= m2.m[0][0];
509 m.m[1][1] *= m2.m[1][1];
510 m.m[2][2] *= m2.m[2][2];
511 m.flagBits = flagBits;
512 return m;
513 }
514
515 QDoubleMatrix4x4 m(1);
516 m.m[0][0] = m1.m[0][0] * m2.m[0][0]
517 + m1.m[1][0] * m2.m[0][1]
518 + m1.m[2][0] * m2.m[0][2]
519 + m1.m[3][0] * m2.m[0][3];
520 m.m[0][1] = m1.m[0][1] * m2.m[0][0]
521 + m1.m[1][1] * m2.m[0][1]
522 + m1.m[2][1] * m2.m[0][2]
523 + m1.m[3][1] * m2.m[0][3];
524 m.m[0][2] = m1.m[0][2] * m2.m[0][0]
525 + m1.m[1][2] * m2.m[0][1]
526 + m1.m[2][2] * m2.m[0][2]
527 + m1.m[3][2] * m2.m[0][3];
528 m.m[0][3] = m1.m[0][3] * m2.m[0][0]
529 + m1.m[1][3] * m2.m[0][1]
530 + m1.m[2][3] * m2.m[0][2]
531 + m1.m[3][3] * m2.m[0][3];
532
533 m.m[1][0] = m1.m[0][0] * m2.m[1][0]
534 + m1.m[1][0] * m2.m[1][1]
535 + m1.m[2][0] * m2.m[1][2]
536 + m1.m[3][0] * m2.m[1][3];
537 m.m[1][1] = m1.m[0][1] * m2.m[1][0]
538 + m1.m[1][1] * m2.m[1][1]
539 + m1.m[2][1] * m2.m[1][2]
540 + m1.m[3][1] * m2.m[1][3];
541 m.m[1][2] = m1.m[0][2] * m2.m[1][0]
542 + m1.m[1][2] * m2.m[1][1]
543 + m1.m[2][2] * m2.m[1][2]
544 + m1.m[3][2] * m2.m[1][3];
545 m.m[1][3] = m1.m[0][3] * m2.m[1][0]
546 + m1.m[1][3] * m2.m[1][1]
547 + m1.m[2][3] * m2.m[1][2]
548 + m1.m[3][3] * m2.m[1][3];
549
550 m.m[2][0] = m1.m[0][0] * m2.m[2][0]
551 + m1.m[1][0] * m2.m[2][1]
552 + m1.m[2][0] * m2.m[2][2]
553 + m1.m[3][0] * m2.m[2][3];
554 m.m[2][1] = m1.m[0][1] * m2.m[2][0]
555 + m1.m[1][1] * m2.m[2][1]
556 + m1.m[2][1] * m2.m[2][2]
557 + m1.m[3][1] * m2.m[2][3];
558 m.m[2][2] = m1.m[0][2] * m2.m[2][0]
559 + m1.m[1][2] * m2.m[2][1]
560 + m1.m[2][2] * m2.m[2][2]
561 + m1.m[3][2] * m2.m[2][3];
562 m.m[2][3] = m1.m[0][3] * m2.m[2][0]
563 + m1.m[1][3] * m2.m[2][1]
564 + m1.m[2][3] * m2.m[2][2]
565 + m1.m[3][3] * m2.m[2][3];
566
567 m.m[3][0] = m1.m[0][0] * m2.m[3][0]
568 + m1.m[1][0] * m2.m[3][1]
569 + m1.m[2][0] * m2.m[3][2]
570 + m1.m[3][0] * m2.m[3][3];
571 m.m[3][1] = m1.m[0][1] * m2.m[3][0]
572 + m1.m[1][1] * m2.m[3][1]
573 + m1.m[2][1] * m2.m[3][2]
574 + m1.m[3][1] * m2.m[3][3];
575 m.m[3][2] = m1.m[0][2] * m2.m[3][0]
576 + m1.m[1][2] * m2.m[3][1]
577 + m1.m[2][2] * m2.m[3][2]
578 + m1.m[3][2] * m2.m[3][3];
579 m.m[3][3] = m1.m[0][3] * m2.m[3][0]
580 + m1.m[1][3] * m2.m[3][1]
581 + m1.m[2][3] * m2.m[3][2]
582 + m1.m[3][3] * m2.m[3][3];
583 m.flagBits = flagBits;
584 return m;
585}
586
587inline QDoubleVector3D operator*(const QDoubleVector3D& vector, const QDoubleMatrix4x4& matrix)
588{
589 double x, y, z, w;
590 x = vector.x() * matrix.m[0][0] +
591 vector.y() * matrix.m[0][1] +
592 vector.z() * matrix.m[0][2] +
593 matrix.m[0][3];
594 y = vector.x() * matrix.m[1][0] +
595 vector.y() * matrix.m[1][1] +
596 vector.z() * matrix.m[1][2] +
597 matrix.m[1][3];
598 z = vector.x() * matrix.m[2][0] +
599 vector.y() * matrix.m[2][1] +
600 vector.z() * matrix.m[2][2] +
601 matrix.m[2][3];
602 w = vector.x() * matrix.m[3][0] +
603 vector.y() * matrix.m[3][1] +
604 vector.z() * matrix.m[3][2] +
605 matrix.m[3][3];
606 if (w == 1.0f)
607 return QDoubleVector3D(x, y, z);
608 else
609 return QDoubleVector3D(x / w, y / w, z / w);
610}
611
612inline QDoubleVector3D operator*(const QDoubleMatrix4x4& matrix, const QDoubleVector3D& vector)
613{
614 double x, y, z, w;
615 if (matrix.flagBits == QDoubleMatrix4x4::Identity) {
616 return vector;
617 } else if (matrix.flagBits < QDoubleMatrix4x4::Rotation2D) {
618 // Translation | Scale
619 return QDoubleVector3D(vector.x() * matrix.m[0][0] + matrix.m[3][0],
620 vector.y() * matrix.m[1][1] + matrix.m[3][1],
621 vector.z() * matrix.m[2][2] + matrix.m[3][2]);
622 } else if (matrix.flagBits < QDoubleMatrix4x4::Rotation) {
623 // Translation | Scale | Rotation2D
624 return QDoubleVector3D(vector.x() * matrix.m[0][0] + vector.y() * matrix.m[1][0] + matrix.m[3][0],
625 vector.x() * matrix.m[0][1] + vector.y() * matrix.m[1][1] + matrix.m[3][1],
626 vector.z() * matrix.m[2][2] + matrix.m[3][2]);
627 } else {
628 x = vector.x() * matrix.m[0][0] +
629 vector.y() * matrix.m[1][0] +
630 vector.z() * matrix.m[2][0] +
631 matrix.m[3][0];
632 y = vector.x() * matrix.m[0][1] +
633 vector.y() * matrix.m[1][1] +
634 vector.z() * matrix.m[2][1] +
635 matrix.m[3][1];
636 z = vector.x() * matrix.m[0][2] +
637 vector.y() * matrix.m[1][2] +
638 vector.z() * matrix.m[2][2] +
639 matrix.m[3][2];
640 w = vector.x() * matrix.m[0][3] +
641 vector.y() * matrix.m[1][3] +
642 vector.z() * matrix.m[2][3] +
643 matrix.m[3][3];
644 if (w == 1.0f)
645 return QDoubleVector3D(x, y, z);
646 else
647 return QDoubleVector3D(x / w, y / w, z / w);
648 }
649}
650
651inline QPoint operator*(const QPoint& point, const QDoubleMatrix4x4& matrix)
652{
653 double xin, yin;
654 double x, y, w;
655 xin = point.x();
656 yin = point.y();
657 x = xin * matrix.m[0][0] +
658 yin * matrix.m[0][1] +
659 matrix.m[0][3];
660 y = xin * matrix.m[1][0] +
661 yin * matrix.m[1][1] +
662 matrix.m[1][3];
663 w = xin * matrix.m[3][0] +
664 yin * matrix.m[3][1] +
665 matrix.m[3][3];
666 if (w == 1.0f)
667 return QPoint(qRound(x), qRound(y));
668 else
669 return QPoint(qRound(x / w), qRound(y / w));
670}
671
672inline QPointF operator*(const QPointF& point, const QDoubleMatrix4x4& matrix)
673{
674 double xin, yin;
675 double x, y, w;
676 xin = point.x();
677 yin = point.y();
678 x = xin * matrix.m[0][0] +
679 yin * matrix.m[0][1] +
680 matrix.m[0][3];
681 y = xin * matrix.m[1][0] +
682 yin * matrix.m[1][1] +
683 matrix.m[1][3];
684 w = xin * matrix.m[3][0] +
685 yin * matrix.m[3][1] +
686 matrix.m[3][3];
687 if (w == 1.0f) {
688 return QPointF(double(x), double(y));
689 } else {
690 return QPointF(double(x / w), double(y / w));
691 }
692}
693
694inline QPoint operator*(const QDoubleMatrix4x4& matrix, const QPoint& point)
695{
696 double xin, yin;
697 double x, y, w;
698 xin = point.x();
699 yin = point.y();
700 if (matrix.flagBits == QDoubleMatrix4x4::Identity) {
701 return point;
702 } else if (matrix.flagBits < QDoubleMatrix4x4::Rotation2D) {
703 // Translation | Scale
704 return QPoint(qRound(xin * matrix.m[0][0] + matrix.m[3][0]),
705 qRound(yin * matrix.m[1][1] + matrix.m[3][1]));
706 } else if (matrix.flagBits < QDoubleMatrix4x4::Perspective) {
707 return QPoint(qRound(xin * matrix.m[0][0] + yin * matrix.m[1][0] + matrix.m[3][0]),
708 qRound(xin * matrix.m[0][1] + yin * matrix.m[1][1] + matrix.m[3][1]));
709 } else {
710 x = xin * matrix.m[0][0] +
711 yin * matrix.m[1][0] +
712 matrix.m[3][0];
713 y = xin * matrix.m[0][1] +
714 yin * matrix.m[1][1] +
715 matrix.m[3][1];
716 w = xin * matrix.m[0][3] +
717 yin * matrix.m[1][3] +
718 matrix.m[3][3];
719 if (w == 1.0f)
720 return QPoint(qRound(x), qRound(y));
721 else
722 return QPoint(qRound(x / w), qRound(y / w));
723 }
724}
725
726inline QPointF operator*(const QDoubleMatrix4x4& matrix, const QPointF& point)
727{
728 double xin, yin;
729 double x, y, w;
730 xin = point.x();
731 yin = point.y();
732 if (matrix.flagBits == QDoubleMatrix4x4::Identity) {
733 return point;
734 } else if (matrix.flagBits < QDoubleMatrix4x4::Rotation2D) {
735 // Translation | Scale
736 return QPointF(xin * matrix.m[0][0] + matrix.m[3][0],
737 yin * matrix.m[1][1] + matrix.m[3][1]);
738 } else if (matrix.flagBits < QDoubleMatrix4x4::Perspective) {
739 return QPointF(xin * matrix.m[0][0] + yin * matrix.m[1][0] + matrix.m[3][0],
740 xin * matrix.m[0][1] + yin * matrix.m[1][1] + matrix.m[3][1]);
741 } else {
742 x = xin * matrix.m[0][0] +
743 yin * matrix.m[1][0] +
744 matrix.m[3][0];
745 y = xin * matrix.m[0][1] +
746 yin * matrix.m[1][1] +
747 matrix.m[3][1];
748 w = xin * matrix.m[0][3] +
749 yin * matrix.m[1][3] +
750 matrix.m[3][3];
751 if (w == 1.0f) {
752 return QPointF(double(x), double(y));
753 } else {
754 return QPointF(double(x / w), double(y / w));
755 }
756 }
757}
758
759inline QDoubleMatrix4x4 operator-(const QDoubleMatrix4x4& matrix)
760{
761 QDoubleMatrix4x4 m(1);
762 m.m[0][0] = -matrix.m[0][0];
763 m.m[0][1] = -matrix.m[0][1];
764 m.m[0][2] = -matrix.m[0][2];
765 m.m[0][3] = -matrix.m[0][3];
766 m.m[1][0] = -matrix.m[1][0];
767 m.m[1][1] = -matrix.m[1][1];
768 m.m[1][2] = -matrix.m[1][2];
769 m.m[1][3] = -matrix.m[1][3];
770 m.m[2][0] = -matrix.m[2][0];
771 m.m[2][1] = -matrix.m[2][1];
772 m.m[2][2] = -matrix.m[2][2];
773 m.m[2][3] = -matrix.m[2][3];
774 m.m[3][0] = -matrix.m[3][0];
775 m.m[3][1] = -matrix.m[3][1];
776 m.m[3][2] = -matrix.m[3][2];
777 m.m[3][3] = -matrix.m[3][3];
778 m.flagBits = QDoubleMatrix4x4::General;
779 return m;
780}
781
782inline QDoubleMatrix4x4 operator*(double factor, const QDoubleMatrix4x4& matrix)
783{
784 QDoubleMatrix4x4 m(1);
785 m.m[0][0] = matrix.m[0][0] * factor;
786 m.m[0][1] = matrix.m[0][1] * factor;
787 m.m[0][2] = matrix.m[0][2] * factor;
788 m.m[0][3] = matrix.m[0][3] * factor;
789 m.m[1][0] = matrix.m[1][0] * factor;
790 m.m[1][1] = matrix.m[1][1] * factor;
791 m.m[1][2] = matrix.m[1][2] * factor;
792 m.m[1][3] = matrix.m[1][3] * factor;
793 m.m[2][0] = matrix.m[2][0] * factor;
794 m.m[2][1] = matrix.m[2][1] * factor;
795 m.m[2][2] = matrix.m[2][2] * factor;
796 m.m[2][3] = matrix.m[2][3] * factor;
797 m.m[3][0] = matrix.m[3][0] * factor;
798 m.m[3][1] = matrix.m[3][1] * factor;
799 m.m[3][2] = matrix.m[3][2] * factor;
800 m.m[3][3] = matrix.m[3][3] * factor;
801 m.flagBits = QDoubleMatrix4x4::General;
802 return m;
803}
804
805inline QDoubleMatrix4x4 operator*(const QDoubleMatrix4x4& matrix, double factor)
806{
807 QDoubleMatrix4x4 m(1);
808 m.m[0][0] = matrix.m[0][0] * factor;
809 m.m[0][1] = matrix.m[0][1] * factor;
810 m.m[0][2] = matrix.m[0][2] * factor;
811 m.m[0][3] = matrix.m[0][3] * factor;
812 m.m[1][0] = matrix.m[1][0] * factor;
813 m.m[1][1] = matrix.m[1][1] * factor;
814 m.m[1][2] = matrix.m[1][2] * factor;
815 m.m[1][3] = matrix.m[1][3] * factor;
816 m.m[2][0] = matrix.m[2][0] * factor;
817 m.m[2][1] = matrix.m[2][1] * factor;
818 m.m[2][2] = matrix.m[2][2] * factor;
819 m.m[2][3] = matrix.m[2][3] * factor;
820 m.m[3][0] = matrix.m[3][0] * factor;
821 m.m[3][1] = matrix.m[3][1] * factor;
822 m.m[3][2] = matrix.m[3][2] * factor;
823 m.m[3][3] = matrix.m[3][3] * factor;
824 m.flagBits = QDoubleMatrix4x4::General;
825 return m;
826}
827
828inline bool qFuzzyCompare(const QDoubleMatrix4x4& m1, const QDoubleMatrix4x4& m2)
829{
830 return QtPrivate::fuzzyCompare(m1.m[0][0], m2.m[0][0])
831 && QtPrivate::fuzzyCompare(m1.m[0][1], m2.m[0][1])
832 && QtPrivate::fuzzyCompare(m1.m[0][2], m2.m[0][2])
833 && QtPrivate::fuzzyCompare(m1.m[0][3], m2.m[0][3])
834 && QtPrivate::fuzzyCompare(m1.m[1][0], m2.m[1][0])
835 && QtPrivate::fuzzyCompare(m1.m[1][1], m2.m[1][1])
836 && QtPrivate::fuzzyCompare(m1.m[1][2], m2.m[1][2])
837 && QtPrivate::fuzzyCompare(m1.m[1][3], m2.m[1][3])
838 && QtPrivate::fuzzyCompare(m1.m[2][0], m2.m[2][0])
839 && QtPrivate::fuzzyCompare(m1.m[2][1], m2.m[2][1])
840 && QtPrivate::fuzzyCompare(m1.m[2][2], m2.m[2][2])
841 && QtPrivate::fuzzyCompare(m1.m[2][3], m2.m[2][3])
842 && QtPrivate::fuzzyCompare(m1.m[3][0], m2.m[3][0])
843 && QtPrivate::fuzzyCompare(m1.m[3][1], m2.m[3][1])
844 && QtPrivate::fuzzyCompare(m1.m[3][2], m2.m[3][2])
845 && QtPrivate::fuzzyCompare(m1.m[3][3], m2.m[3][3]);
846}
847
848inline QPoint QDoubleMatrix4x4::map(const QPoint& point) const
849{
850 return *this * point;
851}
852
853inline QPointF QDoubleMatrix4x4::map(const QPointF& point) const
854{
855 return *this * point;
856}
857
858inline QDoubleVector3D QDoubleMatrix4x4::map(const QDoubleVector3D& point) const
859{
860 return *this * point;
861}
862
863inline QDoubleVector3D QDoubleMatrix4x4::mapVector(const QDoubleVector3D& vector) const
864{
865 if (flagBits < Scale) {
866 // Translation
867 return vector;
868 } else if (flagBits < Rotation2D) {
869 // Translation | Scale
870 return QDoubleVector3D(vector.x() * m[0][0],
871 vector.y() * m[1][1],
872 vector.z() * m[2][2]);
873 } else {
874 return QDoubleVector3D(vector.x() * m[0][0] +
875 vector.y() * m[1][0] +
876 vector.z() * m[2][0],
877 vector.x() * m[0][1] +
878 vector.y() * m[1][1] +
879 vector.z() * m[2][1],
880 vector.x() * m[0][2] +
881 vector.y() * m[1][2] +
882 vector.z() * m[2][2]);
883 }
884}
885
886inline double *QDoubleMatrix4x4::data()
887{
888 // We have to assume that the caller will modify the matrix elements,
889 // so we flip it over to "General" mode.
890 flagBits = General;
891 return *m;
892}
893
894inline void QDoubleMatrix4x4::viewport(const QRectF &rect)
895{
896 viewport(rect.x(), rect.y(), rect.width(), rect.height());
897}
898
899#ifndef QT_NO_DEBUG_STREAM
900Q_POSITIONING_EXPORT QDebug operator<<(QDebug dbg, const QDoubleMatrix4x4 &m);
901#endif
902
903#ifndef QT_NO_DATASTREAM
904Q_POSITIONING_EXPORT QDataStream &operator<<(QDataStream &, const QDoubleMatrix4x4 &);
905Q_POSITIONING_EXPORT QDataStream &operator>>(QDataStream &, QDoubleMatrix4x4 &);
906#endif
907
908
909QT_END_NAMESPACE
910
911
912#endif // QDOUBLEMATRIX4X4_H
\inmodule QtCore\reentrant
Definition qdatastream.h:50
QVariant operator*(const QVariant &arg1, double multiplier)
QByteArray operator+(const QByteArray &a1, const QByteArray &a2)
Definition qbytearray.h:705
Q_DECLARE_TYPEINFO(QByteArrayView, Q_PRIMITIVE_TYPE)
Q_CORE_EXPORT QDebug operator<<(QDebug debug, QDir::Filters filters)
Definition qdir.cpp:2582
static double matrixDet4(const double m[4][4])
QDoubleMatrix4x4 operator/(const QDoubleMatrix4x4 &matrix, double divisor)
static double matrixDet2(const double m[4][4], int col0, int col1, int row0, int row1)
static double matrixDet3(const double m[4][4], int col0, int col1, int col2, int row0, int row1, int row2)
QDoubleMatrix4x4 operator*(double factor, const QDoubleMatrix4x4 &matrix)
QDebug operator<<(QDebug dbg, const QFileInfo &fi)
bool qFuzzyCompare(const QMatrix4x4 &m1, const QMatrix4x4 &m2) noexcept
QMatrix4x4 operator*(const QMatrix4x4 &m1, const QMatrix4x4 &m2)
Definition qmatrix4x4.h:612
QMatrix4x4 operator-(const QMatrix4x4 &matrix)
Definition qmatrix4x4.h:860
QMatrix4x4 operator-(const QMatrix4x4 &m1, const QMatrix4x4 &m2)
Definition qmatrix4x4.h:589
QDataStream & operator<<(QDataStream &stream, const QImage &image)
[0]
Definition qimage.cpp:4010
QDataStream & operator>>(QDataStream &stream, QImage &image)
Definition qimage.cpp:4036