// Copyright (C) 2003 Davis E. King (davisking@users.sourceforge.net) // License: Boost Software License See LICENSE.txt for the full license. #undef DLIB_VECTOR_ABSTRACT_ #ifdef DLIB_VECTOR_ABSTRACT_ #include "../serialize.h" #include <functional> #include <iostream> #include "../matrix/matrix_abstract.h" namespace dlib { class point; template < typename T > class vector { /*! REQUIREMENTS ON T T should be some object that provides an interface that is compatible with double, float and the like. INITIAL VALUE x() == 0 y() == 0 z() == 0 WHAT THIS OBJECT REPRESENTS This object represents a three dimensional vector. 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: typedef T type; vector ( ); /*! ensures - #*this has been properly initialized !*/ vector ( const T _x, const T _y, const T _z ); /*! ensures - #*this properly initialized - #x() == _x - #y() == _y - #z() == _z !*/ vector ( const point& p ); /*! ensures - #*this properly initialized - #x() == p.x() - #y() == p.y() - #z() == 0 !*/ vector ( const vector& v ); /*! ensures - #*this properly initialized - #x() == v.x() - #y() == v.y() - #z() == v.z() !*/ template <typename EXP> vector ( const matrix_exp<EXP>& m ); /*! requires - m.size() == 3 - m.nr() == 1 || m.nc() == 1 (i.e. m must be a row or column matrix) ensures - #x() == m(0) - #y() == m(1) - #z() == m(2) !*/ template <long NR, long NC, typename MM> operator matrix<T,NR, NC, MM> ( ) const; /*! ensures - provides automatic conversions from a vector object to a column matrix - returns a matrix object m such that: - m.nr() == 3 - m.nc() == 1 - m(0) == x() - m(1) == y() - m(2) == z() !*/ ~vector ( ); /*! ensures - all resources associated with *this have been released !*/ T length( ) const; /*! ensures - returns the length of the vector !*/ T& x ( ); /*! ensures - returns a reference to the x component of the vector !*/ T& y ( ); /*! ensures - returns a reference to the y component of the vector !*/ T& z ( ); /*! ensures - returns a reference to the z component of the vector !*/ const T& x ( ) const; /*! ensures - returns a const reference to the x component of the vector !*/ const T& y ( ) const; /*! ensures - returns a const reference to the y component of the vector !*/ const T& z ( ) const; /*! ensures - returns a const reference to the z component of the vector !*/ T dot ( const vector& rhs ) const; /*! ensures - returns the result of the dot product between *this and rhs !*/ vector cross ( const vector& rhs ) const; /*! ensures - returns the result of the cross product between *this and rhs !*/ vector normalize ( ) const; /*! ensures - returns a vector with length() == 1 and in the same direction as *this !*/ vector operator+ ( const vector& rhs ) const; /*! ensures - returns the result of adding *this to rhs !*/ vector operator- ( const vector& rhs ) const; /*! ensures - returns the result of subtracting rhs from *this !*/ vector operator/ ( const T rhs ) const; /*! ensures - returns the result of dividing *this by rhs !*/ vector& operator= ( const vector& rhs ); /*! ensures - #x() == rhs.x() - #y() == rhs.y() - #z() == rhs.z() - returns #*this !*/ vector& operator += ( const vector& rhs ); /*! ensures - #*this == *this + rhs - returns #*this !*/ vector& operator -= ( const vector& rhs ); /*! ensures - #*this == *this - rhs - returns #*this !*/ vector& operator *= ( const T rhs ); /*! ensures - #*this == *this * rhs - returns #*this !*/ vector& operator /= ( const T rhs ); /*! ensures - #*this == *this / rhs - returns #*this !*/ bool operator== ( const vector& rhs ) const; /*! ensures - if (x() == rhs.x() && y() == rhs.y() && z() == rhs.z()) then - returns true - else - returns false !*/ bool operator!= ( const vector& rhs ) const; /*! ensures - returns !((*this) == rhs) !*/ void swap ( vector& item ); /*! ensures - swaps *this and item !*/ }; template<typename T, typename U> 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 ( vector<T> & a, vector<T> & b ) { a.swap(b); } /*! provides a global swap function !*/ template<typename T> void serialize ( const vector<T> & item, std::ostream& out ); /*! provides serialization support !*/ template<typename T> void deserialize ( vector<T> & item, std::istream& in ); /*! provides deserialization support !*/ template<typename T> std::ostream& operator<< ( std::ostream& out, const vector<T>& item ); /*! ensures - writes item to out in the form "(x, y, z)" !*/ template<typename T> std::istream& operator>>( std::istream& in, vector<T>& item ); /*! ensures - 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, z) !*/ // ---------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------- 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& out, const point& item ); /*! ensures - writes item to out in the form "(x, y)" !*/ std::istream& operator>>( std::istream& in, point& item ); /*! ensures - reads a point from the input stream in and stores it in #item. The data in the input stream should be of the form (x, y) !*/ // ---------------------------------------------------------------------------------------- } namespace std { /*! Define std::less<vector<T> > so that you can use vectors in the associative containers. !*/ template<typename T> struct less<dlib::vector<T> > : public binary_function<dlib::vector<T> ,dlib::vector<T> ,bool> { inline bool operator() (const dlib::vector<T> & a, const dlib::vector<T> & 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; } }; /*! Define std::less<point> so that you can use points in the associative containers. !*/ template<> struct less<dlib::point> : public binary_function<dlib::point,dlib::point,bool> { inline bool operator() (const dlib::point& a, const dlib::point& 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; } }; } #endif // DLIB_VECTOR_ABSTRACT_