Commit aec7c847 authored by Davis King's avatar Davis King
Browse files

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;
/*! /*!
......
This diff is collapsed.
...@@ -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