Merge "Merge branch 'newdocs'" into refs/staging/master
[profile/ivi/qtbase.git] / src / gui / math3d / qvector4d.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
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 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.
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 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.
24 **
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.
28 **
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.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
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>
49
50 QT_BEGIN_NAMESPACE
51
52 #ifndef QT_NO_VECTOR4D
53
54 /*!
55     \class QVector4D
56     \brief The QVector4D class represents a vector or vertex in 4D space.
57     \since 4.6
58     \ingroup painting-3D
59     \inmodule QtGui
60
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.
63
64     \sa QQuaternion, QVector2D, QVector3D
65 */
66
67 /*!
68     \fn QVector4D::QVector4D()
69
70     Constructs a null vector, i.e. with coordinates (0, 0, 0, 0).
71 */
72
73 /*!
74     \fn QVector4D::QVector4D(float xpos, float ypos, float zpos, float wpos)
75
76     Constructs a vector with coordinates (\a xpos, \a ypos, \a zpos, \a wpos).
77 */
78
79 /*!
80     \fn QVector4D::QVector4D(const QPoint& point)
81
82     Constructs a vector with x and y coordinates from a 2D \a point, and
83     z and w coordinates of 0.
84 */
85
86 /*!
87     \fn QVector4D::QVector4D(const QPointF& point)
88
89     Constructs a vector with x and y coordinates from a 2D \a point, and
90     z and w coordinates of 0.
91 */
92
93 #ifndef QT_NO_VECTOR2D
94
95 /*!
96     Constructs a 4D vector from the specified 2D \a vector.  The z
97     and w coordinates are set to zero.
98
99     \sa toVector2D()
100 */
101 QVector4D::QVector4D(const QVector2D& vector)
102 {
103     xp = vector.xp;
104     yp = vector.yp;
105     zp = 0.0f;
106     wp = 0.0f;
107 }
108
109 /*!
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.
112
113     \sa toVector2D()
114 */
115 QVector4D::QVector4D(const QVector2D& vector, float zpos, float wpos)
116 {
117     xp = vector.xp;
118     yp = vector.yp;
119     zp = zpos;
120     wp = wpos;
121 }
122
123 #endif
124
125 #ifndef QT_NO_VECTOR3D
126
127 /*!
128     Constructs a 4D vector from the specified 3D \a vector.  The w
129     coordinate is set to zero.
130
131     \sa toVector3D()
132 */
133 QVector4D::QVector4D(const QVector3D& vector)
134 {
135     xp = vector.xp;
136     yp = vector.yp;
137     zp = vector.zp;
138     wp = 0.0f;
139 }
140
141 /*!
142     Constructs a 4D vector from the specified 3D \a vector.  The w
143     coordinate is set to \a wpos.
144
145     \sa toVector3D()
146 */
147 QVector4D::QVector4D(const QVector3D& vector, float wpos)
148 {
149     xp = vector.xp;
150     yp = vector.yp;
151     zp = vector.zp;
152     wp = wpos;
153 }
154
155 #endif
156
157 /*!
158     \fn bool QVector4D::isNull() const
159
160     Returns true if the x, y, z, and w coordinates are set to 0.0,
161     otherwise returns false.
162 */
163
164 /*!
165     \fn float QVector4D::x() const
166
167     Returns the x coordinate of this point.
168
169     \sa setX(), y(), z(), w()
170 */
171
172 /*!
173     \fn float QVector4D::y() const
174
175     Returns the y coordinate of this point.
176
177     \sa setY(), x(), z(), w()
178 */
179
180 /*!
181     \fn float QVector4D::z() const
182
183     Returns the z coordinate of this point.
184
185     \sa setZ(), x(), y(), w()
186 */
187
188 /*!
189     \fn float QVector4D::w() const
190
191     Returns the w coordinate of this point.
192
193     \sa setW(), x(), y(), z()
194 */
195
196 /*!
197     \fn void QVector4D::setX(float x)
198
199     Sets the x coordinate of this point to the given \a x coordinate.
200
201     \sa x(), setY(), setZ(), setW()
202 */
203
204 /*!
205     \fn void QVector4D::setY(float y)
206
207     Sets the y coordinate of this point to the given \a y coordinate.
208
209     \sa y(), setX(), setZ(), setW()
210 */
211
212 /*!
213     \fn void QVector4D::setZ(float z)
214
215     Sets the z coordinate of this point to the given \a z coordinate.
216
217     \sa z(), setX(), setY(), setW()
218 */
219
220 /*!
221     \fn void QVector4D::setW(float w)
222
223     Sets the w coordinate of this point to the given \a w coordinate.
224
225     \sa w(), setX(), setY(), setZ()
226 */
227
228 /*!
229     Returns the length of the vector from the origin.
230
231     \sa lengthSquared(), normalized()
232 */
233 float QVector4D::length() const
234 {
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));
241 }
242
243 /*!
244     Returns the squared length of the vector from the origin.
245     This is equivalent to the dot product of the vector with itself.
246
247     \sa length(), dotProduct()
248 */
249 float QVector4D::lengthSquared() const
250 {
251     return xp * xp + yp * yp + zp * zp + wp * wp;
252 }
253
254 /*!
255     Returns the normalized unit vector form of this vector.
256
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.
260
261     \sa length(), normalize()
262 */
263 QVector4D QVector4D::normalized() const
264 {
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)) {
271         return *this;
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));
278     } else {
279         return QVector4D();
280     }
281 }
282
283 /*!
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.
286
287     \sa length(), normalized()
288 */
289 void QVector4D::normalize()
290 {
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))
297         return;
298
299     len = sqrt(len);
300
301     xp = float(double(xp) / len);
302     yp = float(double(yp) / len);
303     zp = float(double(zp) / len);
304     wp = float(double(wp) / len);
305 }
306
307 /*!
308     \fn QVector4D &QVector4D::operator+=(const QVector4D &vector)
309
310     Adds the given \a vector to this vector and returns a reference to
311     this vector.
312
313     \sa operator-=()
314 */
315
316 /*!
317     \fn QVector4D &QVector4D::operator-=(const QVector4D &vector)
318
319     Subtracts the given \a vector from this vector and returns a reference to
320     this vector.
321
322     \sa operator+=()
323 */
324
325 /*!
326     \fn QVector4D &QVector4D::operator*=(float factor)
327
328     Multiplies this vector's coordinates by the given \a factor, and
329     returns a reference to this vector.
330
331     \sa operator/=()
332 */
333
334 /*!
335     \fn QVector4D &QVector4D::operator*=(const QVector4D &vector)
336
337     Multiplies the components of this vector by the corresponding
338     components in \a vector.
339 */
340
341 /*!
342     \fn QVector4D &QVector4D::operator/=(float divisor)
343
344     Divides this vector's coordinates by the given \a divisor, and
345     returns a reference to this vector.
346
347     \sa operator*=()
348 */
349
350 /*!
351     Returns the dot product of \a v1 and \a v2.
352 */
353 float QVector4D::dotProduct(const QVector4D& v1, const QVector4D& v2)
354 {
355     return v1.xp * v2.xp + v1.yp * v2.yp + v1.zp * v2.zp + v1.wp * v2.wp;
356 }
357
358 /*!
359     \fn bool operator==(const QVector4D &v1, const QVector4D &v2)
360     \relates QVector4D
361
362     Returns true if \a v1 is equal to \a v2; otherwise returns false.
363     This operator uses an exact floating-point comparison.
364 */
365
366 /*!
367     \fn bool operator!=(const QVector4D &v1, const QVector4D &v2)
368     \relates QVector4D
369
370     Returns true if \a v1 is not equal to \a v2; otherwise returns false.
371     This operator uses an exact floating-point comparison.
372 */
373
374 /*!
375     \fn const QVector4D operator+(const QVector4D &v1, const QVector4D &v2)
376     \relates QVector4D
377
378     Returns a QVector4D object that is the sum of the given vectors, \a v1
379     and \a v2; each component is added separately.
380
381     \sa QVector4D::operator+=()
382 */
383
384 /*!
385     \fn const QVector4D operator-(const QVector4D &v1, const QVector4D &v2)
386     \relates QVector4D
387
388     Returns a QVector4D object that is formed by subtracting \a v2 from \a v1;
389     each component is subtracted separately.
390
391     \sa QVector4D::operator-=()
392 */
393
394 /*!
395     \fn const QVector4D operator*(float factor, const QVector4D &vector)
396     \relates QVector4D
397
398     Returns a copy of the given \a vector,  multiplied by the given \a factor.
399
400     \sa QVector4D::operator*=()
401 */
402
403 /*!
404     \fn const QVector4D operator*(const QVector4D &vector, float factor)
405     \relates QVector4D
406
407     Returns a copy of the given \a vector,  multiplied by the given \a factor.
408
409     \sa QVector4D::operator*=()
410 */
411
412 /*!
413     \fn const QVector4D operator*(const QVector4D &v1, const QVector4D& v2)
414     \relates QVector4D
415
416     Returns the vector consisting of the multiplication of the
417     components from \a v1 and \a v2.
418
419     \sa QVector4D::operator*=()
420 */
421
422 /*!
423     \fn const QVector4D operator-(const QVector4D &vector)
424     \relates QVector4D
425     \overload
426
427     Returns a QVector4D object that is formed by changing the sign of
428     all three components of the given \a vector.
429
430     Equivalent to \c {QVector4D(0,0,0,0) - vector}.
431 */
432
433 /*!
434     \fn const QVector4D operator/(const QVector4D &vector, float divisor)
435     \relates QVector4D
436
437     Returns the QVector4D object formed by dividing all four components of
438     the given \a vector by the given \a divisor.
439
440     \sa QVector4D::operator/=()
441 */
442
443 /*!
444     \fn bool qFuzzyCompare(const QVector4D& v1, const QVector4D& v2)
445     \relates QVector4D
446
447     Returns true if \a v1 and \a v2 are equal, allowing for a small
448     fuzziness factor for floating-point comparisons; false otherwise.
449 */
450
451 #ifndef QT_NO_VECTOR2D
452
453 /*!
454     Returns the 2D vector form of this 4D vector, dropping the z and w coordinates.
455
456     \sa toVector2DAffine(), toVector3D(), toPoint()
457 */
458 QVector2D QVector4D::toVector2D() const
459 {
460     return QVector2D(xp, yp);
461 }
462
463 /*!
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.
467
468     \sa toVector2D(), toVector3DAffine(), toPoint()
469 */
470 QVector2D QVector4D::toVector2DAffine() const
471 {
472     if (qIsNull(wp))
473         return QVector2D();
474     return QVector2D(xp / wp, yp / wp);
475 }
476
477 #endif
478
479 #ifndef QT_NO_VECTOR3D
480
481 /*!
482     Returns the 3D vector form of this 4D vector, dropping the w coordinate.
483
484     \sa toVector3DAffine(), toVector2D(), toPoint()
485 */
486 QVector3D QVector4D::toVector3D() const
487 {
488     return QVector3D(xp, yp, zp);
489 }
490
491 /*!
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.
494
495     \sa toVector3D(), toVector2DAffine(), toPoint()
496 */
497 QVector3D QVector4D::toVector3DAffine() const
498 {
499     if (qIsNull(wp))
500         return QVector3D();
501     return QVector3D(xp / wp, yp / wp, zp / wp);
502 }
503
504 #endif
505
506 /*!
507     \fn QPoint QVector4D::toPoint() const
508
509     Returns the QPoint form of this 4D vector. The z and w coordinates
510     are dropped.
511
512     \sa toPointF(), toVector2D()
513 */
514
515 /*!
516     \fn QPointF QVector4D::toPointF() const
517
518     Returns the QPointF form of this 4D vector. The z and w coordinates
519     are dropped.
520
521     \sa toPoint(), toVector2D()
522 */
523
524 /*!
525     Returns the 4D vector as a QVariant.
526 */
527 QVector4D::operator QVariant() const
528 {
529     return QVariant(QVariant::Vector4D, this);
530 }
531
532 #ifndef QT_NO_DEBUG_STREAM
533
534 QDebug operator<<(QDebug dbg, const QVector4D &vector)
535 {
536     dbg.nospace() << "QVector4D("
537         << vector.x() << ", " << vector.y() << ", "
538         << vector.z() << ", " << vector.w() << ')';
539     return dbg.space();
540 }
541
542 #endif
543
544 #ifndef QT_NO_DATASTREAM
545
546 /*!
547     \fn QDataStream &operator<<(QDataStream &stream, const QVector4D &vector)
548     \relates QVector4D
549
550     Writes the given \a vector to the given \a stream and returns a
551     reference to the stream.
552
553     \sa {Serializing Qt Data Types}
554 */
555
556 QDataStream &operator<<(QDataStream &stream, const QVector4D &vector)
557 {
558     stream << vector.x() << vector.y()
559            << vector.z() << vector.w();
560     return stream;
561 }
562
563 /*!
564     \fn QDataStream &operator>>(QDataStream &stream, QVector4D &vector)
565     \relates QVector4D
566
567     Reads a 4D vector from the given \a stream into the given \a vector
568     and returns a reference to the stream.
569
570     \sa {Serializing Qt Data Types}
571 */
572
573 QDataStream &operator>>(QDataStream &stream, QVector4D &vector)
574 {
575     float x, y, z, w;
576     stream >> x;
577     stream >> y;
578     stream >> z;
579     stream >> w;
580     vector.setX(x);
581     vector.setY(y);
582     vector.setZ(z);
583     vector.setW(w);
584     return stream;
585 }
586
587 #endif // QT_NO_DATASTREAM
588
589 #endif // QT_NO_VECTOR4D
590
591 QT_END_NAMESPACE