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
36
38
46template <class T > class T2DVector
47{
48public:
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
299template <typename T>
301 static const int value = attribute_type<T>::value | vector_2d_bit;
302};
303
304
306
307template <typename T>
308struct atomic_data<T2DVector<T>> {
309 typedef T type;
310 static const int size;
311};
312
313template <typename T>
314const int atomic_data<T2DVector<T>>::size = 2;
315
317
318template <typename T>
320
321template <typename T>
323
331template <typename T>
332std::ostream& operator << (std::ostream& os, const T2DVector<T>& a)
333{
334 a.print(os);
335 return os;
336}
337
345template <typename T>
346std::istream& operator >> (std::istream& is, T2DVector<T>& a)
347{
348 a.read(is);
349 return is;
350}
351
359template <typename T>
361{
362 T2DVector<T> r(a);
363 r += b;
364 return r;
365}
366
375template <typename T, typename S>
377{
378 return T2DVector<T>(a.x + b.x, a.y + b.y);
379}
380
388template <typename T>
390{
391 T2DVector<T> r(a);
392 r *= b;
393 return r;
394}
395
404template <typename T>
406{
407 T2DVector<T> r(a);
408 r /= b;
409 return r;
410}
411
420template <typename T>
422{
423 T2DVector<T> r(a);
424 r -= b;
425 return r;
426}
427
436template <typename T>
437T dot(const T2DVector<T>& a, const T2DVector<T>& b)
438{
439 return b.x * a.x + b.y * a.y;
440}
441
451template <typename T>
453{
454 T2DVector<T> r(a);
455 r /= f;
456 return r;
457}
458
466template <typename T>
468{
469 T2DVector<T> r(a);
470 r *= f;
471 return r;
472}
473
481template <typename T>
483{
484 return a * f;
485}
486
494template <typename T, typename S>
495bool operator < (const T2DVector<T>& a, const T2DVector<S>& b)
496{
497 return a.x < b.x && a.y < b.y;
498}
499
500template <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
517template <typename T>
518T cross(const T2DVector<T>& a, const T2DVector<T>& b)
519{
521}
522
523
524template <typename T>
525struct 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< T > operator*(const T2DVector< T > &a, const T2DVector< T > &b)
Definition: 2d/vector.hh:389
T2DVector< unsigned int > C2DBounds
unsigned int valued 2D vector - used as 2D size parameter
Definition: 2d/vector.hh:540
T2DVector< T > operator/(const T2DVector< T > &a, const T2DVector< T > &b)
Definition: 2d/vector.hh:405
T2DVector< float > C2DFVector
float valued 2D vector
Definition: 2d/vector.hh:534
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:421
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
std::ostream & operator<<(std::ostream &os, const T2DVector< T > &a)
Definition: 2d/vector.hh:332
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
T y
second element
Definition: 2d/vector.hh:57
T & operator[](int i)
Definition: 2d/vector.hh:184
void print(std::ostream &os) const
print the vector to a stream with special formatting
Definition: 2d/vector.hh:236
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-=(const T2DVector &a)
in place subtraction
Definition: 2d/vector.hh:125
T x
first element
Definition: 2d/vector.hh:54
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
T2DVector & operator*=(double a)
in place multiplication with a scalar
Definition: 2d/vector.hh:133
size_t size() const
returns the size of this vector, always 2
Definition: 2d/vector.hh:176
T2DVector & operator/=(const T2DVector &a)
in place element wise division of two 2D vectors
Definition: 2d/vector.hh:149
T norm() const
Definition: 2d/vector.hh:103
T2DVector(T _x, T _y)
Definition: 2d/vector.hh:80
T2DVector & operator+=(const T2DVector &a)
in place addition
Definition: 2d/vector.hh:117
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