lemon/xy.h
changeset 2199 1229af45cc69
parent 2006 00d59f733817
equal deleted inserted replaced
9:269c2e7d5d36 10:434771fe659a
    45 
    45 
    46   /// A simple two dimensional vector (plainvector) implementation
    46   /// A simple two dimensional vector (plainvector) implementation
    47   ///with the usual vector
    47   ///with the usual vector
    48   /// operators.
    48   /// operators.
    49   ///
    49   ///
       
    50   ///\note As you might have noticed, this class does not follow the
       
    51   ///\ref naming_conv "LEMON Coding Style" (it should be called \c Xy
       
    52   ///according to it). There is a stupid Hungarian proverb, "A kivétel
       
    53   ///erõsíti a szabályt" ("An exception
       
    54   ///reinforces a rule", which is
       
    55   ///actually a mistranslation of the Latin proverb "Exceptio probat regulam").
       
    56   ///This class is an example for that.
    50   ///\author Attila Bernath
    57   ///\author Attila Bernath
    51   template<typename T>
    58   template<typename T>
    52     class xy {
    59     class xy {
    53 
    60 
    54     public:
    61     public:
    61       T y;     
    68       T y;     
    62       
    69       
    63       ///Default constructor
    70       ///Default constructor
    64       xy() {}
    71       xy() {}
    65 
    72 
    66       ///Constructing the instance from coordinates
    73       ///Construct an instance from coordinates
    67       xy(T a, T b) : x(a), y(b) { }
    74       xy(T a, T b) : x(a), y(b) { }
    68 
    75 
    69 
    76 
    70       ///Conversion constructor
    77       ///Conversion constructor
    71       template<class TT> xy(const xy<TT> &p) : x(p.x), y(p.y) {}
    78       template<class TT> xy(const xy<TT> &p) : x(p.x), y(p.y) {}
    72 
    79 
    73       ///Gives back the square of the norm of the vector
    80       ///Give back the square of the norm of the vector
    74       T normSquare() const {
    81       T normSquare() const {
    75         return x*x+y*y;
    82         return x*x+y*y;
    76       }
    83       }
    77   
    84   
    78       ///Increments the left hand side by u
    85       ///Increment the left hand side by u
    79       xy<T>& operator +=(const xy<T>& u) {
    86       xy<T>& operator +=(const xy<T>& u) {
    80         x += u.x;
    87         x += u.x;
    81         y += u.y;
    88         y += u.y;
    82         return *this;
    89         return *this;
    83       }
    90       }
    84   
    91   
    85       ///Decrements the left hand side by u
    92       ///Decrement the left hand side by u
    86       xy<T>& operator -=(const xy<T>& u) {
    93       xy<T>& operator -=(const xy<T>& u) {
    87         x -= u.x;
    94         x -= u.x;
    88         y -= u.y;
    95         y -= u.y;
    89         return *this;
    96         return *this;
    90       }
    97       }
    91 
    98 
    92       ///Multiplying the left hand side with a scalar
    99       ///Multiply the left hand side with a scalar
    93       xy<T>& operator *=(const T &u) {
   100       xy<T>& operator *=(const T &u) {
    94         x *= u;
   101         x *= u;
    95         y *= u;
   102         y *= u;
    96         return *this;
   103         return *this;
    97       }
   104       }
    98 
   105 
    99       ///Dividing the left hand side by a scalar
   106       ///Divide the left hand side by a scalar
   100       xy<T>& operator /=(const T &u) {
   107       xy<T>& operator /=(const T &u) {
   101         x /= u;
   108         x /= u;
   102         y /= u;
   109         y /= u;
   103         return *this;
   110         return *this;
   104       }
   111       }
   105   
   112   
   106       ///Returns the scalar product of two vectors
   113       ///Return the scalar product of two vectors
   107       T operator *(const xy<T>& u) const {
   114       T operator *(const xy<T>& u) const {
   108         return x*u.x+y*u.y;
   115         return x*u.x+y*u.y;
   109       }
   116       }
   110   
   117   
   111       ///Returns the sum of two vectors
   118       ///Return the sum of two vectors
   112       xy<T> operator+(const xy<T> &u) const {
   119       xy<T> operator+(const xy<T> &u) const {
   113         xy<T> b=*this;
   120         xy<T> b=*this;
   114         return b+=u;
   121         return b+=u;
   115       }
   122       }
   116 
   123 
   117       ///Returns the neg of the vectors
   124       ///Return the neg of the vectors
   118       xy<T> operator-() const {
   125       xy<T> operator-() const {
   119         xy<T> b=*this;
   126         xy<T> b=*this;
   120         b.x=-b.x; b.y=-b.y;
   127         b.x=-b.x; b.y=-b.y;
   121         return b;
   128         return b;
   122       }
   129       }
   123 
   130 
   124       ///Returns the difference of two vectors
   131       ///Return the difference of two vectors
   125       xy<T> operator-(const xy<T> &u) const {
   132       xy<T> operator-(const xy<T> &u) const {
   126         xy<T> b=*this;
   133         xy<T> b=*this;
   127         return b-=u;
   134         return b-=u;
   128       }
   135       }
   129 
   136 
   130       ///Returns a vector multiplied by a scalar
   137       ///Return a vector multiplied by a scalar
   131       xy<T> operator*(const T &u) const {
   138       xy<T> operator*(const T &u) const {
   132         xy<T> b=*this;
   139         xy<T> b=*this;
   133         return b*=u;
   140         return b*=u;
   134       }
   141       }
   135 
   142 
   136       ///Returns a vector divided by a scalar
   143       ///Return a vector divided by a scalar
   137       xy<T> operator/(const T &u) const {
   144       xy<T> operator/(const T &u) const {
   138         xy<T> b=*this;
   145         xy<T> b=*this;
   139         return b/=u;
   146         return b/=u;
   140       }
   147       }
   141 
   148 
   142       ///Testing equality
   149       ///Test equality
   143       bool operator==(const xy<T> &u) const {
   150       bool operator==(const xy<T> &u) const {
   144         return (x==u.x) && (y==u.y);
   151         return (x==u.x) && (y==u.y);
   145       }
   152       }
   146 
   153 
   147       ///Testing inequality
   154       ///Test inequality
   148       bool operator!=(xy u) const {
   155       bool operator!=(xy u) const {
   149         return  (x!=u.x) || (y!=u.y);
   156         return  (x!=u.x) || (y!=u.y);
   150       }
   157       }
   151 
   158 
   152     };
   159     };
   153 
   160 
   154   ///Returns an xy 
   161   ///Return an xy 
   155 
   162 
   156   ///Returns an xy
   163   ///Return an xy
   157   ///\relates xy
   164   ///\relates xy
   158   template <typename T>
   165   template <typename T>
   159   inline xy<T> make_xy(const T& x, const T& y) {
   166   inline xy<T> make_xy(const T& x, const T& y) {
   160     return xy<T>(x, y);
   167     return xy<T>(x, y);
   161   }
   168   }
   162 
   169 
   163   ///Returns a vector multiplied by a scalar
   170   ///Return a vector multiplied by a scalar
   164 
   171 
   165   ///Returns a vector multiplied by a scalar
   172   ///Return a vector multiplied by a scalar
   166   ///\relates xy
   173   ///\relates xy
   167   template<typename T> xy<T> operator*(const T &u,const xy<T> &x) {
   174   template<typename T> xy<T> operator*(const T &u,const xy<T> &x) {
   168     return x*u;
   175     return x*u;
   169   }
   176   }
   170 
   177 
   217   inline xy<T> rot90(const xy<T> &z)
   224   inline xy<T> rot90(const xy<T> &z)
   218   {
   225   {
   219     return xy<T>(-z.y,z.x);
   226     return xy<T>(-z.y,z.x);
   220   }
   227   }
   221 
   228 
       
   229   ///Rotate by 180 degrees
       
   230 
       
   231   ///Returns its parameter rotated by 180 degrees.
       
   232   ///\relates xy
       
   233   ///
       
   234   template<typename T>
       
   235   inline xy<T> rot180(const xy<T> &z)
       
   236   {
       
   237     return xy<T>(-z.x,-z.y);
       
   238   }
       
   239 
   222   ///Rotate by 270 degrees
   240   ///Rotate by 270 degrees
   223 
   241 
   224   ///Returns its parameter rotated by 90 degrees in negative direction.
   242   ///Returns its parameter rotated by 90 degrees in negative direction.
   225   ///\relates xy
   243   ///\relates xy
   226   ///
   244   ///
   244     public:
   262     public:
   245       
   263       
   246       ///Default constructor: creates an empty bounding box
   264       ///Default constructor: creates an empty bounding box
   247       BoundingBox() { _empty = true; }
   265       BoundingBox() { _empty = true; }
   248 
   266 
   249       ///Constructing the instance from one point
   267       ///Construct an instance from one point
   250       BoundingBox(xy<T> a) { bottom_left=top_right=a; _empty = false; }
   268       BoundingBox(xy<T> a) { bottom_left=top_right=a; _empty = false; }
   251 
   269 
   252       ///Were any points added?
   270       ///Were any points added?
   253       bool empty() const {
   271       bool empty() const {
   254         return _empty;
   272         return _empty;
   255       }
   273       }
   256 
   274 
   257       ///Makes the BoundingBox empty
   275       ///Make the BoundingBox empty
   258       void clear() {
   276       void clear() {
   259         _empty=1;
   277         _empty=1;
   260       }
   278       }
   261 
   279 
   262       ///\brief Gives back the bottom left corner
   280       ///Give back the bottom left corner
   263       ///(if the bounding box is empty, then the return value is not defined) 
   281 
       
   282       ///Give back the bottom left corner.
       
   283       ///If the bounding box is empty, then the return value is not defined.
   264       xy<T> bottomLeft() const {
   284       xy<T> bottomLeft() const {
   265         return bottom_left;
   285         return bottom_left;
   266       }
   286       }
   267 
   287 
   268       ///\brief Sets the bottom left corner
   288       ///Set the bottom left corner
   269       ///(should only bee used for non-empty box) 
   289 
       
   290       ///Set the bottom left corner.
       
   291       ///It should only bee used for non-empty box.
   270       void bottomLeft(xy<T> p) {
   292       void bottomLeft(xy<T> p) {
   271 	bottom_left = p;
   293 	bottom_left = p;
   272       }
   294       }
   273 
   295 
   274       ///\brief Gives back the top right corner
   296       ///Give back the top right corner
   275       ///(if the bounding box is empty, then the return value is not defined) 
   297 
       
   298       ///Give back the top right corner.
       
   299       ///If the bounding box is empty, then the return value is not defined.
   276       xy<T> topRight() const {
   300       xy<T> topRight() const {
   277         return top_right;
   301         return top_right;
   278       }
   302       }
   279 
   303 
   280       ///\brief Sets the top right corner
   304       ///Set the top right corner
   281       ///(should only bee used for non-empty box) 
   305 
       
   306       ///Set the top right corner.
       
   307       ///It should only bee used for non-empty box.
   282       void topRight(xy<T> p) {
   308       void topRight(xy<T> p) {
   283 	top_right = p;
   309 	top_right = p;
   284       }
   310       }
   285 
   311 
   286       ///\brief Gives back the bottom right corner
   312       ///Give back the bottom right corner
   287       ///(if the bounding box is empty, then the return value is not defined) 
   313 
       
   314       ///Give back the bottom right corner.
       
   315       ///If the bounding box is empty, then the return value is not defined.
   288       xy<T> bottomRight() const {
   316       xy<T> bottomRight() const {
   289         return xy<T>(top_right.x,bottom_left.y);
   317         return xy<T>(top_right.x,bottom_left.y);
   290       }
   318       }
   291 
   319 
   292       ///\brief Sets the bottom right corner
   320       ///Set the bottom right corner
   293       ///(should only bee used for non-empty box) 
   321 
       
   322       ///Set the bottom right corner.
       
   323       ///It should only bee used for non-empty box.
   294       void bottomRight(xy<T> p) {
   324       void bottomRight(xy<T> p) {
   295 	top_right.x = p.x;
   325 	top_right.x = p.x;
   296 	bottom_left.y = p.y;
   326 	bottom_left.y = p.y;
   297       }
   327       }
   298 
   328  
   299       ///\brief Gives back the top left corner
   329       ///Give back the top left corner
   300       ///(if the bounding box is empty, then the return value is not defined) 
   330 
       
   331       ///Give back the top left corner.
       
   332       ///If the bounding box is empty, then the return value is not defined.
   301       xy<T> topLeft() const {
   333       xy<T> topLeft() const {
   302         return xy<T>(bottom_left.x,top_right.y);
   334         return xy<T>(bottom_left.x,top_right.y);
   303       }
   335       }
   304 
   336 
   305       ///\brief Sets the top left corner
   337       ///Set the top left corner
   306       ///(should only bee used for non-empty box) 
   338 
       
   339       ///Set the top left corner.
       
   340       ///It should only bee used for non-empty box.
   307       void topLeft(xy<T> p) {
   341       void topLeft(xy<T> p) {
   308 	top_right.y = p.y;
   342 	top_right.y = p.y;
   309 	bottom_left.x = p.x;
   343 	bottom_left.x = p.x;
   310       }
   344       }
   311 
   345 
   312       ///\brief Gives back the bottom of the box
   346       ///Give back the bottom of the box
   313       ///(if the bounding box is empty, then the return value is not defined) 
   347 
       
   348       ///Give back the bottom of the box.
       
   349       ///If the bounding box is empty, then the return value is not defined.
   314       T bottom() const {
   350       T bottom() const {
   315         return bottom_left.y;
   351         return bottom_left.y;
   316       }
   352       }
   317 
   353 
   318       ///\brief Sets the bottom of the box
   354       ///Set the bottom of the box
   319       ///(should only bee used for non-empty box) 
   355 
       
   356       ///Set the bottom of the box.
       
   357       ///It should only bee used for non-empty box.
   320       void bottom(T t) {
   358       void bottom(T t) {
   321 	bottom_left.y = t;
   359 	bottom_left.y = t;
   322       }
   360       }
   323 
   361 
   324       ///\brief Gives back the top of the box
   362       ///Give back the top of the box
   325       ///(if the bounding box is empty, then the return value is not defined) 
   363 
       
   364       ///Give back the top of the box.
       
   365       ///If the bounding box is empty, then the return value is not defined.
   326       T top() const {
   366       T top() const {
   327         return top_right.y;
   367         return top_right.y;
   328       }
   368       }
   329 
   369 
   330       ///\brief Sets the top of the box
   370       ///Set the top of the box
   331       ///(should only bee used for non-empty box) 
   371 
       
   372       ///Set the top of the box.
       
   373       ///It should only bee used for non-empty box.
   332       void top(T t) {
   374       void top(T t) {
   333 	top_right.y = t;
   375 	top_right.y = t;
   334       }
   376       }
   335 
   377 
   336       ///\brief Gives back the left side of the box
   378       ///Give back the left side of the box
   337       ///(if the bounding box is empty, then the return value is not defined) 
   379 
       
   380       ///Give back the left side of the box.
       
   381       ///If the bounding box is empty, then the return value is not defined.
   338       T left() const {
   382       T left() const {
   339         return bottom_left.x;
   383         return bottom_left.x;
   340       }
   384       }
   341 
   385  
   342       ///\brief Sets the left side of the box
   386       ///Set the left side of the box
   343       ///(should only bee used for non-empty box) 
   387 
       
   388       ///Set the left side of the box.
       
   389       ///It should only bee used for non-empty box
   344       void left(T t) {
   390       void left(T t) {
   345 	bottom_left.x = t;
   391 	bottom_left.x = t;
   346       }
   392       }
   347 
   393 
   348       ///\brief Gives back the right side of the box
   394       /// Give back the right side of the box
   349       ///(if the bounding box is empty, then the return value is not defined) 
   395 
       
   396       /// Give back the right side of the box.
       
   397       ///If the bounding box is empty, then the return value is not defined.
   350       T right() const {
   398       T right() const {
   351         return top_right.x;
   399         return top_right.x;
   352       }
   400       }
   353 
   401 
   354       ///\brief Sets the right side of the box
   402       ///Set the right side of the box
   355       ///(should only bee used for non-empty box) 
   403 
       
   404       ///Set the right side of the box.
       
   405       ///It should only bee used for non-empty box
   356       void right(T t) {
   406       void right(T t) {
   357 	top_right.x = t;
   407 	top_right.x = t;
   358       }
   408       }
   359 
   409 
   360       ///\brief Gives back the height of the box
   410       ///Give back the height of the box
   361       ///(if the bounding box is empty, then the return value is not defined) 
   411 
       
   412       ///Give back the height of the box.
       
   413       ///If the bounding box is empty, then the return value is not defined.
   362       T height() const {
   414       T height() const {
   363         return top_right.y-bottom_left.y;
   415         return top_right.y-bottom_left.y;
   364       }
   416       }
   365 
   417 
   366       ///\brief Gives back the width of the box
   418       ///Give back the width of the box
   367       ///(if the bounding box is empty, then the return value is not defined) 
   419 
       
   420       ///Give back the width of the box.
       
   421       ///If the bounding box is empty, then the return value is not defined.
   368       T width() const {
   422       T width() const {
   369         return top_right.x-bottom_left.x;
   423         return top_right.x-bottom_left.x;
   370       }
   424       }
   371 
   425 
   372       ///Checks whether a point is inside a bounding box
   426       ///Checks whether a point is inside a bounding box