Vector3D.h
1 /*
2  * Medical Image Registration ToolKit (MIRTK)
3  *
4  * Copyright 2008-2015 Imperial College London
5  * Copyright 2008-2015 Daniel Rueckert, Julia Schnabel
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 
20 #ifndef MIRTK_Vector3D_H
21 #define MIRTK_Vector3D_H
22 
23 #include "mirtk/Math.h"
24 #include "mirtk/Point.h"
25 #include "mirtk/Vector3.h"
26 
27 
28 namespace mirtk {
29 
30 
31 /// Represents a 3D vector
32 ///
33 /// Must be a primitive type which can be treated as an array of three
34 /// values of type T such that sizeof(Vector<T>) == 3 * sizeof(T).
35 /// Thus, this primitive vector type may not have any other data members
36 /// besides the three vector components. This is required especially
37 /// when Vector3D is used as voxel type of an image and further an
38 /// externally allocated continuous block of 3 * sizeof(T) bytes used
39 /// internally by the image instance which only reinterprets the memory
40 /// as consecutive Vector3D<T> instances, i.e.,
41 ///
42 /// \code
43 /// const int X = 256;
44 /// const int Y = 256;
45 /// const int Z = 128;
46 /// const int num = X * Y * Z;
47 /// double *data = new double[3 * num];
48 /// GenericImage<Vector3D<double> > image(X, Y, Z, data);
49 /// \endcode
50 template <typename T>
51 struct Vector3D
52 {
53  typedef T ComponentType;
54 
55  // ---------------------------------------------------------------------------
56  // Attributes
57 
58  T _x; ///< The x component
59  T _y; ///< The y component
60  T _z; ///< The z component
61 
62  // ---------------------------------------------------------------------------
63  // Construction/Destruction
64 
65  /// Default constructor
66  Vector3D();
67 
68  /// Construct from scalar
69  Vector3D(T);
70 
71  /// Construct from vector components
72  Vector3D(T, T, T);
73 
74  /// Construct from C array
75  explicit Vector3D(const T [3]);
76 
77  /// Construct from non-template 3D vector type
78  explicit Vector3D(const Vector3 &);
79 
80  /// Construct from 3D point
81  explicit Vector3D(const Point &);
82 
83  /// Assignment operator
84  Vector3D &operator =(const Vector3D &);
85 
86  /// Assignment operator
87  Vector3D &operator =(const Point &);
88 
89  /// Copy constructor
90  template <typename T2> Vector3D(const Vector3D<T2> &);
91 
92  // ---------------------------------------------------------------------------
93  // Accessors
94 
95  /// Number of vector components
96  static int Rows() { return 3; }
97 
98  /// Set/get vector component at index 0: _x, 1: _y, or 2: _z
99  T &operator ()(int);
100 
101  /// Get vector component at index 0: _x, 1: _y, or 2: _z
102  T operator ()(int) const;
103 
104  /// Cast to C array pointer
105  operator T *();
106 
107  /// Cast to C array pointer
108  operator const T *() const;
109 
110  // ---------------------------------------------------------------------------
111  // Vector/integral-valued scalar operators
112 
113  /// Assign integral valued scalar
114  Vector3D &operator =(int);
115 
116  /// Add integral valued scalar
117  Vector3D &operator +=(int);
118 
119  /// Subtract integral valued scalar
120  Vector3D &operator -=(int);
121 
122  /// Multiply by integral valued scalar
123  Vector3D &operator *=(int);
124 
125  /// Divide by integral valued scalar
126  Vector3D &operator /=(int);
127 
128  /// Add integral valued scalar to vector
129  Vector3D operator +(int) const;
130 
131  /// Subtract integral valued scalar to vector
132  Vector3D operator -(int) const;
133 
134  /// Multiply vector by integral valued scalar
135  Vector3D operator *(int) const;
136 
137  /// Divide vector by integral valued scalar
138  Vector3D operator /(int) const;
139 
140  // ---------------------------------------------------------------------------
141  // Vector/real-valued scalar operators
142 
143  /// Assign real valued scalar
144  Vector3D &operator =(double);
145 
146  /// Add real valued scalar
147  Vector3D &operator +=(double);
148 
149  /// Subtract real valued scalar
150  Vector3D &operator -=(double);
151 
152  /// Multiply by real valued scalar
153  Vector3D &operator *=(double);
154 
155  /// Divide by real valued scalar
156  Vector3D &operator /=(double);
157 
158  /// Add real valued scalar to vector
159  Vector3D operator +(double) const;
160 
161  /// Subtract real valued scalar to vector
162  Vector3D operator -(double) const;
163 
164  /// Multiply vector by real valued scalar
165  Vector3D operator *(double) const;
166 
167  /// Divide vector by real valued scalar
168  Vector3D operator /(double) const;
169 
170  // ---------------------------------------------------------------------------
171  // Vector/vector operators
172 
173  /// Unary negation operator
174  Vector3D operator -() const;
175 
176  /// Assignment from other vector
177  template <typename T2> Vector3D &operator =(const Vector3D<T2> &);
178 
179  /// Addition of other vector
180  template <typename T2> Vector3D &operator +=(const Vector3D<T2> &);
181 
182  /// Subtraction of other vector
183  template <typename T2> Vector3D &operator -=(const Vector3D<T2> &);
184 
185  /// Element-wise multiplication with other vector
186  template <typename T2> Vector3D &operator *=(const Vector3D<T2> &);
187 
188  /// Element-wise division by other vector
189  template <typename T2> Vector3D &operator /=(const Vector3D<T2> &);
190 
191  /// Addition of two vectors
192  template <typename T2> Vector3D operator +(const Vector3D<T2> &) const;
193 
194  /// Subtraction of two vectors
195  template <typename T2> Vector3D operator -(const Vector3D<T2> &) const;
196 
197  /// Element-wise multiplication of two vectors
198  template <typename T2> Vector3D operator *(const Vector3D<T2> &) const;
199 
200  /// Element-wise division of two vectors
201  template <typename T2> Vector3D operator /(const Vector3D<T2> &) const;
202 
203  // ---------------------------------------------------------------------------
204  // Vector/integral-valued scalar comparison
205 
206  /// Element-wise equality comparison with inegral-valued scalar
207  bool operator ==(int) const;
208 
209  /// Element-wise inequality comparison with inegral-valued scalar
210  bool operator !=(int) const;
211 
212  /// Element-wise less than comparison to inegral-valued scalar
213  bool operator <(int) const;
214 
215  /// Element-wise greater than comparison to inegral-valued scalar
216  bool operator >(int) const;
217 
218  /// Element-wise less or equal than comparison to inegral-valued scalar
219  bool operator <=(int) const;
220 
221  /// Element-wise greater or equal than comparison to inegral-valued scalar
222  bool operator >=(int) const;
223 
224  // ---------------------------------------------------------------------------
225  // Vector/real-valued scalar comparison
226 
227  /// Element-wise equality comparison with real-valued scalar
228  bool operator ==(double) const;
229 
230  /// Element-wise inequality comparison with real-valued scalar
231  bool operator !=(double) const;
232 
233  /// Element-wise less than comparison to real-valued scalar
234  bool operator <(double) const;
235 
236  /// Element-wise greater than comparison to real-valued scalar
237  bool operator >(double) const;
238 
239  /// Element-wise less or equal than comparison to real-valued scalar
240  bool operator <=(double) const;
241 
242  /// Element-wise greater or equal than comparison to real-valued scalar
243  bool operator >=(double) const;
244 
245  // ---------------------------------------------------------------------------
246  // Vector/vector comparison
247 
248  /** Operator for testing equality of two vectors. */
249  template <typename T2> bool operator ==(const Vector3D<T2> &) const;
250 
251  /** Operator for testing non-equality of two vector. */
252  template <typename T2> bool operator !=(const Vector3D<T2> &) const;
253 
254  /** Operator for comparing sizes of vectors. */
255  template <typename T2> bool operator <(const Vector3D<T2> &) const;
256 
257  /** Operator for comparing sizes of vectors. */
258  template <typename T2> bool operator >(const Vector3D<T2> &) const;
259 
260  /** Operator for comparing sizes of vectors. */
261  template <typename T2> bool operator <=(const Vector3D<T2> &) const;
262 
263  /** Operator for comparing sizes of vectors. */
264  template <typename T2> bool operator >=(const Vector3D<T2> &) const;
265 
266  // ---------------------------------------------------------------------------
267  // Other vector functions
268 
269  /// Compute squared length of vector
270  double SquaredLength() const;
271 
272  /// Compute length of vector
273  double Length() const;
274 
275  /// Normalize vector to length one
276  void Normalize();
277 
278  /// Cross-product with other vector
279  Vector3D CrossProduct(const Vector3D &) const;
280 
281  /// Dot-product with other vector
282  double DotProduct(const Vector3D &) const;
283 
284  /// Cross-product of two vectors
285  ///
286  /// \deprecated Use v1.CrossProduct(v2) instead which is less to type because
287  /// it does not require the Vector<T>:: type prefix and further
288  /// puts the name of the operation in between the arguments.
289  static Vector3D CrossProduct(const Vector3D &, const Vector3D &);
290 
291  /// Dot-product of two vectors
292  ///
293  /// \deprecated Use v1.DotProduct(v2) instead which is less to type because
294  /// it does not require the Vector<T>:: type prefix and further
295  /// puts the name of the operation in between the arguments.
296  static double DotProduct(const Vector3D &, const Vector3D &);
297 
298 };
299 
300 ////////////////////////////////////////////////////////////////////////////////
301 // Inline definitions
302 ////////////////////////////////////////////////////////////////////////////////
303 
304 // =============================================================================
305 // Construction/Destruction
306 // =============================================================================
307 
308 // -----------------------------------------------------------------------------
309 template <typename T>
311 {
312  _x = _y = _z = T();
313 }
314 
315 // -----------------------------------------------------------------------------
316 template <typename T>
318 {
319  _x = _y = _z = s;
320 }
321 
322 // -----------------------------------------------------------------------------
323 template <typename T>
324 inline Vector3D<T>::Vector3D(T x, T y, T z)
325 {
326  _x = x;
327  _y = y;
328  _z = z;
329 }
330 
331 // -----------------------------------------------------------------------------
332 template <typename T>
333 inline Vector3D<T>::Vector3D(const T v[3])
334 {
335  _x = v[0];
336  _y = v[1];
337  _z = v[2];
338 }
339 
340 // -----------------------------------------------------------------------------
341 template <typename T>
343 {
344  _x = static_cast<T>(v[0]);
345  _y = static_cast<T>(v[1]);
346  _z = static_cast<T>(v[2]);
347 }
348 
349 // -----------------------------------------------------------------------------
350 template <typename T>
351 inline Vector3D<T>::Vector3D(const Point &p)
352 {
353  _x = static_cast<T>(p._x);
354  _y = static_cast<T>(p._y);
355  _z = static_cast<T>(p._z);
356 }
357 
358 // -----------------------------------------------------------------------------
359 template <typename T1> template <typename T2>
361 {
362  _x = static_cast<T1>(v._x);
363  _y = static_cast<T1>(v._y);
364  _z = static_cast<T1>(v._z);
365 }
366 
367 // -----------------------------------------------------------------------------
368 template <typename T>
370 {
371  _x = static_cast<T>(v._x);
372  _y = static_cast<T>(v._y);
373  _z = static_cast<T>(v._z);
374  return *this;
375 }
376 
377 // -----------------------------------------------------------------------------
378 template <typename T>
380 {
381  _x = static_cast<T>(p._x);
382  _y = static_cast<T>(p._y);
383  _z = static_cast<T>(p._z);
384  return *this;
385 }
386 
387 // =============================================================================
388 // Accessors
389 // =============================================================================
390 
391 // -----------------------------------------------------------------------------
392 template <typename T>
393 inline T& Vector3D<T>::operator ()(int i)
394 {
395  switch (i) {
396  case 0: return _x;
397  case 1: return _y;
398  case 2: return _z;
399  default:
400  cerr << "Vector3D::operator(): Invalid index " << i << endl;
401  exit(1);
402  }
403 }
404 
405 // -----------------------------------------------------------------------------
406 template <typename T>
407 inline T Vector3D<T>::operator ()(int i) const
408 {
409  return const_cast<Vector3D<T> *>(this)->operator()(i);
410 }
411 
412 // -----------------------------------------------------------------------------
413 template <typename T>
415 {
416  return &_x;
417 }
418 
419 // -----------------------------------------------------------------------------
420 template <typename T>
421 inline Vector3D<T>::operator const T *() const
422 {
423  return &_x;
424 }
425 
426 // =============================================================================
427 // 3D vector/integral-valued scalar operators
428 // =============================================================================
429 
430 // -----------------------------------------------------------------------------
431 template <typename T>
433 {
434  _x = static_cast<T>(s);
435  _y = static_cast<T>(s);
436  _z = static_cast<T>(s);
437  return *this;
438 }
439 
440 // -----------------------------------------------------------------------------
441 template <typename T>
443 {
444  _x = static_cast<T>(static_cast<double>(_x) + static_cast<double>(s));
445  _y = static_cast<T>(static_cast<double>(_y) + static_cast<double>(s));
446  _z = static_cast<T>(static_cast<double>(_z) + static_cast<double>(s));
447  return *this;
448 }
449 
450 // -----------------------------------------------------------------------------
451 template <typename T>
453 {
454  _x = static_cast<T>(static_cast<double>(_x) - static_cast<double>(s));
455  _y = static_cast<T>(static_cast<double>(_y) - static_cast<double>(s));
456  _z = static_cast<T>(static_cast<double>(_z) - static_cast<double>(s));
457  return *this;
458 }
459 
460 // -----------------------------------------------------------------------------
461 template <typename T>
463 {
464  _x = static_cast<T>(static_cast<double>(_x) * static_cast<double>(s));
465  _y = static_cast<T>(static_cast<double>(_y) * static_cast<double>(s));
466  _z = static_cast<T>(static_cast<double>(_z) * static_cast<double>(s));
467  return *this;
468 }
469 
470 // -----------------------------------------------------------------------------
471 template <typename T>
473 {
474  _x = static_cast<T>(static_cast<double>(_x) / static_cast<double>(s));
475  _y = static_cast<T>(static_cast<double>(_y) / static_cast<double>(s));
476  _z = static_cast<T>(static_cast<double>(_z) / static_cast<double>(s));
477  return *this;
478 }
479 
480 // -----------------------------------------------------------------------------
481 template <typename T>
483 {
484  Vector3D<T> r(*this);
485  r += s;
486  return r;
487 }
488 
489 // -----------------------------------------------------------------------------
490 template <typename T>
492 {
493  Vector3D<T> r(*this);
494  r -= s;
495  return r;
496 }
497 
498 // -----------------------------------------------------------------------------
499 template <typename T>
501 {
502  Vector3D<T> r(*this);
503  r *= s;
504  return r;
505 }
506 
507 // -----------------------------------------------------------------------------
508 template <typename T>
510 {
511  Vector3D<T> r(*this);
512  r /= s;
513  return r;
514 }
515 
516 // -----------------------------------------------------------------------------
517 template <typename T>
518 inline Vector3D<T> operator +(int s, const Vector3D<T> &v)
519 {
520  return v + s;
521 }
522 
523 // -----------------------------------------------------------------------------
524 template <typename T>
525 inline Vector3D<T> operator -(int s, const Vector3D<T> &v)
526 {
527  return v - s;
528 }
529 
530 // -----------------------------------------------------------------------------
531 template <typename T>
532 inline Vector3D<T> operator *(int s, const Vector3D<T> &v)
533 {
534  return v * s;
535 }
536 
537 // =============================================================================
538 // 3D vector/real-valued scalar operators
539 // =============================================================================
540 
541 // -----------------------------------------------------------------------------
542 template <typename T>
544 {
545  _x = static_cast<T>(s);
546  _y = static_cast<T>(s);
547  _z = static_cast<T>(s);
548  return *this;
549 }
550 
551 // -----------------------------------------------------------------------------
552 template <typename T>
554 {
555  _x = static_cast<T>(static_cast<double>(_x) + s);
556  _y = static_cast<T>(static_cast<double>(_y) + s);
557  _z = static_cast<T>(static_cast<double>(_z) + s);
558  return *this;
559 }
560 
561 // -----------------------------------------------------------------------------
562 template <typename T>
564 {
565  _x = static_cast<T>(static_cast<double>(_x) - s);
566  _y = static_cast<T>(static_cast<double>(_y) - s);
567  _z = static_cast<T>(static_cast<double>(_z) - s);
568  return *this;
569 }
570 
571 // -----------------------------------------------------------------------------
572 template <typename T>
574 {
575  _x = static_cast<T>(static_cast<double>(_x) * s);
576  _y = static_cast<T>(static_cast<double>(_y) * s);
577  _z = static_cast<T>(static_cast<double>(_z) * s);
578  return *this;
579 }
580 
581 // -----------------------------------------------------------------------------
582 template <typename T>
584 {
585  _x = static_cast<T>(static_cast<double>(_x) / s);
586  _y = static_cast<T>(static_cast<double>(_y) / s);
587  _z = static_cast<T>(static_cast<double>(_z) / s);
588  return *this;
589 }
590 
591 // -----------------------------------------------------------------------------
592 template <typename T>
593 inline Vector3D<T> Vector3D<T>::operator +(double s) const
594 {
595  Vector3D<T> r(*this);
596  r += s;
597  return r;
598 }
599 
600 // -----------------------------------------------------------------------------
601 template <typename T>
602 inline Vector3D<T> Vector3D<T>::operator -(double s) const
603 {
604  Vector3D<T> r(*this);
605  r -= s;
606  return r;
607 }
608 
609 // -----------------------------------------------------------------------------
610 template <typename T>
611 inline Vector3D<T> Vector3D<T>::operator *(double s) const
612 {
613  Vector3D<T> r(*this);
614  r *= s;
615  return r;
616 }
617 
618 // -----------------------------------------------------------------------------
619 template <typename T>
620 inline Vector3D<T> Vector3D<T>::operator /(double s) const
621 {
622  Vector3D<T> r(*this);
623  r /= s;
624  return r;
625 }
626 
627 // -----------------------------------------------------------------------------
628 template <typename T>
629 inline Vector3D<T> operator +(double s, const Vector3D<T> &v)
630 {
631  return v + s;
632 }
633 
634 // -----------------------------------------------------------------------------
635 template <typename T>
636 inline Vector3D<T> operator -(double s, const Vector3D<T> &v)
637 {
638  return v - s;
639 }
640 
641 // -----------------------------------------------------------------------------
642 template <typename T>
643 inline Vector3D<T> operator *(double s, const Vector3D<T> &v)
644 {
645  return v * s;
646 }
647 
648 // =============================================================================
649 // 3D vector/vector operators
650 // =============================================================================
651 
652 // -----------------------------------------------------------------------------
653 template <typename T>
655 {
656  return Vector3D<T>(-_x, -_y, -_z);
657 }
658 
659 // -----------------------------------------------------------------------------
660 template <typename T1> template <typename T2>
662 {
663  _x = static_cast<T1>(v._x);
664  _y = static_cast<T1>(v._y);
665  _z = static_cast<T1>(v._z);
666  return *this;
667 }
668 
669 // -----------------------------------------------------------------------------
670 template <typename T1> template <typename T2>
672 {
673  _x = static_cast<T1>(static_cast<double>(_x) + static_cast<double>(v._x));
674  _y = static_cast<T1>(static_cast<double>(_y) + static_cast<double>(v._y));
675  _z = static_cast<T1>(static_cast<double>(_z) + static_cast<double>(v._z));
676  return *this;
677 }
678 
679 // -----------------------------------------------------------------------------
680 template <typename T1> template <typename T2>
682 {
683  _x = static_cast<T1>(static_cast<double>(_x) - static_cast<double>(v._x));
684  _y = static_cast<T1>(static_cast<double>(_y) - static_cast<double>(v._y));
685  _z = static_cast<T1>(static_cast<double>(_z) - static_cast<double>(v._z));
686  return *this;
687 }
688 
689 // -----------------------------------------------------------------------------
690 template <typename T1> template <typename T2>
692 {
693  _x = static_cast<T1>(static_cast<double>(_x) * static_cast<double>(v._x));
694  _y = static_cast<T1>(static_cast<double>(_y) * static_cast<double>(v._y));
695  _z = static_cast<T1>(static_cast<double>(_z) * static_cast<double>(v._z));
696  return *this;
697 }
698 
699 // -----------------------------------------------------------------------------
700 template <typename T1> template <typename T2>
702 {
703  _x = static_cast<T1>(static_cast<double>(_x) / static_cast<double>(v._x));
704  _y = static_cast<T1>(static_cast<double>(_y) / static_cast<double>(v._y));
705  _z = static_cast<T1>(static_cast<double>(_z) / static_cast<double>(v._z));
706  return *this;
707 }
708 
709 // -----------------------------------------------------------------------------
710 template <typename T1> template <typename T2>
712 {
713  Vector3D<T1> r(*this);
714  r += v;
715  return r;
716 }
717 
718 // -----------------------------------------------------------------------------
719 template <typename T1> template <typename T2>
721 {
722  Vector3D<T1> r(*this);
723  r -= v;
724  return r;
725 }
726 
727 // -----------------------------------------------------------------------------
728 template <typename T1> template <typename T2>
730 {
731  Vector3D<T1> r(*this);
732  r *= v;
733  return r;
734 }
735 
736 // -----------------------------------------------------------------------------
737 template <typename T1> template <typename T2>
739 {
740  Vector3D<T1> r(*this);
741  r /= v;
742  return r;
743 }
744 
745 // =============================================================================
746 // 3D Vector/integral-valued scalar comparison
747 // =============================================================================
748 
749 // -----------------------------------------------------------------------------
750 template <typename T>
751 inline bool Vector3D<T>::operator ==(int s) const
752 {
753  return (_x == s && _y == s && _z == s);
754 }
755 
756 // -----------------------------------------------------------------------------
757 template <typename T>
758 inline bool Vector3D<T>::operator !=(int s) const
759 {
760  return !(*this == s);
761 }
762 
763 // -----------------------------------------------------------------------------
764 template <typename T>
765 inline bool Vector3D<T>::operator <(int s) const
766 {
767  return (_x < s && _y < s && _z < s);
768 }
769 
770 // -----------------------------------------------------------------------------
771 template <typename T>
772 inline bool Vector3D<T>::operator >(int s) const
773 {
774  return (_x > s && _y > s && _z > s);
775 }
776 
777 // -----------------------------------------------------------------------------
778 template <typename T>
779 inline bool Vector3D<T>::operator <=(int s) const
780 {
781  return (_x <= s && _y <= s && _z <= s);
782 }
783 
784 // -----------------------------------------------------------------------------
785 template <typename T>
786 inline bool Vector3D<T>::operator >=(int s) const
787 {
788  return (_x >= s && _y >= s && _z >= s);
789 }
790 
791 // =============================================================================
792 // 3D Vector/real-valued scalar comparison
793 // =============================================================================
794 
795 // -----------------------------------------------------------------------------
796 template <typename T>
797 inline bool Vector3D<T>::operator ==(double s) const
798 {
799  return (_x == s && _y == s && _z == s);
800 }
801 
802 // -----------------------------------------------------------------------------
803 template <typename T>
804 inline bool Vector3D<T>::operator !=(double s) const
805 {
806  return !(*this == s);
807 }
808 
809 // -----------------------------------------------------------------------------
810 template <typename T>
811 inline bool Vector3D<T>::operator <(double s) const
812 {
813  return (_x < s && _y < s && _z < s);
814 }
815 
816 // -----------------------------------------------------------------------------
817 template <typename T>
818 inline bool Vector3D<T>::operator >(double s) const
819 {
820  return (_x > s && _y > s && _z > s);
821 }
822 
823 // -----------------------------------------------------------------------------
824 template <typename T>
825 inline bool Vector3D<T>::operator <=(double s) const
826 {
827  return (_x <= s && _y <= s && _z <= s);
828 }
829 
830 // -----------------------------------------------------------------------------
831 template <typename T>
832 inline bool Vector3D<T>::operator >=(double s) const
833 {
834  return (_x >= s && _y >= s && _z >= s);
835 }
836 
837 // =============================================================================
838 // 3D Vector/vector comparison
839 // =============================================================================
840 
841 // -----------------------------------------------------------------------------
842 template <typename T1> template <typename T2>
843 inline bool Vector3D<T1>::operator ==(const Vector3D<T2> &v) const
844 {
845  return ((_z == v._z) && (_y == v._y) && (_x == v._x));
846 }
847 
848 // -----------------------------------------------------------------------------
849 template <typename T1> template <typename T2>
850 inline bool Vector3D<T1>::operator !=(const Vector3D<T2> &v) const
851 {
852  return ((_z != v._z) || (_y != v._y) || (_x != v._x));
853 }
854 
855 // -----------------------------------------------------------------------------
856 template <typename T1> template <typename T2>
857 inline bool Vector3D<T1>::operator <(const Vector3D<T2> &v) const
858 {
859  return ((_z < v._z) ||
860  ((_z == v._z) && (_y < v._y)) ||
861  ((_z == v._z) && (_y == v._y) && (_x < v._x)));
862 }
863 
864 // -----------------------------------------------------------------------------
865 template <typename T1> template <typename T2>
866 inline bool Vector3D<T1>::operator >(const Vector3D<T2> &v) const
867 {
868  return ((_z > v._z) ||
869  ((_z == v._z) && (_y > v._y)) ||
870  ((_z == v._z) && (_y == v._y) && (_x > v._x)));
871 }
872 
873 // -----------------------------------------------------------------------------
874 template <typename T1> template <typename T2>
875 inline bool Vector3D<T1>::operator <=(const Vector3D<T2> &v) const
876 {
877  return ((*this < v) || (*this == v));
878 }
879 
880 // -----------------------------------------------------------------------------
881 template <typename T1> template <typename T2>
882 inline bool Vector3D<T1>::operator >=(const Vector3D<T2> &v) const
883 {
884  return ((*this > v) || (*this == v));
885 }
886 
887 // =============================================================================
888 // 3D vector functions
889 // =============================================================================
890 
891 // -----------------------------------------------------------------------------
892 template <typename T>
893 inline double Vector3D<T>::SquaredLength() const
894 {
895  return static_cast<double>(_x*_x + _y*_y + _z*_z);
896 }
897 
898 // -----------------------------------------------------------------------------
899 template <typename T>
900 inline double Vector3D<T>::Length() const
901 {
902  return sqrt(SquaredLength());
903 }
904 
905 // -----------------------------------------------------------------------------
906 template <typename T>
908 {
909  const double length = Length();
910  if (length != .0) (*this) /= length;
911 }
912 
913 // -----------------------------------------------------------------------------
914 template<typename T>
915 inline Vector3D<T>
917 {
918  return Vector3D<T>((_y * v._z - _z * v._y),
919  (_z * v._x - _x * v._z),
920  (_x * v._y - _y * v._x));
921 }
922 
923 // -----------------------------------------------------------------------------
924 template<typename T>
926  const Vector3D<T> &v2)
927 {
928  return v1.CrossProduct(v2);
929 }
930 
931 // -----------------------------------------------------------------------------
932 template <typename T>
933 inline double Vector3D<T>::DotProduct(const Vector3D<T> &v) const
934 {
935  return (_x * v._x + _y * v._y + _z * v._z);
936 }
937 
938 // -----------------------------------------------------------------------------
939 template<typename T>
940 inline double Vector3D<T>::DotProduct(const Vector3D<T> &v1,
941  const Vector3D<T> &v2)
942 {
943  return v1.DotProduct(v2);
944 }
945 
946 // =============================================================================
947 // Indexed element access
948 // =============================================================================
949 
950 // -----------------------------------------------------------------------------
951 template <class T>
952 inline T get(const mirtk::Vector3D<T> &v, int n)
953 {
954  switch (n) {
955  case 0: return v._x;
956  case 1: return v._y;
957  case 2: return v._z;
958  default:
959  cerr << "Invalid 3D vector element index: " << n << endl;
960  cerr << "Set breakpoint in " << __FILE__ << ":" << __LINE__ << " to debug." << endl;
961  exit(1);
962  }
963 }
964 
965 // -----------------------------------------------------------------------------
966 template <class T>
967 inline void put(mirtk::Vector3D<T> &v, int n, const T &value)
968 {
969  switch (n) {
970  case 0: v._x = value;
971  case 1: v._y = value;
972  case 2: v._z = value;
973  default:
974  cerr << "Invalid 3D vector element index: " << n << endl;
975  cerr << "Set breakpoint in " << __FILE__ << ":" << __LINE__ << " to debug." << endl;
976  exit(1);
977  }
978 }
979 
980 // =============================================================================
981 // Element-wise <cmath> functions
982 // =============================================================================
983 
984 // -----------------------------------------------------------------------------
985 template <typename T>
986 Vector3D<T> pow(const Vector3D<T> &v, int e)
987 {
988  return Vector3D<T>(pow(v._x, e), pow(v._y, e), pow(v._z, e));
989 }
990 
991 // -----------------------------------------------------------------------------
992 template <typename T>
993 Vector3D<T> pow(const Vector3D<T> &v, double e)
994 {
995  return Vector3D<T>(pow(v._x, e), pow(v._y, e), pow(v._z, e));
996 }
997 
998 // -----------------------------------------------------------------------------
999 template <typename T>
1000 Vector3D<T> sqrt(const Vector3D<T> &v)
1001 {
1002  return Vector3D<T>(sqrt(v._x), sqrt(v._y), sqrt(v._z));
1003 }
1004 
1005 
1006 } // namespace mirtk
1007 
1008 #endif // MIRTK_Vector3D_H
double Length() const
Compute length of vector.
Definition: Vector3D.h:900
double _x
x coordinate of Point
Definition: Point.h:46
Vector3D operator/(int) const
Divide vector by integral valued scalar.
Definition: Vector3D.h:509
Vector3D operator-() const
Unary negation operator.
Definition: Vector3D.h:654
Definition: IOConfig.h:41
double SquaredLength() const
Compute squared length of vector.
Definition: Vector3D.h:893
Vector3D & operator+=(int)
Add integral valued scalar.
Definition: Vector3D.h:442
void Normalize()
Normalize vector to length one.
Definition: Vector3D.h:907
bool operator>(int) const
Element-wise greater than comparison to inegral-valued scalar.
Definition: Vector3D.h:772
bool operator<=(int) const
Element-wise less or equal than comparison to inegral-valued scalar.
Definition: Vector3D.h:779
double DotProduct(const Vector3D &) const
Dot-product with other vector.
Definition: Vector3D.h:933
bool operator>=(int) const
Element-wise greater or equal than comparison to inegral-valued scalar.
Definition: Vector3D.h:786
bool operator==(int) const
Element-wise equality comparison with inegral-valued scalar.
Definition: Vector3D.h:751
T _z
The z component.
Definition: Vector3D.h:60
static int Rows()
Number of vector components.
Definition: Vector3D.h:96
T _y
The y component.
Definition: Vector3D.h:59
Vector3D & operator-=(int)
Subtract integral valued scalar.
Definition: Vector3D.h:452
T & operator()(int)
Set/get vector component at index 0: _x, 1: _y, or 2: _z.
Definition: Vector3D.h:393
Vector3D CrossProduct(const Vector3D &) const
Cross-product with other vector.
Definition: Vector3D.h:916
Vector3D & operator=(const Vector3D &)
Assignment operator.
Definition: Vector3D.h:369
double _z
z coordinate of Point
Definition: Point.h:48
T _x
The x component.
Definition: Vector3D.h:58
double _y
y coordinate of Point
Definition: Point.h:47
Vector3D & operator*=(int)
Multiply by integral valued scalar.
Definition: Vector3D.h:462
Vector3D operator+(int) const
Add integral valued scalar to vector.
Definition: Vector3D.h:482
Vector3D()
Default constructor.
Definition: Vector3D.h:310
bool operator!=(int) const
Element-wise inequality comparison with inegral-valued scalar.
Definition: Vector3D.h:758
bool operator<(int) const
Element-wise less than comparison to inegral-valued scalar.
Definition: Vector3D.h:765
Vector3D operator*(int) const
Multiply vector by integral valued scalar.
Definition: Vector3D.h:500
Vector3D & operator/=(int)
Divide by integral valued scalar.
Definition: Vector3D.h:472