Library of Assembled Shared Sources
vector_4d.inl
Go to the documentation of this file.
1/** @file
2 * @author Bram de Greve (bram@cocamware.com)
3 * @author Tom De Muer (tom@cocamware.com)
4 *
5 * *** BEGIN LICENSE INFORMATION ***
6 *
7 * The contents of this file are subject to the Common Public Attribution License
8 * Version 1.0 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://lass.sourceforge.net/cpal-license. The License is based on the
11 * Mozilla Public License Version 1.1 but Sections 14 and 15 have been added to cover
12 * use of software over a computer network and provide for limited attribution for
13 * the Original Developer. In addition, Exhibit A has been modified to be consistent
14 * with Exhibit B.
15 *
16 * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
17 * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
18 * language governing rights and limitations under the License.
19 *
20 * The Original Code is LASS - Library of Assembled Shared Sources.
21 *
22 * The Initial Developer of the Original Code is Bram de Greve and Tom De Muer.
23 * The Original Developer is the Initial Developer.
24 *
25 * All portions of the code written by the Initial Developer are:
26 * Copyright (C) 2004-2011 the Initial Developer.
27 * All Rights Reserved.
28 *
29 * Contributor(s):
30 *
31 * Alternatively, the contents of this file may be used under the terms of the
32 * GNU General Public License Version 2 or later (the GPL), in which case the
33 * provisions of GPL are applicable instead of those above. If you wish to allow use
34 * of your version of this file only under the terms of the GPL and not to allow
35 * others to use your version of this file under the CPAL, indicate your decision by
36 * deleting the provisions above and replace them with the notice and other
37 * provisions required by the GPL License. If you do not delete the provisions above,
38 * a recipient may use your version of this file under either the CPAL or the GPL.
39 *
40 * *** END LICENSE INFORMATION ***
41 */
42
43
44
45#ifndef LASS_GUARDIAN_OF_INCLUSION_PRIM_VECTOR_4D_INL
46#define LASS_GUARDIAN_OF_INCLUSION_PRIM_VECTOR_4D_INL
47
48
49
50
51#include "vector_4d.h"
52
53
54
55namespace lass
56{
57
58namespace prim
59{
60
61template<typename T> inline
62Vector4D<T>::Vector4D() :
63 x(T()),
64 y(T()),
65 z(T()),
66 w(T())
67{
68}
69
70
71
72template<typename T> inline
73Vector4D<T>::Vector4D(TParam x, TParam y, TParam z, TParam w) :
74 x(x),
75 y(y),
76 z(z),
77 w(w)
78{
79}
80
81
82
83template <typename T>
84template <typename U>
85Vector4D<T>::Vector4D(const Vector4D<U>& other):
86 x(static_cast<TValue>(other.x)),
87 y(static_cast<TValue>(other.y)),
88 z(static_cast<TValue>(other.z)),
89 w(static_cast<TValue>(other.w))
90{
91}
92
93
94
95template <typename T>
96template <typename U>
97Vector4D<T>::Vector4D(const U& x, const U& y, const U& z, const U& w):
98 x(static_cast<TValue>(x)),
99 y(static_cast<TValue>(y)),
100 z(static_cast<TValue>(z)),
101 w(static_cast<TValue>(w))
102{
103}
104
107template<typename T> inline
108typename Vector4D<T>::TConstReference Vector4D<T>::operator[](size_t index) const
109{
110 LASS_ASSERT(index < dimension);
111 return *(&x + index);
116template<typename T> inline
117typename Vector4D<T>::TReference Vector4D<T>::operator[](size_t index)
118{
119 LASS_ASSERT(index < dimension);
120 return *(&x + index);
124
125/** Wrap index around range.
126 */
127template<typename T> inline
128typename Vector4D<T>::TConstReference Vector4D<T>::at(signed index) const
129{
130 return *(&x + num::mod(index, dimension));
131}
132
133
134
135/** Wrap index around range.
136 */
137template<typename T> inline
138typename Vector4D<T>::TReference Vector4D<T>::at(signed index)
139{
140 return *(&x + num::mod(index, dimension));
141}
142
143
144
145/** A weird way to get back the same object
146 */
147template<typename T> inline
148const Vector4D<T>& Vector4D<T>::operator+() const
149{
150 return *this;
151}
152
153
154
155template<typename T> inline
156const Vector4D<T> Vector4D<T>::operator-() const
157{
158 return Vector4D(-x, -y, -z, -w);
159}
160
161
162
163/** componentwise addition
164 */
165template<typename T> inline
166Vector4D<T>& Vector4D<T>::operator+=(const Vector4D<T>& other)
167{
168 x += other.x;
169 y += other.y;
170 z += other.z;
171 w += other.w;
172 return *this;
173}
174
175
176
177/** componentwise subtraction
178 */
179template<typename T> inline
180Vector4D<T>& Vector4D<T>::operator-=(const Vector4D<T>& other)
181{
182 x -= other.x;
183 y -= other.y;
184 z -= other.z;
185 w -= other.w;
186 return *this;
187}
188
189
190
191/** Componentwise multiplication.
192 */
193template<typename T> inline
194Vector4D<T>& Vector4D<T>::operator*=(const Vector4D<T>& other)
195{
196 x *= other.x;
197 y *= other.y;
198 z *= other.z;
199 w *= other.w;
200 return *this;
201}
202
203
204
205/** Componentwise division.
206 */
207template<typename T> inline
208Vector4D<T>& Vector4D<T>::operator/=(const Vector4D<T>& other)
209{
210 x /= other.x;
211 y /= other.y;
212 z /= other.z;
213 w /= other.w;
214 return *this;
215}
216
217
218
219/** add other to each component of this.
220 */
221template<typename T> inline
222Vector4D<T>& Vector4D<T>::operator+=(TParam other)
223{
224 x += other;
225 y += other;
226 z += other;
227 w += other;
228 return *this;
229}
230
231
232
233/** subtract other of each component of this.
234 */
235template<typename T> inline
236Vector4D<T>& Vector4D<T>::operator-=(TParam other)
237{
238 x -= other;
239 y -= other;
240 z -= other;
241 w -= other;
242 return *this;
243}
244
245
246
247/** multiply each component of this with other.
248 */
249template<typename T> inline
250Vector4D<T>& Vector4D<T>::operator*=(TParam other)
251{
252 x *= other;
253 y *= other;
254 z *= other;
255 w *= other;
256 return *this;
257}
258
259
260
261/** divide each component of this by other.
262 */
263template<typename T> inline
264Vector4D<T>& Vector4D<T>::operator/=(TParam other)
265{
266 x /= other;
267 y /= other;
268 z /= other;
269 w /= other;
270 return *this;
271}
272
273
274
275/** Return true if all the components are (exactly!) zero
276 */
277template<typename T> inline
279{
280 return x == TNumTraits::zero && y == TNumTraits::zero &&
281 z == TNumTraits::zero && w == TNumTraits::zero;
282}
283
284
285
286/** Return true if at least one of the components is NaN
287 */
288template<typename T> inline
290{
291 return num::isNaN(x) || num::isNaN(y) || num::isNaN(z) || num::isNaN(w);
292}
293
294
295
296/** Return squared norm of vector.
297 */
298template<typename T> inline
299const typename Vector4D<T>::TValue Vector4D<T>::squaredNorm() const
300{
301 return dot(*this, *this);
302}
303
304
305
306/** Return norm of vector.
307 */
308template<typename T> inline
309const typename Vector4D<T>::TValue Vector4D<T>::norm() const
310{
311 return num::sqrt(squaredNorm());
312}
313
314
315
316/** return a unit vector with same direction/sense as this vector.
317 *
318 * <i>The normalized vector of <b>X</b> is a vector in the same direction but with norm (length) 1.
319 * It is denoted <b>X^</b> and given by <b>X^</b> = <b>X</b> / |<b>X</b>|</i>,
320 * http://mathworld.wolfram.com/NormalizedVector.html.
321 */
322template<typename T>
323const Vector4D<T> Vector4D<T>::normal() const
324{
325 Vector4D<T> result(*this);
326 result.normalize();
327 return result;
328}
329
330
331
332/** Project vector on this one
333 */
334template <typename T>
335const Vector4D<T> Vector4D<T>::project(const Vector4D<T>& other) const
336{
337 Vector4D<T> result(*this);
338 result *= dot(other, *this);
339 result /= squaredNorm();
340 return result;
341}
342
343
344
345/** Project vector on this one
346 */
347template<typename T> inline
348const Vector4D<T> Vector4D<T>::reject(const Vector4D<T>& other) const
349{
350 return other - project(other);
351}
352
353
354
355template<typename T> inline
356const Vector4D<T> Vector4D<T>::reflect(const Vector4D<T>& other) const
357{
358 return 2 * project(other) - other;
359}
360
361
362
363/** apply a function to every component
364 */
365template <typename T>
366const Vector4D<T> Vector4D<T>::transform(T (*iOperator)(T)) const
367{
368 return Vector4D<T>(iOperator(x), iOperator(y), iOperator(z), iOperator(w));
369}
370
371
372
373/** Normalize vector.
374 */
375template<typename T> inline
377{
378 *this /= norm();
379}
380
381
382
383/** dot product.
384 * @relates lass::prim::Vector4D
385 */
386template<typename T> inline
387typename Vector4D<T>::TValue dot(const Vector4D<T>& a, const Vector4D<T>& b)
388{
389 return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
390}
391
392
393
394/** @relates lass::prim::Vector4D
395 */
396template<typename T> inline
397bool operator==(const Vector4D<T>& a, const Vector4D<T>& b)
398{
399 return a.x == b.x && a.y == b.y && a.z == b.z && a.w == b.w;
400}
401
402
403
404/** @relates lass::prim::Vector4D
405 */
406template<typename T> inline
407bool operator!=(const Vector4D<T>& a, const Vector4D<T>& b)
408{
409 return !(a == b);
410}
411
412
413
414/** componentwise addition
415 * @relates lass::prim::Vector4D
416 */
417template<typename T> inline
418Vector4D<T> operator+(const Vector4D<T>& a, const Vector4D<T>& b)
419{
420 Vector4D<T> result(a);
421 result += b;
422 return result;
423}
424
425
426
427/** componentwise subtraction
428 * @relates lass::prim::Vector4D
429 */
430template<typename T> inline
431Vector4D<T> operator-(const Vector4D<T>& a, const Vector4D<T>& b)
432{
433 Vector4D<T> result(a);
434 result -= b;
435 return result;
436}
437
438
439
440/** Componentwise multiplication
441 * @relates lass::prim::Vector4D
442 */
443template<typename T> inline
444Vector4D<T> operator*(const Vector4D<T>& a, const Vector4D<T>& b)
445{
446 Vector4D<T> result(a);
447 result *= b;
448 return result;
449}
450
451
452
453/** Componentwise division
454 * @relates lass::prim::Vector4D
455 */
456template<typename T> inline
457Vector4D<T> operator/(const Vector4D<T>& a, const Vector4D<T>& b)
458{
459 Vector4D<T> result(a);
460 result /= b;
461 return result;
462}
463
464
465
466/** add b to all components of a.
467 * @relates lass::prim::Vector4D
468 */
469template<typename T> inline
470Vector4D<T> operator+(const Vector4D<T>& a, typename Vector4D<T>::TParam b)
471{
472 Vector4D<T> result(a);
473 result += b;
474 return result;
475}
476
477
478
479/** subtract b of all components of a.
480 * @relates lass::prim::Vector4D
481 */
482template<typename T> inline
483Vector4D<T> operator-(const Vector4D<T>& a, typename Vector4D<T>::TParam b)
484{
485 Vector4D<T> result(a);
486 result -= b;
487 return result;
488}
489
490
491
492/** muliply all components of a by b
493 * @relates lass::prim::Vector4D
494 */
495template<typename T> inline
496Vector4D<T> operator*(const Vector4D<T>& a, typename Vector4D<T>::TParam b)
497{
498 Vector4D<T> result(a);
499 result *= b;
500 return result;
501}
502
503
504
505/** divide all components of a by b
506 * @relates lass::prim::Vector4D
507 */
508template<typename T> inline
509Vector4D<T> operator/(const Vector4D<T>& a, typename Vector4D<T>::TParam b)
510{
511 Vector4D<T> result(a);
512 result /= b;
513 return result;
514}
515
516
517
518/** add a to all components of b
519 * @relates lass::prim::Vector4D
520 */
521template<typename T> inline
522Vector4D<T> operator+(typename Vector4D<T>::TParam a, const Vector4D<T>& b)
523{
524 Vector4D<T> result(b);
525 result += a;
526 return result;
527}
528
529
530
531/** subtract a of all components of b
532 * @relates lass::prim::Vector4D
533 */
534template<typename T> inline
535Vector4D<T> operator-(typename Vector4D<T>::TParam a, const Vector4D<T>& b)
536{
537 Vector4D<T> result(-b);
538 result += a;
539 return result;
540}
541
542
543
544/** multiply all components of b with a
545 * @relates lass::prim::Vector4D
546 */
547template<typename T> inline
548Vector4D<T> operator*(typename Vector4D<T>::TParam a, const Vector4D<T>& b)
549{
550 Vector4D<T> result(b);
551 result *= a;
552 return result;
553}
554
555
556
557/** return a vector with, for each coordinate, the minimum value of @a a and @a b
558 * @relates lass::prim::Vector4D
559 */
560template<typename T> inline
561Vector4D<T> pointwiseMin(const Vector4D<T>& a, const Vector4D<T>& b)
562{
563 return Vector4D<T>(std::min(a.x, b.x), std::min(a.y, b.y),
564 std::min(a.z, b.z), std::min(a.w, b.w));
565}
566
567
568
569/** return a vector with, for each coordinate, the maximum value of @a a and @a b
570 * @relates lass::prim::Vector4D
571 */
572template<typename T> inline
573Vector4D<T> pointwiseMax(const Vector4D<T>& a, const Vector4D<T>& b)
574{
575 return Vector4D<T>(std::max(a.x, b.x), std::max(a.y, b.y),
576 std::max(a.z, b.z), std::max(a.w, b.w));
577}
578
579
580
581/** interpolate linearly between two vectors: a + t * (b - a)
582 * @relates lass::prim::Vector4D
583 */
584template<typename T>
585inline Vector4D<T> lerp(const Vector4D<T>& a, const Vector4D<T>& b, typename Vector4D<T>::TParam t)
586{
587 Vector4D<T> result = b;
588 result -= a;
589 result *= t;
590 result += a;
591 return result;
592}
593
594
595
596/** @relates lass::prim::Vector4D
597 */
598template<typename T, typename Char, typename Traits>
599std::basic_ostream<Char, Traits>& operator<<(
600 std::basic_ostream<Char, Traits>& stream, const Vector4D<T>& b)
601{
602 LASS_ENFORCE_STREAM(stream) << "(" << b.x << ", " << b.y << ", " << b.z << ", " << b.w << ")";
603 return stream;
604}
605
606
607
608/** @relates lass::prim::Vector4D
609 */
610template<typename T, typename Char, typename Traits>
611std::basic_istream<Char, Traits>& operator>>(
612 std::basic_istream<Char, Traits>& stream, Vector4D<T>& b)
613{
614 Vector4D<T> result;
615
616 char c = 0;
617 stream >> c;
618 if (c != '(')
619 {
620 stream.clear(std::ios::failbit);
621 return stream;
622 }
623
624 c = 0;
625 stream >> result.x >> c;
626 if (c != ',')
627 {
628 stream.clear(std::ios::failbit);
629 return stream;
630 }
631
632 c = 0;
633 stream >> result.y >> c;
634 if (c != ',')
635 {
636 stream.clear(std::ios::failbit);
637 return stream;
638 }
639
640 c = 0;
641 stream >> result.z >> c;
642 if (c != ',')
643 {
644 stream.clear(std::ios::failbit);
645 return stream;
646 }
647
648 c = 0;
649 stream >> result.w >> c;
650 if (c != ')')
651 {
652 stream.clear(std::ios::failbit);
653 return stream;
654 }
655
656 b = result;
657 return stream;
658}
659
660
661
662/** @relates lass::prim::Vector4D
663 */
664template<typename T>
665io::XmlOStream& operator<<(io::XmlOStream& stream, const Vector4D<T>& b)
666{
667 LASS_ENFORCE_STREAM(stream)
668 << "<Vector4D>" << b.x << " " << b.y << " " << b.z << " " << b.w << "</Vector4D>\n";
669 return stream;
670}
671
672
673
674}
675
676}
677
678#endif
LineSegment3D< T, PP > project(const Plane3D< T, EP, NP > &plane, const LineSegment3D< T, PP > &lineSegment)
project a linesegment on a plane.
T norm(const T &x)
return norm of x as if x is real part of complex number: sqr(x)
set of geometrical primitives
Definition aabb_2d.h:81
Library for Assembled Shared Sources.
Definition config.h:53
Vector4D< T > operator/(const Vector4D< T > &a, typename Vector4D< T >::TParam b)
divide all components of a by b
const Vector4D< T > & operator+() const
A weird way to get back the same object.
Vector4D< T >::TValue dot(const Vector4D< T > &a, const Vector4D< T > &b)
dot product.
const Vector4D< T > reject(const Vector4D< T > &other) const
Project vector on this one.
Vector4D< T > operator+(const Vector4D< T > &a, const Vector4D< T > &b)
componentwise addition
Vector4D< T > lerp(const Vector4D< T > &a, const Vector4D< T > &b, typename Vector4D< T >::TParam t)
interpolate linearly between two vectors: a + t * (b - a)
Vector4D< T > operator-(typename Vector4D< T >::TParam a, const Vector4D< T > &b)
subtract a of all components of b
const Vector4D< T > normal() const
return a unit vector with same direction/sense as this vector.
Vector4D::TConstReference at(signed index) const
Wrap index around range.
const TValue norm() const
Return norm of vector.
Vector4D< T > operator*(typename Vector4D< T >::TParam a, const Vector4D< T > &b)
multiply all components of b with a
bool isZero() const
Return true if all the components are (exactly!) zero.
Vector4D< T > operator+(const Vector4D< T > &a, typename Vector4D< T >::TParam b)
add b to all components of a.
const TValue squaredNorm() const
Return squared norm of vector.
Vector4D< T > & operator+=(const Vector4D< T > &other)
componentwise addition
void normalize()
Normalize vector.
Vector4D< T > operator*(const Vector4D< T > &a, const Vector4D< T > &b)
Componentwise multiplication.
Vector4D< T > & operator/=(const Vector4D< T > &other)
Componentwise division.
Vector4D< T > & operator*=(const Vector4D< T > &other)
Componentwise multiplication.
const Vector4D< T > transform(T(*op)(T)) const
apply a function to every component
Vector4D< T > pointwiseMin(const Vector4D< T > &a, const Vector4D< T > &b)
return a vector with, for each coordinate, the minimum value of a and b
Vector4D< T > & operator-=(const Vector4D< T > &other)
componentwise subtraction
const Vector4D< T > project(const Vector4D< T > &other) const
Project vector on this one.
Vector4D< T > operator*(const Vector4D< T > &a, typename Vector4D< T >::TParam b)
muliply all components of a by b
bool isNaN() const
Return true if at least one of the components is NaN.
Vector4D< T > operator-(const Vector4D< T > &a, typename Vector4D< T >::TParam b)
subtract b of all components of a.
Vector4D< T > operator/(const Vector4D< T > &a, const Vector4D< T > &b)
Componentwise division.
Vector4D< T > pointwiseMax(const Vector4D< T > &a, const Vector4D< T > &b)
return a vector with, for each coordinate, the maximum value of a and b
Vector4D< T > operator+(typename Vector4D< T >::TParam a, const Vector4D< T > &b)
add a to all components of b
Vector4D< T > operator-(const Vector4D< T > &a, const Vector4D< T > &b)
componentwise subtraction