source: trunk/src/gui/math3d/qvector4d.cpp@ 855

Last change on this file since 855 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

  • Property svn:eol-style set to native
File size: 13.6 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtGui module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
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** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
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
49QT_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*/
99QVector4D::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*/
113QVector4D::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*/
131QVector4D::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*/
145QVector4D::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*/
231qreal 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*/
242qreal 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*/
256QVector4D 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*/
277void 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*/
341qreal 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*/
446QVector2D 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*/
458QVector2D 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*/
474QVector3D 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*/
485QVector3D 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*/
515QVector4D::operator QVariant() const
516{
517 return QVariant(QVariant::Vector4D, this);
518}
519
520#ifndef QT_NO_DEBUG_STREAM
521
522QDebug 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 {Serializing Qt Data Types}
542*/
543
544QDataStream &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 {Serializing Qt Data Types}
559*/
560
561QDataStream &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
579QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.