Merge "Merge branch 'newdocs'" into refs/staging/master
[profile/ivi/qtbase.git] / src / gui / math3d / qvector3d.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 "qvector3d.h"
43 #include "qvector2d.h"
44 #include "qvector4d.h"
45 #include <QtCore/qdatastream.h>
46 #include <QtCore/qmath.h>
47 #include <QtCore/qvariant.h>
48 #include <QtCore/qdebug.h>
49
50 QT_BEGIN_NAMESPACE
51
52 #ifndef QT_NO_VECTOR3D
53
54 /*!
55     \class QVector3D
56     \brief The QVector3D class represents a vector or vertex in 3D space.
57     \since 4.6
58     \ingroup painting-3D
59     \inmodule QtGui
60
61     Vectors are one of the main building blocks of 3D representation and
62     drawing.  They consist of three coordinates, traditionally called
63     x, y, and z.
64
65     The QVector3D class can also be used to represent vertices in 3D space.
66     We therefore do not need to provide a separate vertex class.
67
68     \sa QVector2D, QVector4D, QQuaternion
69 */
70
71 /*!
72     \fn QVector3D::QVector3D()
73
74     Constructs a null vector, i.e. with coordinates (0, 0, 0).
75 */
76
77 /*!
78     \fn QVector3D::QVector3D(float xpos, float ypos, float zpos)
79
80     Constructs a vector with coordinates (\a xpos, \a ypos, \a zpos).
81 */
82
83 /*!
84     \fn QVector3D::QVector3D(const QPoint& point)
85
86     Constructs a vector with x and y coordinates from a 2D \a point, and a
87     z coordinate of 0.
88 */
89
90 /*!
91     \fn QVector3D::QVector3D(const QPointF& point)
92
93     Constructs a vector with x and y coordinates from a 2D \a point, and a
94     z coordinate of 0.
95 */
96
97 #ifndef QT_NO_VECTOR2D
98
99 /*!
100     Constructs a 3D vector from the specified 2D \a vector.  The z
101     coordinate is set to zero.
102
103     \sa toVector2D()
104 */
105 QVector3D::QVector3D(const QVector2D& vector)
106 {
107     xp = vector.xp;
108     yp = vector.yp;
109     zp = 0.0f;
110 }
111
112 /*!
113     Constructs a 3D vector from the specified 2D \a vector.  The z
114     coordinate is set to \a zpos.
115
116     \sa toVector2D()
117 */
118 QVector3D::QVector3D(const QVector2D& vector, float zpos)
119 {
120     xp = vector.xp;
121     yp = vector.yp;
122     zp = zpos;
123 }
124
125 #endif
126
127 #ifndef QT_NO_VECTOR4D
128
129 /*!
130     Constructs a 3D vector from the specified 4D \a vector.  The w
131     coordinate is dropped.
132
133     \sa toVector4D()
134 */
135 QVector3D::QVector3D(const QVector4D& vector)
136 {
137     xp = vector.xp;
138     yp = vector.yp;
139     zp = vector.zp;
140 }
141
142 #endif
143
144 /*!
145     \fn bool QVector3D::isNull() const
146
147     Returns true if the x, y, and z coordinates are set to 0.0,
148     otherwise returns false.
149 */
150
151 /*!
152     \fn float QVector3D::x() const
153
154     Returns the x coordinate of this point.
155
156     \sa setX(), y(), z()
157 */
158
159 /*!
160     \fn float QVector3D::y() const
161
162     Returns the y coordinate of this point.
163
164     \sa setY(), x(), z()
165 */
166
167 /*!
168     \fn float QVector3D::z() const
169
170     Returns the z coordinate of this point.
171
172     \sa setZ(), x(), y()
173 */
174
175 /*!
176     \fn void QVector3D::setX(float x)
177
178     Sets the x coordinate of this point to the given \a x coordinate.
179
180     \sa x(), setY(), setZ()
181 */
182
183 /*!
184     \fn void QVector3D::setY(float y)
185
186     Sets the y coordinate of this point to the given \a y coordinate.
187
188     \sa y(), setX(), setZ()
189 */
190
191 /*!
192     \fn void QVector3D::setZ(float z)
193
194     Sets the z coordinate of this point to the given \a z coordinate.
195
196     \sa z(), setX(), setY()
197 */
198
199 /*!
200     Returns the normalized unit vector form of this vector.
201
202     If this vector is null, then a null vector is returned.  If the length
203     of the vector is very close to 1, then the vector will be returned as-is.
204     Otherwise the normalized form of the vector of length 1 will be returned.
205
206     \sa length(), normalize()
207 */
208 QVector3D QVector3D::normalized() const
209 {
210     // Need some extra precision if the length is very small.
211     double len = double(xp) * double(xp) +
212                  double(yp) * double(yp) +
213                  double(zp) * double(zp);
214     if (qFuzzyIsNull(len - 1.0f)) {
215         return *this;
216     } else if (!qFuzzyIsNull(len)) {
217         double sqrtLen = sqrt(len);
218         return QVector3D(float(double(xp) / sqrtLen),
219                          float(double(yp) / sqrtLen),
220                          float(double(zp) / sqrtLen));
221     } else {
222         return QVector3D();
223     }
224 }
225
226 /*!
227     Normalizes the currect vector in place.  Nothing happens if this
228     vector is a null vector or the length of the vector is very close to 1.
229
230     \sa length(), normalized()
231 */
232 void QVector3D::normalize()
233 {
234     // Need some extra precision if the length is very small.
235     double len = double(xp) * double(xp) +
236                  double(yp) * double(yp) +
237                  double(zp) * double(zp);
238     if (qFuzzyIsNull(len - 1.0f) || qFuzzyIsNull(len))
239         return;
240
241     len = sqrt(len);
242
243     xp = float(double(xp) / len);
244     yp = float(double(yp) / len);
245     zp = float(double(zp) / len);
246 }
247
248 /*!
249     \fn QVector3D &QVector3D::operator+=(const QVector3D &vector)
250
251     Adds the given \a vector to this vector and returns a reference to
252     this vector.
253
254     \sa operator-=()
255 */
256
257 /*!
258     \fn QVector3D &QVector3D::operator-=(const QVector3D &vector)
259
260     Subtracts the given \a vector from this vector and returns a reference to
261     this vector.
262
263     \sa operator+=()
264 */
265
266 /*!
267     \fn QVector3D &QVector3D::operator*=(float factor)
268
269     Multiplies this vector's coordinates by the given \a factor, and
270     returns a reference to this vector.
271
272     \sa operator/=()
273 */
274
275 /*!
276     \fn QVector3D &QVector3D::operator*=(const QVector3D& vector)
277     \overload
278
279     Multiplies the components of this vector by the corresponding
280     components in \a vector.
281
282     Note: this is not the same as the crossProduct() of this
283     vector and \a vector.
284
285     \sa crossProduct()
286 */
287
288 /*!
289     \fn QVector3D &QVector3D::operator/=(float divisor)
290
291     Divides this vector's coordinates by the given \a divisor, and
292     returns a reference to this vector.
293
294     \sa operator*=()
295 */
296
297 /*!
298     Returns the dot product of \a v1 and \a v2.
299 */
300 float QVector3D::dotProduct(const QVector3D& v1, const QVector3D& v2)
301 {
302     return v1.xp * v2.xp + v1.yp * v2.yp + v1.zp * v2.zp;
303 }
304
305 /*!
306     Returns the cross-product of vectors \a v1 and \a v2, which corresponds
307     to the normal vector of a plane defined by \a v1 and \a v2.
308
309     \sa normal()
310 */
311 QVector3D QVector3D::crossProduct(const QVector3D& v1, const QVector3D& v2)
312 {
313     return QVector3D(v1.yp * v2.zp - v1.zp * v2.yp,
314                      v1.zp * v2.xp - v1.xp * v2.zp,
315                      v1.xp * v2.yp - v1.yp * v2.xp);
316 }
317
318 /*!
319     Returns the normal vector of a plane defined by vectors \a v1 and \a v2,
320     normalized to be a unit vector.
321
322     Use crossProduct() to compute the cross-product of \a v1 and \a v2 if you
323     do not need the result to be normalized to a unit vector.
324
325     \sa crossProduct(), distanceToPlane()
326 */
327 QVector3D QVector3D::normal(const QVector3D& v1, const QVector3D& v2)
328 {
329     return crossProduct(v1, v2).normalized();
330 }
331
332 /*!
333     \overload
334
335     Returns the normal vector of a plane defined by vectors
336     \a v2 - \a v1 and \a v3 - \a v1, normalized to be a unit vector.
337
338     Use crossProduct() to compute the cross-product of \a v2 - \a v1 and
339     \a v3 - \a v1 if you do not need the result to be normalized to a
340     unit vector.
341
342     \sa crossProduct(), distanceToPlane()
343 */
344 QVector3D QVector3D::normal
345         (const QVector3D& v1, const QVector3D& v2, const QVector3D& v3)
346 {
347     return crossProduct((v2 - v1), (v3 - v1)).normalized();
348 }
349
350 /*!
351     Returns the distance from this vertex to a plane defined by
352     the vertex \a plane and a \a normal unit vector.  The \a normal
353     parameter is assumed to have been normalized to a unit vector.
354
355     The return value will be negative if the vertex is below the plane,
356     or zero if it is on the plane.
357
358     \sa normal(), distanceToLine()
359 */
360 float QVector3D::distanceToPlane
361         (const QVector3D& plane, const QVector3D& normal) const
362 {
363     return dotProduct(*this - plane, normal);
364 }
365
366 /*!
367     \overload
368
369     Returns the distance from this vertex a plane defined by
370     the vertices \a plane1, \a plane2 and \a plane3.
371
372     The return value will be negative if the vertex is below the plane,
373     or zero if it is on the plane.
374
375     The two vectors that define the plane are \a plane2 - \a plane1
376     and \a plane3 - \a plane1.
377
378     \sa normal(), distanceToLine()
379 */
380 float QVector3D::distanceToPlane
381     (const QVector3D& plane1, const QVector3D& plane2, const QVector3D& plane3) const
382 {
383     QVector3D n = normal(plane2 - plane1, plane3 - plane1);
384     return dotProduct(*this - plane1, n);
385 }
386
387 /*!
388     Returns the distance that this vertex is from a line defined
389     by \a point and the unit vector \a direction.
390
391     If \a direction is a null vector, then it does not define a line.
392     In that case, the distance from \a point to this vertex is returned.
393
394     \sa distanceToPlane()
395 */
396 float QVector3D::distanceToLine
397         (const QVector3D& point, const QVector3D& direction) const
398 {
399     if (direction.isNull())
400         return (*this - point).length();
401     QVector3D p = point + dotProduct(*this - point, direction) * direction;
402     return (*this - p).length();
403 }
404
405 /*!
406     \fn bool operator==(const QVector3D &v1, const QVector3D &v2)
407     \relates QVector3D
408
409     Returns true if \a v1 is equal to \a v2; otherwise returns false.
410     This operator uses an exact floating-point comparison.
411 */
412
413 /*!
414     \fn bool operator!=(const QVector3D &v1, const QVector3D &v2)
415     \relates QVector3D
416
417     Returns true if \a v1 is not equal to \a v2; otherwise returns false.
418     This operator uses an exact floating-point comparison.
419 */
420
421 /*!
422     \fn const QVector3D operator+(const QVector3D &v1, const QVector3D &v2)
423     \relates QVector3D
424
425     Returns a QVector3D object that is the sum of the given vectors, \a v1
426     and \a v2; each component is added separately.
427
428     \sa QVector3D::operator+=()
429 */
430
431 /*!
432     \fn const QVector3D operator-(const QVector3D &v1, const QVector3D &v2)
433     \relates QVector3D
434
435     Returns a QVector3D object that is formed by subtracting \a v2 from \a v1;
436     each component is subtracted separately.
437
438     \sa QVector3D::operator-=()
439 */
440
441 /*!
442     \fn const QVector3D operator*(float factor, const QVector3D &vector)
443     \relates QVector3D
444
445     Returns a copy of the given \a vector,  multiplied by the given \a factor.
446
447     \sa QVector3D::operator*=()
448 */
449
450 /*!
451     \fn const QVector3D operator*(const QVector3D &vector, float factor)
452     \relates QVector3D
453
454     Returns a copy of the given \a vector,  multiplied by the given \a factor.
455
456     \sa QVector3D::operator*=()
457 */
458
459 /*!
460     \fn const QVector3D operator*(const QVector3D &v1, const QVector3D& v2)
461     \relates QVector3D
462
463     Multiplies the components of \a v1 by the corresponding components in \a v2.
464
465     Note: this is not the same as the crossProduct() of \a v1 and \a v2.
466
467     \sa QVector3D::crossProduct()
468 */
469
470 /*!
471     \fn const QVector3D operator-(const QVector3D &vector)
472     \relates QVector3D
473     \overload
474
475     Returns a QVector3D object that is formed by changing the sign of
476     all three components of the given \a vector.
477
478     Equivalent to \c {QVector3D(0,0,0) - vector}.
479 */
480
481 /*!
482     \fn const QVector3D operator/(const QVector3D &vector, float divisor)
483     \relates QVector3D
484
485     Returns the QVector3D object formed by dividing all three components of
486     the given \a vector by the given \a divisor.
487
488     \sa QVector3D::operator/=()
489 */
490
491 /*!
492     \fn bool qFuzzyCompare(const QVector3D& v1, const QVector3D& v2)
493     \relates QVector3D
494
495     Returns true if \a v1 and \a v2 are equal, allowing for a small
496     fuzziness factor for floating-point comparisons; false otherwise.
497 */
498
499 #ifndef QT_NO_VECTOR2D
500
501 /*!
502     Returns the 2D vector form of this 3D vector, dropping the z coordinate.
503
504     \sa toVector4D(), toPoint()
505 */
506 QVector2D QVector3D::toVector2D() const
507 {
508     return QVector2D(xp, yp);
509 }
510
511 #endif
512
513 #ifndef QT_NO_VECTOR4D
514
515 /*!
516     Returns the 4D form of this 3D vector, with the w coordinate set to zero.
517
518     \sa toVector2D(), toPoint()
519 */
520 QVector4D QVector3D::toVector4D() const
521 {
522     return QVector4D(xp, yp, zp, 0.0f);
523 }
524
525 #endif
526
527 /*!
528     \fn QPoint QVector3D::toPoint() const
529
530     Returns the QPoint form of this 3D vector. The z coordinate
531     is dropped.
532
533     \sa toPointF(), toVector2D()
534 */
535
536 /*!
537     \fn QPointF QVector3D::toPointF() const
538
539     Returns the QPointF form of this 3D vector. The z coordinate
540     is dropped.
541
542     \sa toPoint(), toVector2D()
543 */
544
545 /*!
546     Returns the 3D vector as a QVariant.
547 */
548 QVector3D::operator QVariant() const
549 {
550     return QVariant(QVariant::Vector3D, this);
551 }
552
553 /*!
554     Returns the length of the vector from the origin.
555
556     \sa lengthSquared(), normalized()
557 */
558 float QVector3D::length() const
559 {
560     // Need some extra precision if the length is very small.
561     double len = double(xp) * double(xp) +
562                  double(yp) * double(yp) +
563                  double(zp) * double(zp);
564     return float(sqrt(len));
565 }
566
567 /*!
568     Returns the squared length of the vector from the origin.
569     This is equivalent to the dot product of the vector with itself.
570
571     \sa length(), dotProduct()
572 */
573 float QVector3D::lengthSquared() const
574 {
575     return xp * xp + yp * yp + zp * zp;
576 }
577
578 #ifndef QT_NO_DEBUG_STREAM
579
580 QDebug operator<<(QDebug dbg, const QVector3D &vector)
581 {
582     dbg.nospace() << "QVector3D("
583         << vector.x() << ", " << vector.y() << ", " << vector.z() << ')';
584     return dbg.space();
585 }
586
587 #endif
588
589 #ifndef QT_NO_DATASTREAM
590
591 /*!
592     \fn QDataStream &operator<<(QDataStream &stream, const QVector3D &vector)
593     \relates QVector3D
594
595     Writes the given \a vector to the given \a stream and returns a
596     reference to the stream.
597
598     \sa {Serializing Qt Data Types}
599 */
600
601 QDataStream &operator<<(QDataStream &stream, const QVector3D &vector)
602 {
603     stream << vector.x() << vector.y() << vector.z();
604     return stream;
605 }
606
607 /*!
608     \fn QDataStream &operator>>(QDataStream &stream, QVector3D &vector)
609     \relates QVector3D
610
611     Reads a 3D vector from the given \a stream into the given \a vector
612     and returns a reference to the stream.
613
614     \sa {Serializing Qt Data Types}
615 */
616
617 QDataStream &operator>>(QDataStream &stream, QVector3D &vector)
618 {
619     float x, y, z;
620     stream >> x;
621     stream >> y;
622     stream >> z;
623     vector.setX(x);
624     vector.setY(y);
625     vector.setZ(z);
626     return stream;
627 }
628
629 #endif // QT_NO_DATASTREAM
630
631 #endif // QT_NO_VECTOR3D
632
633 QT_END_NAMESPACE