My Project
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-2017 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>
36 
38 
46 template <class T > class T2DVector
47 {
48 public:
49 
51  typedef T value_type;
52 
54  T x;
55 
57  T y;
58 
60  static const T2DVector<T> _1;
61 
63  static const T2DVector<T> _0;
64 
65  T2DVector(): x(T()), y(T()) {}
66 
70  explicit T2DVector(int dim): x(T()), y(T())
71  {
72  assert(dim == 2);
73  }
74 
80  T2DVector(T _x, T _y): x(_x), y(_y) {};
81 
82 
86  template <typename In>
88  x(in.x),
89  y(in.y)
90  {
91  }
92 
93  // Functions
94 
95 
97  T norm2() const
98  {
99  return T(x * x + y * y);
100  }
101 
103  T norm() const
104  {
105  return T(sqrt(norm2()));
106  }
107 
109  double product() const
110  {
111  return x * y;
112  }
113 
114  // Operators
115 
118  {
119  x += a.x;
120  y += a.y;
121  return *this;
122  }
123 
126  {
127  x -= a.x;
128  y -= a.y;
129  return *this;
130  }
131 
134  {
135  x *= a;
136  y *= a;
137  return *this;
138  }
139 
142  {
143  x *= a.x;
144  y *= a.y;
145  return *this;
146  }
147 
150  {
151  if ( a.x == 0.0 || a.y == 0.0)
152  throw std::invalid_argument("T2DVector<T>::operator /=: division by zero not allowed");
153 
154  x /= a.x;
155  y /= a.y;
156  return *this;
157  }
158 
161  {
162  if ( a == 0.0 )
163  throw std::invalid_argument("T2DVector<T>::operator /=: division by zero not allowed");
164 
165  x /= a;
166  y /= a;
167  return *this;
168  }
169 
171  {
172  return T2DVector<T>(-x, -y);
173  }
174 
176  size_t size() const
177  {
178  return 2;
179  }
180 
184  T& operator [](int i)
185  {
186  switch (i) {
187  case 0:
188  return x;
189 
190  case 1:
191  return y;
192 
193  default: {
194  DEBUG_ASSERT_RELEASE_THROW(false, "access to value at (", i, ") outside of range (0-1)");
195  }
196  }
197  }
198 
202  const T& operator [](int i) const
203  {
204  switch (i) {
205  case 0:
206  return x;
207 
208  case 1:
209  return y;
210 
211  default: {
212  DEBUG_ASSERT_RELEASE_THROW(false, "access to value at (", i, ") outside of range (0-1)");
213  }
214  }
215  }
216 
218  void fill(T v)
219  {
220  x = y = v;
221  }
222 
224  bool operator == (const T2DVector& a)const
225  {
226  return (x == a.x && y == a.y);
227  }
228 
230  bool operator != (const T2DVector& a)const
231  {
232  return (! (*this == a));
233  }
234 
236  void print(std::ostream& os) const
237  {
238  os << x << "," << y;
239  }
240 
242  void read(std::istream& is)
243  {
244  char c;
245  T r, s;
246  is >> c;
247 
248  // if we get the opening delimiter '<' then we also expect the closing '>'
249  // otherwise just read two coma separated values.
250  // could use the BOOST lexicel cast for better error handling
251  if (c == '<') {
252  is >> r;
253  is >> c;
254 
255  if (c != ',') {
256  is.clear(std::ios::badbit);
257  return;
258  }
259 
260  is >> s;
261  is >> c;
262 
263  if (c != '>') {
264  is.clear(std::ios::badbit);
265  return;
266  }
267 
268  x = r;
269  y = s;
270  } else {
271  is.putback(c);
272  is >> r;
273  is >> c;
274 
275  if (c != ',') {
276  is.clear(std::ios::badbit);
277  return;
278  }
279 
280  is >> s;
281  x = r;
282  y = s;
283  }
284  }
285 
286 };
287 
288 
290 
291  static const int vector_2d_bit = 0x20000;
292 
293  static bool is_vector2d(int type)
294  {
295  return type & vector_2d_bit;
296  }
297 };
298 
299 template <typename T>
301  static const int value = attribute_type<T>::value | vector_2d_bit;
302 };
303 
304 
306 
307 template <typename T>
308 struct atomic_data<T2DVector<T>> {
309  typedef T type;
310  static const int size;
311 };
312 
313 template <typename T>
314 const int atomic_data<T2DVector<T>>::size = 2;
315 
317 
318 template <typename T>
320 
321 template <typename T>
323 
331 template <typename T>
332 std::ostream& operator << (std::ostream& os, const T2DVector<T>& a)
333 {
334  a.print(os);
335  return os;
336 }
337 
345 template <typename T>
346 std::istream& operator >> (std::istream& is, T2DVector<T>& a)
347 {
348  a.read(is);
349  return is;
350 }
351 
359 template <typename T>
361 {
362  T2DVector<T> r(a);
363  r += b;
364  return r;
365 }
366 
375 template <typename T, typename S>
377 {
378  return T2DVector<T>(a.x + b.x, a.y + b.y);
379 }
380 
388 template <typename T>
390 {
391  T2DVector<T> r(a);
392  r *= b;
393  return r;
394 }
395 
404 template <typename T>
406 {
407  T2DVector<T> r(a);
408  r /= b;
409  return r;
410 }
411 
420 template <typename T>
422 {
423  T2DVector<T> r(a);
424  r -= b;
425  return r;
426 }
427 
436 template <typename T>
437 T dot(const T2DVector<T>& a, const T2DVector<T>& b)
438 {
439  return b.x * a.x + b.y * a.y;
440 }
441 
451 template <typename T>
453 {
454  T2DVector<T> r(a);
455  r /= f;
456  return r;
457 }
458 
466 template <typename T>
468 {
469  T2DVector<T> r(a);
470  r *= f;
471  return r;
472 }
473 
481 template <typename T>
483 {
484  return a * f;
485 }
486 
494 template <typename T, typename S>
495 bool operator < (const T2DVector<T>& a, const T2DVector<S>& b)
496 {
497  return a.x < b.x && a.y < b.y;
498 }
499 
500 template <typename T, template <typename> class Vector>
502  typedef T return_type;
503  static return_type apply(const Vector<T>& a, const Vector<T>& b)
504  {
505  return a.x * b.y - a.y * b.x;
506  };
507 };
508 
517 template <typename T>
518 T cross(const T2DVector<T>& a, const T2DVector<T>& b)
519 {
521 }
522 
523 
524 template <typename T>
525 struct less_then<T2DVector<T>> {
526  bool operator() (const T2DVector<T>& a, const T2DVector<T>& b) const
527  {
528  return a.y < b.y || (a.y == b.y && a.x < b.x);
529  }
530 };
531 
532 
535 
538 
541 
542 
544 
545 #endif
546 
T cross(const T2DVector< T > &a, const T2DVector< T > &b)
Definition: 2d/vector.hh:518
T2DVector< unsigned int > C2DBounds
unsigned int valued 2D vector - used as 2D size parameter
Definition: 2d/vector.hh:540
T2DVector< float > C2DFVector
float valued 2D vector
Definition: 2d/vector.hh:534
std::ostream & operator<<(std::ostream &os, const T2DVector< T > &a)
Definition: 2d/vector.hh:332
T2DVector< T > operator*(const T2DVector< T > &a, const T2DVector< T > &b)
Definition: 2d/vector.hh:389
T2DVector< T > operator-(const T2DVector< T > &a, const T2DVector< T > &b)
Definition: 2d/vector.hh:421
std::istream & operator>>(std::istream &is, T2DVector< T > &a)
Definition: 2d/vector.hh:346
T2DVector< T > operator/(const T2DVector< T > &a, const T2DVector< T > &b)
Definition: 2d/vector.hh:405
T2DVector< double > C2DDVector
double valued 2D vector
Definition: 2d/vector.hh:537
bool operator<(const T2DVector< T > &a, const T2DVector< S > &b)
Definition: 2d/vector.hh:495
T2DVector< T > operator+(const T2DVector< T > &a, const T2DVector< T > &b)
Definition: 2d/vector.hh:360
T dot(const T2DVector< T > &a, const T2DVector< T > &b)
Definition: 2d/vector.hh:437
a 2D vector
Definition: 2d/vector.hh:47
T2DVector(int dim)
Definition: 2d/vector.hh:70
T2DVector(const T2DVector< In > &in)
Definition: 2d/vector.hh:87
T2DVector operator-() const
Definition: 2d/vector.hh:170
T value_type
typedef for generic access to the element type
Definition: 2d/vector.hh:51
static const T2DVector< T > _1
a static for the value <1,1>.
Definition: 2d/vector.hh:60
T2DVector & operator-=(const T2DVector &a)
in place subtraction
Definition: 2d/vector.hh:125
T y
second element
Definition: 2d/vector.hh:57
T2DVector & operator/=(const T2DVector &a)
in place element wise division of two 2D vectors
Definition: 2d/vector.hh:149
void print(std::ostream &os) const
print the vector to a stream with special formatting
Definition: 2d/vector.hh:236
T2DVector & operator+=(const T2DVector &a)
in place addition
Definition: 2d/vector.hh:117
T norm2() const
Definition: 2d/vector.hh:97
double product() const
Definition: 2d/vector.hh:109
void fill(T v)
fill all the elements with the given value
Definition: 2d/vector.hh:218
T2DVector & operator*=(double a)
in place multiplication with a scalar
Definition: 2d/vector.hh:133
T x
first element
Definition: 2d/vector.hh:54
T & operator[](int i)
Definition: 2d/vector.hh:184
static const T2DVector< T > _0
a static for the value <0,0>.
Definition: 2d/vector.hh:63
void read(std::istream &is)
read the properly formatted 2D vector from a stream
Definition: 2d/vector.hh:242
size_t size() const
returns the size of this vector, always 2
Definition: 2d/vector.hh:176
T norm() const
Definition: 2d/vector.hh:103
T2DVector(T _x, T _y)
Definition: 2d/vector.hh:80
bool operator==(const T2DVector &a) const
Equal operator.
Definition: 2d/vector.hh:224
bool operator!=(const T2DVector &a) const
not equal operator
Definition: 2d/vector.hh:230
#define NS_MIA_BEGIN
conveniance define to start the mia namespace
Definition: defines.hh:33
#define NS_MIA_END
conveniance define to end the mia namespace
Definition: defines.hh:36
#define DEBUG_ASSERT_RELEASE_THROW(cond, msg...)
Definition: errormacro.hh:99
static bool is_vector2d(int type)
Definition: 2d/vector.hh:293
static const int vector_2d_bit
Definition: 2d/vector.hh:291
static const int value
static return_type apply(const Vector< T > &a, const Vector< T > &b)
Definition: 2d/vector.hh:503