Coverage Report

Created: 2025-07-12 07:23

/src/qtbase/src/gui/math3d/qvector2d.cpp
Line
Count
Source (jump to first uncovered line)
1
/****************************************************************************
2
**
3
** Copyright (C) 2016 The Qt Company Ltd.
4
** Contact: https://www.qt.io/licensing/
5
**
6
** This file is part of the QtGui module of the Qt Toolkit.
7
**
8
** $QT_BEGIN_LICENSE:LGPL$
9
** Commercial License Usage
10
** Licensees holding valid commercial Qt licenses may use this file in
11
** accordance with the commercial license agreement provided with the
12
** Software or, alternatively, in accordance with the terms contained in
13
** a written agreement between you and The Qt Company. For licensing terms
14
** and conditions see https://www.qt.io/terms-conditions. For further
15
** information use the contact form at https://www.qt.io/contact-us.
16
**
17
** GNU Lesser General Public License Usage
18
** Alternatively, this file may be used under the terms of the GNU Lesser
19
** General Public License version 3 as published by the Free Software
20
** Foundation and appearing in the file LICENSE.LGPL3 included in the
21
** packaging of this file. Please review the following information to
22
** ensure the GNU Lesser General Public License version 3 requirements
23
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24
**
25
** GNU General Public License Usage
26
** Alternatively, this file may be used under the terms of the GNU
27
** General Public License version 2.0 or (at your option) the GNU General
28
** Public license version 3 or any later version approved by the KDE Free
29
** Qt Foundation. The licenses are as published by the Free Software
30
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31
** included in the packaging of this file. Please review the following
32
** information to ensure the GNU General Public License requirements will
33
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34
** https://www.gnu.org/licenses/gpl-3.0.html.
35
**
36
** $QT_END_LICENSE$
37
**
38
****************************************************************************/
39
40
#include "qvector2d.h"
41
#include "qvector3d.h"
42
#include "qvector4d.h"
43
#include <QtCore/qdatastream.h>
44
#include <QtCore/qdebug.h>
45
#include <QtCore/qvariant.h>
46
#include <QtCore/qmath.h>
47
48
QT_BEGIN_NAMESPACE
49
50
#ifndef QT_NO_VECTOR2D
51
52
Q_STATIC_ASSERT_X(std::is_standard_layout<QVector2D>::value, "QVector2D is supposed to be standard layout");
53
Q_STATIC_ASSERT_X(sizeof(QVector2D) == sizeof(float) * 2, "QVector2D is not supposed to have padding at the end");
54
55
// QVector2D used to be defined as class QVector2D { float x, y; };,
56
// now instead it is defined as classs QVector2D { float v[2]; };.
57
// Check that binary compatibility is preserved.
58
// ### Qt 6: remove all of these checks.
59
60
namespace {
61
62
struct QVector2DOld
63
{
64
    float x, y;
65
};
66
67
struct QVector2DNew
68
{
69
    float v[2];
70
};
71
72
Q_STATIC_ASSERT_X(std::is_standard_layout<QVector2DOld>::value, "Binary compatibility break in QVector2D");
73
Q_STATIC_ASSERT_X(std::is_standard_layout<QVector2DNew>::value, "Binary compatibility break in QVector2D");
74
75
Q_STATIC_ASSERT_X(sizeof(QVector2DOld) == sizeof(QVector2DNew), "Binary compatibility break in QVector2D");
76
77
// requires a constexpr offsetof
78
#if !defined(Q_CC_MSVC) || (_MSC_VER >= 1910)
79
Q_STATIC_ASSERT_X(offsetof(QVector2DOld, x) == offsetof(QVector2DNew, v) + sizeof(QVector2DNew::v[0]) * 0, "Binary compatibility break in QVector2D");
80
Q_STATIC_ASSERT_X(offsetof(QVector2DOld, y) == offsetof(QVector2DNew, v) + sizeof(QVector2DNew::v[0]) * 1, "Binary compatibility break in QVector2D");
81
#endif
82
83
} // anonymous namespace
84
85
/*!
86
    \class QVector2D
87
    \brief The QVector2D class represents a vector or vertex in 2D space.
88
    \since 4.6
89
    \ingroup painting
90
    \ingroup painting-3D
91
    \inmodule QtGui
92
93
    The QVector2D class can also be used to represent vertices in 2D space.
94
    We therefore do not need to provide a separate vertex class.
95
96
    \sa QVector3D, QVector4D, QQuaternion
97
*/
98
99
/*!
100
    \fn QVector2D::QVector2D()
101
102
    Constructs a null vector, i.e. with coordinates (0, 0).
103
*/
104
105
/*!
106
    \fn QVector2D::QVector2D(Qt::Initialization)
107
    \since 5.5
108
    \internal
109
110
    Constructs a vector without initializing the contents.
111
*/
112
113
/*!
114
    \fn QVector2D::QVector2D(float xpos, float ypos)
115
116
    Constructs a vector with coordinates (\a xpos, \a ypos).
117
*/
118
119
/*!
120
    \fn QVector2D::QVector2D(const QPoint& point)
121
122
    Constructs a vector with x and y coordinates from a 2D \a point.
123
*/
124
125
/*!
126
    \fn QVector2D::QVector2D(const QPointF& point)
127
128
    Constructs a vector with x and y coordinates from a 2D \a point.
129
*/
130
131
#ifndef QT_NO_VECTOR3D
132
133
/*!
134
    Constructs a vector with x and y coordinates from a 3D \a vector.
135
    The z coordinate of \a vector is dropped.
136
137
    \sa toVector3D()
138
*/
139
QVector2D::QVector2D(const QVector3D& vector)
140
0
{
141
0
    v[0] = vector.v[0];
142
0
    v[1] = vector.v[1];
143
0
}
144
145
#endif
146
147
#ifndef QT_NO_VECTOR4D
148
149
/*!
150
    Constructs a vector with x and y coordinates from a 3D \a vector.
151
    The z and w coordinates of \a vector are dropped.
152
153
    \sa toVector4D()
154
*/
155
QVector2D::QVector2D(const QVector4D& vector)
156
0
{
157
0
    v[0] = vector.v[0];
158
0
    v[1] = vector.v[1];
159
0
}
160
161
#endif
162
163
/*!
164
    \fn bool QVector2D::isNull() const
165
166
    Returns \c true if the x and y coordinates are set to 0.0,
167
    otherwise returns \c false.
168
*/
169
170
/*!
171
    \fn float QVector2D::x() const
172
173
    Returns the x coordinate of this point.
174
175
    \sa setX(), y()
176
*/
177
178
/*!
179
    \fn float QVector2D::y() const
180
181
    Returns the y coordinate of this point.
182
183
    \sa setY(), x()
184
*/
185
186
/*!
187
    \fn void QVector2D::setX(float x)
188
189
    Sets the x coordinate of this point to the given \a x coordinate.
190
191
    \sa x(), setY()
192
*/
193
194
/*!
195
    \fn void QVector2D::setY(float y)
196
197
    Sets the y coordinate of this point to the given \a y coordinate.
198
199
    \sa y(), setX()
200
*/
201
202
/*! \fn float &QVector2D::operator[](int i)
203
    \since 5.2
204
205
    Returns the component of the vector at index position \a i
206
    as a modifiable reference.
207
208
    \a i must be a valid index position in the vector (i.e., 0 <= \a i
209
    < 2).
210
*/
211
212
/*! \fn float QVector2D::operator[](int i) const
213
    \since 5.2
214
215
    Returns the component of the vector at index position \a i.
216
217
    \a i must be a valid index position in the vector (i.e., 0 <= \a i
218
    < 2).
219
*/
220
221
/*!
222
    Returns the length of the vector from the origin.
223
224
    \sa lengthSquared(), normalized()
225
*/
226
float QVector2D::length() const
227
0
{
228
    // Need some extra precision if the length is very small.
229
0
    double len = double(v[0]) * double(v[0]) +
230
0
                 double(v[1]) * double(v[1]);
231
0
    return float(std::sqrt(len));
232
0
}
233
234
/*!
235
    Returns the squared length of the vector from the origin.
236
    This is equivalent to the dot product of the vector with itself.
237
238
    \sa length(), dotProduct()
239
*/
240
float QVector2D::lengthSquared() const
241
0
{
242
0
    return v[0] * v[0] + v[1] * v[1];
243
0
}
244
245
/*!
246
    Returns the normalized unit vector form of this vector.
247
248
    If this vector is null, then a null vector is returned.  If the length
249
    of the vector is very close to 1, then the vector will be returned as-is.
250
    Otherwise the normalized form of the vector of length 1 will be returned.
251
252
    \sa length(), normalize()
253
*/
254
QVector2D QVector2D::normalized() const
255
0
{
256
    // Need some extra precision if the length is very small.
257
0
    double len = double(v[0]) * double(v[0]) +
258
0
                 double(v[1]) * double(v[1]);
259
0
    if (qFuzzyIsNull(len - 1.0f)) {
260
0
        return *this;
261
0
    } else if (!qFuzzyIsNull(len)) {
262
0
        double sqrtLen = std::sqrt(len);
263
0
        return QVector2D(float(double(v[0]) / sqrtLen), float(double(v[1]) / sqrtLen));
264
0
    } else {
265
0
        return QVector2D();
266
0
    }
267
0
}
268
269
/*!
270
    Normalizes the currect vector in place.  Nothing happens if this
271
    vector is a null vector or the length of the vector is very close to 1.
272
273
    \sa length(), normalized()
274
*/
275
void QVector2D::normalize()
276
0
{
277
    // Need some extra precision if the length is very small.
278
0
    double len = double(v[0]) * double(v[0]) +
279
0
                 double(v[1]) * double(v[1]);
280
0
    if (qFuzzyIsNull(len - 1.0f) || qFuzzyIsNull(len))
281
0
        return;
282
283
0
    len = std::sqrt(len);
284
285
0
    v[0] = float(double(v[0]) / len);
286
0
    v[1] = float(double(v[1]) / len);
287
0
}
288
289
/*!
290
    \since 5.1
291
292
    Returns the distance from this vertex to a point defined by
293
    the vertex \a point.
294
295
    \sa distanceToLine()
296
*/
297
float QVector2D::distanceToPoint(const QVector2D& point) const
298
0
{
299
0
    return (*this - point).length();
300
0
}
301
302
/*!
303
    \since 5.1
304
305
    Returns the distance that this vertex is from a line defined
306
    by \a point and the unit vector \a direction.
307
308
    If \a direction is a null vector, then it does not define a line.
309
    In that case, the distance from \a point to this vertex is returned.
310
311
    \sa distanceToPoint()
312
*/
313
float QVector2D::distanceToLine
314
        (const QVector2D& point, const QVector2D& direction) const
315
0
{
316
0
    if (direction.isNull())
317
0
        return (*this - point).length();
318
0
    QVector2D p = point + dotProduct(*this - point, direction) * direction;
319
0
    return (*this - p).length();
320
0
}
321
322
/*!
323
    \fn QVector2D &QVector2D::operator+=(const QVector2D &vector)
324
325
    Adds the given \a vector to this vector and returns a reference to
326
    this vector.
327
328
    \sa operator-=()
329
*/
330
331
/*!
332
    \fn QVector2D &QVector2D::operator-=(const QVector2D &vector)
333
334
    Subtracts the given \a vector from this vector and returns a reference to
335
    this vector.
336
337
    \sa operator+=()
338
*/
339
340
/*!
341
    \fn QVector2D &QVector2D::operator*=(float factor)
342
343
    Multiplies this vector's coordinates by the given \a factor, and
344
    returns a reference to this vector.
345
346
    \sa operator/=()
347
*/
348
349
/*!
350
    \fn QVector2D &QVector2D::operator*=(const QVector2D &vector)
351
352
    Multiplies the components of this vector by the corresponding
353
    components in \a vector.
354
*/
355
356
/*!
357
    \fn QVector2D &QVector2D::operator/=(float divisor)
358
359
    Divides this vector's coordinates by the given \a divisor, and
360
    returns a reference to this vector.
361
362
    \sa operator*=()
363
*/
364
365
/*!
366
    \fn QVector2D &QVector2D::operator/=(const QVector2D &vector)
367
    \since 5.5
368
369
    Divides the components of this vector by the corresponding
370
    components in \a vector.
371
372
    \sa operator*=()
373
*/
374
375
/*!
376
    Returns the dot product of \a v1 and \a v2.
377
*/
378
float QVector2D::dotProduct(const QVector2D& v1, const QVector2D& v2)
379
0
{
380
0
    return v1.v[0] * v2.v[0] + v1.v[1] * v2.v[1];
381
0
}
382
383
/*!
384
    \fn bool operator==(const QVector2D &v1, const QVector2D &v2)
385
    \relates QVector2D
386
387
    Returns \c true if \a v1 is equal to \a v2; otherwise returns \c false.
388
    This operator uses an exact floating-point comparison.
389
*/
390
391
/*!
392
    \fn bool operator!=(const QVector2D &v1, const QVector2D &v2)
393
    \relates QVector2D
394
395
    Returns \c true if \a v1 is not equal to \a v2; otherwise returns \c false.
396
    This operator uses an exact floating-point comparison.
397
*/
398
399
/*!
400
    \fn const QVector2D operator+(const QVector2D &v1, const QVector2D &v2)
401
    \relates QVector2D
402
403
    Returns a QVector2D object that is the sum of the given vectors, \a v1
404
    and \a v2; each component is added separately.
405
406
    \sa QVector2D::operator+=()
407
*/
408
409
/*!
410
    \fn const QVector2D operator-(const QVector2D &v1, const QVector2D &v2)
411
    \relates QVector2D
412
413
    Returns a QVector2D object that is formed by subtracting \a v2 from \a v1;
414
    each component is subtracted separately.
415
416
    \sa QVector2D::operator-=()
417
*/
418
419
/*!
420
    \fn const QVector2D operator*(float factor, const QVector2D &vector)
421
    \relates QVector2D
422
423
    Returns a copy of the given \a vector,  multiplied by the given \a factor.
424
425
    \sa QVector2D::operator*=()
426
*/
427
428
/*!
429
    \fn const QVector2D operator*(const QVector2D &vector, float factor)
430
    \relates QVector2D
431
432
    Returns a copy of the given \a vector,  multiplied by the given \a factor.
433
434
    \sa QVector2D::operator*=()
435
*/
436
437
/*!
438
    \fn const QVector2D operator*(const QVector2D &v1, const QVector2D &v2)
439
    \relates QVector2D
440
441
    Multiplies the components of \a v1 by the corresponding
442
    components in \a v2.
443
*/
444
445
/*!
446
    \fn const QVector2D operator-(const QVector2D &vector)
447
    \relates QVector2D
448
    \overload
449
450
    Returns a QVector2D object that is formed by changing the sign of
451
    the components of the given \a vector.
452
453
    Equivalent to \c {QVector2D(0,0) - vector}.
454
*/
455
456
/*!
457
    \fn const QVector2D operator/(const QVector2D &vector, float divisor)
458
    \relates QVector2D
459
460
    Returns the QVector2D object formed by dividing all three components of
461
    the given \a vector by the given \a divisor.
462
463
    \sa QVector2D::operator/=()
464
*/
465
466
/*!
467
    \fn const QVector2D operator/(const QVector2D &vector, const QVector2D &divisor)
468
    \relates QVector2D
469
    \since 5.5
470
471
    Returns the QVector2D object formed by dividing components of the given
472
    \a vector by a respective components of the given \a divisor.
473
474
    \sa QVector2D::operator/=()
475
*/
476
477
/*!
478
    \fn bool qFuzzyCompare(const QVector2D& v1, const QVector2D& v2)
479
    \relates QVector2D
480
481
    Returns \c true if \a v1 and \a v2 are equal, allowing for a small
482
    fuzziness factor for floating-point comparisons; false otherwise.
483
*/
484
485
#ifndef QT_NO_VECTOR3D
486
487
/*!
488
    Returns the 3D form of this 2D vector, with the z coordinate set to zero.
489
490
    \sa toVector4D(), toPoint()
491
*/
492
QVector3D QVector2D::toVector3D() const
493
0
{
494
0
    return QVector3D(v[0], v[1], 0.0f);
495
0
}
496
497
#endif
498
499
#ifndef QT_NO_VECTOR4D
500
501
/*!
502
    Returns the 4D form of this 2D vector, with the z and w coordinates set to zero.
503
504
    \sa toVector3D(), toPoint()
505
*/
506
QVector4D QVector2D::toVector4D() const
507
0
{
508
0
    return QVector4D(v[0], v[1], 0.0f, 0.0f);
509
0
}
510
511
#endif
512
513
/*!
514
    \fn QPoint QVector2D::toPoint() const
515
516
    Returns the QPoint form of this 2D vector.
517
518
    \sa toPointF(), toVector3D()
519
*/
520
521
/*!
522
    \fn QPointF QVector2D::toPointF() const
523
524
    Returns the QPointF form of this 2D vector.
525
526
    \sa toPoint(), toVector3D()
527
*/
528
529
/*!
530
    Returns the 2D vector as a QVariant.
531
*/
532
QVector2D::operator QVariant() const
533
0
{
534
0
    return QVariant(QMetaType::QVector2D, this);
535
0
}
536
537
#ifndef QT_NO_DEBUG_STREAM
538
539
QDebug operator<<(QDebug dbg, const QVector2D &vector)
540
0
{
541
0
    QDebugStateSaver saver(dbg);
542
0
    dbg.nospace() << "QVector2D(" << vector.x() << ", " << vector.y() << ')';
543
0
    return dbg;
544
0
}
545
546
#endif
547
548
#ifndef QT_NO_DATASTREAM
549
550
/*!
551
    \fn QDataStream &operator<<(QDataStream &stream, const QVector2D &vector)
552
    \relates QVector2D
553
554
    Writes the given \a vector to the given \a stream and returns a
555
    reference to the stream.
556
557
    \sa {Serializing Qt Data Types}
558
*/
559
560
QDataStream &operator<<(QDataStream &stream, const QVector2D &vector)
561
0
{
562
0
    stream << vector.x() << vector.y();
563
0
    return stream;
564
0
}
565
566
/*!
567
    \fn QDataStream &operator>>(QDataStream &stream, QVector2D &vector)
568
    \relates QVector2D
569
570
    Reads a 2D vector from the given \a stream into the given \a vector
571
    and returns a reference to the stream.
572
573
    \sa {Serializing Qt Data Types}
574
*/
575
576
QDataStream &operator>>(QDataStream &stream, QVector2D &vector)
577
0
{
578
0
    float x, y;
579
0
    stream >> x;
580
0
    stream >> y;
581
0
    vector.setX(x);
582
0
    vector.setY(y);
583
0
    return stream;
584
0
}
585
586
#endif // QT_NO_DATASTREAM
587
588
#endif // QT_NO_VECTOR2D
589
590
QT_END_NAMESPACE