2d/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_2D_VECTOR_HH
22 #define MIA_2D_VECTOR_HH
23 
24 #include <cmath>
25 #include <cassert>
26 #include <stdexcept>
27 #include <ostream>
28 #include <istream>
29 #include <iomanip>
30 #include <type_traits>
31 
32 // MIA specific
33 #include <mia/core/type_traits.hh>
34 #include <mia/core/errormacro.hh>
35 
37 
45 template <class T > class T2DVector {
46 public:
47 
49  typedef T value_type;
50 
52  T x;
53 
55  T y;
56 
58  static const T2DVector<T> _1;
59 
61  static const T2DVector<T> _0;
62 
63  T2DVector():x(T()),y(T()){}
64 
68  explicit T2DVector(int dim):x(T()),y(T()){
69  assert(dim ==2);
70  }
71 
77  T2DVector(T _x, T _y):x(_x),y(_y){};
78 
79 
83  template <typename In>
85  x(in.x),
86  y(in.y)
87  {
88  }
89 
90  // Functions
91 
92 
94  T norm2() const {
95  return T(x * x + y * y);
96  }
97 
99  T norm() const {
100  return T(sqrt(norm2()));
101  }
102 
104  double product() const {
105  return x * y;
106  }
107 
108  // Operators
109 
112  x += a.x; y += a.y;
113  return *this;
114  }
115 
118  x -= a.x; y -= a.y;
119  return *this;
120  }
121 
124  x *= a; y *= a;
125  return *this;
126  }
127 
130  x *= a.x; y *= a.y;
131  return *this;
132  }
133 
136  if ( a.x == 0.0 || a.y == 0.0)
137  throw std::invalid_argument("T2DVector<T>::operator /=: division by zero not allowed");
138  x /= a.x; y /= a.y;
139  return *this;
140  }
141 
144  if ( a == 0.0 )
145  throw std::invalid_argument("T2DVector<T>::operator /=: division by zero not allowed");
146  x /= a; y /= a;
147  return *this;
148  }
149 
151  size_t size() const {
152  return 2;
153  }
154 
158  T& operator [](int i) {
159  switch (i) {
160  case 0:return x;
161  case 1:return y;
162  default: {
163  DEBUG_ASSERT_RELEASE_THROW(false, "access to value at (", i, ") outside of range (0-1)");
164  }
165  }
166  }
167 
171  const T& operator [](int i) const {
172  switch (i) {
173  case 0:return x;
174  case 1:return y;
175  default: {
176  DEBUG_ASSERT_RELEASE_THROW(false, "access to value at (", i, ") outside of range (0-1)");
177  }
178  }
179  }
180 
182  void fill(T v) {
183  x = y = v;
184  }
185 
187  bool operator == (const T2DVector& a)const{
188  return (x == a.x && y == a.y);
189  }
190 
192  bool operator != (const T2DVector& a)const{
193  return (! (*this == a));
194  }
195 
197  void print(std::ostream& os) const {
198  os << x << "," << y;
199  }
200 
202  void read(std::istream& is) {
203  char c;
204 
205  T r,s;
206  is >> c;
207  // if we get the opening delimiter '<' then we also expect the closing '>'
208  // otherwise just read two coma separated values.
209  // could use the BOOST lexicel cast for better error handling
210  if (c == '<') {
211  is >> r;
212  is >> c;
213  if (c != ',') {
214  is.clear(std::ios::badbit);
215  return;
216  }
217  is >> s;
218  is >> c;
219  if (c != '>') {
220  is.clear(std::ios::badbit);
221  return;
222  }
223  x = r;
224  y = s;
225  }else {
226  is.putback(c);
227  is >> r;
228  is >> c;
229  if (c != ',') {
230  is.clear(std::ios::badbit);
231  return;
232  }
233  is >> s;
234  x = r;
235  y = s;
236  }
237 
238  }
239 
240 };
241 
243 
244 template <typename T>
245 struct atomic_data<T2DVector<T> > {
246  typedef T type;
247  static const int size;
248 };
249 
250 template <typename T>
251 const int atomic_data<T2DVector<T> >::size = 2;
252 
254 
255 template <typename T>
257 
258 template <typename T>
260 
268 template <typename T>
269 std::ostream& operator << (std::ostream& os, const T2DVector<T>& a)
270 {
271  a.print(os);
272  return os;
273 }
274 
282 template <typename T>
283 std::istream& operator >> (std::istream& is, T2DVector<T>& a)
284 {
285  a.read(is);
286  return is;
287 }
288 
296 template <typename T>
298 {
299  T2DVector<T> r(a);
300  r += b;
301  return r;
302 }
303 
312 template <typename T, typename S>
314 {
315  return T2DVector<T>(a.x + b.x, a.y + b.y);
316 }
317 
325 template <typename T>
327 {
328  T2DVector<T> r(a);
329  r *= b;
330  return r;
331 }
332 
341 template <typename T>
343 {
344  T2DVector<T> r(a);
345  r /= b;
346  return r;
347 }
348 
357 template <typename T>
359 {
360  T2DVector<T> r(a);
361  r -= b;
362  return r;
363 }
364 
373 template <typename T>
374 T dot(const T2DVector<T>& a, const T2DVector<T>& b)
375 {
376  return b.x * a.x + b.y * a.y;
377 }
378 
388 template <typename T>
390 {
391  T2DVector<T> r(a);
392  r /= f;
393  return r;
394 }
395 
403 template <typename T>
405 {
406  T2DVector<T> r(a);
407  r *= f;
408  return r;
409 }
410 
418 template <typename T>
420 {
421  return a * f;
422 }
423 
431 template <typename T, typename S>
432 bool operator < (const T2DVector<T>& a, const T2DVector<S>& b)
433 {
434  return a.x < b.x && a.y < b.y;
435 }
436 
437 template <typename T, template <typename> class Vector>
439  typedef T return_type;
440  static return_type apply(const Vector<T>& a, const Vector<T>& b) {
441  return a.x * b.y - a.y * b.x;
442  };
443 };
444 
453 template <typename T>
454 T cross(const T2DVector<T>& a, const T2DVector<T>& b)
455 {
457 }
458 
459 
460 template <typename T>
461 struct less_then<T2DVector<T> > {
462  bool operator() (const T2DVector<T>& a, const T2DVector<T>& b) const {
463  return a.y < b.y || (a.y == b.y && a.x < b.x);
464  }
465 };
466 
467 
470 
473 
476 
477 
479 
480 #endif
481