source: trunk/src/gui/math3d/qvector3d.cpp@ 661

Last change on this file since 661 was 651, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.2 sources.

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