Commit aec7c847 authored by Davis King's avatar Davis King

Cleaned up the vector and point classes. Now there is only one class, the vector,

class and it is capable of representing everything the old vector and point
class could.

--HG--
extra : convert_revision : svn%3Afdd8eb12-d10e-0410-9acb-85c331704f74/trunk%402727
parent 3fc0a290
...@@ -70,17 +70,6 @@ namespace dlib ...@@ -70,17 +70,6 @@ namespace dlib
{ {
} }
template <typename T>
rectangle (
const vector<T>& v
) :
l(static_cast<long>(v.x()+0.5)),
t(static_cast<long>(v.y()+0.5)),
r(static_cast<long>(v.x()+0.5)),
b(static_cast<long>(v.y()+0.5))
{
}
rectangle ( rectangle (
const point& p1, const point& p1,
const point& p2 const point& p2
...@@ -89,15 +78,6 @@ namespace dlib ...@@ -89,15 +78,6 @@ namespace dlib
*this = rectangle(p1) + rectangle(p2); *this = rectangle(p1) + rectangle(p2);
} }
template <typename T>
rectangle (
const vector<T>& v1,
const vector<T>& v2
)
{
*this = rectangle(v1) + rectangle(v2);
}
rectangle ( rectangle (
) : ) :
l(0), l(0),
...@@ -228,6 +208,14 @@ namespace dlib ...@@ -228,6 +208,14 @@ namespace dlib
return (rect + *this == *this); return (rect + *this == *this);
} }
rectangle& operator+= (
const point& p
)
{
*this = *this + rectangle(p);
return *this;
}
rectangle& operator+= ( rectangle& operator+= (
const rectangle& rect const rectangle& rect
) )
......
...@@ -90,18 +90,6 @@ namespace dlib ...@@ -90,18 +90,6 @@ namespace dlib
- #bottom() == p.y() - #bottom() == p.y()
!*/ !*/
template <typename T>
rectangle (
const vector<T>& v
);
/*!
ensures
- #left() == static_cast<long>(floor(v.x()+0.5))
- #top() == static_cast<long>(floor(v.y()+0.5))
- #right() == static_cast<long>(floor(v.x()+0.5))
- #bottom() == static_cast<long>(floor(v.y()+0.5))
!*/
rectangle ( rectangle (
const point& p1, const point& p1,
const point& p2 const point& p2
...@@ -111,16 +99,6 @@ namespace dlib ...@@ -111,16 +99,6 @@ namespace dlib
- #*this == rectangle(p1) + rectangle(p2) - #*this == rectangle(p1) + rectangle(p2)
!*/ !*/
template <typename T>
rectangle (
const vector<T>& v1,
const vector<T>& v2
);
/*!
ensures
- #*this == rectangle(v1) + rectangle(v2)
!*/
long left ( long left (
) const; ) const;
/*! /*!
......
...@@ -13,12 +13,17 @@ ...@@ -13,12 +13,17 @@
namespace dlib namespace dlib
{ {
class point;
template < template <
typename T typename T,
long NR = 3
> >
class vector class vector;
// ----------------------------------------------------------------------------------------
template <typename T>
class vector<T,3>
{ {
/*! /*!
INITIAL VALUE INITIAL VALUE
...@@ -38,11 +43,12 @@ namespace dlib ...@@ -38,11 +43,12 @@ namespace dlib
typedef T type; typedef T type;
vector ( vector (
) : )
x_value(0.0), {
y_value(0.0), x() = 0;
z_value(0.0) y() = 0;
{} z() = 0;
}
// --------------------------------------- // ---------------------------------------
...@@ -50,35 +56,506 @@ namespace dlib ...@@ -50,35 +56,506 @@ namespace dlib
const T _x, const T _x,
const T _y, const T _y,
const T _z const T _z
) : )
x_value(_x), {
y_value(_y), x() = _x;
z_value(_z) y() = _y;
{} z() = _z;
}
// ---------------------------------------
vector (
const vector& item
)
{
x() = item.x();
y() = item.y();
z() = item.z();
}
// ---------------------------------------
template <typename U>
vector (
const vector<U,2>& item
)
{
// Do this so that we get the appropriate rounding depending on the relative
// type of T and U.
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>
const typename enable_if_c<std::numeric_limits<T>::is_integer == true &&
std::numeric_limits<typename EXP::type>::is_integer == false, vector>::type&
operator = (
const matrix_exp<EXP>& m
)
{
// you can only assign vectors with 3 elements to a dlib::vector<T,3> object
COMPILE_TIME_ASSERT(EXP::NR*EXP::NC == 3 || EXP::NR*EXP::NC == 0);
// make sure requires clause is not broken
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
);
x() = std::floor(m(0)+0.5);
y() = std::floor(m(1)+0.5);
z() = std::floor(m(2)+0.5);
return *this;
}
template <typename EXP>
const typename disable_if_c<std::numeric_limits<T>::is_integer == true &&
std::numeric_limits<typename EXP::type>::is_integer == false, vector>::type&
operator = (
const matrix_exp<EXP>& m
)
{
// you can only assign vectors with 3 elements to a dlib::vector<T,3> object
COMPILE_TIME_ASSERT(EXP::NR*EXP::NC == 3 || EXP::NR*EXP::NC == 0);
// make sure requires clause is not broken
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
);
x() = m(0);
y() = m(1);
z() = m(2);
return *this;
}
// ---------------------------------------
template <typename U>
const typename enable_if_c<std::numeric_limits<T>::is_integer == true && std::numeric_limits<U>::is_integer == false, vector>::type&
operator = (
const vector<U,3>& item
)
{
x() = static_cast<T>(std::floor(item.x() + 0.5));
y() = static_cast<T>(std::floor(item.y() + 0.5));
z() = static_cast<T>(std::floor(item.z() + 0.5));
return *this;
}
template <typename U>
const typename disable_if_c<std::numeric_limits<T>::is_integer == true && std::numeric_limits<U>::is_integer == false, vector>::type&
operator = (
const vector<U,3>& item
)
{
x() = static_cast<T>(item.x());
y() = static_cast<T>(item.y());
z() = static_cast<T>(item.z());
return *this;
}
// ---------------------------------------
vector& operator= (
const vector& item
)
{
x() = item.x();
y() = item.y();
z() = item.z();
return *this;
}
// ---------------------------------------
T length(
) const
{
return (T)std::sqrt((double)(x()*x() + y()*y() + z()*z()));
}
// ---------------------------------------
vector normalize (
) const
{
T tmp = (T)std::sqrt((double)(x()*x() + y()*y() + z()*z()));
return vector ( x()/tmp,
y()/tmp,
z()/tmp
);
}
// ---------------------------------------
T& x (
)
{
return x_value;
}
// ---------------------------------------
T& y (
)
{
return y_value;
}
// ---------------------------------------
T& z (
)
{
return z_value;
}
// ---------------------------------------
const T& x (
) const
{
return x_value;
}
// ---------------------------------------
const T& y (
) const
{
return y_value;
}
// ---------------------------------------
const T& z (
) const
{
return z_value;
}
// ---------------------------------------
T dot (
const vector& rhs
) const
{
return x()*rhs.x() + y()*rhs.y() + z()*rhs.z();
}
// ---------------------------------------
vector cross (
const vector& rhs
) const
{
return vector (
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 vector& rhs
) const
{
return vector(x()+rhs.x(), y()+rhs.y(), z()+rhs.z());
}
// ---------------------------------------
vector operator - (
const vector& rhs
) const
{
return vector(x()-rhs.x(), y()-rhs.y(), z()-rhs.z());
}
// ---------------------------------------
vector operator / (
const T& val
) const
{
return vector(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);
}
// --------------------------------------- // ---------------------------------------
template <long NRm, long NC, typename MM, typename l>
operator matrix<T,NRm, NC, MM,l> (
) const
{
matrix<T,NRm, NC, MM,l> m(3,1);
m(0) = x();
m(1) = y();
m(2) = z();
return m;
}
// ---------------------------------------
void swap (
vector& item
)
{
dlib::exchange(x_value, item.x_value);
dlib::exchange(y_value, item.y_value);
dlib::exchange(z_value, item.z_value);
}
// ---------------------------------------
private:
T x_value;
T y_value;
T z_value;
};
// ----------------------------------------------------------------------------------------
template <typename T>
class vector<T,2>
{
/*!
INITIAL VALUE
- x_value == 0
- y_value == 0
CONVENTION
- x_value == x()
- y_value == y()
- z() == 0
!*/
public:
typedef T type;
vector ( vector (
const vector& v )
) : {
x_value(v.x_value), x() = 0;
y_value(v.y_value), y() = 0;
z_value(v.z_value) }
{}
// --------------------------------------- // ---------------------------------------
inline vector ( vector (
const point& p const T _x,
); const T _y
)
{
x() = _x;
y() = _y;
}
// ---------------------------------------
template <typename U>
vector (
const vector<U,3>& item
)
{
// Do this so that we get the appropriate rounding depending on the relative
// type of T and U.
vector<T,3> temp(item);
x() = temp.x();
y() = temp.y();
}
// ---------------------------------------
vector (
const vector& item
)
{
x() = item.x();
y() = item.y();
}
// ---------------------------------------
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>
const typename enable_if_c<std::numeric_limits<T>::is_integer == true &&
std::numeric_limits<typename EXP::type>::is_integer == false, vector>::type&
operator = (
const matrix_exp<EXP>& m
)
{
// you can only assign vectors with 2 elements to a dlib::vector<T,2> object
COMPILE_TIME_ASSERT(EXP::NR*EXP::NC == 2 || EXP::NR*EXP::NC == 0);
// make sure requires clause is not broken
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
);
// --------------------------------------- x() = std::floor(m(0)+0.5);
y() = std::floor(m(1)+0.5);
return *this;
}
template <typename EXP> template <typename EXP>
vector ( const matrix_exp<EXP>& m) const typename disable_if_c<std::numeric_limits<T>::is_integer == true &&
std::numeric_limits<typename EXP::type>::is_integer == false, vector>::type&
operator = (
const matrix_exp<EXP>& m
)
{ {
// you can only assign vectors with 2 elements to a dlib::vector<T,2> object
COMPILE_TIME_ASSERT(EXP::NR*EXP::NC == 2 || EXP::NR*EXP::NC == 0);
// make sure requires clause is not broken // make sure requires clause is not broken
DLIB_ASSERT((m.nr() == 1 || m.nc() == 1) && m.size() == 3, DLIB_ASSERT((m.nr() == 1 || m.nc() == 1) && (m.size() == 2),
"\t vector(const matrix_exp& m)" "\t vector(const matrix_exp& m)"
<< "\n\t the given matrix is of the wrong size" << "\n\t the given matrix is of the wrong size"
<< "\n\t m.nr(): " << m.nr() << "\n\t m.nr(): " << m.nr()
...@@ -86,32 +563,53 @@ namespace dlib ...@@ -86,32 +563,53 @@ namespace dlib
<< "\n\t m.size(): " << m.size() << "\n\t m.size(): " << m.size()
<< "\n\t this: " << this << "\n\t this: " << this
); );
x_value = m(0);
y_value = m(1); x() = m(0);
z_value = m(2); y() = m(1);
return *this;
} }
template <long NR, long NC, typename MM> // ---------------------------------------
operator matrix<T,NR, NC, MM> () const
template <typename U>
const typename enable_if_c<std::numeric_limits<T>::is_integer == true && std::numeric_limits<U>::is_integer == false, vector>::type&
operator = (
const vector<U,2>& item
)
{ {
matrix<T,3,1> m; x() = static_cast<T>(std::floor(item.x() + 0.5));
m(0) = x_value; y() = static_cast<T>(std::floor(item.y() + 0.5));
m(1) = y_value; return *this;
m(2) = z_value; }
return m;
template <typename U>
const typename disable_if_c<std::numeric_limits<T>::is_integer == true && std::numeric_limits<U>::is_integer == false, vector>::type&
operator = (
const vector<U,2>& item
)
{
x() = static_cast<T>(item.x());
y() = static_cast<T>(item.y());
return *this;
} }
// --------------------------------------- // ---------------------------------------
~vector ( vector& operator= (
){} const vector& item
)
{
x() = item.x();
y() = item.y();
return *this;
}
// --------------------------------------- // ---------------------------------------
T length( T length(
) const ) const
{ {
return (T)std::sqrt((double)(x_value*x_value + y_value*y_value + z_value*z_value)); return (T)std::sqrt((double)(x()*x() + y()*y()));
} }
// --------------------------------------- // ---------------------------------------
...@@ -119,11 +617,10 @@ namespace dlib ...@@ -119,11 +617,10 @@ namespace dlib
vector normalize ( vector normalize (
) const ) const
{ {
T tmp = (T)std::sqrt((double)(x_value*x_value + y_value*y_value + z_value*z_value)); T tmp = (T)std::sqrt((double)(x()*x() + y()*y()));
return vector ( x_value/tmp, return vector ( x()/tmp,
y_value/tmp, y()/tmp
z_value/tmp );
);
} }
// --------------------------------------- // ---------------------------------------
...@@ -131,7 +628,7 @@ namespace dlib ...@@ -131,7 +628,7 @@ namespace dlib
T& x ( T& x (
) )
{ {
return x_value; return x_value;
} }
// --------------------------------------- // ---------------------------------------
...@@ -139,15 +636,7 @@ namespace dlib ...@@ -139,15 +636,7 @@ namespace dlib
T& y ( T& y (
) )
{ {
return y_value; return y_value;
}
// ---------------------------------------
T& z (
)
{
return z_value;
} }
// --------------------------------------- // ---------------------------------------
...@@ -155,7 +644,7 @@ namespace dlib ...@@ -155,7 +644,7 @@ namespace dlib
const T& x ( const T& x (
) const ) const
{ {
return x_value; return x_value;
} }
// --------------------------------------- // ---------------------------------------
...@@ -163,15 +652,15 @@ namespace dlib ...@@ -163,15 +652,15 @@ namespace dlib
const T& y ( const T& y (
) const ) const
{ {
return y_value; return y_value;
} }
// --------------------------------------- // ---------------------------------------
const T& z ( const T z (
) const ) const
{ {
return z_value; return 0;
} }
// --------------------------------------- // ---------------------------------------
...@@ -180,130 +669,107 @@ namespace dlib ...@@ -180,130 +669,107 @@ namespace dlib
const vector& rhs const vector& rhs
) const ) const
{ {
return x_value*rhs.x_value + y_value*rhs.y_value + z_value*rhs.z_value; return x()*rhs.x() + y()*rhs.y();
} }
// --------------------------------------- // ---------------------------------------
vector cross ( vector& operator += (
const vector& rhs const vector& rhs
) const )
{ {
return vector ( x() += rhs.x();
y_value*rhs.z_value - z_value*rhs.y_value, y() += rhs.y();
z_value*rhs.x_value - x_value*rhs.z_value, return *this;
x_value*rhs.y_value - y_value*rhs.x_value
);
} }
// --------------------------------------- // ---------------------------------------
vector operator+ ( vector& operator -= (
const vector& rhs const vector& rhs
) const )
{ {
return vector ( x() -= rhs.x();
x_value+rhs.x_value, y() -= rhs.y();
y_value+rhs.y_value, return *this;
z_value+rhs.z_value
);
} }
// --------------------------------------- // ---------------------------------------
vector operator- ( vector& operator /= (
const vector& rhs const T& rhs
) const )
{ {
return vector ( x() /= rhs;
x_value-rhs.x_value, y() /= rhs;
y_value-rhs.y_value, return *this;
z_value-rhs.z_value
);
} }
// --------------------------------------- // ---------------------------------------
vector& operator= ( vector& operator *= (
const vector& rhs const T& rhs
) )
{ {
x_value = rhs.x_value; x() *= rhs;
y_value = rhs.y_value; y() *= rhs;
z_value = rhs.z_value;
return *this; return *this;
} }
// --------------------------------------- // ---------------------------------------
vector operator/ ( vector operator + (
const T rhs const vector& rhs
) const ) const
{ {
return vector ( return vector(x()+rhs.x(), y()+rhs.y());
x_value/rhs,
y_value/rhs,
z_value/rhs
);
} }
// --------------------------------------- // ---------------------------------------
vector& operator += ( vector operator - (
const vector& rhs const vector& rhs
) ) const
{ {
x_value += rhs.x_value; return vector(x()-rhs.x(), y()-rhs.y());
y_value += rhs.y_value;
z_value += rhs.z_value;
return *this;
} }
// --------------------------------------- // ---------------------------------------
vector& operator -= ( vector operator / (
const vector& rhs const T& val
) ) const
{ {
x_value -= rhs.x_value; return vector(x()/val, y()/val);
y_value -= rhs.y_value;
z_value -= rhs.z_value;
return *this;
} }
// --------------------------------------- // ---------------------------------------
vector& operator *= ( template <typename U, long NR2>
const T rhs bool operator== (
) const vector<U,NR2>& rhs
) const
{ {
x_value *= rhs; return x()==rhs.x() && y()==rhs.y() && z()==rhs.z();
y_value *= rhs;
z_value *= rhs;
return *this;
} }
// --------------------------------------- // ---------------------------------------
vector& operator /= ( bool operator== (
const T rhs const vector& rhs
) ) const
{ {
x_value /= rhs; return x()==rhs.x() && y()==rhs.y();
y_value /= rhs;
z_value /= rhs;
return *this;
} }
// --------------------------------------- // ---------------------------------------
bool operator== ( template <typename U, long NR2>
const vector& rhs bool operator!= (
const vector<U,NR2>& rhs
) const ) const
{ {
return (x_value == rhs.x_value && return !(*this == rhs);
y_value == rhs.y_value &&
z_value == rhs.z_value );
} }
// --------------------------------------- // ---------------------------------------
...@@ -312,7 +778,19 @@ namespace dlib ...@@ -312,7 +778,19 @@ namespace dlib
const vector& rhs const vector& rhs
) const ) const
{ {
return !((*this) == rhs); return !(*this == rhs);
}
// ---------------------------------------
template <long NRm, long NC, typename MM, typename l>
operator matrix<T,NRm, NC, MM,l> (
) const
{
matrix<T,NRm, NC, MM,l> m(2,1);
m(0) = x();
m(1) = y();
return m;
} }
// --------------------------------------- // ---------------------------------------
...@@ -321,58 +799,89 @@ namespace dlib ...@@ -321,58 +799,89 @@ namespace dlib
vector& item vector& item
) )
{ {
exchange(x_value,item.x_value); dlib::exchange(x_value, item.x_value);
exchange(y_value,item.y_value); dlib::exchange(y_value, item.y_value);
exchange(z_value,item.z_value);
} }
// --------------------------------------- // ---------------------------------------
private: vector<T,3> cross (
T x_value; const vector<T,3>& rhs
T y_value; ) const
T z_value; {
return vector<T,3> (
y()*rhs.z(),
- x()*rhs.z(),
x()*rhs.y() - y()*rhs.x()
);
}
// ---------------------------------------
private:
T x_value;
T y_value;
}; };
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template<typename T, typename U> template <typename T, typename U>
inline vector<T> operator* ( inline const vector<T,2> operator* (
const vector<T> & lhs, const vector<T,2>& v,
const U rhs const U& s
)
{
return vector<T,2>(v.x()*s, v.y()*s);
}
// ----------------------------------------------------------------------------------------
template <typename T, typename U>
inline const vector<T,2> operator* (
const U& s,
const vector<T,2>& v
)
{
return vector<T,2>(v.x()*s, v.y()*s);
}
// ----------------------------------------------------------------------------------------
template <typename T, typename U>
inline const vector<T,3> operator* (
const vector<T,3>& v,
const U& s
) )
{ {
return vector<T> ( return vector<T,3>(v.x()*s, v.y()*s, v.z()*s);
lhs.x()*rhs,
lhs.y()*rhs,
lhs.z()*rhs
);
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template<typename T, typename U> template <typename T, typename U>
inline vector<T> operator* ( inline const vector<T,3> operator* (
const U lhs, const U& s,
const vector<T> & rhs const vector<T,3>& v
) { return rhs*lhs; } )
{
return vector<T,3>(v.x()*s, v.y()*s, v.z()*s);
}
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template<typename T> template<typename T, long NR>
inline void swap ( inline void swap (
vector<T> & a, vector<T,NR> & a,
vector<T> & b vector<T,NR> & b
) { a.swap(b); } ) { a.swap(b); }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template<typename T> template<typename T>
inline void serialize ( inline void serialize (
const vector<T> & item, const vector<T,3>& item,
std::ostream& out std::ostream& out
) )
{ {
...@@ -382,7 +891,7 @@ namespace dlib ...@@ -382,7 +891,7 @@ namespace dlib
serialize(item.y(),out); serialize(item.y(),out);
serialize(item.z(),out); serialize(item.z(),out);
} }
catch (serialization_error e) catch (serialization_error& e)
{ {
throw serialization_error(e.info + "\n while serializing object of type vector"); throw serialization_error(e.info + "\n while serializing object of type vector");
} }
...@@ -390,7 +899,7 @@ namespace dlib ...@@ -390,7 +899,7 @@ namespace dlib
template<typename T> template<typename T>
inline void deserialize ( inline void deserialize (
vector<T> & item, vector<T,3>& item,
std::istream& in std::istream& in
) )
{ {
...@@ -400,7 +909,7 @@ namespace dlib ...@@ -400,7 +909,7 @@ namespace dlib
deserialize(item.y(),in); deserialize(item.y(),in);
deserialize(item.z(),in); deserialize(item.z(),in);
} }
catch (serialization_error e) catch (serialization_error& e)
{ {
item.x() = 0; item.x() = 0;
item.y() = 0; item.y() = 0;
...@@ -409,12 +918,50 @@ namespace dlib ...@@ -409,12 +918,50 @@ namespace dlib
} }
} }
// ----------------------------------------------------------------------------------------
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> template<typename T>
std::ostream& operator<< ( std::ostream& operator<< (
std::ostream& out, std::ostream& out,
const vector<T>& item const vector<T,3>& item
) )
{ {
out << "(" << item.x() << ", " << item.y() << ", " << item.z() << ")"; out << "(" << item.x() << ", " << item.y() << ", " << item.z() << ")";
...@@ -424,7 +971,7 @@ namespace dlib ...@@ -424,7 +971,7 @@ namespace dlib
template<typename T> template<typename T>
std::istream& operator>>( std::istream& operator>>(
std::istream& in, std::istream& in,
vector<T>& item vector<T,3>& item
) )
{ {
...@@ -474,164 +1021,25 @@ namespace dlib ...@@ -474,164 +1021,25 @@ namespace dlib
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
class point
{
/*!
INITIAL VALUE
The initial value of this object is defined by its constructor.
CONVENTION
- x_ == x()
- y_ == y()
!*/
public:
point (
) : x_(0), y_(0) {}
point (
long x__,
long y__
)
{
x_ = x__;
y_ = y__;
}
point (
const point& p
)
{
x_ = p.x_;
y_ = p.y_;
}
template <typename T>
point (
const vector<T>& v
) :
x_(static_cast<long>(v.x()+0.5)),
y_(static_cast<long>(v.y()+0.5))
{}
long x (
) const { return x_; }
long y (
) const { return y_; }
long& x (
) { return x_; }
long& y (
) { return y_; }
const point operator+ (
const point& rhs
) const
{
return point(x()+rhs.x(), y()+rhs.y());
}
const point operator- (
const point& rhs
) const
{
return point(x()-rhs.x(), y()-rhs.y());
}
point& operator= (
const point& p
)
{
x_ = p.x_;
y_ = p.y_;
return *this;
}
point& operator+= (
const point& rhs
)
{
x_ += rhs.x_;
y_ += rhs.y_;
return *this;
}
point& operator-= (
const point& rhs
)
{
x_ -= rhs.x_;
y_ -= rhs.y_;
return *this;
}
bool operator== (
const point& p
) const { return p.x_ == x_ && p.y_ == y_; }
bool operator!= (
const point& p
) const { return p.x_ != x_ || p.y_ != y_; }
private:
long x_;
long y_;
};
// ----------------------------------------------------------------------------------------
inline void serialize (
const point& 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 an object of type point");
}
}
inline void deserialize (
point& item,
std::istream& in
)
{
try
{
deserialize(item.x(),in);
deserialize(item.y(),in);
}
catch (serialization_error& e)
{
throw serialization_error(e.info + "\n while deserializing an object of type point");
}
}
inline std::ostream& operator<< ( template<typename T>
std::ostream& operator<< (
std::ostream& out, std::ostream& out,
const point& item const vector<T,2>& item
) )
{ {
out << "(" << item.x() << ", " << item.y() << ")"; out << "(" << item.x() << ", " << item.y() << ")";
return out; return out;
} }
inline std::istream& operator>>( template<typename T>
std::istream& operator>>(
std::istream& in, std::istream& in,
point& item vector<T,2>& item
) )
{ {
// eat all the crap up to the '(' // eat all the crap up to the '('
while (in.peek() == ' ' || in.peek() == '\t' || in.peek() == '\r' || in.peek() == '\n') while (in.peek() == ' ' || in.peek() == '\t' || in.peek() == '\r' || in.peek() == '\n')
in.get(); in.get();
...@@ -646,23 +1054,7 @@ namespace dlib ...@@ -646,23 +1054,7 @@ namespace dlib
// eat all the crap up to the first number // eat all the crap up to the first number
while (in.peek() == ' ' || in.peek() == '\t') while (in.peek() == ' ' || in.peek() == '\t')
in.get(); in.get();
in >> item.x();
bool is_negative = false;
if (in.peek() == '-')
{
in.get();
is_negative = true;
}
// read in the number and store it in item.x()
item.x() = 0;
while (in.peek() >= '0' && in.peek() <= '9')
{
long temp = in.get()-'0';
item.x() = item.x()*10 + temp;
}
if (is_negative)
item.x() *= -1;
if (!in.good()) if (!in.good())
return in; return in;
...@@ -670,24 +1062,7 @@ namespace dlib ...@@ -670,24 +1062,7 @@ namespace dlib
// eat all the crap up to the next number // eat all the crap up to the next number
while (in.peek() == ' ' || in.peek() == '\t' || in.peek() == ',') while (in.peek() == ' ' || in.peek() == '\t' || in.peek() == ',')
in.get(); in.get();
in >> item.y();
is_negative = false;
if (in.peek() == '-')
{
in.get();
is_negative = true;
}
// read in the number and store it in item.y()
item.y() = 0;
while (in.peek() >= '0' && in.peek() <= '9')
{
long temp = in.get()-'0';
item.y() = item.y()*10 + temp;
}
if (is_negative)
item.y() *= -1;
if (!in.good()) if (!in.good())
return in; return in;
...@@ -704,14 +1079,7 @@ namespace dlib ...@@ -704,14 +1079,7 @@ namespace dlib
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename T> typedef vector<long,2> point;
vector<T>::vector (
const point& p
) :
x_value(p.x()),
y_value(p.y()),
z_value(0)
{}
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -720,12 +1088,12 @@ namespace dlib ...@@ -720,12 +1088,12 @@ namespace dlib
namespace std namespace std
{ {
/*! /*!
Define std::less<vector<T> > so that you can use vectors in the associative containers. Define std::less<vector<T,3> > so that you can use vectors in the associative containers.
!*/ !*/
template<typename T> template<typename T>
struct less<dlib::vector<T> > : public binary_function<dlib::vector<T> ,dlib::vector<T> ,bool> struct less<dlib::vector<T,3> > : public binary_function<dlib::vector<T,3> ,dlib::vector<T,3> ,bool>
{ {
inline bool operator() (const dlib::vector<T> & a, const dlib::vector<T> & b) const inline bool operator() (const dlib::vector<T,3> & a, const dlib::vector<T,3> & b) const
{ {
if (a.x() < b.x()) return true; if (a.x() < b.x()) return true;
else if (a.x() > b.x()) return false; else if (a.x() > b.x()) return false;
...@@ -738,12 +1106,12 @@ namespace std ...@@ -738,12 +1106,12 @@ namespace std
}; };
/*! /*!
Define std::less<point> so that you can use points in the associative containers. Define std::less<vector<T,2> > so that you can use vector<T,2>s in the associative containers.
!*/ !*/
template<> template<typename T>
struct less<dlib::point> : public binary_function<dlib::point,dlib::point,bool> struct less<dlib::vector<T,2> > : public binary_function<dlib::vector<T,2> ,dlib::vector<T,2> ,bool>
{ {
inline bool operator() (const dlib::point& a, const dlib::point& b) const inline bool operator() (const dlib::vector<T,2> & a, const dlib::vector<T,2> & b) const
{ {
if (a.x() < b.x()) return true; if (a.x() < b.x()) return true;
else if (a.x() > b.x()) return false; else if (a.x() > b.x()) return false;
......
...@@ -10,17 +10,19 @@ ...@@ -10,17 +10,19 @@
namespace dlib namespace dlib
{ {
class point;
template < template <
typename T typename T,
long NR = 3
> >
class vector class vector
{ {
/*! /*!
REQUIREMENTS ON T REQUIREMENTS ON T
T should be some object that provides an interface that is T should be some object that provides an interface that is
compatible with double, float and the like. compatible with double, float, int, long and the like.
REQUIREMENTS ON NR
NR == 3 || NR == 2
INITIAL VALUE INITIAL VALUE
x() == 0 x() == 0
...@@ -28,11 +30,10 @@ namespace dlib ...@@ -28,11 +30,10 @@ namespace dlib
z() == 0 z() == 0
WHAT THIS OBJECT REPRESENTS WHAT THIS OBJECT REPRESENTS
This object represents a three dimensional vector. This object represents a three dimensional vector. If NR == 2 then
this object is limited to representing points on the XY plane where
Z is set to 0.
THREAD SAFETY
Note that the vector object is not allowed to be reference counted.
This is to ensure a minimum amount of thread safety.
!*/ !*/
public: public:
...@@ -52,33 +53,53 @@ namespace dlib ...@@ -52,33 +53,53 @@ namespace dlib
const T _z const T _z
); );
/*! /*!
requires
- NR == 3
ensures ensures
- #*this properly initialized
- #x() == _x - #x() == _x
- #y() == _y - #y() == _y
- #z() == _z - #z() == _z
!*/ !*/
vector ( vector (
const point& p const T _x,
const T _y
); );
/*! /*!
requires
- NR == 2
ensures ensures
- #*this properly initialized - #x() == _x
- #x() == p.x() - #y() == _y
- #y() == p.y() - #z() == 0
- #z() == 0
!*/ !*/
template <typename U, long NRv>
vector ( vector (
const vector& v const vector<U,NRv>& v
); );
/*! /*!
ensures ensures
- #*this properly initialized - Initializes *this with the contents of v and does any rounding if necessary and also
- #x() == v.x() takes care of converting between 2 and 3 dimensional vectors.
- #y() == v.y() - if (U is a real valued type like float or double and T is an integral type like long) then
- #z() == v.z() - if (NR == 3) then
- #x() == floor(v.x() + 0.5)
- #y() == floor(v.y() + 0.5)
- #z() == floor(v.z() + 0.5)
- else // NR == 2
- #x() == floor(v.x() + 0.5)
- #y() == floor(v.y() + 0.5)
- #z() == 0
- else
- if (NR == 3) then
- #x() == v.x()
- #y() == v.y()
- #z() == v.z()
- else // NR == 2
- #x() == v.x()
- #y() == v.y()
- #z() == 0
!*/ !*/
template <typename EXP> template <typename EXP>
...@@ -87,27 +108,40 @@ namespace dlib ...@@ -87,27 +108,40 @@ namespace dlib
); );
/*! /*!
requires requires
- m.size() == 3 - m.size() == NR
- m.nr() == 1 || m.nc() == 1 (i.e. m must be a row or column matrix) - m.nr() == 1 || m.nc() == 1 (i.e. m must be a row or column matrix)
ensures ensures
- #x() == m(0) - Initializes *this with the contents of m and does any rounding if necessary and also
- #y() == m(1) takes care of converting between 2 and 3 dimensional vectors.
- #z() == m(2) - if (m contains real valued values like float or double and T is an integral type like long) then
- #x() == floor(m(0) + 0.5)
- #y() == floor(m(1) + 0.5)
- if (NR == 3) then
- #z() == floor(m(2) + 0.5)
- else
- #z() == 0
- else
- #x() == m(0)
- #y() == m(1)
- if (NR == 3) then
- #z() == m(2)
- else
- #z() == 0
!*/ !*/
template <long NR, long NC, typename MM> operator matrix<T> (
operator matrix<T,NR, NC, MM> (
) const; ) const;
/*! /*!
ensures ensures
- provides automatic conversions from a vector object to a column - provides automatic conversions from a vector object to a column
matrix matrix
- returns a matrix object m such that: - returns a matrix object m such that:
- m.nr() == 3 - m.nr() == NR
- m.nc() == 1 - m.nc() == 1
- m(0) == x() - m(0) == x()
- m(1) == y() - m(1) == y()
- m(2) == z() - if (NR == 3) then
- m(2) == z()
!*/ !*/
~vector ( ~vector (
...@@ -142,6 +176,8 @@ namespace dlib ...@@ -142,6 +176,8 @@ namespace dlib
T& z ( T& z (
); );
/*! /*!
requires
- NR == 3 (this function actually doesn't exist when NR != 3)
ensures ensures
- returns a reference to the z component of the vector - returns a reference to the z component of the vector
!*/ !*/
...@@ -164,7 +200,11 @@ namespace dlib ...@@ -164,7 +200,11 @@ namespace dlib
) const; ) const;
/*! /*!
ensures ensures
- returns a const reference to the z component of the vector - if (NR == 3) then
- returns a const reference to the z component of the vector
- else
- return 0
(there isn't really a z in this case so we just return 0)
!*/ !*/
T dot ( T dot (
...@@ -175,7 +215,7 @@ namespace dlib ...@@ -175,7 +215,7 @@ namespace dlib
- returns the result of the dot product between *this and rhs - returns the result of the dot product between *this and rhs
!*/ !*/
vector cross ( vector<T,3> cross (
const vector& rhs const vector& rhs
) const; ) const;
/*! /*!
...@@ -261,8 +301,9 @@ namespace dlib ...@@ -261,8 +301,9 @@ namespace dlib
- returns #*this - returns #*this
!*/ !*/
template <typename U, long NR2>
bool operator== ( bool operator== (
const vector& rhs const vector<U,NR2>& rhs
) const; ) const;
/*! /*!
ensures ensures
...@@ -272,8 +313,9 @@ namespace dlib ...@@ -272,8 +313,9 @@ namespace dlib
- returns false - returns false
!*/ !*/
template <typename U, long NR2>
bool operator!= ( bool operator!= (
const vector& rhs const vector<U,NR2>& rhs
) const; ) const;
/*! /*!
ensures ensures
...@@ -290,47 +332,27 @@ namespace dlib ...@@ -290,47 +332,27 @@ namespace dlib
}; };
template<typename T, typename U> template<typename T, long NR>
vector<T> operator* (
const vector<T> & lhs,
const U rhs
);
/*!
ensures
- returns the result of multiplying the scalar rhs by lhs
!*/
template<typename T, typename U>
vector<T> operator* (
const U lhs,
const vector<T> & rhs
);
/*!
ensures
- returns the result of multiplying the scalar lhs by rhs
!*/
template<typename T>
inline void swap ( inline void swap (
vector<T> & a, vector<T,NR> & a,
vector<T> & b vector<T,NR> & b
) { a.swap(b); } ) { a.swap(b); }
/*! /*!
provides a global swap function provides a global swap function
!*/ !*/
template<typename T> template<typename T, long NR>
void serialize ( void serialize (
const vector<T> & item, const vector<T,NR>& item,
std::ostream& out std::ostream& out
); );
/*! /*!
provides serialization support provides serialization support
!*/ !*/
template<typename T> template<typename T, long NR>
void deserialize ( void deserialize (
vector<T> & item, vector<T,NR>& item,
std::istream& in std::istream& in
); );
/*! /*!
...@@ -340,7 +362,7 @@ namespace dlib ...@@ -340,7 +362,7 @@ namespace dlib
template<typename T> template<typename T>
std::ostream& operator<< ( std::ostream& operator<< (
std::ostream& out, std::ostream& out,
const vector<T>& item const vector<T,3>& item
); );
/*! /*!
ensures ensures
...@@ -350,7 +372,7 @@ namespace dlib ...@@ -350,7 +372,7 @@ namespace dlib
template<typename T> template<typename T>
std::istream& operator>>( std::istream& operator>>(
std::istream& in, std::istream& in,
vector<T>& item vector<T,3>& item
); );
/*! /*!
ensures ensures
...@@ -358,190 +380,35 @@ namespace dlib ...@@ -358,190 +380,35 @@ namespace dlib
The data in the input stream should be of the form (x, y, z) The data in the input stream should be of the form (x, y, z)
!*/ !*/
// ---------------------------------------------------------------------------------------- template<typename T>
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
class point
{
/*!
INITIAL VALUE
The initial value of this object is defined by its constructor.
WHAT THIS OBJECT REPRESENTS
This object represents a point inside a Cartesian coordinate system.
!*/
public:
point (
);
/*!
ensures
- #x() == 0
- #y() == 0
!*/
point (
long x_
long y_
);
/*!
ensures
- #x() == x_
- #y() == y_
!*/
point (
const point& p
);
/*!
ensures
- #x() == p.x()
- #y() == p.y()
!*/
template <typename T>
point (
const vector<T>& v
);
/*!
ensures
- #x() == floor(v.x()+0.5)
- #y() == floor(v.y()+0.5)
!*/
long x (
) const;
/*!
ensures
- returns the x coordinate of this point
!*/
long y (
) const;
/*!
ensures
- returns the y coordinate of this point
!*/
long& x (
);
/*!
ensures
- returns a non-const reference to the x coordinate of
this point
!*/
long& y (
);
/*!
ensures
- returns a non-const reference to the y coordinate of
this point
!*/
const point operator+ (
const point& rhs
) const;
/*!
ensures
- returns point(x()+rhs.x(), y()+rhs.y())
!*/
const point operator- (
const point& rhs
) const;
/*!
ensures
- returns point(x()-rhs.x(), y()-rhs.y())
!*/
point& operator= (
const point& p
);
/*!
ensures
- #x() == p.x()
- #y() == p.y()
- returns #*this
!*/
point& operator+= (
const point& rhs
);
/*!
ensures
- #*this = *this + rhs
- returns #*this
!*/
point& operator-= (
const point& rhs
);
/*!
ensures
- #*this = *this - rhs
- returns #*this
!*/
bool operator== (
const point& p
) const;
/*!
ensures
- if (x() == p.x() && y() == p.y()) then
- returns true
- else
- returns false
!*/
bool operator!= (
const point& p
) const;
/*!
ensures
- returns !(*this == p)
!*/
};
// ----------------------------------------------------------------------------------------
void serialize (
const point& item,
std::ostream& out
);
/*!
provides serialization support
!*/
void deserialize (
point& item,
std::istream& in
);
/*!
provides deserialization support
!*/
std::ostream& operator<< ( std::ostream& operator<< (
std::ostream& out, std::ostream& out,
const point& item const vector<T,2>& item
); );
/*! /*!
ensures ensures
- writes item to out in the form "(x, y)" - writes item to out in the form "(x, y)"
!*/ !*/
template<typename T>
std::istream& operator>>( std::istream& operator>>(
std::istream& in, std::istream& in,
point& item vector<T,2>& item
); );
/*! /*!
ensures ensures
- reads a point from the input stream in and stores it in #item. - reads a vector from the input stream in and stores it in #item.
The data in the input stream should be of the form (x, y) The data in the input stream should be of the form (x, y)
!*/ !*/
// ----------------------------------------------------------------------------------------
/*!A point
This is just a typedef of the vector object.
!*/
typedef vector<long,2> point;
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
} }
...@@ -549,12 +416,12 @@ namespace dlib ...@@ -549,12 +416,12 @@ namespace dlib
namespace std namespace std
{ {
/*! /*!
Define std::less<vector<T> > so that you can use vectors in the associative containers. Define std::less<vector<T,3> > so that you can use vectors in the associative containers.
!*/ !*/
template<typename T> template<typename T>
struct less<dlib::vector<T> > : public binary_function<dlib::vector<T> ,dlib::vector<T> ,bool> struct less<dlib::vector<T,3> > : public binary_function<dlib::vector<T,3> ,dlib::vector<T,3> ,bool>
{ {
inline bool operator() (const dlib::vector<T> & a, const dlib::vector<T> & b) const inline bool operator() (const dlib::vector<T,3> & a, const dlib::vector<T,3> & b) const
{ {
if (a.x() < b.x()) return true; if (a.x() < b.x()) return true;
else if (a.x() > b.x()) return false; else if (a.x() > b.x()) return false;
...@@ -567,12 +434,12 @@ namespace std ...@@ -567,12 +434,12 @@ namespace std
}; };
/*! /*!
Define std::less<point> so that you can use points in the associative containers. Define std::less<vector<T,2> > so that you can use vector<T,2>s in the associative containers.
!*/ !*/
template<> template<typename T>
struct less<dlib::point> : public binary_function<dlib::point,dlib::point,bool> struct less<dlib::vector<T,2> > : public binary_function<dlib::vector<T,2> ,dlib::vector<T,2> ,bool>
{ {
inline bool operator() (const dlib::point& a, const dlib::point& b) const inline bool operator() (const dlib::vector<T,2> & a, const dlib::vector<T,2> & b) const
{ {
if (a.x() < b.x()) return true; if (a.x() < b.x()) return true;
else if (a.x() > b.x()) return false; else if (a.x() > b.x()) return false;
......
...@@ -129,6 +129,65 @@ namespace ...@@ -129,6 +129,65 @@ namespace
DLIB_CASSERT(v1.y() == 6,""); DLIB_CASSERT(v1.y() == 6,"");
DLIB_CASSERT(v1.z() == 7,""); DLIB_CASSERT(v1.z() == 7,"");
{
dlib::vector<double,2> vd2;
dlib::vector<double,3> vd3;
dlib::vector<long,2> vl2;
dlib::vector<long,3> vl3;
vd2.x() = 2.3;
vd2.y() = 4.7;
vd3.z() = 9;
vd3 = vd2;
vl2 = vd3;
vl3 = vd3;
DLIB_CASSERT(vd2.z() == 0,"");
DLIB_CASSERT(vd3.z() == 0,"");
DLIB_CASSERT(vl2.z() == 0,"");
DLIB_CASSERT(vl3.z() == 0,"");
DLIB_CASSERT(vl2.x() == 2,"");
DLIB_CASSERT(vl3.x() == 2,"");
DLIB_CASSERT(vl2.y() == 5,"");
DLIB_CASSERT(vl3.y() == 5,"");
DLIB_CASSERT(abs(vd2.cross(vd3).dot(vd2)) < 1e-7,"");
DLIB_CASSERT(abs(vd3.cross(vd2).dot(vd2)) < 1e-7,"");
DLIB_CASSERT(abs(vd2.cross(vd3).dot(vd3)) < 1e-7,"");
DLIB_CASSERT(abs(vd3.cross(vd2).dot(vd3)) < 1e-7,"");
DLIB_CASSERT(abs(vl2.cross(vl3).dot(vl2)) == 0,"");
DLIB_CASSERT(abs(vl3.cross(vl2).dot(vl2)) == 0,"");
DLIB_CASSERT(abs(vl2.cross(vl3).dot(vl3)) == 0,"");
DLIB_CASSERT(abs(vl3.cross(vl2).dot(vl3)) == 0,"");
DLIB_CASSERT((vd2-vd3).length() < 1e-7,"");
DLIB_CASSERT(vl2 == vl3,"");
vl2.x() = 0;
vl2.y() = 0;
vl3 = vl2;
vl2.x() = 4;
vl3.y() = 3;
DLIB_CASSERT(vl2.cross(vl3).length() == 12,"");
DLIB_CASSERT(vl3.cross(vl2).length() == 12,"");
}
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment