2d/vector.hh
Go to the documentation of this file.
/* -*- mia-c++ -*-
*
* This file is part of MIA - a toolbox for medical image analysis
* Copyright (c) Leipzig, Madrid 1999-2017 Gert Wollny
*
* MIA is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MIA; if not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef MIA_2D_VECTOR_HH
#define MIA_2D_VECTOR_HH
#include <cmath>
#include <cassert>
#include <stdexcept>
#include <ostream>
#include <istream>
#include <iomanip>
#include <type_traits>
// MIA specific
#include <mia/core/type_traits.hh>
#include <mia/core/errormacro.hh>
#include <mia/core/attributetype.hh>
NS_MIA_BEGIN
template <class T > class T2DVector
{
public:
typedef T value_type;
T x;
T y;
static const T2DVector<T> _1;
static const T2DVector<T> _0;
T2DVector(): x(T()), y(T()) {}
explicit T2DVector(int dim): x(T()), y(T())
{
assert(dim == 2);
}
T2DVector(T _x, T _y): x(_x), y(_y) {};
template <typename In>
T2DVector(const T2DVector<In>& in):
x(in.x),
y(in.y)
{
}
// Functions
T norm2() const
{
return T(x * x + y * y);
}
T norm() const
{
return T(sqrt(norm2()));
}
double product() const
{
return x * y;
}
// Operators
T2DVector& operator += (const T2DVector& a)
{
x += a.x;
y += a.y;
return *this;
}
T2DVector& operator -= (const T2DVector& a)
{
x -= a.x;
y -= a.y;
return *this;
}
T2DVector& operator *= (double a)
{
x *= a;
y *= a;
return *this;
}
T2DVector& operator *= (const T2DVector& a)
{
x *= a.x;
y *= a.y;
return *this;
}
T2DVector& operator /= (const T2DVector& a)
{
if ( a.x == 0.0 || a.y == 0.0)
throw std::invalid_argument("T2DVector<T>::operator /=: division by zero not allowed");
x /= a.x;
y /= a.y;
return *this;
}
T2DVector& operator /= (double a)
{
if ( a == 0.0 )
throw std::invalid_argument("T2DVector<T>::operator /=: division by zero not allowed");
x /= a;
y /= a;
return *this;
}
T2DVector operator -() const
{
return T2DVector<T>(-x, -y);
}
size_t size() const
{
return 2;
}
T& operator [](int i)
{
switch (i) {
case 0:
return x;
case 1:
return y;
default: {
DEBUG_ASSERT_RELEASE_THROW(false, "access to value at (", i, ") outside of range (0-1)");
}
}
}
const T& operator [](int i) const
{
switch (i) {
case 0:
return x;
case 1:
return y;
default: {
DEBUG_ASSERT_RELEASE_THROW(false, "access to value at (", i, ") outside of range (0-1)");
}
}
}
void fill(T v)
{
x = y = v;
}
bool operator == (const T2DVector& a)const
{
return (x == a.x && y == a.y);
}
bool operator != (const T2DVector& a)const
{
return (! (*this == a));
}
void print(std::ostream& os) const
{
os << x << "," << y;
}
void read(std::istream& is)
{
char c;
T r, s;
is >> c;
// if we get the opening delimiter '<' then we also expect the closing '>'
// otherwise just read two coma separated values.
// could use the BOOST lexicel cast for better error handling
if (c == '<') {
is >> r;
is >> c;
if (c != ',') {
is.clear(std::ios::badbit);
return;
}
is >> s;
is >> c;
if (c != '>') {
is.clear(std::ios::badbit);
return;
}
x = r;
y = s;
} else {
is.putback(c);
is >> r;
is >> c;
if (c != ',') {
is.clear(std::ios::badbit);
return;
}
is >> s;
x = r;
y = s;
}
}
};
struct EAttributeType_2d : public EAttributeType {
static const int vector_2d_bit = 0x20000;
static bool is_vector2d(int type)
{
return type & vector_2d_bit;
}
};
template <typename T>
struct attribute_type<T2DVector<T>> : public EAttributeType_2d {
static const int value = attribute_type<T>::value | vector_2d_bit;
};
template <typename T>
struct atomic_data<T2DVector<T>> {
typedef T type;
static const int size;
};
template <typename T>
const int atomic_data<T2DVector<T>>::size = 2;
template <typename T>
const T2DVector<T> T2DVector<T>::_1 = T2DVector<T>(1, 1);
template <typename T>
const T2DVector<T> T2DVector<T>::_0 = T2DVector<T>(0, 0);
template <typename T>
std::ostream& operator << (std::ostream& os, const T2DVector<T>& a)
{
a.print(os);
return os;
}
template <typename T>
std::istream& operator >> (std::istream& is, T2DVector<T>& a)
{
a.read(is);
return is;
}
template <typename T>
T2DVector<T> operator +(const T2DVector<T>& a, const T2DVector<T>& b)
{
T2DVector<T> r(a);
r += b;
return r;
}
template <typename T, typename S>
T2DVector<T> operator +(const T2DVector<T>& a, const T2DVector<S>& b)
{
return T2DVector<T>(a.x + b.x, a.y + b.y);
}
template <typename T>
T2DVector<T> operator *(const T2DVector<T>& a, const T2DVector<T>& b)
{
T2DVector<T> r(a);
r *= b;
return r;
}
template <typename T>
T2DVector<T> operator /(const T2DVector<T>& a, const T2DVector<T>& b)
{
T2DVector<T> r(a);
r /= b;
return r;
}
template <typename T>
T2DVector<T> operator -(const T2DVector<T>& a, const T2DVector<T>& b)
{
T2DVector<T> r(a);
r -= b;
return r;
}
template <typename T>
T dot(const T2DVector<T>& a, const T2DVector<T>& b)
{
return b.x * a.x + b.y * a.y;
}
template <typename T>
T2DVector<T> operator / (const T2DVector<T>& a, double f)
{
T2DVector<T> r(a);
r /= f;
return r;
}
template <typename T>
T2DVector<T> operator * (const T2DVector<T>& a, double f)
{
T2DVector<T> r(a);
r *= f;
return r;
}
template <typename T>
T2DVector<T> operator * (double f, const T2DVector<T>& a)
{
return a * f;
}
template <typename T, typename S>
bool operator < (const T2DVector<T>& a, const T2DVector<S>& b)
{
return a.x < b.x && a.y < b.y;
}
template <typename T, template <typename> class Vector>
struct cross_product {
typedef T return_type;
static return_type apply(const Vector<T>& a, const Vector<T>& b)
{
return a.x * b.y - a.y * b.x;
};
};
template <typename T>
T cross(const T2DVector<T>& a, const T2DVector<T>& b)
{
return cross_product<T, T2DVector>::apply(a, b);
}
template <typename T>
struct less_then<T2DVector<T>> {
bool operator() (const T2DVector<T>& a, const T2DVector<T>& b) const
{
return a.y < b.y || (a.y == b.y && a.x < b.x);
}
};
typedef T2DVector<float> C2DFVector;
typedef T2DVector<double> C2DDVector;
typedef T2DVector<unsigned int> C2DBounds;
NS_MIA_END
#endif
cross
T cross(const T2DVector< T > &a, const T2DVector< T > &b)
Definition 2d/vector.hh:518
operator*
T2DVector< T > operator*(const T2DVector< T > &a, const T2DVector< T > &b)
Definition 2d/vector.hh:389
C2DBounds
T2DVector< unsigned int > C2DBounds
unsigned int valued 2D vector - used as 2D size parameter
Definition 2d/vector.hh:540
operator/
T2DVector< T > operator/(const T2DVector< T > &a, const T2DVector< T > &b)
Definition 2d/vector.hh:405
C2DFVector
T2DVector< float > C2DFVector
float valued 2D vector
Definition 2d/vector.hh:534
operator>>
std::istream & operator>>(std::istream &is, T2DVector< T > &a)
Definition 2d/vector.hh:346
operator-
T2DVector< T > operator-(const T2DVector< T > &a, const T2DVector< T > &b)
Definition 2d/vector.hh:421
C2DDVector
T2DVector< double > C2DDVector
double valued 2D vector
Definition 2d/vector.hh:537
operator<
bool operator<(const T2DVector< T > &a, const T2DVector< S > &b)
Definition 2d/vector.hh:495
operator+
T2DVector< T > operator+(const T2DVector< T > &a, const T2DVector< T > &b)
Definition 2d/vector.hh:360
operator<<
std::ostream & operator<<(std::ostream &os, const T2DVector< T > &a)
Definition 2d/vector.hh:332
dot
T dot(const T2DVector< T > &a, const T2DVector< T > &b)
Definition 2d/vector.hh:437
attributetype.hh
type
T2DVector
a 2D vector
Definition 2d/vector.hh:47
T2DVector::T2DVector
T2DVector(int dim)
Definition 2d/vector.hh:70
T2DVector::T2DVector
T2DVector(const T2DVector< In > &in)
Definition 2d/vector.hh:87
T2DVector::operator-
T2DVector operator-() const
Definition 2d/vector.hh:170
T2DVector::T2DVector
T2DVector()
Definition 2d/vector.hh:65
T2DVector< int >::value_type
int value_type
Definition 2d/vector.hh:51
T2DVector< int >::y
int y
Definition 2d/vector.hh:57
T2DVector::operator[]
T & operator[](int i)
Definition 2d/vector.hh:184
T2DVector::print
void print(std::ostream &os) const
print the vector to a stream with special formatting
Definition 2d/vector.hh:236
T2DVector::norm2
T norm2() const
Definition 2d/vector.hh:97
T2DVector::product
double product() const
Definition 2d/vector.hh:109
T2DVector::fill
void fill(T v)
fill all the elements with the given value
Definition 2d/vector.hh:218
T2DVector::operator-=
T2DVector & operator-=(const T2DVector &a)
in place subtraction
Definition 2d/vector.hh:125
T2DVector< int >::x
int x
Definition 2d/vector.hh:54
T2DVector::read
void read(std::istream &is)
read the properly formatted 2D vector from a stream
Definition 2d/vector.hh:242
T2DVector::operator*=
T2DVector & operator*=(double a)
in place multiplication with a scalar
Definition 2d/vector.hh:133
T2DVector::size
size_t size() const
returns the size of this vector, always 2
Definition 2d/vector.hh:176
T2DVector::operator/=
T2DVector & operator/=(const T2DVector &a)
in place element wise division of two 2D vectors
Definition 2d/vector.hh:149
T2DVector< int >::_1
static const T2DVector< int > _1
Definition 2d/vector.hh:60
T2DVector::norm
T norm() const
Definition 2d/vector.hh:103
T2DVector::T2DVector
T2DVector(T _x, T _y)
Definition 2d/vector.hh:80
T2DVector::operator+=
T2DVector & operator+=(const T2DVector &a)
in place addition
Definition 2d/vector.hh:117
T2DVector< int >::_0
static const T2DVector< int > _0
Definition 2d/vector.hh:63
T2DVector::operator==
bool operator==(const T2DVector &a) const
Equal operator.
Definition 2d/vector.hh:224
T2DVector::operator!=
bool operator!=(const T2DVector &a) const
not equal operator
Definition 2d/vector.hh:230
NS_MIA_BEGIN
#define NS_MIA_BEGIN
conveniance define to start the mia namespace
Definition defines.hh:33
NS_MIA_END
#define NS_MIA_END
conveniance define to end the mia namespace
Definition defines.hh:36
errormacro.hh
DEBUG_ASSERT_RELEASE_THROW
#define DEBUG_ASSERT_RELEASE_THROW(cond, msg...)
Definition errormacro.hh:99
EAttributeType_2d
Definition 2d/vector.hh:289
EAttributeType_2d::is_vector2d
static bool is_vector2d(int type)
Definition 2d/vector.hh:293
EAttributeType_2d::vector_2d_bit
static const int vector_2d_bit
Definition 2d/vector.hh:291
EAttributeType
Definition attributetype.hh:32
attribute_type< T2DVector< T > >::value
static const int value
Definition 2d/vector.hh:301
attribute_type
Definition attributetype.hh:65
attribute_type::value
static const int value
Definition attributetype.hh:66
cross_product
Definition 2d/vector.hh:501
cross_product::apply
static return_type apply(const Vector< T > &a, const Vector< T > &b)
Definition 2d/vector.hh:503
cross_product::return_type
T return_type
Definition 2d/vector.hh:502
type_traits.hh