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 public:
48 
50  typedef T value_type;
51 
53  T x;
54 
56  T y;
57 
59  static const T2DVector<T> _1;
60 
62  static const T2DVector<T> _0;
63 
64  T2DVector():x(T()),y(T()){}
65 
69  explicit T2DVector(int dim):x(T()),y(T()){
70  assert(dim ==2);
71  }
72 
78  T2DVector(T _x, T _y):x(_x),y(_y){};
79 
80 
84  template <typename In>
86  x(in.x),
87  y(in.y)
88  {
89  }
90 
91  // Functions
92 
93 
95  T norm2() const {
96  return T(x * x + y * y);
97  }
98 
100  T norm() const {
101  return T(sqrt(norm2()));
102  }
103 
105  double product() const {
106  return x * y;
107  }
108 
109  // Operators
110 
113  x += a.x; y += a.y;
114  return *this;
115  }
116 
119  x -= a.x; y -= a.y;
120  return *this;
121  }
122 
125  x *= a; y *= a;
126  return *this;
127  }
128 
131  x *= a.x; y *= a.y;
132  return *this;
133  }
134 
137  if ( a.x == 0.0 || a.y == 0.0)
138  throw std::invalid_argument("T2DVector<T>::operator /=: division by zero not allowed");
139  x /= a.x; y /= a.y;
140  return *this;
141  }
142 
145  if ( a == 0.0 )
146  throw std::invalid_argument("T2DVector<T>::operator /=: division by zero not allowed");
147  x /= a; y /= a;
148  return *this;
149  }
150 
152  return T2DVector<T>(-x, -y);
153  }
154 
156  size_t size() const {
157  return 2;
158  }
159 
163  T& operator [](int i) {
164  switch (i) {
165  case 0:return x;
166  case 1:return y;
167  default: {
168  DEBUG_ASSERT_RELEASE_THROW(false, "access to value at (", i, ") outside of range (0-1)");
169  }
170  }
171  }
172 
176  const T& operator [](int i) const {
177  switch (i) {
178  case 0:return x;
179  case 1:return y;
180  default: {
181  DEBUG_ASSERT_RELEASE_THROW(false, "access to value at (", i, ") outside of range (0-1)");
182  }
183  }
184  }
185 
187  void fill(T v) {
188  x = y = v;
189  }
190 
192  bool operator == (const T2DVector& a)const{
193  return (x == a.x && y == a.y);
194  }
195 
197  bool operator != (const T2DVector& a)const{
198  return (! (*this == a));
199  }
200 
202  void print(std::ostream& os) const {
203  os << x << "," << y;
204  }
205 
207  void read(std::istream& is) {
208  char c;
209 
210  T r,s;
211  is >> c;
212  // if we get the opening delimiter '<' then we also expect the closing '>'
213  // otherwise just read two coma separated values.
214  // could use the BOOST lexicel cast for better error handling
215  if (c == '<') {
216  is >> r;
217  is >> c;
218  if (c != ',') {
219  is.clear(std::ios::badbit);
220  return;
221  }
222  is >> s;
223  is >> c;
224  if (c != '>') {
225  is.clear(std::ios::badbit);
226  return;
227  }
228  x = r;
229  y = s;
230  }else {
231  is.putback(c);
232  is >> r;
233  is >> c;
234  if (c != ',') {
235  is.clear(std::ios::badbit);
236  return;
237  }
238  is >> s;
239  x = r;
240  y = s;
241  }
242 
243  }
244 
245 };
246 
247 
249 
250  static const int vector_2d_bit = 0x20000;
251 
252  static bool is_vector2d(int type) {
253  return type & vector_2d_bit;
254  }
255 };
256 
257 template <typename T>
259  static const int value = attribute_type<T>::value | vector_2d_bit;
260 };
261 
262 
264 
265 template <typename T>
266 struct atomic_data<T2DVector<T> > {
267  typedef T type;
268  static const int size;
269 };
270 
271 template <typename T>
272 const int atomic_data<T2DVector<T> >::size = 2;
273 
275 
276 template <typename T>
278 
279 template <typename T>
281 
289 template <typename T>
290 std::ostream& operator << (std::ostream& os, const T2DVector<T>& a)
291 {
292  a.print(os);
293  return os;
294 }
295 
303 template <typename T>
304 std::istream& operator >> (std::istream& is, T2DVector<T>& a)
305 {
306  a.read(is);
307  return is;
308 }
309 
317 template <typename T>
319 {
320  T2DVector<T> r(a);
321  r += b;
322  return r;
323 }
324 
333 template <typename T, typename S>
335 {
336  return T2DVector<T>(a.x + b.x, a.y + b.y);
337 }
338 
346 template <typename T>
348 {
349  T2DVector<T> r(a);
350  r *= b;
351  return r;
352 }
353 
362 template <typename T>
364 {
365  T2DVector<T> r(a);
366  r /= b;
367  return r;
368 }
369 
378 template <typename T>
380 {
381  T2DVector<T> r(a);
382  r -= b;
383  return r;
384 }
385 
394 template <typename T>
395 T dot(const T2DVector<T>& a, const T2DVector<T>& b)
396 {
397  return b.x * a.x + b.y * a.y;
398 }
399 
409 template <typename T>
411 {
412  T2DVector<T> r(a);
413  r /= f;
414  return r;
415 }
416 
424 template <typename T>
426 {
427  T2DVector<T> r(a);
428  r *= f;
429  return r;
430 }
431 
439 template <typename T>
441 {
442  return a * f;
443 }
444 
452 template <typename T, typename S>
453 bool operator < (const T2DVector<T>& a, const T2DVector<S>& b)
454 {
455  return a.x < b.x && a.y < b.y;
456 }
457 
458 template <typename T, template <typename> class Vector>
460  typedef T return_type;
461  static return_type apply(const Vector<T>& a, const Vector<T>& b) {
462  return a.x * b.y - a.y * b.x;
463  };
464 };
465 
474 template <typename T>
475 T cross(const T2DVector<T>& a, const T2DVector<T>& b)
476 {
478 }
479 
480 
481 template <typename T>
482 struct less_then<T2DVector<T> > {
483  bool operator() (const T2DVector<T>& a, const T2DVector<T>& b) const {
484  return a.y < b.y || (a.y == b.y && a.x < b.x);
485  }
486 };
487 
488 
491 
494 
497 
498 
500 
501 #endif
502 
size_t size() const
returns the size of this vector, always 2
Definition: 2d/vector.hh:156
T norm2() const
Definition: 2d/vector.hh:95
T2DVector< T > operator/(const T2DVector< T > &a, const T2DVector< T > &b)
Definition: 2d/vector.hh:363
a 2D vector
Definition: 2d/vector.hh:46
T value_type
typedef for generic access to the element type
Definition: 2d/vector.hh:50
T y
second element
Definition: 2d/vector.hh:56
T2DVector(const T2DVector< In > &in)
Definition: 2d/vector.hh:85
#define NS_MIA_BEGIN
conveniance define to start the mia namespace
Definition: defines.hh:33
#define DEBUG_ASSERT_RELEASE_THROW(cond, msg...)
Definition: errormacro.hh:99
T2DVector(int dim)
Definition: 2d/vector.hh:69
double product() const
Definition: 2d/vector.hh:105
T2DVector< T > operator+(const T2DVector< T > &a, const T2DVector< T > &b)
Definition: 2d/vector.hh:318
static const T2DVector< T > _0
a static for the value <0,0>.
Definition: 2d/vector.hh:62
T2DVector(T _x, T _y)
Definition: 2d/vector.hh:78
T norm() const
Definition: 2d/vector.hh:100
void read(std::istream &is)
read the properly formatted 2D vector from a stream
Definition: 2d/vector.hh:207
T2DVector< unsigned int > C2DBounds
unsigned int valued 2D vector - used as 2D size parameter
Definition: 2d/vector.hh:496
bool operator==(const T2DVector &a) const
Equal operator.
Definition: 2d/vector.hh:192
T2DVector & operator+=(const T2DVector &a)
in place addition
Definition: 2d/vector.hh:112
T2DVector< T > operator*(const T2DVector< T > &a, const T2DVector< T > &b)
Definition: 2d/vector.hh:347
T cross(const T2DVector< T > &a, const T2DVector< T > &b)
Definition: 2d/vector.hh:475
T & operator[](int i)
Definition: 2d/vector.hh:163
bool operator!=(const T2DVector &a) const
not equal operator
Definition: 2d/vector.hh:197
T2DVector & operator/=(const T2DVector &a)
in place element wise division of two 2D vectors
Definition: 2d/vector.hh:136
void fill(T v)
fill all the elements with the given value
Definition: 2d/vector.hh:187
T2DVector operator-() const
Definition: 2d/vector.hh:151
T2DVector & operator-=(const T2DVector &a)
in place subtraction
Definition: 2d/vector.hh:118
T2DVector< float > C2DFVector
float valued 2D vector
Definition: 2d/vector.hh:490
static const T2DVector< T > _1
a static for the value <1,1>.
Definition: 2d/vector.hh:59
static bool is_vector2d(int type)
Definition: 2d/vector.hh:252
T dot(const T2DVector< T > &a, const T2DVector< T > &b)
Definition: 2d/vector.hh:395
std::istream & operator>>(std::istream &is, T2DVector< T > &a)
Definition: 2d/vector.hh:304
T2DVector< double > C2DDVector
double valued 2D vector
Definition: 2d/vector.hh:493
void print(std::ostream &os) const
print the vector to a stream with special formatting
Definition: 2d/vector.hh:202
static return_type apply(const Vector< T > &a, const Vector< T > &b)
Definition: 2d/vector.hh:461
T2DVector & operator*=(double a)
in place multiplication with a scalar
Definition: 2d/vector.hh:124
T x
first element
Definition: 2d/vector.hh:53
#define NS_MIA_END
conveniance define to end the mia namespace
Definition: defines.hh:36