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 */
QVector2D(const QVector3D & vector)139 QVector2D::QVector2D(const QVector3D& vector)
140 {
141     v[0] = vector.v[0];
142     v[1] = vector.v[1];
143 }
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 */
QVector2D(const QVector4D & vector)155 QVector2D::QVector2D(const QVector4D& vector)
156 {
157     v[0] = vector.v[0];
158     v[1] = vector.v[1];
159 }
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 */
length() const226 float QVector2D::length() const
227 {
228     // Need some extra precision if the length is very small.
229     double len = double(v[0]) * double(v[0]) +
230                  double(v[1]) * double(v[1]);
231     return float(std::sqrt(len));
232 }
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 */
lengthSquared() const240 float QVector2D::lengthSquared() const
241 {
242     return v[0] * v[0] + v[1] * v[1];
243 }
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 */
normalized() const254 QVector2D QVector2D::normalized() const
255 {
256     // Need some extra precision if the length is very small.
257     double len = double(v[0]) * double(v[0]) +
258                  double(v[1]) * double(v[1]);
259     if (qFuzzyIsNull(len - 1.0f)) {
260         return *this;
261     } else if (!qFuzzyIsNull(len)) {
262         double sqrtLen = std::sqrt(len);
263         return QVector2D(float(double(v[0]) / sqrtLen), float(double(v[1]) / sqrtLen));
264     } else {
265         return QVector2D();
266     }
267 }
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 */
normalize()275 void QVector2D::normalize()
276 {
277     // Need some extra precision if the length is very small.
278     double len = double(v[0]) * double(v[0]) +
279                  double(v[1]) * double(v[1]);
280     if (qFuzzyIsNull(len - 1.0f) || qFuzzyIsNull(len))
281         return;
282 
283     len = std::sqrt(len);
284 
285     v[0] = float(double(v[0]) / len);
286     v[1] = float(double(v[1]) / len);
287 }
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 */
distanceToPoint(const QVector2D & point) const297 float QVector2D::distanceToPoint(const QVector2D& point) const
298 {
299     return (*this - point).length();
300 }
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 */
distanceToLine(const QVector2D & point,const QVector2D & direction) const313 float QVector2D::distanceToLine
314         (const QVector2D& point, const QVector2D& direction) const
315 {
316     if (direction.isNull())
317         return (*this - point).length();
318     QVector2D p = point + dotProduct(*this - point, direction) * direction;
319     return (*this - p).length();
320 }
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 */
dotProduct(const QVector2D & v1,const QVector2D & v2)378 float QVector2D::dotProduct(const QVector2D& v1, const QVector2D& v2)
379 {
380     return v1.v[0] * v2.v[0] + v1.v[1] * v2.v[1];
381 }
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 */
toVector3D() const492 QVector3D QVector2D::toVector3D() const
493 {
494     return QVector3D(v[0], v[1], 0.0f);
495 }
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 */
toVector4D() const506 QVector4D QVector2D::toVector4D() const
507 {
508     return QVector4D(v[0], v[1], 0.0f, 0.0f);
509 }
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 */
operator QVariant() const532 QVector2D::operator QVariant() const
533 {
534     return QVariant(QMetaType::QVector2D, this);
535 }
536 
537 #ifndef QT_NO_DEBUG_STREAM
538 
operator <<(QDebug dbg,const QVector2D & vector)539 QDebug operator<<(QDebug dbg, const QVector2D &vector)
540 {
541     QDebugStateSaver saver(dbg);
542     dbg.nospace() << "QVector2D(" << vector.x() << ", " << vector.y() << ')';
543     return dbg;
544 }
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 
operator <<(QDataStream & stream,const QVector2D & vector)560 QDataStream &operator<<(QDataStream &stream, const QVector2D &vector)
561 {
562     stream << vector.x() << vector.y();
563     return stream;
564 }
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 
operator >>(QDataStream & stream,QVector2D & vector)576 QDataStream &operator>>(QDataStream &stream, QVector2D &vector)
577 {
578     float x, y;
579     stream >> x;
580     stream >> y;
581     vector.setX(x);
582     vector.setY(y);
583     return stream;
584 }
585 
586 #endif // QT_NO_DATASTREAM
587 
588 #endif // QT_NO_VECTOR2D
589 
590 QT_END_NAMESPACE
591