|
|
|
|
|
#ifndef DLIB_VECTOr_H_ |
|
#define DLIB_VECTOr_H_ |
|
|
|
#include <cmath> |
|
#include "vector_abstract.h" |
|
#include "../algs.h" |
|
#include "../serialize.h" |
|
#include <functional> |
|
#include <iostream> |
|
#include "../matrix/matrix.h" |
|
#include <limits> |
|
#include <array> |
|
|
|
#if defined(_MSC_VER) && _MSC_VER < 1400 |
|
#pragma warning(push) |
|
|
|
|
|
|
|
|
|
|
|
#pragma warning(disable:4805) |
|
#endif |
|
|
|
namespace dlib |
|
{ |
|
|
|
template < |
|
typename T, |
|
long NR = 3 |
|
> |
|
class vector; |
|
|
|
|
|
|
|
template <typename T, typename U, typename enabled = void> |
|
struct vect_promote; |
|
|
|
template <typename T, typename U, bool res = (sizeof(T) <= sizeof(U))> |
|
struct largest_type |
|
{ |
|
typedef T type; |
|
}; |
|
template <typename T, typename U> |
|
struct largest_type<T,U,true> |
|
{ |
|
typedef U type; |
|
}; |
|
|
|
template <typename T, typename U> |
|
struct vect_promote<T,U, typename enable_if_c<std::numeric_limits<T>::is_integer == std::numeric_limits<U>::is_integer>::type> |
|
{ |
|
|
|
|
|
typedef typename largest_type<T,U>::type type; |
|
}; |
|
|
|
template <typename T, typename U> |
|
struct vect_promote<T,U, typename enable_if_c<std::numeric_limits<T>::is_integer != std::numeric_limits<U>::is_integer>::type> |
|
{ |
|
typedef double type; |
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template <typename T, long N> |
|
struct vc_rebind |
|
{ |
|
typedef vector<T,N> type; |
|
}; |
|
template <typename T, typename U, long N> |
|
struct vc_rebind_promote |
|
{ |
|
typedef vector<typename vect_promote<T,U>::type,N> type; |
|
}; |
|
|
|
|
|
|
|
template <typename T, typename U, typename enabled = void> |
|
struct vector_assign_helper |
|
{ |
|
template <long NR> |
|
static void assign ( |
|
vector<T,2>& dest, |
|
const vector<U,NR>& src |
|
) |
|
{ |
|
dest.x() = static_cast<T>(src.x()); |
|
dest.y() = static_cast<T>(src.y()); |
|
} |
|
|
|
template <long NR> |
|
static void assign ( |
|
vector<T,3>& dest, |
|
const vector<U,NR>& src |
|
) |
|
{ |
|
dest.x() = static_cast<T>(src.x()); |
|
dest.y() = static_cast<T>(src.y()); |
|
dest.z() = static_cast<T>(src.z()); |
|
} |
|
|
|
template <typename EXP> |
|
static void assign ( |
|
vector<T,2>& dest, |
|
const matrix_exp<EXP>& m |
|
) |
|
{ |
|
T x = static_cast<T>(m(0)); |
|
T y = static_cast<T>(m(1)); |
|
dest.x() = x; |
|
dest.y() = y; |
|
} |
|
|
|
template <typename EXP> |
|
static void assign ( |
|
vector<T,3>& dest, |
|
const matrix_exp<EXP>& m |
|
) |
|
{ |
|
T x = static_cast<T>(m(0)); |
|
T y = static_cast<T>(m(1)); |
|
T z = static_cast<T>(m(2)); |
|
|
|
dest.x() = x; |
|
dest.y() = y; |
|
dest.z() = z; |
|
} |
|
}; |
|
|
|
|
|
|
|
|
|
template <typename T, typename U> |
|
struct vector_assign_helper<T,U, typename enable_if_c<std::numeric_limits<T>::is_integer == true && |
|
std::numeric_limits<U>::is_integer == false>::type> |
|
{ |
|
template <long NR> |
|
static void assign ( |
|
vector<T,2>& dest, |
|
const vector<U,NR>& src |
|
) |
|
{ |
|
dest.x() = static_cast<T>(std::floor(src.x() + 0.5)); |
|
dest.y() = static_cast<T>(std::floor(src.y() + 0.5)); |
|
} |
|
|
|
template <long NR> |
|
static void assign ( |
|
vector<T,3>& dest, |
|
const vector<U,NR>& src |
|
) |
|
{ |
|
dest.x() = static_cast<T>(std::floor(src.x() + 0.5)); |
|
dest.y() = static_cast<T>(std::floor(src.y() + 0.5)); |
|
dest.z() = static_cast<T>(std::floor(src.z() + 0.5)); |
|
} |
|
|
|
template <typename EXP> |
|
static void assign ( |
|
vector<T,3>& dest, |
|
const matrix_exp<EXP>& m |
|
) |
|
{ |
|
dest.x() = static_cast<T>(std::floor(m(0) + 0.5)); |
|
dest.y() = static_cast<T>(std::floor(m(1) + 0.5)); |
|
dest.z() = static_cast<T>(std::floor(m(2) + 0.5)); |
|
} |
|
|
|
template <typename EXP> |
|
static void assign ( |
|
vector<T,2>& dest, |
|
const matrix_exp<EXP>& m |
|
) |
|
{ |
|
dest.x() = static_cast<T>(std::floor(m(0) + 0.5)); |
|
dest.y() = static_cast<T>(std::floor(m(1) + 0.5)); |
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
template <typename T> |
|
class vector<T,3> : public matrix<T,3,1> |
|
{ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template <typename V, long N> |
|
struct vc_rebind |
|
{ |
|
typedef vector<V,N> type; |
|
}; |
|
template <typename V, typename U, long N> |
|
struct vc_rebind_promote |
|
{ |
|
typedef vector<typename vect_promote<V,U>::type,N> type; |
|
}; |
|
|
|
public: |
|
|
|
typedef T type; |
|
|
|
vector ( |
|
) |
|
{ |
|
x() = 0; |
|
y() = 0; |
|
z() = 0; |
|
} |
|
|
|
|
|
|
|
vector ( |
|
const T _x, |
|
const T _y, |
|
const T _z |
|
) |
|
{ |
|
x() = _x; |
|
y() = _y; |
|
z() = _z; |
|
} |
|
|
|
|
|
|
|
vector ( |
|
const vector& item |
|
) : matrix<T,3,1>(item) |
|
{ |
|
} |
|
|
|
|
|
|
|
template <typename U> |
|
vector ( |
|
const vector<U,2>& item |
|
) |
|
{ |
|
|
|
|
|
vector<T,2> temp(item); |
|
x() = temp.x(); |
|
y() = temp.y(); |
|
z() = 0; |
|
} |
|
|
|
|
|
|
|
vector ( |
|
const vector<T,2>& item |
|
) |
|
{ |
|
x() = item.x(); |
|
y() = item.y(); |
|
z() = 0; |
|
} |
|
|
|
|
|
|
|
template <typename U> |
|
vector ( |
|
const vector<U,3>& item |
|
) |
|
{ |
|
(*this) = item; |
|
} |
|
|
|
|
|
|
|
template <typename EXP> |
|
vector ( const matrix_exp<EXP>& m) |
|
{ |
|
(*this) = m; |
|
} |
|
|
|
|
|
|
|
template <typename EXP> |
|
vector& operator = ( |
|
const matrix_exp<EXP>& m |
|
) |
|
{ |
|
|
|
COMPILE_TIME_ASSERT(EXP::NR*EXP::NC == 3 || EXP::NR*EXP::NC == 0); |
|
|
|
|
|
DLIB_ASSERT((m.nr() == 1 || m.nc() == 1) && (m.size() == 3), |
|
"\t vector(const matrix_exp& m)" |
|
<< "\n\t the given matrix is of the wrong size" |
|
<< "\n\t m.nr(): " << m.nr() |
|
<< "\n\t m.nc(): " << m.nc() |
|
<< "\n\t m.size(): " << m.size() |
|
<< "\n\t this: " << this |
|
); |
|
|
|
vector_assign_helper<T, typename EXP::type>::assign(*this, m); |
|
return *this; |
|
} |
|
|
|
|
|
|
|
template <typename U, long N> |
|
vector& operator = ( |
|
const vector<U,N>& item |
|
) |
|
{ |
|
vector_assign_helper<T,U>::assign(*this, item); |
|
return *this; |
|
} |
|
|
|
|
|
|
|
vector& operator= ( |
|
const vector& item |
|
) |
|
{ |
|
x() = item.x(); |
|
y() = item.y(); |
|
z() = item.z(); |
|
return *this; |
|
} |
|
|
|
|
|
|
|
double length( |
|
) const |
|
{ |
|
return std::sqrt((double)(x()*x() + y()*y() + z()*z())); |
|
} |
|
|
|
|
|
|
|
double length_squared( |
|
) const |
|
{ |
|
return (double)(x()*x() + y()*y() + z()*z()); |
|
} |
|
|
|
|
|
|
|
typename vc_rebind<double,3>::type normalize ( |
|
) const |
|
{ |
|
const double tmp = std::sqrt((double)(x()*x() + y()*y() + z()*z())); |
|
return vector<double,3> ( x()/tmp, |
|
y()/tmp, |
|
z()/tmp |
|
); |
|
} |
|
|
|
|
|
|
|
T& x ( |
|
) |
|
{ |
|
return (*this)(0); |
|
} |
|
|
|
|
|
|
|
T& y ( |
|
) |
|
{ |
|
return (*this)(1); |
|
} |
|
|
|
|
|
|
|
T& z ( |
|
) |
|
{ |
|
return (*this)(2); |
|
} |
|
|
|
|
|
|
|
const T& x ( |
|
) const |
|
{ |
|
return (*this)(0); |
|
} |
|
|
|
|
|
|
|
const T& y ( |
|
) const |
|
{ |
|
return (*this)(1); |
|
} |
|
|
|
|
|
|
|
const T& z ( |
|
) const |
|
{ |
|
return (*this)(2); |
|
} |
|
|
|
|
|
|
|
T dot ( |
|
const vector& rhs |
|
) const |
|
{ |
|
return x()*rhs.x() + y()*rhs.y() + z()*rhs.z(); |
|
} |
|
|
|
|
|
|
|
template <typename U, long N> |
|
typename vect_promote<T,U>::type dot ( |
|
const vector<U,N>& rhs |
|
) const |
|
{ |
|
return x()*rhs.x() + y()*rhs.y() + z()*rhs.z(); |
|
} |
|
|
|
|
|
|
|
template <typename U, long N> |
|
typename vc_rebind_promote<T,U,3>::type cross ( |
|
const vector<U,N>& rhs |
|
) const |
|
{ |
|
typedef vector<typename vect_promote<T,U>::type,3> ret_type; |
|
|
|
return ret_type ( |
|
y()*rhs.z() - z()*rhs.y(), |
|
z()*rhs.x() - x()*rhs.z(), |
|
x()*rhs.y() - y()*rhs.x() |
|
); |
|
} |
|
|
|
|
|
|
|
vector& operator += ( |
|
const vector& rhs |
|
) |
|
{ |
|
x() += rhs.x(); |
|
y() += rhs.y(); |
|
z() += rhs.z(); |
|
return *this; |
|
} |
|
|
|
|
|
|
|
vector& operator -= ( |
|
const vector& rhs |
|
) |
|
{ |
|
x() -= rhs.x(); |
|
y() -= rhs.y(); |
|
z() -= rhs.z(); |
|
return *this; |
|
} |
|
|
|
|
|
|
|
vector& operator /= ( |
|
const T& rhs |
|
) |
|
{ |
|
x() /= rhs; |
|
y() /= rhs; |
|
z() /= rhs; |
|
return *this; |
|
} |
|
|
|
|
|
|
|
vector& operator *= ( |
|
const T& rhs |
|
) |
|
{ |
|
x() *= rhs; |
|
y() *= rhs; |
|
z() *= rhs; |
|
return *this; |
|
} |
|
|
|
|
|
|
|
vector operator - ( |
|
) const |
|
{ |
|
return vector(-x(), -y(), -z()); |
|
} |
|
|
|
|
|
|
|
template <typename U> |
|
typename vc_rebind_promote<T,U,3>::type operator / ( |
|
const U& val |
|
) const |
|
{ |
|
typedef vector<typename vect_promote<T,U>::type,3> ret_type; |
|
return ret_type(x()/val, y()/val, z()/val); |
|
} |
|
|
|
|
|
|
|
template <typename U, long NR2> |
|
bool operator== ( |
|
const vector<U,NR2>& rhs |
|
) const |
|
{ |
|
return x()==rhs.x() && y()==rhs.y() && z()==rhs.z(); |
|
} |
|
|
|
|
|
|
|
template <typename U, long NR2> |
|
bool operator!= ( |
|
const vector<U,NR2>& rhs |
|
) const |
|
{ |
|
return !(*this == rhs); |
|
} |
|
|
|
|
|
|
|
void swap ( |
|
vector& item |
|
) |
|
{ |
|
dlib::exchange(x(), item.x()); |
|
dlib::exchange(y(), item.y()); |
|
dlib::exchange(z(), item.z()); |
|
} |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
template <typename T> |
|
class vector<T,2> : public matrix<T,2,1> |
|
{ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template <typename V, long N> |
|
struct vc_rebind |
|
{ |
|
typedef vector<V,N> type; |
|
}; |
|
template <typename V, typename U, long N> |
|
struct vc_rebind_promote |
|
{ |
|
typedef vector<typename vect_promote<V,U>::type,N> type; |
|
}; |
|
|
|
|
|
public: |
|
|
|
typedef T type; |
|
|
|
vector ( |
|
) |
|
{ |
|
x() = 0; |
|
y() = 0; |
|
} |
|
|
|
|
|
|
|
vector ( |
|
const T _x, |
|
const T _y |
|
) |
|
{ |
|
x() = _x; |
|
y() = _y; |
|
} |
|
|
|
|
|
|
|
template <typename U> |
|
vector ( |
|
const vector<U,3>& item |
|
) |
|
{ |
|
|
|
|
|
vector<T,3> temp(item); |
|
x() = temp.x(); |
|
y() = temp.y(); |
|
} |
|
|
|
|
|
|
|
vector ( |
|
const vector& item |
|
) : matrix<T,2,1>(item) |
|
{ |
|
} |
|
|
|
|
|
|
|
vector ( |
|
const vector<T,3>& item |
|
) |
|
{ |
|
x() = item.x(); |
|
y() = item.y(); |
|
} |
|
|
|
|
|
|
|
template <typename U> |
|
vector ( |
|
const vector<U,2>& item |
|
) |
|
{ |
|
(*this) = item; |
|
} |
|
|
|
|
|
|
|
template <typename EXP> |
|
vector ( const matrix_exp<EXP>& m) |
|
{ |
|
(*this) = m; |
|
} |
|
|
|
|
|
|
|
template <typename EXP> |
|
vector& operator = ( |
|
const matrix_exp<EXP>& m |
|
) |
|
{ |
|
|
|
COMPILE_TIME_ASSERT(EXP::NR*EXP::NC == 2 || EXP::NR*EXP::NC == 0); |
|
|
|
|
|
DLIB_ASSERT((m.nr() == 1 || m.nc() == 1) && (m.size() == 2), |
|
"\t vector(const matrix_exp& m)" |
|
<< "\n\t the given matrix is of the wrong size" |
|
<< "\n\t m.nr(): " << m.nr() |
|
<< "\n\t m.nc(): " << m.nc() |
|
<< "\n\t m.size(): " << m.size() |
|
<< "\n\t this: " << this |
|
); |
|
|
|
vector_assign_helper<T, typename EXP::type>::assign(*this, m); |
|
return *this; |
|
} |
|
|
|
|
|
|
|
template <typename U, long N> |
|
vector& operator = ( |
|
const vector<U,N>& item |
|
) |
|
{ |
|
vector_assign_helper<T,U>::assign(*this, item); |
|
return *this; |
|
} |
|
|
|
|
|
|
|
vector& operator= ( |
|
const vector& item |
|
) |
|
{ |
|
x() = item.x(); |
|
y() = item.y(); |
|
return *this; |
|
} |
|
|
|
|
|
|
|
double length( |
|
) const |
|
{ |
|
return std::sqrt((double)(x()*x() + y()*y())); |
|
} |
|
|
|
|
|
|
|
double length_squared( |
|
) const |
|
{ |
|
return (double)(x()*x() + y()*y()); |
|
} |
|
|
|
|
|
|
|
typename vc_rebind<double,2>::type normalize ( |
|
) const |
|
{ |
|
const double tmp = std::sqrt((double)(x()*x() + y()*y())); |
|
return vector<double,2> ( x()/tmp, |
|
y()/tmp |
|
); |
|
} |
|
|
|
|
|
|
|
T& x ( |
|
) |
|
{ |
|
return (*this)(0); |
|
} |
|
|
|
|
|
|
|
T& y ( |
|
) |
|
{ |
|
return (*this)(1); |
|
} |
|
|
|
|
|
|
|
const T& x ( |
|
) const |
|
{ |
|
return (*this)(0); |
|
} |
|
|
|
|
|
|
|
const T& y ( |
|
) const |
|
{ |
|
return (*this)(1); |
|
} |
|
|
|
|
|
|
|
const T z ( |
|
) const |
|
{ |
|
return 0; |
|
} |
|
|
|
|
|
|
|
T dot ( |
|
const vector& rhs |
|
) const |
|
{ |
|
return x()*rhs.x() + y()*rhs.y(); |
|
} |
|
|
|
|
|
|
|
template <typename U, long N> |
|
typename vect_promote<T,U>::type dot ( |
|
const vector<U,N>& rhs |
|
) const |
|
{ |
|
return x()*rhs.x() + y()*rhs.y() + z()*rhs.z(); |
|
} |
|
|
|
|
|
|
|
vector& operator += ( |
|
const vector& rhs |
|
) |
|
{ |
|
x() += rhs.x(); |
|
y() += rhs.y(); |
|
return *this; |
|
} |
|
|
|
|
|
|
|
vector& operator -= ( |
|
const vector& rhs |
|
) |
|
{ |
|
x() -= rhs.x(); |
|
y() -= rhs.y(); |
|
return *this; |
|
} |
|
|
|
|
|
|
|
vector& operator /= ( |
|
const T& rhs |
|
) |
|
{ |
|
x() /= rhs; |
|
y() /= rhs; |
|
return *this; |
|
} |
|
|
|
|
|
|
|
vector& operator *= ( |
|
const T& rhs |
|
) |
|
{ |
|
x() *= rhs; |
|
y() *= rhs; |
|
return *this; |
|
} |
|
|
|
|
|
|
|
vector operator - ( |
|
) const |
|
{ |
|
return vector(-x(), -y()); |
|
} |
|
|
|
|
|
|
|
template <typename U> |
|
typename vc_rebind_promote<T,U,2>::type operator / ( |
|
const U& val |
|
) const |
|
{ |
|
typedef vector<typename vect_promote<T,U>::type,2> ret_type; |
|
return ret_type(x()/val, y()/val); |
|
} |
|
|
|
|
|
|
|
template <typename U, long NR2> |
|
bool operator== ( |
|
const vector<U,NR2>& rhs |
|
) const |
|
{ |
|
return x()==rhs.x() && y()==rhs.y() && z()==rhs.z(); |
|
} |
|
|
|
|
|
|
|
bool operator== ( |
|
const vector& rhs |
|
) const |
|
{ |
|
return x()==rhs.x() && y()==rhs.y(); |
|
} |
|
|
|
|
|
|
|
template <typename U, long NR2> |
|
bool operator!= ( |
|
const vector<U,NR2>& rhs |
|
) const |
|
{ |
|
return !(*this == rhs); |
|
} |
|
|
|
|
|
|
|
bool operator!= ( |
|
const vector& rhs |
|
) const |
|
{ |
|
return !(*this == rhs); |
|
} |
|
|
|
|
|
|
|
void swap ( |
|
vector& item |
|
) |
|
{ |
|
dlib::exchange(x(), item.x()); |
|
dlib::exchange(y(), item.y()); |
|
} |
|
|
|
|
|
|
|
template <typename U, long N> |
|
typename vc_rebind_promote<T,U,3>::type cross ( |
|
const vector<U,N>& rhs |
|
) const |
|
{ |
|
typedef vector<typename vect_promote<T,U>::type,3> ret_type; |
|
return ret_type ( |
|
y()*rhs.z(), |
|
- x()*rhs.z(), |
|
x()*rhs.y() - y()*rhs.x() |
|
); |
|
} |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
template <typename T, typename U> |
|
inline const typename vc_rebind_promote<T,U,2>::type operator+ ( |
|
const vector<T,2>& lhs, |
|
const vector<U,2>& rhs |
|
) |
|
{ |
|
typedef typename vc_rebind_promote<T,U,2>::type ret_type; |
|
return ret_type(lhs.x()+rhs.x(), lhs.y()+rhs.y()); |
|
} |
|
|
|
|
|
|
|
template <typename T, typename U> |
|
inline const typename vc_rebind_promote<T,U,3>::type operator+ ( |
|
const vector<T,3>& lhs, |
|
const vector<U,3>& rhs |
|
) |
|
{ |
|
typedef typename vc_rebind_promote<T,U,3>::type ret_type; |
|
return ret_type(lhs.x()+rhs.x(), lhs.y()+rhs.y(), lhs.z()+rhs.z()); |
|
} |
|
|
|
|
|
|
|
template <typename T, typename U> |
|
inline const typename vc_rebind_promote<T,U,3>::type operator+ ( |
|
const vector<T,2>& lhs, |
|
const vector<U,3>& rhs |
|
) |
|
{ |
|
typedef typename vc_rebind_promote<T,U,3>::type ret_type; |
|
return ret_type(lhs.x()+rhs.x(), lhs.y()+rhs.y(), rhs.z()); |
|
} |
|
|
|
|
|
|
|
template <typename T, typename U> |
|
inline const typename vc_rebind_promote<T,U,3>::type operator+ ( |
|
const vector<T,3>& lhs, |
|
const vector<U,2>& rhs |
|
) |
|
{ |
|
typedef typename vc_rebind_promote<T,U,3>::type ret_type; |
|
return ret_type(lhs.x()+rhs.x(), lhs.y()+rhs.y(), lhs.z()); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
template <typename T, typename U> |
|
inline const typename vc_rebind_promote<T,U,2>::type operator- ( |
|
const vector<T,2>& lhs, |
|
const vector<U,2>& rhs |
|
) |
|
{ |
|
typedef typename vc_rebind_promote<T,U,2>::type ret_type; |
|
return ret_type(lhs.x()-rhs.x(), lhs.y()-rhs.y()); |
|
} |
|
|
|
|
|
|
|
template <typename T, typename U> |
|
inline const typename vc_rebind_promote<T,U,3>::type operator- ( |
|
const vector<T,3>& lhs, |
|
const vector<U,3>& rhs |
|
) |
|
{ |
|
typedef typename vc_rebind_promote<T,U,3>::type ret_type; |
|
return ret_type(lhs.x()-rhs.x(), lhs.y()-rhs.y(), lhs.z()-rhs.z()); |
|
} |
|
|
|
|
|
|
|
template <typename T, typename U> |
|
inline const typename vc_rebind_promote<T,U,3>::type operator- ( |
|
const vector<T,2>& lhs, |
|
const vector<U,3>& rhs |
|
) |
|
{ |
|
typedef typename vc_rebind_promote<T,U,3>::type ret_type; |
|
return ret_type(lhs.x()-rhs.x(), lhs.y()-rhs.y(), -rhs.z()); |
|
} |
|
|
|
|
|
|
|
template <typename T, typename U> |
|
inline const typename vc_rebind_promote<T,U,3>::type operator- ( |
|
const vector<T,3>& lhs, |
|
const vector<U,2>& rhs |
|
) |
|
{ |
|
typedef typename vc_rebind_promote<T,U,3>::type ret_type; |
|
return ret_type(lhs.x()-rhs.x(), lhs.y()-rhs.y(), lhs.z()); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
template <typename T, typename U> |
|
inline typename disable_if<is_matrix<U>, const typename vc_rebind_promote<T,U,2>::type >::type operator* ( |
|
const vector<T,2>& v, |
|
const U& s |
|
) |
|
{ |
|
typedef typename vc_rebind_promote<T,U,2>::type ret_type; |
|
return ret_type(v.x()*s, v.y()*s); |
|
} |
|
|
|
|
|
|
|
template <typename T, typename U> |
|
inline typename disable_if<is_matrix<U>, const typename vc_rebind_promote<T,U,2>::type >::type operator* ( |
|
const U& s, |
|
const vector<T,2>& v |
|
) |
|
{ |
|
typedef typename vc_rebind_promote<T,U,2>::type ret_type; |
|
return ret_type(v.x()*s, v.y()*s); |
|
} |
|
|
|
|
|
|
|
template <typename T, typename U> |
|
inline typename disable_if<is_matrix<U>, const typename vc_rebind_promote<T,U,3>::type >::type operator* ( |
|
const vector<T,3>& v, |
|
const U& s |
|
) |
|
{ |
|
typedef typename vc_rebind_promote<T,U,3>::type ret_type; |
|
return ret_type(v.x()*s, v.y()*s, v.z()*s); |
|
} |
|
|
|
|
|
|
|
template <typename T, typename U> |
|
inline typename disable_if<is_matrix<U>, const typename vc_rebind_promote<T,U,3>::type >::type operator* ( |
|
const U& s, |
|
const vector<T,3>& v |
|
) |
|
{ |
|
typedef typename vc_rebind_promote<T,U,3>::type ret_type; |
|
return ret_type(v.x()*s, v.y()*s, v.z()*s); |
|
} |
|
|
|
|
|
|
|
template<typename T, long NR> |
|
inline void swap ( |
|
vector<T,NR> & a, |
|
vector<T,NR> & b |
|
) { a.swap(b); } |
|
|
|
|
|
|
|
template<typename T> |
|
inline void serialize ( |
|
const vector<T,3>& item, |
|
std::ostream& out |
|
) |
|
{ |
|
try |
|
{ |
|
serialize(item.x(),out); |
|
serialize(item.y(),out); |
|
serialize(item.z(),out); |
|
} |
|
catch (serialization_error& e) |
|
{ |
|
throw serialization_error(e.info + "\n while serializing object of type vector"); |
|
} |
|
} |
|
|
|
template<typename T> |
|
inline void deserialize ( |
|
vector<T,3>& item, |
|
std::istream& in |
|
) |
|
{ |
|
try |
|
{ |
|
deserialize(item.x(),in); |
|
deserialize(item.y(),in); |
|
deserialize(item.z(),in); |
|
} |
|
catch (serialization_error& e) |
|
{ |
|
item.x() = 0; |
|
item.y() = 0; |
|
item.z() = 0; |
|
throw serialization_error(e.info + "\n while deserializing object of type vector"); |
|
} |
|
} |
|
|
|
|
|
|
|
template<typename T> |
|
inline void serialize ( |
|
const vector<T,2>& item, |
|
std::ostream& out |
|
) |
|
{ |
|
try |
|
{ |
|
serialize(item.x(),out); |
|
serialize(item.y(),out); |
|
} |
|
catch (serialization_error& e) |
|
{ |
|
throw serialization_error(e.info + "\n while serializing object of type vector"); |
|
} |
|
} |
|
|
|
template<typename T> |
|
inline void deserialize ( |
|
vector<T,2>& item, |
|
std::istream& in |
|
) |
|
{ |
|
try |
|
{ |
|
deserialize(item.x(),in); |
|
deserialize(item.y(),in); |
|
} |
|
catch (serialization_error& e) |
|
{ |
|
item.x() = 0; |
|
item.y() = 0; |
|
throw serialization_error(e.info + "\n while deserializing object of type vector"); |
|
} |
|
} |
|
|
|
|
|
|
|
template<typename T> |
|
std::ostream& operator<< ( |
|
std::ostream& out, |
|
const vector<T,3>& item |
|
) |
|
{ |
|
out << "(" << item.x() << ", " << item.y() << ", " << item.z() << ")"; |
|
return out; |
|
} |
|
|
|
template<typename T> |
|
std::istream& operator>>( |
|
std::istream& in, |
|
vector<T,3>& item |
|
) |
|
{ |
|
|
|
|
|
while (in.peek() == ' ' || in.peek() == '\t' || in.peek() == '\r' || in.peek() == '\n') |
|
in.get(); |
|
|
|
|
|
if (in.get() != '(') |
|
{ |
|
in.setstate(in.rdstate() | std::ios::failbit); |
|
return in; |
|
} |
|
|
|
|
|
while (in.peek() == ' ' || in.peek() == '\t') |
|
in.get(); |
|
in >> item.x(); |
|
|
|
if (!in.good()) |
|
return in; |
|
|
|
|
|
while (in.peek() == ' ' || in.peek() == '\t' || in.peek() == ',') |
|
in.get(); |
|
in >> item.y(); |
|
|
|
if (!in.good()) |
|
return in; |
|
|
|
|
|
while (in.peek() == ' ' || in.peek() == '\t' || in.peek() == ',') |
|
in.get(); |
|
in >> item.z(); |
|
|
|
if (!in.good()) |
|
return in; |
|
|
|
|
|
while (in.peek() == ' ' || in.peek() == '\t') |
|
in.get(); |
|
|
|
|
|
if (in.get() != ')') |
|
in.setstate(in.rdstate() | std::ios::failbit); |
|
return in; |
|
} |
|
|
|
|
|
|
|
|
|
template<typename T> |
|
std::ostream& operator<< ( |
|
std::ostream& out, |
|
const vector<T,2>& item |
|
) |
|
{ |
|
out << "(" << item.x() << ", " << item.y() << ")"; |
|
return out; |
|
} |
|
|
|
template<typename T> |
|
std::istream& operator>>( |
|
std::istream& in, |
|
vector<T,2>& item |
|
) |
|
{ |
|
|
|
|
|
while (in.peek() == ' ' || in.peek() == '\t' || in.peek() == '\r' || in.peek() == '\n') |
|
in.get(); |
|
|
|
|
|
if (in.get() != '(') |
|
{ |
|
in.setstate(in.rdstate() | std::ios::failbit); |
|
return in; |
|
} |
|
|
|
|
|
while (in.peek() == ' ' || in.peek() == '\t') |
|
in.get(); |
|
in >> item.x(); |
|
|
|
if (!in.good()) |
|
return in; |
|
|
|
|
|
while (in.peek() == ' ' || in.peek() == '\t' || in.peek() == ',') |
|
in.get(); |
|
in >> item.y(); |
|
|
|
if (!in.good()) |
|
return in; |
|
|
|
|
|
while (in.peek() == ' ' || in.peek() == '\t') |
|
in.get(); |
|
|
|
|
|
if (in.get() != ')') |
|
in.setstate(in.rdstate() | std::ios::failbit); |
|
return in; |
|
} |
|
|
|
|
|
|
|
typedef vector<long,2> point; |
|
typedef vector<double,2> dpoint; |
|
|
|
|
|
|
|
inline bool is_convex_quadrilateral ( |
|
const std::array<dpoint,4>& pts |
|
) |
|
{ |
|
auto orientation = [&](size_t i) |
|
{ |
|
size_t a = (i+1)%4; |
|
size_t b = (i+3)%4; |
|
return (pts[a]-pts[i]).cross(pts[b]-pts[i]).z(); |
|
}; |
|
|
|
|
|
for (auto& p : pts) |
|
{ |
|
if (p.x() == std::numeric_limits<double>::infinity()) |
|
return false; |
|
if (p.y() == std::numeric_limits<double>::infinity()) |
|
return false; |
|
} |
|
|
|
double s0 = orientation(0); |
|
double s1 = orientation(1); |
|
double s2 = orientation(2); |
|
double s3 = orientation(3); |
|
|
|
|
|
return (s0>0&&s1>0&&s2>0&&s3>0) || (s0<0&&s1<0&&s2<0&&s3<0); |
|
} |
|
|
|
|
|
|
|
template < |
|
typename array_of_dpoints |
|
> |
|
inline double polygon_area ( |
|
const array_of_dpoints& pts |
|
) |
|
{ |
|
if (pts.size() <= 2) |
|
return 0; |
|
|
|
double val = 0; |
|
|
|
|
|
for (size_t i = 1; i < pts.size(); ++i) |
|
val += (double)pts[i].x()*pts[i-1].y() - pts[i].y()*pts[i-1].x(); |
|
|
|
const size_t end = pts.size()-1; |
|
val += (double)pts[0].x()*pts[end].y() - pts[0].y()*pts[end].x(); |
|
|
|
return std::abs(val)/2.0; |
|
} |
|
|
|
|
|
|
|
} |
|
|
|
namespace std |
|
{ |
|
|
|
|
|
|
|
template<typename T> |
|
struct less<dlib::vector<T,3> > |
|
{ |
|
typedef dlib::vector<T, 3> first_argument_type; |
|
typedef dlib::vector<T, 3> second_argument_type; |
|
typedef bool result_type; |
|
inline bool operator() (const dlib::vector<T,3> & a, const dlib::vector<T,3> & b) const |
|
{ |
|
if (a.x() < b.x()) return true; |
|
else if (a.x() > b.x()) return false; |
|
else if (a.y() < b.y()) return true; |
|
else if (a.y() > b.y()) return false; |
|
else if (a.z() < b.z()) return true; |
|
else if (a.z() > b.z()) return false; |
|
else return false; |
|
} |
|
}; |
|
|
|
|
|
|
|
|
|
template<typename T> |
|
struct less<dlib::vector<T,2> > |
|
{ |
|
typedef dlib::vector<T, 2> first_argument_type; |
|
typedef dlib::vector<T, 2> second_argument_type; |
|
typedef bool result_type; |
|
inline bool operator() (const dlib::vector<T,2> & a, const dlib::vector<T,2> & b) const |
|
{ |
|
if (a.x() < b.x()) return true; |
|
else if (a.x() > b.x()) return false; |
|
else if (a.y() < b.y()) return true; |
|
else if (a.y() > b.y()) return false; |
|
else return false; |
|
} |
|
}; |
|
} |
|
|
|
#if defined(_MSC_VER) && _MSC_VER < 1400 |
|
|
|
#pragma warning(pop) |
|
#endif |
|
|
|
#endif |
|
|
|
|