Coverage Report

Created: 2026-10-14 08:19

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/qtbase/src/gui/math3d/qvectornd.h
Line
Count
Source
1
// Copyright (C) 2020 The Qt Company Ltd.
2
// Copyright (C) 2020 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
3
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
// Qt-Security score:significant reason:default
5
6
#ifndef QVECTORND_H
7
#define QVECTORND_H
8
9
#include <QtGui/qtguiglobal.h>
10
11
#include <QtCore/qhashfunctions.h>
12
#include <QtCore/qpoint.h>
13
#include <QtCore/qrect.h>
14
#include <QtCore/qmath.h>
15
16
#include <QtCore/q20type_traits.h>
17
#include <QtCore/q23utility.h>
18
19
QT_BEGIN_NAMESPACE
20
21
// QT_ENABLE_P0846_SEMANTICS_FOR(get) // from qpoint.h
22
23
class QVector2D;
24
class QVector3D;
25
class QVector4D;
26
class QMatrix4x4;
27
class QVariant;
28
29
/***************************** QVector2D *****************************/
30
31
#ifndef QT_NO_VECTOR2D
32
33
class QVector2D
34
{
35
public:
36
    constexpr QVector2D() noexcept;
37
0
    explicit QVector2D(Qt::Initialization) noexcept {}
38
    constexpr QVector2D(float xpos, float ypos) noexcept;
39
    constexpr explicit QVector2D(QPoint point) noexcept;
40
    constexpr explicit QVector2D(QPointF point) noexcept;
41
#ifndef QT_NO_VECTOR3D
42
    constexpr explicit QVector2D(QVector3D vector) noexcept;
43
#endif
44
#ifndef QT_NO_VECTOR4D
45
    constexpr explicit QVector2D(QVector4D vector) noexcept;
46
#endif
47
48
    constexpr bool isNull() const noexcept;
49
50
    constexpr float x() const noexcept;
51
    constexpr float y() const noexcept;
52
53
    constexpr void setX(float x) noexcept;
54
    constexpr void setY(float y) noexcept;
55
56
    constexpr float &operator[](int i);
57
    constexpr float operator[](int i) const;
58
59
    [[nodiscard]] float length() const noexcept;
60
    [[nodiscard]] constexpr float lengthSquared() const noexcept;
61
62
    [[nodiscard]] QVector2D normalized() const noexcept;
63
    void normalize() noexcept;
64
65
    [[nodiscard]] float distanceToPoint(QVector2D point) const noexcept;
66
    [[nodiscard]] float distanceToLine(QVector2D point, QVector2D direction) const noexcept;
67
68
    constexpr QVector2D &operator+=(QVector2D vector) noexcept;
69
    constexpr QVector2D &operator-=(QVector2D vector) noexcept;
70
    constexpr QVector2D &operator*=(float factor) noexcept;
71
    constexpr QVector2D &operator*=(QVector2D vector) noexcept;
72
    constexpr QVector2D &operator/=(float divisor);
73
    constexpr QVector2D &operator/=(QVector2D vector);
74
75
    [[nodiscard]] static constexpr float dotProduct(QVector2D v1, QVector2D v2) noexcept;
76
77
QT_WARNING_PUSH
78
QT_WARNING_DISABLE_FLOAT_COMPARE
79
    constexpr friend inline bool operator==(QVector2D v1, QVector2D v2) noexcept
80
0
    {
81
0
        return v1.v[0] == v2.v[0] && v1.v[1] == v2.v[1];
82
0
    }
83
84
    constexpr friend inline bool operator!=(QVector2D v1, QVector2D v2) noexcept
85
0
    {
86
0
        return v1.v[0] != v2.v[0] || v1.v[1] != v2.v[1];
87
0
    }
88
QT_WARNING_POP
89
    constexpr friend size_t qHash(QVector2D key, size_t seed = 0) noexcept
90
0
    {
91
0
        return qHashMulti(seed, key.x(), key.y());
92
0
    }
93
94
    constexpr friend inline QVector2D operator+(QVector2D v1, QVector2D v2) noexcept
95
0
    {
96
0
        return QVector2D(v1.v[0] + v2.v[0], v1.v[1] + v2.v[1]);
97
0
    }
98
99
    constexpr friend inline QVector2D operator-(QVector2D v1, QVector2D v2) noexcept
100
0
    {
101
0
        return QVector2D(v1.v[0] - v2.v[0], v1.v[1] - v2.v[1]);
102
0
    }
103
104
    constexpr friend inline QVector2D operator*(float factor, QVector2D vector) noexcept
105
0
    {
106
0
        return QVector2D(vector.v[0] * factor, vector.v[1] * factor);
107
0
    }
108
109
    constexpr friend inline QVector2D operator*(QVector2D vector, float factor) noexcept
110
0
    {
111
0
        return QVector2D(vector.v[0] * factor, vector.v[1] * factor);
112
0
    }
113
114
    constexpr friend inline QVector2D operator*(QVector2D v1, QVector2D v2) noexcept
115
0
    {
116
0
        return QVector2D(v1.v[0] * v2.v[0], v1.v[1] * v2.v[1]);
117
0
    }
118
119
    constexpr friend inline QVector2D operator-(QVector2D vector) noexcept
120
0
    {
121
0
        return QVector2D(-vector.v[0], -vector.v[1]);
122
0
    }
123
124
    constexpr friend inline QVector2D operator/(QVector2D vector, float divisor)
125
0
    {
126
0
        Q_ASSERT(divisor < 0 || divisor > 0);
127
0
        return QVector2D(vector.v[0] / divisor, vector.v[1] / divisor);
128
0
    }
129
130
    constexpr friend inline QVector2D operator/(QVector2D vector, QVector2D divisor)
131
0
    {
132
0
        Q_ASSERT(divisor.v[0] < 0 || divisor.v[0] > 0);
133
0
        Q_ASSERT(divisor.v[1] < 0 || divisor.v[1] > 0);
134
0
        return QVector2D(vector.v[0] / divisor.v[0], vector.v[1] / divisor.v[1]);
135
0
    }
136
137
    friend Q_GUI_EXPORT bool qFuzzyCompare(QVector2D v1, QVector2D v2) noexcept;
138
139
#ifndef QT_NO_VECTOR3D
140
    constexpr QVector3D toVector3D() const noexcept;
141
#endif
142
#ifndef QT_NO_VECTOR4D
143
    constexpr QVector4D toVector4D() const noexcept;
144
#endif
145
146
    constexpr QPoint toPoint() const noexcept;
147
    constexpr QPointF toPointF() const noexcept;
148
149
    Q_GUI_EXPORT operator QVariant() const;
150
151
private:
152
    float v[2];
153
154
    friend class QVector3D;
155
    friend class QVector4D;
156
157
    template <std::size_t I,
158
              typename V,
159
              std::enable_if_t<(I < 2), bool> = true,
160
              std::enable_if_t<std::is_same_v<q20::remove_cvref_t<V>, QVector2D>, bool> = true>
161
    friend constexpr decltype(auto) get(V &&vec) noexcept
162
    {
163
        return q23::forward_like<V>(vec.v[I]);
164
    }
165
};
166
167
Q_DECLARE_TYPEINFO(QVector2D, Q_PRIMITIVE_TYPE);
168
169
#endif // QT_NO_VECTOR2D
170
171
172
173
/***************************** QVector3D *****************************/
174
175
#ifndef QT_NO_VECTOR3D
176
177
class QVector3D
178
{
179
public:
180
    constexpr QVector3D() noexcept;
181
0
    explicit QVector3D(Qt::Initialization) noexcept {}
182
0
    constexpr QVector3D(float xpos, float ypos, float zpos) noexcept : v{xpos, ypos, zpos} {}
183
184
    constexpr explicit QVector3D(QPoint point) noexcept;
185
    constexpr explicit QVector3D(QPointF point) noexcept;
186
#ifndef QT_NO_VECTOR2D
187
    constexpr explicit QVector3D(QVector2D vector) noexcept;
188
    constexpr QVector3D(QVector2D vector, float zpos) noexcept;
189
#endif
190
#ifndef QT_NO_VECTOR4D
191
    constexpr explicit QVector3D(QVector4D vector) noexcept;
192
#endif
193
194
    constexpr bool isNull() const noexcept;
195
196
    constexpr float x() const noexcept;
197
    constexpr float y() const noexcept;
198
    constexpr float z() const noexcept;
199
200
    constexpr void setX(float x) noexcept;
201
    constexpr void setY(float y) noexcept;
202
    constexpr void setZ(float z) noexcept;
203
204
    constexpr float &operator[](int i);
205
    constexpr float operator[](int i) const;
206
207
    [[nodiscard]] float length() const noexcept;
208
    [[nodiscard]] constexpr float lengthSquared() const noexcept;
209
210
    [[nodiscard]] QVector3D normalized() const noexcept;
211
    void normalize() noexcept;
212
213
    constexpr QVector3D &operator+=(QVector3D vector) noexcept;
214
    constexpr QVector3D &operator-=(QVector3D vector) noexcept;
215
    constexpr QVector3D &operator*=(float factor) noexcept;
216
    constexpr QVector3D &operator*=(QVector3D vector) noexcept;
217
    constexpr QVector3D &operator/=(float divisor);
218
    constexpr QVector3D &operator/=(QVector3D vector);
219
220
    [[nodiscard]] static constexpr float dotProduct(QVector3D v1, QVector3D v2) noexcept;
221
    [[nodiscard]] static constexpr QVector3D crossProduct(QVector3D v1, QVector3D v2) noexcept;
222
223
    [[nodiscard]] static QVector3D normal(QVector3D v1, QVector3D v2) noexcept;
224
    [[nodiscard]] static QVector3D normal(QVector3D v1, QVector3D v2, QVector3D v3) noexcept;
225
226
    Q_GUI_EXPORT QVector3D project(const QMatrix4x4 &modelView, const QMatrix4x4 &projection, const QRect &viewport) const;
227
    Q_GUI_EXPORT QVector3D unproject(const QMatrix4x4 &modelView, const QMatrix4x4 &projection, const QRect &viewport) const;
228
229
QT_WARNING_PUSH
230
QT_WARNING_DISABLE_FLOAT_COMPARE
231
    constexpr friend inline bool operator==(QVector3D v1, QVector3D v2) noexcept
232
0
    {
233
0
        return v1.v[0] == v2.v[0] && v1.v[1] == v2.v[1] && v1.v[2] == v2.v[2];
234
0
    }
235
236
    constexpr friend inline bool operator!=(QVector3D v1, QVector3D v2) noexcept
237
0
    {
238
0
        return v1.v[0] != v2.v[0] || v1.v[1] != v2.v[1] || v1.v[2] != v2.v[2];
239
0
    }
240
QT_WARNING_POP
241
    constexpr friend size_t qHash(QVector3D key, size_t seed = 0) noexcept
242
0
    {
243
0
        return qHashMulti(seed, key.x(), key.y(), key.z());
244
0
    }
245
    float distanceToPoint(QVector3D point) const noexcept;
246
    constexpr float distanceToPlane(QVector3D plane, QVector3D normal) const noexcept;
247
    float distanceToPlane(QVector3D plane1, QVector3D plane2, QVector3D plane3) const noexcept;
248
    float distanceToLine(QVector3D point, QVector3D direction) const noexcept;
249
250
251
    constexpr friend inline QVector3D operator+(QVector3D v1, QVector3D v2) noexcept
252
0
    {
253
0
        return QVector3D(v1.v[0] + v2.v[0], v1.v[1] + v2.v[1], v1.v[2] + v2.v[2]);
254
0
    }
255
256
    constexpr friend inline QVector3D operator-(QVector3D v1, QVector3D v2) noexcept
257
0
    {
258
0
        return QVector3D(v1.v[0] - v2.v[0], v1.v[1] - v2.v[1], v1.v[2] - v2.v[2]);
259
0
    }
260
261
    constexpr friend inline QVector3D operator*(float factor, QVector3D vector) noexcept
262
0
    {
263
0
        return QVector3D(vector.v[0] * factor, vector.v[1] * factor, vector.v[2] * factor);
264
0
    }
265
266
    constexpr friend inline QVector3D operator*(QVector3D vector, float factor) noexcept
267
0
    {
268
0
        return QVector3D(vector.v[0] * factor, vector.v[1] * factor, vector.v[2] * factor);
269
0
    }
270
271
    constexpr friend inline QVector3D operator*(QVector3D v1, QVector3D v2) noexcept
272
0
    {
273
0
        return QVector3D(v1.v[0] * v2.v[0], v1.v[1] * v2.v[1], v1.v[2] * v2.v[2]);
274
0
    }
275
276
    constexpr friend inline QVector3D operator-(QVector3D vector) noexcept
277
0
    {
278
0
        return QVector3D(-vector.v[0], -vector.v[1], -vector.v[2]);
279
0
    }
280
281
    constexpr friend inline QVector3D operator/(QVector3D vector, float divisor)
282
0
    {
283
0
        Q_ASSERT(divisor < 0 || divisor > 0);
284
0
        return QVector3D(vector.v[0] / divisor, vector.v[1] / divisor, vector.v[2] / divisor);
285
0
    }
286
287
    constexpr friend inline QVector3D operator/(QVector3D vector, QVector3D divisor)
288
0
    {
289
0
        Q_ASSERT(divisor.v[0] > 0 || divisor.v[0] < 0);
290
0
        Q_ASSERT(divisor.v[1] > 0 || divisor.v[1] < 0);
291
0
        Q_ASSERT(divisor.v[2] > 0 || divisor.v[2] < 0);
292
0
        return QVector3D(vector.v[0] / divisor.v[0], vector.v[1] / divisor.v[1],
293
0
                         vector.v[2] / divisor.v[2]);
294
0
    }
295
296
    friend Q_GUI_EXPORT bool qFuzzyCompare(QVector3D v1, QVector3D v2) noexcept;
297
298
#ifndef QT_NO_VECTOR2D
299
    constexpr QVector2D toVector2D() const noexcept;
300
#endif
301
#ifndef QT_NO_VECTOR4D
302
    constexpr QVector4D toVector4D() const noexcept;
303
#endif
304
305
    constexpr QPoint toPoint() const noexcept;
306
    constexpr QPointF toPointF() const noexcept;
307
308
    Q_GUI_EXPORT operator QVariant() const;
309
310
private:
311
    float v[3];
312
313
    friend class QVector2D;
314
    friend class QVector4D;
315
#ifndef QT_NO_MATRIX4X4
316
    friend QVector3D operator*(const QVector3D& vector, const QMatrix4x4& matrix);
317
    friend QVector3D operator*(const QMatrix4x4& matrix, const QVector3D& vector);
318
#endif
319
320
    template <std::size_t I,
321
              typename V,
322
              std::enable_if_t<(I < 3), bool> = true,
323
              std::enable_if_t<std::is_same_v<q20::remove_cvref_t<V>, QVector3D>, bool> = true>
324
    friend constexpr decltype(auto) get(V &&vec) noexcept
325
    {
326
        return q23::forward_like<V>(vec.v[I]);
327
    }
328
};
329
330
Q_DECLARE_TYPEINFO(QVector3D, Q_PRIMITIVE_TYPE);
331
332
#endif // QT_NO_VECTOR3D
333
334
335
336
/***************************** QVector4D *****************************/
337
338
#ifndef QT_NO_VECTOR4D
339
340
class QVector4D
341
{
342
public:
343
    constexpr QVector4D() noexcept;
344
0
    explicit QVector4D(Qt::Initialization) noexcept {}
345
    constexpr QVector4D(float xpos, float ypos, float zpos, float wpos) noexcept;
346
    constexpr explicit QVector4D(QPoint point) noexcept;
347
    constexpr explicit QVector4D(QPointF point) noexcept;
348
#ifndef QT_NO_VECTOR2D
349
    constexpr explicit QVector4D(QVector2D vector) noexcept;
350
    constexpr QVector4D(QVector2D vector, float zpos, float wpos) noexcept;
351
#endif
352
#ifndef QT_NO_VECTOR3D
353
    constexpr explicit QVector4D(QVector3D vector) noexcept;
354
    constexpr QVector4D(QVector3D vector, float wpos) noexcept;
355
#endif
356
357
    constexpr bool isNull() const noexcept;
358
359
    constexpr float x() const noexcept;
360
    constexpr float y() const noexcept;
361
    constexpr float z() const noexcept;
362
    constexpr float w() const noexcept;
363
364
    constexpr void setX(float x) noexcept;
365
    constexpr void setY(float y) noexcept;
366
    constexpr void setZ(float z) noexcept;
367
    constexpr void setW(float w) noexcept;
368
369
    constexpr float &operator[](int i);
370
    constexpr float operator[](int i) const;
371
372
    [[nodiscard]] float length() const noexcept;
373
    [[nodiscard]] constexpr float lengthSquared() const noexcept;
374
375
    [[nodiscard]] QVector4D normalized() const noexcept;
376
    void normalize() noexcept;
377
378
    constexpr QVector4D &operator+=(QVector4D vector) noexcept;
379
    constexpr QVector4D &operator-=(QVector4D vector) noexcept;
380
    constexpr QVector4D &operator*=(float factor) noexcept;
381
    constexpr QVector4D &operator*=(QVector4D vector) noexcept;
382
    constexpr QVector4D &operator/=(float divisor);
383
    constexpr inline QVector4D &operator/=(QVector4D vector);
384
385
    [[nodiscard]] static constexpr float dotProduct(QVector4D v1, QVector4D v2) noexcept;
386
387
QT_WARNING_PUSH
388
QT_WARNING_DISABLE_FLOAT_COMPARE
389
    constexpr friend inline bool operator==(QVector4D v1, QVector4D v2) noexcept
390
0
    {
391
0
        return v1.v[0] == v2.v[0] && v1.v[1] == v2.v[1] && v1.v[2] == v2.v[2] && v1.v[3] == v2.v[3];
392
0
    }
393
394
    constexpr friend inline bool operator!=(QVector4D v1, QVector4D v2) noexcept
395
0
    {
396
0
        return v1.v[0] != v2.v[0] || v1.v[1] != v2.v[1] || v1.v[2] != v2.v[2] || v1.v[3] != v2.v[3];
397
0
    }
398
QT_WARNING_POP
399
    constexpr friend size_t qHash(QVector4D key, size_t seed = 0) noexcept
400
0
    {
401
0
        return qHashMulti(seed, key.x(), key.y(), key.z(), key.w());
402
0
    }
403
404
    constexpr friend inline QVector4D operator+(QVector4D v1, QVector4D v2) noexcept
405
0
    {
406
0
        return QVector4D(v1.v[0] + v2.v[0], v1.v[1] + v2.v[1], v1.v[2] + v2.v[2], v1.v[3] + v2.v[3]);
407
0
    }
408
409
    constexpr friend inline QVector4D operator-(QVector4D v1, QVector4D v2) noexcept
410
0
    {
411
0
        return QVector4D(v1.v[0] - v2.v[0], v1.v[1] - v2.v[1], v1.v[2] - v2.v[2], v1.v[3] - v2.v[3]);
412
0
    }
413
414
    constexpr friend inline QVector4D operator*(float factor, QVector4D vector) noexcept
415
0
    {
416
0
        return QVector4D(vector.v[0] * factor, vector.v[1] * factor, vector.v[2] * factor, vector.v[3] * factor);
417
0
    }
418
419
    constexpr friend inline QVector4D operator*(QVector4D vector, float factor) noexcept
420
0
    {
421
0
        return QVector4D(vector.v[0] * factor, vector.v[1] * factor, vector.v[2] * factor, vector.v[3] * factor);
422
0
    }
423
424
    constexpr friend inline QVector4D operator*(QVector4D v1, QVector4D v2) noexcept
425
0
    {
426
0
        return QVector4D(v1.v[0] * v2.v[0], v1.v[1] * v2.v[1], v1.v[2] * v2.v[2], v1.v[3] * v2.v[3]);
427
0
    }
428
429
    constexpr friend inline QVector4D operator-(QVector4D vector) noexcept
430
0
    {
431
0
        return QVector4D(-vector.v[0], -vector.v[1], -vector.v[2], -vector.v[3]);
432
0
    }
433
434
    constexpr friend inline QVector4D operator/(QVector4D vector, float divisor)
435
0
    {
436
0
        Q_ASSERT(divisor < 0 || divisor > 0);
437
0
        return QVector4D(vector.v[0] / divisor, vector.v[1] / divisor, vector.v[2] / divisor, vector.v[3] / divisor);
438
0
    }
439
440
    constexpr friend inline QVector4D operator/(QVector4D vector, QVector4D divisor)
441
0
    {
442
0
        Q_ASSERT(divisor.v[0] > 0 || divisor.v[0] < 0);
443
0
        Q_ASSERT(divisor.v[1] > 0 || divisor.v[1] < 0);
444
0
        Q_ASSERT(divisor.v[2] > 0 || divisor.v[2] < 0);
445
0
        Q_ASSERT(divisor.v[3] > 0 || divisor.v[3] < 0);
446
0
        return QVector4D(vector.v[0] / divisor.v[0], vector.v[1] / divisor.v[1],
447
0
                         vector.v[2] / divisor.v[2], vector.v[3] / divisor.v[3]);
448
0
    }
449
450
    friend Q_GUI_EXPORT bool qFuzzyCompare(QVector4D v1, QVector4D v2) noexcept;
451
452
#ifndef QT_NO_VECTOR2D
453
    constexpr QVector2D toVector2D() const noexcept;
454
    constexpr QVector2D toVector2DAffine() const noexcept;
455
#endif
456
#ifndef QT_NO_VECTOR3D
457
    constexpr QVector3D toVector3D() const noexcept;
458
    constexpr QVector3D toVector3DAffine() const noexcept;
459
#endif
460
461
    constexpr QPoint toPoint() const noexcept;
462
    constexpr QPointF toPointF() const noexcept;
463
464
    Q_GUI_EXPORT operator QVariant() const;
465
466
private:
467
    float v[4];
468
469
    friend class QVector2D;
470
    friend class QVector3D;
471
    friend class QMatrix4x4;
472
#ifndef QT_NO_MATRIX4X4
473
    friend QVector4D operator*(const QVector4D& vector, const QMatrix4x4& matrix);
474
    friend QVector4D operator*(const QMatrix4x4& matrix, const QVector4D& vector);
475
#endif
476
477
    template <std::size_t I,
478
              typename V,
479
              std::enable_if_t<(I < 4), bool> = true,
480
              std::enable_if_t<std::is_same_v<q20::remove_cvref_t<V>, QVector4D>, bool> = true>
481
    friend constexpr decltype(auto) get(V &&vec) noexcept
482
    {
483
        return q23::forward_like<V>(vec.v[I]);
484
    }
485
};
486
487
Q_DECLARE_TYPEINFO(QVector4D, Q_PRIMITIVE_TYPE);
488
489
#endif // QT_NO_VECTOR4D
490
491
492
493
/***************************** QVector2D *****************************/
494
495
#ifndef QT_NO_VECTOR2D
496
497
constexpr inline QVector2D::QVector2D() noexcept : v{0.0f, 0.0f} {}
498
499
constexpr inline QVector2D::QVector2D(float xpos, float ypos) noexcept : v{xpos, ypos} {}
500
501
constexpr inline QVector2D::QVector2D(QPoint point) noexcept : v{float(point.x()), float(point.y())} {}
502
503
constexpr inline QVector2D::QVector2D(QPointF point) noexcept : v{float(point.x()), float(point.y())} {}
504
505
#ifndef QT_NO_VECTOR3D
506
constexpr inline QVector2D::QVector2D(QVector3D vector) noexcept : v{vector[0], vector[1]} {}
507
#endif
508
#ifndef QT_NO_VECTOR4D
509
constexpr inline QVector2D::QVector2D(QVector4D vector) noexcept : v{vector[0], vector[1]} {}
510
#endif
511
512
constexpr inline bool QVector2D::isNull() const noexcept
513
0
{
514
0
    return qIsNull(v[0]) && qIsNull(v[1]);
515
0
}
516
517
0
constexpr inline float QVector2D::x() const noexcept { return v[0]; }
518
0
constexpr inline float QVector2D::y() const noexcept { return v[1]; }
519
520
0
constexpr inline void QVector2D::setX(float aX) noexcept { v[0] = aX; }
521
0
constexpr inline void QVector2D::setY(float aY) noexcept { v[1] = aY; }
522
523
constexpr inline float &QVector2D::operator[](int i)
524
0
{
525
0
    Q_ASSERT(uint(i) < 2u);
526
0
    return v[i];
527
0
}
528
529
constexpr inline float QVector2D::operator[](int i) const
530
0
{
531
0
    Q_ASSERT(uint(i) < 2u);
532
0
    return v[i];
533
0
}
534
535
inline float QVector2D::length() const noexcept
536
0
{
537
0
    return qHypot(v[0], v[1]);
538
0
}
539
540
constexpr inline float QVector2D::lengthSquared() const noexcept
541
0
{
542
0
    return v[0] * v[0] + v[1] * v[1];
543
0
}
544
545
inline QVector2D QVector2D::normalized() const noexcept
546
0
{
547
0
    const float len = length();
548
0
    return qFuzzyIsNull(len - 1.0f) ? *this : qFuzzyIsNull(len) ? QVector2D()
549
0
        : QVector2D(v[0] / len, v[1] / len);
550
0
}
551
552
inline void QVector2D::normalize() noexcept
553
0
{
554
0
    const float len = length();
555
0
    if (qFuzzyIsNull(len - 1.0f) || qFuzzyIsNull(len))
556
0
        return;
557
0
558
0
    v[0] /= len;
559
0
    v[1] /= len;
560
0
}
561
562
inline float QVector2D::distanceToPoint(QVector2D point) const noexcept
563
0
{
564
0
    return (*this - point).length();
565
0
}
566
567
inline float QVector2D::distanceToLine(QVector2D point, QVector2D direction) const noexcept
568
0
{
569
0
    if (direction.isNull())
570
0
        return (*this - point).length();
571
0
    QVector2D p = point + dotProduct(*this - point, direction) * direction;
572
0
    return (*this - p).length();
573
0
}
574
575
constexpr inline QVector2D &QVector2D::operator+=(QVector2D vector) noexcept
576
0
{
577
0
    v[0] += vector.v[0];
578
0
    v[1] += vector.v[1];
579
0
    return *this;
580
0
}
581
582
constexpr inline QVector2D &QVector2D::operator-=(QVector2D vector) noexcept
583
0
{
584
0
    v[0] -= vector.v[0];
585
0
    v[1] -= vector.v[1];
586
0
    return *this;
587
0
}
588
589
constexpr inline QVector2D &QVector2D::operator*=(float factor) noexcept
590
0
{
591
0
    v[0] *= factor;
592
0
    v[1] *= factor;
593
0
    return *this;
594
0
}
595
596
constexpr inline QVector2D &QVector2D::operator*=(QVector2D vector) noexcept
597
0
{
598
0
    v[0] *= vector.v[0];
599
0
    v[1] *= vector.v[1];
600
0
    return *this;
601
0
}
602
603
constexpr inline QVector2D &QVector2D::operator/=(float divisor)
604
0
{
605
0
    Q_ASSERT(divisor < 0 || divisor > 0);
606
0
    v[0] /= divisor;
607
0
    v[1] /= divisor;
608
0
    return *this;
609
0
}
610
611
constexpr inline QVector2D &QVector2D::operator/=(QVector2D vector)
612
0
{
613
0
    Q_ASSERT(vector.v[0] > 0 || vector.v[0] < 0);
614
0
    Q_ASSERT(vector.v[1] > 0 || vector.v[1] < 0);
615
0
    v[0] /= vector.v[0];
616
0
    v[1] /= vector.v[1];
617
0
    return *this;
618
0
}
619
620
constexpr inline float QVector2D::dotProduct(QVector2D v1, QVector2D v2) noexcept
621
0
{
622
0
    return v1.v[0] * v2.v[0] + v1.v[1] * v2.v[1];
623
0
}
624
625
#ifndef QT_NO_VECTOR3D
626
constexpr inline QVector3D QVector2D::toVector3D() const noexcept
627
0
{
628
0
    return QVector3D(v[0], v[1], 0.0f);
629
0
}
630
#endif
631
#ifndef QT_NO_VECTOR4D
632
constexpr inline QVector4D QVector2D::toVector4D() const noexcept
633
0
{
634
0
    return QVector4D(v[0], v[1], 0.0f, 0.0f);
635
0
}
636
#endif
637
638
639
constexpr inline QPoint QVector2D::toPoint() const noexcept
640
0
{
641
0
    return QPoint(qRound(v[0]), qRound(v[1]));
642
0
}
643
644
constexpr inline QPointF QVector2D::toPointF() const noexcept
645
0
{
646
0
    return QPointF(qreal(v[0]), qreal(v[1]));
647
0
}
648
649
#ifndef QT_NO_DEBUG_STREAM
650
Q_GUI_EXPORT QDebug operator<<(QDebug dbg, QVector2D vector);
651
#endif
652
653
#ifndef QT_NO_DATASTREAM
654
Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, QVector2D );
655
Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QVector2D &);
656
#endif
657
658
#endif // QT_NO_VECTOR2D
659
660
661
662
/***************************** QVector3D *****************************/
663
664
#ifndef QT_NO_VECTOR3D
665
666
constexpr inline QVector3D::QVector3D() noexcept : v{0.0f, 0.0f, 0.0f} {}
667
668
constexpr inline QVector3D::QVector3D(QPoint point) noexcept : v{float(point.x()), float(point.y()), 0.0f} {}
669
670
constexpr inline QVector3D::QVector3D(QPointF point) noexcept : v{float(point.x()), float(point.y()), 0.0f} {}
671
672
#ifndef QT_NO_VECTOR2D
673
constexpr inline QVector3D::QVector3D(QVector2D vector) noexcept : v{vector[0], vector[1], 0.0f} {}
674
constexpr inline QVector3D::QVector3D(QVector2D vector, float zpos) noexcept : v{vector[0], vector[1], zpos} {}
675
#endif
676
677
#ifndef QT_NO_VECTOR4D
678
constexpr inline QVector3D::QVector3D(QVector4D vector) noexcept : v{vector[0], vector[1], vector[2]} {}
679
#endif
680
681
constexpr inline bool QVector3D::isNull() const noexcept
682
0
{
683
0
    return qIsNull(v[0]) && qIsNull(v[1]) && qIsNull(v[2]);
684
0
}
685
686
0
constexpr inline float QVector3D::x() const noexcept { return v[0]; }
687
0
constexpr inline float QVector3D::y() const noexcept { return v[1]; }
688
0
constexpr inline float QVector3D::z() const noexcept { return v[2]; }
689
690
0
constexpr inline void QVector3D::setX(float aX) noexcept { v[0] = aX; }
691
0
constexpr inline void QVector3D::setY(float aY) noexcept { v[1] = aY; }
692
0
constexpr inline void QVector3D::setZ(float aZ) noexcept { v[2] = aZ; }
693
694
constexpr inline float &QVector3D::operator[](int i)
695
0
{
696
0
    Q_ASSERT(uint(i) < 3u);
697
0
    return v[i];
698
0
}
699
700
constexpr inline float QVector3D::operator[](int i) const
701
0
{
702
0
    Q_ASSERT(uint(i) < 3u);
703
0
    return v[i];
704
0
}
705
706
inline float QVector3D::length() const noexcept
707
0
{
708
0
    return qHypot(v[0], v[1], v[2]);
709
0
}
710
711
inline QVector3D QVector3D::normalized() const noexcept
712
0
{
713
0
    const float len = length();
714
0
    return qFuzzyIsNull(len - 1.0f) ? *this : qFuzzyIsNull(len) ? QVector3D()
715
0
        : QVector3D(v[0] / len, v[1] / len, v[2] / len);
716
0
}
717
718
inline void QVector3D::normalize() noexcept
719
0
{
720
0
    const float len = length();
721
0
    if (qFuzzyIsNull(len - 1.0f) || qFuzzyIsNull(len))
722
0
        return;
723
0
724
0
    v[0] /= len;
725
0
    v[1] /= len;
726
0
    v[2] /= len;
727
0
}
728
729
constexpr inline float QVector3D::lengthSquared() const noexcept
730
0
{
731
0
    return v[0] * v[0] + v[1] * v[1] + v[2] * v[2];
732
0
}
733
734
constexpr inline QVector3D &QVector3D::operator+=(QVector3D vector) noexcept
735
0
{
736
0
    v[0] += vector.v[0];
737
0
    v[1] += vector.v[1];
738
0
    v[2] += vector.v[2];
739
0
    return *this;
740
0
}
741
742
constexpr inline QVector3D &QVector3D::operator-=(QVector3D vector) noexcept
743
0
{
744
0
    v[0] -= vector.v[0];
745
0
    v[1] -= vector.v[1];
746
0
    v[2] -= vector.v[2];
747
0
    return *this;
748
0
}
749
750
constexpr inline QVector3D &QVector3D::operator*=(float factor) noexcept
751
0
{
752
0
    v[0] *= factor;
753
0
    v[1] *= factor;
754
0
    v[2] *= factor;
755
0
    return *this;
756
0
}
757
758
constexpr inline QVector3D &QVector3D::operator*=(QVector3D vector) noexcept
759
0
{
760
0
    v[0] *= vector.v[0];
761
0
    v[1] *= vector.v[1];
762
0
    v[2] *= vector.v[2];
763
0
    return *this;
764
0
}
765
766
constexpr inline QVector3D &QVector3D::operator/=(float divisor)
767
0
{
768
0
    Q_ASSERT(divisor < 0 || divisor > 0);
769
0
    v[0] /= divisor;
770
0
    v[1] /= divisor;
771
0
    v[2] /= divisor;
772
0
    return *this;
773
0
}
774
775
constexpr inline QVector3D &QVector3D::operator/=(QVector3D vector)
776
0
{
777
0
    Q_ASSERT(vector.v[0] > 0 || vector.v[0] < 0);
778
0
    Q_ASSERT(vector.v[1] > 0 || vector.v[1] < 0);
779
0
    Q_ASSERT(vector.v[2] > 0 || vector.v[2] < 0);
780
0
    v[0] /= vector.v[0];
781
0
    v[1] /= vector.v[1];
782
0
    v[2] /= vector.v[2];
783
0
    return *this;
784
0
}
785
786
constexpr inline float QVector3D::dotProduct(QVector3D v1, QVector3D v2) noexcept
787
0
{
788
0
    return v1.v[0] * v2.v[0] + v1.v[1] * v2.v[1] + v1.v[2] * v2.v[2];
789
0
}
790
791
constexpr inline QVector3D QVector3D::crossProduct(QVector3D v1, QVector3D v2) noexcept
792
0
{
793
0
    return QVector3D(v1.v[1] * v2.v[2] - v1.v[2] * v2.v[1],
794
0
                     v1.v[2] * v2.v[0] - v1.v[0] * v2.v[2],
795
0
                     v1.v[0] * v2.v[1] - v1.v[1] * v2.v[0]);
796
0
}
797
798
inline QVector3D QVector3D::normal(QVector3D v1, QVector3D v2) noexcept
799
0
{
800
0
    return crossProduct(v1, v2).normalized();
801
0
}
802
803
inline QVector3D QVector3D::normal(QVector3D v1, QVector3D v2, QVector3D v3) noexcept
804
0
{
805
0
    return crossProduct((v2 - v1), (v3 - v1)).normalized();
806
0
}
807
808
inline float QVector3D::distanceToPoint(QVector3D point) const noexcept
809
0
{
810
0
    return (*this - point).length();
811
0
}
812
813
constexpr inline float QVector3D::distanceToPlane(QVector3D plane, QVector3D normal) const noexcept
814
0
{
815
0
    return dotProduct(*this - plane, normal);
816
0
}
817
818
inline float QVector3D::distanceToPlane(QVector3D plane1, QVector3D plane2, QVector3D plane3) const noexcept
819
0
{
820
0
    QVector3D n = normal(plane2 - plane1, plane3 - plane1);
821
0
    return dotProduct(*this - plane1, n);
822
0
}
823
824
inline float QVector3D::distanceToLine(QVector3D point, QVector3D direction) const noexcept
825
0
{
826
0
    if (direction.isNull())
827
0
        return (*this - point).length();
828
0
    QVector3D p = point + dotProduct(*this - point, direction) * direction;
829
0
    return (*this - p).length();
830
0
}
831
832
#ifndef QT_NO_VECTOR2D
833
constexpr inline QVector2D QVector3D::toVector2D() const noexcept
834
0
{
835
0
    return QVector2D(v[0], v[1]);
836
0
}
837
#endif
838
#ifndef QT_NO_VECTOR4D
839
constexpr inline QVector4D QVector3D::toVector4D() const noexcept
840
0
{
841
0
    return QVector4D(v[0], v[1], v[2], 0.0f);
842
0
}
843
#endif
844
845
constexpr inline QPoint QVector3D::toPoint() const noexcept
846
0
{
847
0
    return QPoint(qRound(v[0]), qRound(v[1]));
848
0
}
849
850
constexpr inline QPointF QVector3D::toPointF() const noexcept
851
0
{
852
0
    return QPointF(qreal(v[0]), qreal(v[1]));
853
0
}
854
855
#ifndef QT_NO_DEBUG_STREAM
856
Q_GUI_EXPORT QDebug operator<<(QDebug dbg, QVector3D vector);
857
#endif
858
859
#ifndef QT_NO_DATASTREAM
860
Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, QVector3D );
861
Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QVector3D &);
862
#endif
863
864
#endif // QT_NO_VECTOR3D
865
866
867
868
/***************************** QVector4D *****************************/
869
870
#ifndef QT_NO_VECTOR4D
871
872
constexpr inline QVector4D::QVector4D() noexcept : v{0.0f, 0.0f, 0.0f, 0.0f} {}
873
874
constexpr inline QVector4D::QVector4D(float xpos, float ypos, float zpos, float wpos) noexcept : v{xpos, ypos, zpos, wpos} {}
875
876
constexpr inline QVector4D::QVector4D(QPoint point) noexcept : v{float(point.x()), float(point.y()), 0.0f, 0.0f} {}
877
878
constexpr inline QVector4D::QVector4D(QPointF point) noexcept : v{float(point.x()), float(point.y()), 0.0f, 0.0f} {}
879
880
#ifndef QT_NO_VECTOR2D
881
constexpr QVector4D::QVector4D(QVector2D vector) noexcept : v{vector[0], vector[1], 0.0f, 0.0f} {}
882
constexpr QVector4D::QVector4D(QVector2D vector, float zpos, float wpos) noexcept : v{vector[0], vector[1], zpos, wpos} {}
883
#endif
884
#ifndef QT_NO_VECTOR3D
885
constexpr QVector4D::QVector4D(QVector3D vector) noexcept : v{vector[0], vector[1], vector[2], 0.0f} {}
886
constexpr QVector4D::QVector4D(QVector3D vector, float wpos) noexcept : v{vector[0], vector[1], vector[2], wpos} {}
887
#endif
888
889
constexpr inline bool QVector4D::isNull() const noexcept
890
0
{
891
0
    return qIsNull(v[0]) && qIsNull(v[1]) && qIsNull(v[2]) && qIsNull(v[3]);
892
0
}
893
894
0
constexpr inline float QVector4D::x() const noexcept { return v[0]; }
895
0
constexpr inline float QVector4D::y() const noexcept { return v[1]; }
896
0
constexpr inline float QVector4D::z() const noexcept { return v[2]; }
897
0
constexpr inline float QVector4D::w() const noexcept { return v[3]; }
898
899
0
constexpr inline void QVector4D::setX(float aX) noexcept { v[0] = aX; }
900
0
constexpr inline void QVector4D::setY(float aY) noexcept { v[1] = aY; }
901
0
constexpr inline void QVector4D::setZ(float aZ) noexcept { v[2] = aZ; }
902
0
constexpr inline void QVector4D::setW(float aW) noexcept { v[3] = aW; }
903
904
constexpr inline float &QVector4D::operator[](int i)
905
0
{
906
0
    Q_ASSERT(uint(i) < 4u);
907
0
    return v[i];
908
0
}
909
910
constexpr inline float QVector4D::operator[](int i) const
911
0
{
912
0
    Q_ASSERT(uint(i) < 4u);
913
0
    return v[i];
914
0
}
915
916
inline float QVector4D::length() const noexcept
917
0
{
918
0
    return qHypot(v[0], v[1], v[2], v[3]);
919
0
}
920
921
constexpr inline float QVector4D::lengthSquared() const noexcept
922
0
{
923
0
    return v[0] * v[0] + v[1] * v[1] + v[2] * v[2] + v[3] * v[3];
924
0
}
925
926
inline QVector4D QVector4D::normalized() const noexcept
927
0
{
928
0
    const float len = length();
929
0
    return qFuzzyIsNull(len - 1.0f) ? *this : qFuzzyIsNull(len) ? QVector4D()
930
0
        : QVector4D(v[0] / len, v[1] / len, v[2] / len, v[3] / len);
931
0
}
932
933
inline void QVector4D::normalize() noexcept
934
0
{
935
0
    const float len = length();
936
0
    if (qFuzzyIsNull(len - 1.0f) || qFuzzyIsNull(len))
937
0
        return;
938
0
939
0
    v[0] /= len;
940
0
    v[1] /= len;
941
0
    v[2] /= len;
942
0
    v[3] /= len;
943
0
}
944
945
constexpr inline QVector4D &QVector4D::operator+=(QVector4D vector) noexcept
946
0
{
947
0
    v[0] += vector.v[0];
948
0
    v[1] += vector.v[1];
949
0
    v[2] += vector.v[2];
950
0
    v[3] += vector.v[3];
951
0
    return *this;
952
0
}
953
954
constexpr inline QVector4D &QVector4D::operator-=(QVector4D vector) noexcept
955
0
{
956
0
    v[0] -= vector.v[0];
957
0
    v[1] -= vector.v[1];
958
0
    v[2] -= vector.v[2];
959
0
    v[3] -= vector.v[3];
960
0
    return *this;
961
0
}
962
963
constexpr inline QVector4D &QVector4D::operator*=(float factor) noexcept
964
0
{
965
0
    v[0] *= factor;
966
0
    v[1] *= factor;
967
0
    v[2] *= factor;
968
0
    v[3] *= factor;
969
0
    return *this;
970
0
}
971
972
constexpr inline QVector4D &QVector4D::operator*=(QVector4D vector) noexcept
973
0
{
974
0
    v[0] *= vector.v[0];
975
0
    v[1] *= vector.v[1];
976
0
    v[2] *= vector.v[2];
977
0
    v[3] *= vector.v[3];
978
0
    return *this;
979
0
}
980
981
constexpr inline QVector4D &QVector4D::operator/=(float divisor)
982
0
{
983
0
    Q_ASSERT(divisor < 0 || divisor > 0);
984
0
    v[0] /= divisor;
985
0
    v[1] /= divisor;
986
0
    v[2] /= divisor;
987
0
    v[3] /= divisor;
988
0
    return *this;
989
0
}
990
991
constexpr inline QVector4D &QVector4D::operator/=(QVector4D vector)
992
0
{
993
0
    Q_ASSERT(vector.v[0] > 0 || vector.v[0] < 0);
994
0
    Q_ASSERT(vector.v[1] > 0 || vector.v[1] < 0);
995
0
    Q_ASSERT(vector.v[2] > 0 || vector.v[2] < 0);
996
0
    Q_ASSERT(vector.v[3] > 0 || vector.v[3] < 0);
997
0
    v[0] /= vector.v[0];
998
0
    v[1] /= vector.v[1];
999
0
    v[2] /= vector.v[2];
1000
0
    v[3] /= vector.v[3];
1001
0
    return *this;
1002
0
}
1003
1004
constexpr float QVector4D::dotProduct(QVector4D v1, QVector4D v2) noexcept
1005
0
{
1006
0
    return v1.v[0] * v2.v[0] + v1.v[1] * v2.v[1] + v1.v[2] * v2.v[2] + v1.v[3] * v2.v[3];
1007
0
}
1008
1009
#ifndef QT_NO_VECTOR2D
1010
1011
constexpr inline QVector2D QVector4D::toVector2D() const noexcept
1012
0
{
1013
0
    return QVector2D(v[0], v[1]);
1014
0
}
1015
1016
constexpr inline QVector2D QVector4D::toVector2DAffine() const noexcept
1017
0
{
1018
0
    if (qIsNull(v[3]))
1019
0
        return QVector2D();
1020
0
    return QVector2D(v[0] / v[3], v[1] / v[3]);
1021
0
}
1022
1023
#endif // QT_NO_VECTOR2D
1024
1025
#ifndef QT_NO_VECTOR3D
1026
1027
constexpr inline QVector3D QVector4D::toVector3D() const noexcept
1028
0
{
1029
0
    return QVector3D(v[0], v[1], v[2]);
1030
0
}
1031
1032
constexpr QVector3D QVector4D::toVector3DAffine() const noexcept
1033
0
{
1034
0
    if (qIsNull(v[3]))
1035
0
        return QVector3D();
1036
0
    return QVector3D(v[0] / v[3], v[1] / v[3], v[2] / v[3]);
1037
0
}
1038
1039
#endif // QT_NO_VECTOR3D
1040
1041
constexpr inline QPoint QVector4D::toPoint() const noexcept
1042
0
{
1043
0
    return QPoint(qRound(v[0]), qRound(v[1]));
1044
0
}
1045
1046
constexpr inline QPointF QVector4D::toPointF() const noexcept
1047
0
{
1048
0
    return QPointF(qreal(v[0]), qreal(v[1]));
1049
0
}
1050
1051
#ifndef QT_NO_DEBUG_STREAM
1052
Q_GUI_EXPORT QDebug operator<<(QDebug dbg, QVector4D vector);
1053
#endif
1054
1055
#ifndef QT_NO_DATASTREAM
1056
Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, QVector4D );
1057
Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QVector4D &);
1058
#endif
1059
1060
#endif // QT_NO_VECTOR4D
1061
1062
1063
QT_END_NAMESPACE
1064
1065
/***************************** Tuple protocol *****************************/
1066
1067
namespace std {
1068
#ifndef QT_NO_VECTOR2D
1069
    template <>
1070
    class tuple_size<QT_PREPEND_NAMESPACE(QVector2D)> : public integral_constant<size_t, 2> {};
1071
    template <>
1072
    class tuple_element<0, QT_PREPEND_NAMESPACE(QVector2D)> { public: using type = float; };
1073
    template <>
1074
    class tuple_element<1, QT_PREPEND_NAMESPACE(QVector2D)> { public: using type = float; };
1075
#endif // QT_NO_VECTOR2D
1076
1077
#ifndef QT_NO_VECTOR3D
1078
    template <>
1079
    class tuple_size<QT_PREPEND_NAMESPACE(QVector3D)> : public integral_constant<size_t, 3> {};
1080
    template <>
1081
    class tuple_element<0, QT_PREPEND_NAMESPACE(QVector3D)> { public: using type = float; };
1082
    template <>
1083
    class tuple_element<1, QT_PREPEND_NAMESPACE(QVector3D)> { public: using type = float; };
1084
    template <>
1085
    class tuple_element<2, QT_PREPEND_NAMESPACE(QVector3D)> { public: using type = float; };
1086
#endif // QT_NO_VECTOR3D
1087
1088
#ifndef QT_NO_VECTOR4D
1089
    template <>
1090
    class tuple_size<QT_PREPEND_NAMESPACE(QVector4D)> : public integral_constant<size_t, 4> {};
1091
    template <>
1092
    class tuple_element<0, QT_PREPEND_NAMESPACE(QVector4D)> { public: using type = float; };
1093
    template <>
1094
    class tuple_element<1, QT_PREPEND_NAMESPACE(QVector4D)> { public: using type = float; };
1095
    template <>
1096
    class tuple_element<2, QT_PREPEND_NAMESPACE(QVector4D)> { public: using type = float; };
1097
    template <>
1098
    class tuple_element<3, QT_PREPEND_NAMESPACE(QVector4D)> { public: using type = float; };
1099
#endif // QT_NO_VECTOR4D
1100
}
1101
1102
#endif // QVECTORND_H