3d/vector.hh
Go to the documentation of this file.
1 /* -*- mia-c++ -*-
2  *
3  * This file is part of MIA - a toolbox for medical image analysis
4  * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
5  *
6  * MIA is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with MIA; if not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 #ifndef __MIA_3DVECTOR_HH
22 #define __MIA_3DVECTOR_HH 1
23 
24 #include <typeinfo>
25 #include <assert.h>
26 #include <stdexcept>
27 #include <math.h>
28 #include <complex>
29 #include <iostream>
30 #include <type_traits>
31 
32 #include <mia/core/defines.hh>
33 #include <mia/core/type_traits.hh>
34 
36 
45 template < class T >
46 class T3DVector {
47 public:
49  T x;
51  T y;
53  T z;
54 
56  typedef T value_type;
57 
59  T3DVector():x(T()),y(T()),z(T()){};
60 
62  explicit T3DVector(int dim):x(T()),y(T()),z(T()){
63  assert(dim == 3);
64  }
65 
67  T3DVector(const T3DVector<T>& other) = default;
68 
70  T3DVector<T>& operator = (const T3DVector<T>& other) = default;
71 
73  T3DVector(const T& x_,const T& y_,const T& z_):
74  x(x_),y(y_),z(z_){
75  }
76 
78  template <class in> explicit T3DVector(const T3DVector<in>& org):
79  x(T(org.x)),y(T(org.y)),z(T(org.z)){
80  }
81 
83  template <class in>
85  x=org.x; y=org.y; z=org.z;
86  return *this;
87  }
88 
90  double norm2()const{
91  return x * x + y * y + z * z;
92  }
93 
95  double product() const {
96  return x * y * z;
97  }
99  double norm()const{
100  return sqrt(norm2());
101  }
102 
104  int size() const {
105  return 3;
106  }
107 
109  void fill(T v) {
110  x = y = z = v;
111  }
112 
121  const T operator [](size_t i) const {
122  assert(i < 3);
123  switch (i) {
124  case 0:return x;
125  case 1:return y;
126  case 2:return z;
127  default:
128  throw std::logic_error("Access to vectorelement out of range");
129  }
130  }
131 
140  T& operator [](size_t i) {
141  assert(i < 3);
142  switch (i) {
143  case 0:return x;
144  case 1:return y;
145  case 2:return z;
146  default:
147  throw std::logic_error("Access to vectorelement out of range");
148  }
149  }
150 
153  x+=a.x; y+=a.y; z+=a.z;
154  return *this;
155  }
156 
159  x-=a.x; y-=a.y; z-=a.z;
160  return *this;
161  }
162 
164  T3DVector<T>& operator *=(const double a){
165  x = T(x * a); y = T(y * a); z = T(z * a);
166  return *this;
167  }
168 
171  x = T(x * a.x); y = T(y * a.y); z = T(z * a.z);
172  return *this;
173  }
174 
175 
177  T3DVector<T>& operator /=(const double a){
178  assert(a != 0.0);
179  x = T(x/ a); y =T (y / a); z = T(z / a);
180  return *this;
181  }
182 
184  void write(std::ostream& os)const {
185  os << x << "," << y << "," << z;
186  }
187 
189  void read(std::istream& is) {
190  char c;
191 
192  T r,s,t;
193  is >> c;
194  // if we get the opening delimiter '<' then we also expect the closing '>'
195  // otherwise just read three coma separated values.
196  // could use the BOOST lexicel cast for better error handling
197  if (c == '<') {
198  is >> r;
199  is >> c;
200  if (c != ',') {
201  is.clear(std::ios::badbit);
202  return;
203  }
204  is >> s;
205  is >> c;
206  if (c != ',') {
207  is.clear(std::ios::badbit);
208  return;
209  }
210  is >> t;
211  is >> c;
212  if (c != '>') {
213  is.clear(std::ios::badbit);
214  return;
215  }
216  x = r;
217  y = s;
218  z = t;
219  }else{
220  is.putback(c);
221  is >> r;
222  is >> c;
223  if (c != ',') {
224  is.clear(std::ios::badbit);
225  return;
226  }
227  is >> s;
228  is >> c;
229  if (c != ',') {
230  is.clear(std::ios::badbit);
231  return;
232  }
233  is >> t;
234  x = r;
235  y = s;
236  z = t;
237  }
238  }
239 
241  const T3DVector<T>& xyz()const {
242  return *this;
243  }
244 
246  const T3DVector<T> xzy()const {
247  return T3DVector<T>(x,z,y);
248  }
249 
251  const T3DVector<T> yxz()const {
252  return T3DVector<T>(y,x,z);
253  }
254 
256  const T3DVector<T> yzx()const {
257  return T3DVector<T>(y,z,x);
258  }
259 
261  const T3DVector<T> zyx()const {
262  return T3DVector<T>(z,y,x);
263  }
264 
266  const T3DVector<T> zxy()const {
267  return T3DVector<T>(z,x,y);
268  }
269 
271  static T3DVector<T> _1;
272 
274  static T3DVector<T> _0;
275 
277  static const unsigned int elements;
278 };
279 
280 
282 template <typename T>
283 struct atomic_data<T3DVector<T> > {
284  typedef T type;
285  static const int size;
286 };
287 
288 template <typename T>
289 const int atomic_data<T3DVector<T> >::size = 3;
291 
292 
300 template <typename T>
302 {
303  return T3DVector<T>(
304  a.y * b.z - b.y * a.z,
305  a.z * b.x - b.z * a.x,
306  a.x * b.y - b.x * a.y
307  );
308 }
309 
310 
312 template <class T> double fabs(const T3DVector<T>& t)
313 {
314  return t.norm();
315 }
316 
318 template <class T> double dot(const T3DVector<T>& a, const T3DVector<T>& b)
319 {
320  return a.x * b.x + a. y * b.y + a.z * b.z;
321 }
322 
323 
326 
329 
332 
333 
334 
336  template <class T>
337 std::ostream& operator << (std::ostream& os, const T3DVector<T>& v)
338 {
339  v.write(os);
340  return os;
341 }
342 
344 template <class T>
345 std::istream& operator >> (std::istream& is, T3DVector<T>& v)
346 {
347  v.read(is);
348  return is;
349 }
350 
351 
353 template <class T>
354 inline const T3DVector<T> operator +(const T3DVector<T>& a,const T3DVector<T>& b){
355  T3DVector<T> tmp(a);
356  tmp += b;
357  return tmp;
358 }
359 
368 template <typename T, typename S>
370 {
371  return T3DVector<T>(a.x + b.x, a.y + b.y, a.z + b.z);
372 }
373 
374 
376 template <class T>
377 inline const T3DVector<T> operator -(const T3DVector<T>& a,const T3DVector<T>& b){
378  T3DVector<T> tmp(a);
379  tmp -= b;
380  return tmp;
381 }
382 
384 template <class T>
385 inline const T3DVector<T> operator *(const T3DVector<T>& a,const T3DVector<T>& b)
386 {
387  return T3DVector<T>(b.x * a.x, b.y * a.y, b.z * a.z);
388 }
389 
391 template <class T>
392 inline const T3DVector<T> operator /(const T3DVector<T>& a,double f)
393 {
394  assert(f != T());
395  T3DVector<T> tmp (a);
396  tmp /= f;
397  return tmp;
398 }
399 
404 template <class T>
405 inline const T3DVector<T> operator / (const T3DVector<T>& a, const T3DVector<T>& b)
406 {
407  assert(b.x != 0.0 && b.x != 0.0 && b.x != 0.0);
408  return T3DVector<T>(a.x/b.x, a.y/b.y, a.z/b.z);
409 }
410 
411 
413 template <class T>
414 inline const T3DVector<T> operator *(const T3DVector<T>& a, double f)
415 {
416  T3DVector<T> tmp (a);
417  tmp *= f;
418  return tmp;
419 }
420 
421 
423 template <class T>
424 inline const T3DVector<T> operator *(double f, const T3DVector<T>& a)
425 {
426  return a * f;
427 }
428 
429 
431 template <class T>
432 inline const T3DVector<T> operator ^(const T3DVector<T>& a,const T3DVector<T>& b)
433 {
434  return T3DVector<T>( a.y * b.z - b.y * a.z,
435  a.z * b.x - b.z * a.x,
436  a.x * b.y - b.x * a.y);
437 }
438 
440 template <class T>
441 inline bool operator == (const T3DVector<T>& a,const T3DVector<T>& b)
442 {
443  return (b.x == a.x && b.y == a.y && b.z == a.z);
444 }
445 
447 template <class T>
448 inline bool operator != (const T3DVector<T>& a,const T3DVector<T>& b)
449 {
450  return ! (a == b);
451 }
452 
454 template <class T>
455 bool operator < (const T3DVector<T>& a,const T3DVector<T>& b){
456  return (a.x < b.x && a.y < b.y && a.z < b.z);
457 }
458 
460 template <class T>
461 bool operator <= (const T3DVector<T>& b, const T3DVector<T>& a){
462  return (b.x <= a.x && b.y <= a.y && b.z <= a.z);
463 }
464 
466 template <class T>
467 bool operator > (const T3DVector<T>& b, const T3DVector<T>& a){
468  return (b.x > a.x && b.y > a.y && b.z > a.z);
469 }
470 
472 template <class T>
473 bool operator >= (const T3DVector<T>& b, const T3DVector<T>& a){
474  return (b.x >= a.x && b.y >= a.y && b.z >= a.z);
475 }
476 template <typename T >
478 
479 template <typename T >
481 
482 template <typename T>
483 struct less_then<T3DVector<T> > {
484  bool operator() (const T3DVector<T>& a, const T3DVector<T>& b) const{
485  return a.z < b.z ||
486  (a.z == b.z &&
487  (a.y < b.y || (a.y == b.y && a.x < b.x)));
488  }
489 };
490 
491 
492 
494 
495 
496 #endif