athos@207: // -*- c++ -*- athos@201: #ifndef HUGO_XY_H athos@201: #define HUGO_XY_H athos@201: athos@201: #include athos@201: alpar@431: ///ingroup misc alpar@249: ///\file alpar@249: ///\brief A simple two dimensional vector and a bounding box implementation alpar@249: /// alpar@249: /// The class \ref hugo::xy "xy" implements alpar@249: ///a two dimensional vector with the usual alpar@249: /// operations. alpar@249: /// alpar@249: /// The class \ref hugo::BoundingBox "BoundingBox" can be used to determine alpar@249: /// the rectangular bounding box a set of \ref hugo::xy "xy"'s. alpar@249: alpar@249: alpar@431: namespace hugo { alpar@431: alpar@431: /// \addtogroup misc alpar@431: /// @{ alpar@431: alpar@242: /** \brief alpar@242: 2 dimensional vector (plainvector) implementation alpar@242: alpar@242: */ athos@207: template athos@207: class xy { athos@201: athos@207: public: athos@240: athos@240: T x,y; athos@207: athos@207: ///Default constructor: both coordinates become 0 athos@240: xy() : x(0), y(0) {} athos@201: athos@240: ///Constructing the instance from coordinates athos@240: xy(T a, T b) : x(a), y(a) { } athos@201: athos@201: athos@207: ///Gives back the square of the norm of the vector athos@207: T normSquare(){ athos@240: return x*x+y*y; athos@207: }; athos@201: athos@207: ///Increments the left hand side by u athos@207: xy& operator +=(const xy& u){ athos@240: x += u.x; athos@240: y += u.y; athos@207: return *this; athos@207: }; athos@201: athos@207: ///Decrements the left hand side by u athos@207: xy& operator -=(const xy& u){ athos@240: x -= u.x; athos@240: y -= u.y; athos@207: return *this; athos@207: }; athos@201: athos@207: ///Multiplying the left hand side with a scalar athos@207: xy& operator *=(const T &u){ athos@240: x *= u; athos@240: y *= u; athos@207: return *this; athos@207: }; athos@207: athos@207: ///Dividing the left hand side by a scalar athos@207: xy& operator /=(const T &u){ athos@240: x /= u; athos@240: y /= u; athos@207: return *this; athos@207: }; athos@201: athos@207: ///Returns the scalar product of two vectors athos@207: T operator *(const xy& u){ athos@240: return x*u.x+y*u.y; athos@207: }; athos@201: athos@207: ///Returns the sum of two vectors athos@207: xy operator+(const xy &u) const { athos@207: xy b=*this; athos@207: return b+=u; athos@207: }; athos@201: athos@207: ///Returns the difference of two vectors athos@207: xy operator-(const xy &u) const { athos@207: xy b=*this; athos@207: return b-=u; athos@207: }; athos@201: athos@207: ///Returns a vector multiplied by a scalar athos@207: xy operator*(const T &u) const { athos@207: xy b=*this; athos@207: return b*=u; athos@207: }; athos@201: athos@207: ///Returns a vector divided by a scalar athos@207: xy operator/(const T &u) const { athos@207: xy b=*this; athos@207: return b/=u; athos@207: }; athos@201: athos@207: ///Testing equality athos@207: bool operator==(const xy &u){ athos@240: return (x==u.x) && (y==u.y); athos@207: }; athos@201: athos@207: ///Testing inequality athos@207: bool operator!=(xy u){ athos@240: return (x!=u.x) || (y!=u.y); athos@207: }; athos@201: athos@207: }; athos@201: athos@207: ///Reading a plainvector from a stream athos@207: template athos@207: inline athos@207: std::istream& operator>>(std::istream &is, xy &z) athos@207: { athos@240: athos@240: is >> z.x >> z.y; athos@207: return is; athos@207: } athos@201: athos@207: ///Outputting a plainvector to a stream athos@207: template athos@207: inline athos@207: std::ostream& operator<<(std::ostream &os, xy z) athos@207: { athos@240: os << "(" << z.x << ", " << z.y << ")"; athos@207: return os; athos@207: } athos@207: athos@244: athos@244: /** \brief athos@244: Implementation of a bounding box of plainvectors. athos@244: athos@244: */ athos@244: template athos@244: class BoundingBox { athos@244: xy bottom_left, top_right; athos@244: bool _empty; athos@244: public: athos@244: athos@244: ///Default constructor: an empty bounding box athos@244: BoundingBox() { _empty = true; } athos@244: athos@244: ///Constructing the instance from one point athos@244: BoundingBox(xy a) { bottom_left=top_right=a; _empty = false; } athos@244: athos@244: ///Is there any point added athos@244: bool empty() const { athos@244: return _empty; athos@244: } athos@244: athos@244: ///Gives back the bottom left corner (if the bounding box is empty, then the return value is not defined) athos@244: xy bottomLeft() const { athos@244: return bottom_left; athos@244: }; athos@244: athos@244: ///Gives back the top right corner (if the bounding box is empty, then the return value is not defined) athos@244: xy topRight() const { athos@244: return top_right; athos@244: }; athos@244: athos@244: ///Checks whether a point is inside a bounding box athos@244: bool inside(const xy& u){ athos@244: if (_empty) athos@244: return false; athos@244: else{ athos@244: return ((u.x-bottom_left.x)*(top_right.x-u.x) >= 0 && athos@244: (u.y-bottom_left.y)*(top_right.y-u.y) >= 0 ); athos@244: } athos@244: } athos@244: athos@244: ///Increments a bounding box with a point athos@244: BoundingBox& operator +=(const xy& u){ athos@244: if (_empty){ athos@244: bottom_left=top_right=u; athos@244: _empty = false; athos@244: } athos@244: else{ athos@244: if (bottom_left.x > u.x) bottom_left.x = u.x; athos@244: if (bottom_left.y > u.y) bottom_left.y = u.y; athos@244: if (top_right.x < u.x) top_right.x = u.x; athos@244: if (top_right.y < u.y) top_right.y = u.y; athos@244: } athos@244: return *this; athos@244: }; athos@244: athos@244: ///Sums a bounding box and a point athos@244: BoundingBox operator +(const xy& u){ athos@244: BoundingBox b = *this; athos@244: return b += u; athos@244: }; athos@244: athos@244: ///Increments a bounding box with an other bounding box athos@244: BoundingBox& operator +=(const BoundingBox &u){ athos@244: if ( !u.empty() ){ athos@244: *this += u.bottomLeft(); athos@244: *this += u.topRight(); athos@244: } athos@244: return *this; athos@244: }; athos@244: athos@244: ///Sums two bounding boxes athos@244: BoundingBox operator +(const BoundingBox& u){ athos@244: BoundingBox b = *this; athos@244: return b += u; athos@244: }; athos@244: athos@244: };//class Boundingbox athos@244: athos@244: alpar@431: /// @} athos@244: athos@244: athos@207: } //namespace hugo athos@201: athos@201: #endif //HUGO_XY_H