Vector4D.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_Vector4D_H
21 #define MIRTK_Vector4D_H
22 
23 #include "mirtk/Math.h"
24 #include "mirtk/Stream.h"
25 
26 
27 namespace mirtk {
28 
29 
30 /// Represents a 4D vector
31 ///
32 /// \note Must be a primitive type which can be treated as an array of
33 /// four values of type T without virtual function table et al.
34 /// Thus, keep this type as simple as possible!
35 template <typename T>
36 struct Vector4D
37 {
38  typedef T ComponentType;
39 
40  // ---------------------------------------------------------------------------
41  // Attributes
42 
43  T _x; ///< The x component
44  T _y; ///< The y component
45  T _z; ///< The z component
46  T _t; ///< The t component
47 
48  // ---------------------------------------------------------------------------
49 
50  /** Constructor. */
51  Vector4D();
52 
53  /** Constructor. */
54  Vector4D(T x);
55 
56  /** Constructor. */
57  Vector4D(T x, T y, T z, T t);
58 
59  /** Copy Constructor. */
60  Vector4D(const Vector4D &);
61 
62  /** Assignment operator */
63  Vector4D& operator=(T s);
64 
65  /** Assignment operator */
66  Vector4D& operator=(const Vector4D& v);
67 
68  /** Unary negation operator. */
69  Vector4D operator-() const;
70 
71  /** Operator for multiplying by a scalar. */
72  template <typename S>
73  Vector4D operator*(S s) const;
74 
75  /** Operator for adding a scalar to a vector. */
76  template <typename S>
77  Vector4D operator+(S s) const;
78 
79  /** Operator for adding two vectors. */
80  Vector4D operator+(const Vector4D& v) const;
81 
82  /** Operator for subtracting a scalar to a vector. */
83  template <typename S>
84  Vector4D operator-(S s) const;
85 
86  /** Operator for subtraction. */
87  Vector4D operator-(const Vector4D& v) const;
88 
89  /** Operator for multiplying by a scalar. */
90  template <typename S>
91  Vector4D& operator*=(S s);
92 
93  /** Operator for multiplying by a vector. */
94  Vector4D& operator*=(const Vector4D& v);
95 
96  /** Operator for adding a scalar. */
97  template <typename S>
98  Vector4D& operator+=(S s);
99 
100  /** Operator for adding a vector. */
101  Vector4D& operator+=(const Vector4D& v);
102 
103  /** Operator for subtracting a scalar. */
104  template <typename S>
105  Vector4D& operator-=(S s);
106 
107  /** Operator for subtracting a vector. */
108  Vector4D& operator-=(const Vector4D& v);
109 
110  /** Operator for testing equality of two vectors. */
111  bool operator==(const Vector4D& v) const;
112 
113  /** Operator for testing non-equality of two vector. */
114  bool operator!=(const Vector4D& v) const;
115 
116  /** Operator for comparing sizes of vectors. */
117  bool operator<(const Vector4D& v) const;
118 
119  /** Operator for comparing sizes of vectors. */
120  bool operator>(const Vector4D& v) const;
121 
122  /** Operator for comparing sizes of vectors. */
123  bool operator<=(const Vector4D& v) const;
124 
125  /** Operator for comparing sizes of vectors. */
126  bool operator>=(const Vector4D& v) const;
127 
128  /** Operator for dividing one vector by another. */
129  Vector4D& operator/=(const Vector4D& v);
130 
131  /** Operator for dividing one vector by another. */
132  Vector4D operator/(const Vector4D& v) const;
133 
134  /** Operator for dividing a vector by a scalar. */
135  template <typename S>
136  Vector4D& operator/=(S s);
137 
138  /** Operator for dividing a vector by a scalar. */
139  template <typename S>
140  Vector4D operator/(S s) const;
141 
142  /** Normalizes the vector. */
143  void Normalize();
144 
145  /** Returns the length of the vector. */
146  double Length() const;
147 
148  /** Takes the dot-product of two vectors. */
149  static double DotProduct(const Vector4D& v1, const Vector4D& v2);
150 
151 };
152 
153 ////////////////////////////////////////////////////////////////////////////////
154 // Inline definitions
155 ////////////////////////////////////////////////////////////////////////////////
156 
157 // -----------------------------------------------------------------------------
158 template <typename T> inline Vector4D<T>::Vector4D()
159 {
160  _x = 0;
161  _y = 0;
162  _z = 0;
163  _t = 0;
164 }
165 
166 // -----------------------------------------------------------------------------
167 template <typename T> inline Vector4D<T>::Vector4D(T x)
168 {
169  _x = x;
170  _y = x;
171  _z = x;
172  _t = x;
173 }
174 
175 // -----------------------------------------------------------------------------
176 template <typename T> inline Vector4D<T>::Vector4D(T x, T y, T z, T t)
177 {
178  _x = x;
179  _y = y;
180  _z = z;
181  _t = t;
182 }
183 
184 // -----------------------------------------------------------------------------
185 template <typename T> inline Vector4D<T>::Vector4D(const Vector4D &v)
186 {
187  _x = v._x;
188  _y = v._y;
189  _z = v._z;
190  _t = v._t;
191 }
192 
193 // -----------------------------------------------------------------------------
194 template <typename T> inline Vector4D<T>& Vector4D<T>::operator=(T s)
195 {
196  _x = s;
197  _y = s;
198  _z = s;
199  _t = s;
200  return *this;
201 }
202 
203 // -----------------------------------------------------------------------------
204 template <typename T> inline Vector4D<T>& Vector4D<T>::operator=(const Vector4D<T>& v)
205 {
206  _x = v._x;
207  _y = v._y;
208  _z = v._z;
209  _t = v._t;
210  return *this;
211 }
212 
213 // -----------------------------------------------------------------------------
214 template <typename T> template <typename S> inline Vector4D<T> Vector4D<T>::operator*(S s) const
215 {
216  Vector4D<T> r;
217 
218  r._x = _x*s;
219  r._y = _y*s;
220  r._z = _z*s;
221  r._t = _t*s;
222 
223  return r;
224 }
225 
226 // -----------------------------------------------------------------------------
227 template <typename T> template <typename S> inline Vector4D<T> Vector4D<T>::operator+(S s) const
228 {
229  Vector4D<T> r;
230 
231  r._x = _x + s;
232  r._y = _y + s;
233  r._z = _z + s;
234  r._t = _t + s;
235 
236  return r;
237 }
238 
239 // -----------------------------------------------------------------------------
240 template <typename T> inline Vector4D<T> Vector4D<T>::operator+(const Vector4D<T>& v) const
241 {
242  Vector4D<T> r;
243 
244  r._x = _x + v._x;
245  r._y = _y + v._y;
246  r._z = _z + v._z;
247  r._t = _t + v._t;
248 
249  return r;
250 }
251 
252 // -----------------------------------------------------------------------------
253 template <typename T> template <typename S> inline Vector4D<T> Vector4D<T>::operator-(S s) const
254 {
255  Vector4D<T> r;
256 
257  r._x = _x - s;
258  r._y = _y - s;
259  r._z = _z - s;
260  r._t = _t - s;
261 
262  return r;
263 }
264 
265 // -----------------------------------------------------------------------------
266 template <typename T> inline Vector4D<T> Vector4D<T>::operator-(const Vector4D<T>& v) const
267 {
268  Vector4D<T> r;
269 
270  r._x = _x - v._x;
271  r._y = _y - v._y;
272  r._z = _z - v._z;
273  r._t = _t - v._t;
274 
275  return r;
276 }
277 
278 // -----------------------------------------------------------------------------
279 template <typename T> template <typename S> inline Vector4D<T>& Vector4D<T>::operator*=(S s)
280 {
281  _x *= s;
282  _y *= s;
283  _z *= s;
284  _t *= s;
285 
286  return *this;
287 }
288 
289 // -----------------------------------------------------------------------------
290 template <typename T> inline Vector4D<T>& Vector4D<T>::operator*=(const Vector4D<T>& v)
291 {
292  _x *= v._x;
293  _y *= v._y;
294  _z *= v._z;
295  _t *= v._t;
296 
297  return *this;
298 }
299 
300 // -----------------------------------------------------------------------------
301 template <typename T> template <typename S> inline Vector4D<T>& Vector4D<T>::operator+=(S s)
302 {
303  _x += s;
304  _y += s;
305  _z += s;
306  _t += s;
307 
308  return *this;
309 }
310 
311 // -----------------------------------------------------------------------------
312 template <typename T>
314 {
315  return Vector4D<T>(-_x, -_y, -_z, -_t);
316 }
317 
318 // -----------------------------------------------------------------------------
319 template <typename T> inline Vector4D<T>& Vector4D<T>::operator+=(const Vector4D<T>& v)
320 {
321  _x += v._x;
322  _y += v._y;
323  _z += v._z;
324  _t += v._t;
325 
326  return *this;
327 }
328 
329 // -----------------------------------------------------------------------------
330 template <typename T> template <typename S> inline Vector4D<T>& Vector4D<T>::operator-=(S s)
331 {
332  _x -= s;
333  _y -= s;
334  _z -= s;
335  _t -= s;
336 
337  return *this;
338 }
339 
340 // -----------------------------------------------------------------------------
341 template <typename T> inline Vector4D<T>& Vector4D<T>::operator-=(const Vector4D<T>& v)
342 {
343  _x -= v._x;
344  _y -= v._y;
345  _z -= v._z;
346  _t -= v._t;
347 
348  return *this;
349 }
350 
351 // -----------------------------------------------------------------------------
352 template <typename T> inline bool Vector4D<T>::operator==(const Vector4D<T>& v) const
353 {
354  return ((_z == v._z) && (_y == v._y) && (_x == v._x) && (_t == v._t));
355 }
356 
357 // -----------------------------------------------------------------------------
358 template <typename T> inline bool Vector4D<T>::operator!=(const Vector4D<T>& v) const
359 {
360  return ((_z != v._z) || (_y != v._y) || (_x != v._x) || (_t != v._t));
361 }
362 
363 // -----------------------------------------------------------------------------
364 template <typename T> inline bool Vector4D<T>::operator<(const Vector4D<T>& v) const
365 {
366  return ( (_t < v._t) ||
367  ((_t == v._t) && (_z < v._z)) ||
368  ((_t == v._t) && (_z == v._z) && (_y < v._y)) ||
369  ((_t == v._t) && (_z == v._z) && (_y == v._y) && (_x < v._x)));
370 }
371 
372 // -----------------------------------------------------------------------------
373 template <typename T> inline bool Vector4D<T>::operator>(const Vector4D<T>& v) const
374 {
375  return ( (_t > v._t) ||
376  ((_t == v._t) && (_z > v._z)) ||
377  ((_t == v._t) && (_z == v._z) && (_y > v._y)) ||
378  ((_t == v._t) && (_z == v._z) && (_y == v._y) && (_x > v._x)));
379 }
380 
381 // -----------------------------------------------------------------------------
382 template <typename T> inline bool Vector4D<T>::operator<=(const Vector4D<T>& v) const
383 {
384  return ((*this < v) || (*this == v));
385 }
386 
387 // -----------------------------------------------------------------------------
388 template <typename T> inline bool Vector4D<T>::operator>=(const Vector4D<T>& v) const
389 {
390  return ((*this > v) || (*this == v));
391 }
392 
393 // -----------------------------------------------------------------------------
394 template <typename T> template <typename S> inline Vector4D<T>& Vector4D<T>::operator/=(S s)
395 {
396  _x /= s;
397  _y /= s;
398  _z /= s;
399  _t /= s;
400 
401  return *this;
402 }
403 
404 // -----------------------------------------------------------------------------
405 template <typename T> template <typename S> inline Vector4D<T> Vector4D<T>::operator/(S s) const
406 {
407  return Vector4D<T>(_x/s, _y/s, _z/s, _t/s);
408 }
409 
410 // -----------------------------------------------------------------------------
411 template <typename T> inline void Vector4D<T>::Normalize()
412 {
413  double length = sqrt(static_cast<double>(_x*_x + _y*_y + _z*_z + _t*_t));
414  if (length != 0) {
415  _x = static_cast<T>(_x/length);
416  _y = static_cast<T>(_y/length);
417  _z = static_cast<T>(_z/length);
418  _t = static_cast<T>(_t/length);
419  }
420 }
421 
422 // -----------------------------------------------------------------------------
423 template <typename T> inline double Vector4D<T>::Length() const
424 {
425  return sqrt(static_cast<double>(_x*_x + _y*_y + _z*_z + _t*_t));
426 }
427 
428 // -----------------------------------------------------------------------------
429 template <typename T> inline double Vector4D<T>::DotProduct(const Vector4D<T>& v1, const Vector4D<T>& v2)
430 {
431  return v1._x*v2._x + v1._y*v2._y + v1._z*v2._z + v1._t*v2._t;
432 }
433 
434 // =============================================================================
435 // Indexed element access
436 // =============================================================================
437 
438 // -----------------------------------------------------------------------------
439 template <class T>
440 inline T get(const Vector4D<T> &v, int n)
441 {
442  switch (n) {
443  case 0: return v._x;
444  case 1: return v._y;
445  case 2: return v._z;
446  case 3: return v._t;
447  default:
448  cerr << "Invalid 4D vector element index: " << n << endl;
449  cerr << "Set breakpoint in " << __FILE__ << ":" << __LINE__ << " to debug." << endl;
450  exit(1);
451  }
452 }
453 
454 // -----------------------------------------------------------------------------
455 template <class T>
456 inline T put(Vector4D<T> &v, int n, const T &value)
457 {
458  switch (n) {
459  case 0: v._x = value;
460  case 1: v._y = value;
461  case 2: v._z = value;
462  case 3: v._t = value;
463  default:
464  cerr << "Invalid 4D vector element index: " << n << endl;
465  cerr << "Set breakpoint in " << __FILE__ << ":" << __LINE__ << " to debug." << endl;
466  exit(1);
467  }
468 }
469 
470 // =============================================================================
471 // Element-wise <cmath> functions
472 // =============================================================================
473 
474 // -----------------------------------------------------------------------------
475 template <typename T>
476 Vector4D<T> pow(const Vector4D<T> &v, int e)
477 {
478  return Vector4D<T>(pow(v._x, e), pow(v._y, e), pow(v._z, e), pow(v._t, e));
479 }
480 
481 // -----------------------------------------------------------------------------
482 template <typename T>
483 Vector4D<T> pow(const Vector4D<T> &v, double e)
484 {
485  return Vector4D<T>(pow(v._x, e), pow(v._y, e), pow(v._z, e), pow(v._t, e));
486 }
487 
488 // -----------------------------------------------------------------------------
489 template <typename T>
490 Vector4D<T> sqrt(const Vector4D<T> &v)
491 {
492  return Vector4D<T>(sqrt(v._x), sqrt(v._y), sqrt(v._z), sqrt(v._t));
493 }
494 
495 
496 } // namespace mirtk
497 
498 #endif // __IRTKVECTOR4D_H
Vector4D operator-() const
Definition: Vector4D.h:313
Vector4D & operator+=(S s)
Vector4D & operator=(T s)
Definition: Vector4D.h:194
void Normalize()
Definition: Vector4D.h:411
T _z
The z component.
Definition: Vector4D.h:45
bool operator<(const Vector4D &v) const
Definition: Vector4D.h:364
bool operator==(const Vector4D &v) const
Definition: Vector4D.h:352
T _t
The t component.
Definition: Vector4D.h:46
Definition: IOConfig.h:41
bool operator!=(const Vector4D &v) const
Definition: Vector4D.h:358
Vector4D & operator-=(S s)
T _x
The x component.
Definition: Vector4D.h:43
bool operator<=(const Vector4D &v) const
Definition: Vector4D.h:382
Vector4D & operator*=(S s)
Vector4D & operator/=(const Vector4D &v)
Vector4D operator/(const Vector4D &v) const
bool operator>(const Vector4D &v) const
Definition: Vector4D.h:373
Vector4D operator*(S s) const
static double DotProduct(const Vector4D &v1, const Vector4D &v2)
Definition: Vector4D.h:429
T _y
The y component.
Definition: Vector4D.h:44
double Length() const
Definition: Vector4D.h:423
Vector4D operator+(S s) const
bool operator>=(const Vector4D &v) const
Definition: Vector4D.h:388