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