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