|
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 |