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
48QT_BEGIN_NAMESPACE
49
50#ifndef QT_NO_VECTOR2D
51
52static_assert(std::is_standard_layout<QVector2D>::value, "QVector2D is supposed to be standard layout");
53static_assert(sizeof(QVector2D) == sizeof(float) * 2, "QVector2D is not supposed to have padding at the end");
54
55/*!
56 \class QVector2D
57 \brief The QVector2D class represents a vector or vertex in 2D space.
58 \since 4.6
59 \ingroup painting
60 \ingroup painting-3D
61 \inmodule QtGui
62
63 The QVector2D class can also be used to represent vertices in 2D space.
64 We therefore do not need to provide a separate vertex class.
65
66 \sa QVector3D, QVector4D, QQuaternion
67*/
68
69/*!
70 \fn QVector2D::QVector2D()
71
72 Constructs a null vector, i.e. with coordinates (0, 0).
73*/
74
75/*!
76 \fn QVector2D::QVector2D(Qt::Initialization)
77 \since 5.5
78 \internal
79
80 Constructs a vector without initializing the contents.
81*/
82
83/*!
84 \fn QVector2D::QVector2D(float xpos, float ypos)
85
86 Constructs a vector with coordinates (\a xpos, \a ypos).
87*/
88
89/*!
90 \fn QVector2D::QVector2D(const QPoint& point)
91
92 Constructs a vector with x and y coordinates from a 2D \a point.
93*/
94
95/*!
96 \fn QVector2D::QVector2D(const QPointF& point)
97
98 Constructs a vector with x and y coordinates from a 2D \a point.
99*/
100
101#ifndef QT_NO_VECTOR3D
102
103/*!
104 Constructs a vector with x and y coordinates from a 3D \a vector.
105 The z coordinate of \a vector is dropped.
106
107 \sa toVector3D()
108*/
109QVector2D::QVector2D(const QVector3D& vector)
110{
111 v[0] = vector.v[0];
112 v[1] = vector.v[1];
113}
114
115#endif
116
117#ifndef QT_NO_VECTOR4D
118
119/*!
120 Constructs a vector with x and y coordinates from a 3D \a vector.
121 The z and w coordinates of \a vector are dropped.
122
123 \sa toVector4D()
124*/
125QVector2D::QVector2D(const QVector4D& vector)
126{
127 v[0] = vector.v[0];
128 v[1] = vector.v[1];
129}
130
131#endif
132
133/*!
134 \fn bool QVector2D::isNull() const
135
136 Returns \c true if the x and y coordinates are set to 0.0,
137 otherwise returns \c false.
138*/
139
140/*!
141 \fn float QVector2D::x() const
142
143 Returns the x coordinate of this point.
144
145 \sa setX(), y()
146*/
147
148/*!
149 \fn float QVector2D::y() const
150
151 Returns the y coordinate of this point.
152
153 \sa setY(), x()
154*/
155
156/*!
157 \fn void QVector2D::setX(float x)
158
159 Sets the x coordinate of this point to the given \a x coordinate.
160
161 \sa x(), setY()
162*/
163
164/*!
165 \fn void QVector2D::setY(float y)
166
167 Sets the y coordinate of this point to the given \a y coordinate.
168
169 \sa y(), setX()
170*/
171
172/*! \fn float &QVector2D::operator[](int i)
173 \since 5.2
174
175 Returns the component of the vector at index position \a i
176 as a modifiable reference.
177
178 \a i must be a valid index position in the vector (i.e., 0 <= \a i
179 < 2).
180*/
181
182/*! \fn float QVector2D::operator[](int i) const
183 \since 5.2
184
185 Returns the component of the vector at index position \a i.
186
187 \a i must be a valid index position in the vector (i.e., 0 <= \a i
188 < 2).
189*/
190
191/*!
192 Returns the length of the vector from the origin.
193
194 \sa lengthSquared(), normalized()
195*/
196float QVector2D::length() const
197{
198 // Need some extra precision if the length is very small.
199 double len = double(v[0]) * double(v[0]) +
200 double(v[1]) * double(v[1]);
201 return float(std::sqrt(len));
202}
203
204/*!
205 Returns the squared length of the vector from the origin.
206 This is equivalent to the dot product of the vector with itself.
207
208 \sa length(), dotProduct()
209*/
210float QVector2D::lengthSquared() const
211{
212 return v[0] * v[0] + v[1] * v[1];
213}
214
215/*!
216 Returns the normalized unit vector form of this vector.
217
218 If this vector is null, then a null vector is returned. If the length
219 of the vector is very close to 1, then the vector will be returned as-is.
220 Otherwise the normalized form of the vector of length 1 will be returned.
221
222 \sa length(), normalize()
223*/
224QVector2D QVector2D::normalized() const
225{
226 // Need some extra precision if the length is very small.
227 double len = double(v[0]) * double(v[0]) +
228 double(v[1]) * double(v[1]);
229 if (qFuzzyIsNull(len - 1.0f)) {
230 return *this;
231 } else if (!qFuzzyIsNull(len)) {
232 double sqrtLen = std::sqrt(len);
233 return QVector2D(float(double(v[0]) / sqrtLen), float(double(v[1]) / sqrtLen));
234 } else {
235 return QVector2D();
236 }
237}
238
239/*!
240 Normalizes the currect vector in place. Nothing happens if this
241 vector is a null vector or the length of the vector is very close to 1.
242
243 \sa length(), normalized()
244*/
245void QVector2D::normalize()
246{
247 // Need some extra precision if the length is very small.
248 double len = double(v[0]) * double(v[0]) +
249 double(v[1]) * double(v[1]);
250 if (qFuzzyIsNull(len - 1.0f) || qFuzzyIsNull(len))
251 return;
252
253 len = std::sqrt(len);
254
255 v[0] = float(double(v[0]) / len);
256 v[1] = float(double(v[1]) / len);
257}
258
259/*!
260 \since 5.1
261
262 Returns the distance from this vertex to a point defined by
263 the vertex \a point.
264
265 \sa distanceToLine()
266*/
267float QVector2D::distanceToPoint(const QVector2D& point) const
268{
269 return (*this - point).length();
270}
271
272/*!
273 \since 5.1
274
275 Returns the distance that this vertex is from a line defined
276 by \a point and the unit vector \a direction.
277
278 If \a direction is a null vector, then it does not define a line.
279 In that case, the distance from \a point to this vertex is returned.
280
281 \sa distanceToPoint()
282*/
283float QVector2D::distanceToLine
284 (const QVector2D& point, const QVector2D& direction) const
285{
286 if (direction.isNull())
287 return (*this - point).length();
288 QVector2D p = point + dotProduct(*this - point, direction) * direction;
289 return (*this - p).length();
290}
291
292/*!
293 \fn QVector2D &QVector2D::operator+=(const QVector2D &vector)
294
295 Adds the given \a vector to this vector and returns a reference to
296 this vector.
297
298 \sa operator-=()
299*/
300
301/*!
302 \fn QVector2D &QVector2D::operator-=(const QVector2D &vector)
303
304 Subtracts the given \a vector from this vector and returns a reference to
305 this vector.
306
307 \sa operator+=()
308*/
309
310/*!
311 \fn QVector2D &QVector2D::operator*=(float factor)
312
313 Multiplies this vector's coordinates by the given \a factor, and
314 returns a reference to this vector.
315
316 \sa operator/=()
317*/
318
319/*!
320 \fn QVector2D &QVector2D::operator*=(const QVector2D &vector)
321
322 Multiplies the components of this vector by the corresponding
323 components in \a vector.
324*/
325
326/*!
327 \fn QVector2D &QVector2D::operator/=(float divisor)
328
329 Divides this vector's coordinates by the given \a divisor, and
330 returns a reference to this vector.
331
332 \sa operator*=()
333*/
334
335/*!
336 \fn QVector2D &QVector2D::operator/=(const QVector2D &vector)
337 \since 5.5
338
339 Divides the components of this vector by the corresponding
340 components in \a vector.
341
342 \sa operator*=()
343*/
344
345/*!
346 Returns the dot product of \a v1 and \a v2.
347*/
348float QVector2D::dotProduct(const QVector2D& v1, const QVector2D& v2)
349{
350 return v1.v[0] * v2.v[0] + v1.v[1] * v2.v[1];
351}
352
353/*!
354 \fn bool operator==(const QVector2D &v1, const QVector2D &v2)
355 \relates QVector2D
356
357 Returns \c true if \a v1 is equal to \a v2; otherwise returns \c false.
358 This operator uses an exact floating-point comparison.
359*/
360
361/*!
362 \fn bool operator!=(const QVector2D &v1, const QVector2D &v2)
363 \relates QVector2D
364
365 Returns \c true if \a v1 is not equal to \a v2; otherwise returns \c false.
366 This operator uses an exact floating-point comparison.
367*/
368
369/*!
370 \fn const QVector2D operator+(const QVector2D &v1, const QVector2D &v2)
371 \relates QVector2D
372
373 Returns a QVector2D object that is the sum of the given vectors, \a v1
374 and \a v2; each component is added separately.
375
376 \sa QVector2D::operator+=()
377*/
378
379/*!
380 \fn const QVector2D operator-(const QVector2D &v1, const QVector2D &v2)
381 \relates QVector2D
382
383 Returns a QVector2D object that is formed by subtracting \a v2 from \a v1;
384 each component is subtracted separately.
385
386 \sa QVector2D::operator-=()
387*/
388
389/*!
390 \fn const QVector2D operator*(float factor, const QVector2D &vector)
391 \relates QVector2D
392
393 Returns a copy of the given \a vector, multiplied by the given \a factor.
394
395 \sa QVector2D::operator*=()
396*/
397
398/*!
399 \fn const QVector2D operator*(const QVector2D &vector, float factor)
400 \relates QVector2D
401
402 Returns a copy of the given \a vector, multiplied by the given \a factor.
403
404 \sa QVector2D::operator*=()
405*/
406
407/*!
408 \fn const QVector2D operator*(const QVector2D &v1, const QVector2D &v2)
409 \relates QVector2D
410
411 Multiplies the components of \a v1 by the corresponding
412 components in \a v2.
413*/
414
415/*!
416 \fn const QVector2D operator-(const QVector2D &vector)
417 \relates QVector2D
418 \overload
419
420 Returns a QVector2D object that is formed by changing the sign of
421 the components of the given \a vector.
422
423 Equivalent to \c {QVector2D(0,0) - vector}.
424*/
425
426/*!
427 \fn const QVector2D operator/(const QVector2D &vector, float divisor)
428 \relates QVector2D
429
430 Returns the QVector2D object formed by dividing all three components of
431 the given \a vector by the given \a divisor.
432
433 \sa QVector2D::operator/=()
434*/
435
436/*!
437 \fn const QVector2D operator/(const QVector2D &vector, const QVector2D &divisor)
438 \relates QVector2D
439 \since 5.5
440
441 Returns the QVector2D object formed by dividing components of the given
442 \a vector by a respective components of the given \a divisor.
443
444 \sa QVector2D::operator/=()
445*/
446
447/*!
448 \fn bool qFuzzyCompare(const QVector2D& v1, const QVector2D& v2)
449 \relates QVector2D
450
451 Returns \c true if \a v1 and \a v2 are equal, allowing for a small
452 fuzziness factor for floating-point comparisons; false otherwise.
453*/
454
455#ifndef QT_NO_VECTOR3D
456
457/*!
458 Returns the 3D form of this 2D vector, with the z coordinate set to zero.
459
460 \sa toVector4D(), toPoint()
461*/
462QVector3D QVector2D::toVector3D() const
463{
464 return QVector3D(v[0], v[1], 0.0f);
465}
466
467#endif
468
469#ifndef QT_NO_VECTOR4D
470
471/*!
472 Returns the 4D form of this 2D vector, with the z and w coordinates set to zero.
473
474 \sa toVector3D(), toPoint()
475*/
476QVector4D QVector2D::toVector4D() const
477{
478 return QVector4D(v[0], v[1], 0.0f, 0.0f);
479}
480
481#endif
482
483/*!
484 \fn QPoint QVector2D::toPoint() const
485
486 Returns the QPoint form of this 2D vector.
487
488 \sa toPointF(), toVector3D()
489*/
490
491/*!
492 \fn QPointF QVector2D::toPointF() const
493
494 Returns the QPointF form of this 2D vector.
495
496 \sa toPoint(), toVector3D()
497*/
498
499/*!
500 Returns the 2D vector as a QVariant.
501*/
502QVector2D::operator QVariant() const
503{
504 return QVariant::fromValue(*this);
505}
506
507#ifndef QT_NO_DEBUG_STREAM
508
509QDebug operator<<(QDebug dbg, const QVector2D &vector)
510{
511 QDebugStateSaver saver(dbg);
512 dbg.nospace() << "QVector2D(" << vector.x() << ", " << vector.y() << ')';
513 return dbg;
514}
515
516#endif
517
518#ifndef QT_NO_DATASTREAM
519
520/*!
521 \fn QDataStream &operator<<(QDataStream &stream, const QVector2D &vector)
522 \relates QVector2D
523
524 Writes the given \a vector to the given \a stream and returns a
525 reference to the stream.
526
527 \sa {Serializing Qt Data Types}
528*/
529
530QDataStream &operator<<(QDataStream &stream, const QVector2D &vector)
531{
532 stream << vector.x() << vector.y();
533 return stream;
534}
535
536/*!
537 \fn QDataStream &operator>>(QDataStream &stream, QVector2D &vector)
538 \relates QVector2D
539
540 Reads a 2D vector from the given \a stream into the given \a vector
541 and returns a reference to the stream.
542
543 \sa {Serializing Qt Data Types}
544*/
545
546QDataStream &operator>>(QDataStream &stream, QVector2D &vector)
547{
548 float x, y;
549 stream >> x;
550 stream >> y;
551 vector.setX(x);
552 vector.setY(y);
553 return stream;
554}
555
556#endif // QT_NO_DATASTREAM
557
558#endif // QT_NO_VECTOR2D
559
560QT_END_NAMESPACE
561