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