1 /****************************************************************************
3 ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
6 ** This file is part of the QtGui module of the Qt Toolkit.
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 Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
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 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
40 ****************************************************************************/
42 #include "qvector4d.h"
43 #include "qvector3d.h"
44 #include "qvector2d.h"
45 #include <QtCore/qdatastream.h>
46 #include <QtCore/qdebug.h>
47 #include <QtCore/qvariant.h>
48 #include <QtCore/qmath.h>
52 #ifndef QT_NO_VECTOR4D
56 \brief The QVector4D class represents a vector or vertex in 4D space.
61 The QVector4D class can also be used to represent vertices in 4D space.
62 We therefore do not need to provide a separate vertex class.
64 \sa QQuaternion, QVector2D, QVector3D
68 \fn QVector4D::QVector4D()
70 Constructs a null vector, i.e. with coordinates (0, 0, 0, 0).
74 \fn QVector4D::QVector4D(float xpos, float ypos, float zpos, float wpos)
76 Constructs a vector with coordinates (\a xpos, \a ypos, \a zpos, \a wpos).
80 \fn QVector4D::QVector4D(const QPoint& point)
82 Constructs a vector with x and y coordinates from a 2D \a point, and
83 z and w coordinates of 0.
87 \fn QVector4D::QVector4D(const QPointF& point)
89 Constructs a vector with x and y coordinates from a 2D \a point, and
90 z and w coordinates of 0.
93 #ifndef QT_NO_VECTOR2D
96 Constructs a 4D vector from the specified 2D \a vector. The z
97 and w coordinates are set to zero.
101 QVector4D::QVector4D(const QVector2D& vector)
110 Constructs a 4D vector from the specified 2D \a vector. The z
111 and w coordinates are set to \a zpos and \a wpos respectively.
115 QVector4D::QVector4D(const QVector2D& vector, float zpos, float wpos)
125 #ifndef QT_NO_VECTOR3D
128 Constructs a 4D vector from the specified 3D \a vector. The w
129 coordinate is set to zero.
133 QVector4D::QVector4D(const QVector3D& vector)
142 Constructs a 4D vector from the specified 3D \a vector. The w
143 coordinate is set to \a wpos.
147 QVector4D::QVector4D(const QVector3D& vector, float wpos)
158 \fn bool QVector4D::isNull() const
160 Returns true if the x, y, z, and w coordinates are set to 0.0,
161 otherwise returns false.
165 \fn float QVector4D::x() const
167 Returns the x coordinate of this point.
169 \sa setX(), y(), z(), w()
173 \fn float QVector4D::y() const
175 Returns the y coordinate of this point.
177 \sa setY(), x(), z(), w()
181 \fn float QVector4D::z() const
183 Returns the z coordinate of this point.
185 \sa setZ(), x(), y(), w()
189 \fn float QVector4D::w() const
191 Returns the w coordinate of this point.
193 \sa setW(), x(), y(), z()
197 \fn void QVector4D::setX(float x)
199 Sets the x coordinate of this point to the given \a x coordinate.
201 \sa x(), setY(), setZ(), setW()
205 \fn void QVector4D::setY(float y)
207 Sets the y coordinate of this point to the given \a y coordinate.
209 \sa y(), setX(), setZ(), setW()
213 \fn void QVector4D::setZ(float z)
215 Sets the z coordinate of this point to the given \a z coordinate.
217 \sa z(), setX(), setY(), setW()
221 \fn void QVector4D::setW(float w)
223 Sets the w coordinate of this point to the given \a w coordinate.
225 \sa w(), setX(), setY(), setZ()
229 Returns the length of the vector from the origin.
231 \sa lengthSquared(), normalized()
233 float QVector4D::length() const
235 // Need some extra precision if the length is very small.
236 double len = double(xp) * double(xp) +
237 double(yp) * double(yp) +
238 double(zp) * double(zp) +
239 double(wp) * double(wp);
240 return float(sqrt(len));
244 Returns the squared length of the vector from the origin.
245 This is equivalent to the dot product of the vector with itself.
247 \sa length(), dotProduct()
249 float QVector4D::lengthSquared() const
251 return xp * xp + yp * yp + zp * zp + wp * wp;
255 Returns the normalized unit vector form of this vector.
257 If this vector is null, then a null vector is returned. If the length
258 of the vector is very close to 1, then the vector will be returned as-is.
259 Otherwise the normalized form of the vector of length 1 will be returned.
261 \sa length(), normalize()
263 QVector4D QVector4D::normalized() const
265 // Need some extra precision if the length is very small.
266 double len = double(xp) * double(xp) +
267 double(yp) * double(yp) +
268 double(zp) * double(zp) +
269 double(wp) * double(wp);
270 if (qFuzzyIsNull(len - 1.0f)) {
272 } else if (!qFuzzyIsNull(len)) {
273 double sqrtLen = sqrt(len);
274 return QVector4D(float(double(xp) / sqrtLen),
275 float(double(yp) / sqrtLen),
276 float(double(zp) / sqrtLen),
277 float(double(wp) / sqrtLen));
284 Normalizes the currect vector in place. Nothing happens if this
285 vector is a null vector or the length of the vector is very close to 1.
287 \sa length(), normalized()
289 void QVector4D::normalize()
291 // Need some extra precision if the length is very small.
292 double len = double(xp) * double(xp) +
293 double(yp) * double(yp) +
294 double(zp) * double(zp) +
295 double(wp) * double(wp);
296 if (qFuzzyIsNull(len - 1.0f) || qFuzzyIsNull(len))
301 xp = float(double(xp) / len);
302 yp = float(double(yp) / len);
303 zp = float(double(zp) / len);
304 wp = float(double(wp) / len);
308 \fn QVector4D &QVector4D::operator+=(const QVector4D &vector)
310 Adds the given \a vector to this vector and returns a reference to
317 \fn QVector4D &QVector4D::operator-=(const QVector4D &vector)
319 Subtracts the given \a vector from this vector and returns a reference to
326 \fn QVector4D &QVector4D::operator*=(float factor)
328 Multiplies this vector's coordinates by the given \a factor, and
329 returns a reference to this vector.
335 \fn QVector4D &QVector4D::operator*=(const QVector4D &vector)
337 Multiplies the components of this vector by the corresponding
338 components in \a vector.
342 \fn QVector4D &QVector4D::operator/=(float divisor)
344 Divides this vector's coordinates by the given \a divisor, and
345 returns a reference to this vector.
351 Returns the dot product of \a v1 and \a v2.
353 float QVector4D::dotProduct(const QVector4D& v1, const QVector4D& v2)
355 return v1.xp * v2.xp + v1.yp * v2.yp + v1.zp * v2.zp + v1.wp * v2.wp;
359 \fn bool operator==(const QVector4D &v1, const QVector4D &v2)
362 Returns true if \a v1 is equal to \a v2; otherwise returns false.
363 This operator uses an exact floating-point comparison.
367 \fn bool operator!=(const QVector4D &v1, const QVector4D &v2)
370 Returns true if \a v1 is not equal to \a v2; otherwise returns false.
371 This operator uses an exact floating-point comparison.
375 \fn const QVector4D operator+(const QVector4D &v1, const QVector4D &v2)
378 Returns a QVector4D object that is the sum of the given vectors, \a v1
379 and \a v2; each component is added separately.
381 \sa QVector4D::operator+=()
385 \fn const QVector4D operator-(const QVector4D &v1, const QVector4D &v2)
388 Returns a QVector4D object that is formed by subtracting \a v2 from \a v1;
389 each component is subtracted separately.
391 \sa QVector4D::operator-=()
395 \fn const QVector4D operator*(float factor, const QVector4D &vector)
398 Returns a copy of the given \a vector, multiplied by the given \a factor.
400 \sa QVector4D::operator*=()
404 \fn const QVector4D operator*(const QVector4D &vector, float factor)
407 Returns a copy of the given \a vector, multiplied by the given \a factor.
409 \sa QVector4D::operator*=()
413 \fn const QVector4D operator*(const QVector4D &v1, const QVector4D& v2)
416 Returns the vector consisting of the multiplication of the
417 components from \a v1 and \a v2.
419 \sa QVector4D::operator*=()
423 \fn const QVector4D operator-(const QVector4D &vector)
427 Returns a QVector4D object that is formed by changing the sign of
428 all three components of the given \a vector.
430 Equivalent to \c {QVector4D(0,0,0,0) - vector}.
434 \fn const QVector4D operator/(const QVector4D &vector, float divisor)
437 Returns the QVector4D object formed by dividing all four components of
438 the given \a vector by the given \a divisor.
440 \sa QVector4D::operator/=()
444 \fn bool qFuzzyCompare(const QVector4D& v1, const QVector4D& v2)
447 Returns true if \a v1 and \a v2 are equal, allowing for a small
448 fuzziness factor for floating-point comparisons; false otherwise.
451 #ifndef QT_NO_VECTOR2D
454 Returns the 2D vector form of this 4D vector, dropping the z and w coordinates.
456 \sa toVector2DAffine(), toVector3D(), toPoint()
458 QVector2D QVector4D::toVector2D() const
460 return QVector2D(xp, yp);
464 Returns the 2D vector form of this 4D vector, dividing the x and y
465 coordinates by the w coordinate and dropping the z coordinate.
466 Returns a null vector if w is zero.
468 \sa toVector2D(), toVector3DAffine(), toPoint()
470 QVector2D QVector4D::toVector2DAffine() const
474 return QVector2D(xp / wp, yp / wp);
479 #ifndef QT_NO_VECTOR3D
482 Returns the 3D vector form of this 4D vector, dropping the w coordinate.
484 \sa toVector3DAffine(), toVector2D(), toPoint()
486 QVector3D QVector4D::toVector3D() const
488 return QVector3D(xp, yp, zp);
492 Returns the 3D vector form of this 4D vector, dividing the x, y, and
493 z coordinates by the w coordinate. Returns a null vector if w is zero.
495 \sa toVector3D(), toVector2DAffine(), toPoint()
497 QVector3D QVector4D::toVector3DAffine() const
501 return QVector3D(xp / wp, yp / wp, zp / wp);
507 \fn QPoint QVector4D::toPoint() const
509 Returns the QPoint form of this 4D vector. The z and w coordinates
512 \sa toPointF(), toVector2D()
516 \fn QPointF QVector4D::toPointF() const
518 Returns the QPointF form of this 4D vector. The z and w coordinates
521 \sa toPoint(), toVector2D()
525 Returns the 4D vector as a QVariant.
527 QVector4D::operator QVariant() const
529 return QVariant(QVariant::Vector4D, this);
532 #ifndef QT_NO_DEBUG_STREAM
534 QDebug operator<<(QDebug dbg, const QVector4D &vector)
536 dbg.nospace() << "QVector4D("
537 << vector.x() << ", " << vector.y() << ", "
538 << vector.z() << ", " << vector.w() << ')';
544 #ifndef QT_NO_DATASTREAM
547 \fn QDataStream &operator<<(QDataStream &stream, const QVector4D &vector)
550 Writes the given \a vector to the given \a stream and returns a
551 reference to the stream.
553 \sa {Serializing Qt Data Types}
556 QDataStream &operator<<(QDataStream &stream, const QVector4D &vector)
558 stream << vector.x() << vector.y()
559 << vector.z() << vector.w();
564 \fn QDataStream &operator>>(QDataStream &stream, QVector4D &vector)
567 Reads a 4D vector from the given \a stream into the given \a vector
568 and returns a reference to the stream.
570 \sa {Serializing Qt Data Types}
573 QDataStream &operator>>(QDataStream &stream, QVector4D &vector)
587 #endif // QT_NO_DATASTREAM
589 #endif // QT_NO_VECTOR4D