lemon/xy.h
author hegyi
Mon, 21 Nov 2005 18:03:20 +0000
changeset 1823 cb082cdf3667
parent 1588 b79bcba43661
child 1875 98698b69a902
permissions -rw-r--r--
NewMapWin has become Dialog instead of Window. Therefore it is created dynamically, when there is need for it, instead of keeping one instance in memory. This solution is slower, but more correct than before.
     1 /* -*- C++ -*-
     2  * lemon/xy.h - Part of LEMON, a generic C++ optimization library
     3  *
     4  * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     5  * (Egervary Research Group on Combinatorial Optimization, EGRES).
     6  *
     7  * Permission to use, modify and distribute this software is granted
     8  * provided that this copyright notice appears in all copies. For
     9  * precise terms see the accompanying LICENSE file.
    10  *
    11  * This software is provided "AS IS" with no warranty of any kind,
    12  * express or implied, and with no claim as to its suitability for any
    13  * purpose.
    14  *
    15  */
    16 
    17 #ifndef LEMON_XY_H
    18 #define LEMON_XY_H
    19 
    20 #include <iostream>
    21 #include <lemon/utility.h>
    22 
    23 ///\ingroup misc
    24 ///\file
    25 ///\brief A simple two dimensional vector and a bounding box implementation 
    26 ///
    27 /// The class \ref lemon::xy "xy" implements
    28 ///a two dimensional vector with the usual
    29 /// operations.
    30 ///
    31 /// The class \ref lemon::BoundingBox "BoundingBox" can be used to determine
    32 /// the rectangular bounding box of a set of \ref lemon::xy "xy"'s.
    33 ///
    34 ///\author Attila Bernath
    35 
    36 
    37 namespace lemon {
    38 
    39   /// \addtogroup misc
    40   /// @{
    41 
    42   /// A simple two dimensional vector (plainvector) implementation
    43 
    44   /// A simple two dimensional vector (plainvector) implementation
    45   ///with the usual vector
    46   /// operators.
    47   ///
    48   ///\author Attila Bernath
    49   template<typename T>
    50     class xy {
    51 
    52     public:
    53 
    54       typedef T Value;
    55 
    56       T x,y;     
    57       
    58       ///Default constructor
    59       xy() {}
    60 
    61       ///Constructing the instance from coordinates
    62       xy(T a, T b) : x(a), y(b) { }
    63 
    64 
    65       ///Conversion constructor
    66       template<class TT> xy(const xy<TT> &p) : x(p.x), y(p.y) {}
    67 
    68       ///Gives back the square of the norm of the vector
    69       T normSquare() const {
    70         return x*x+y*y;
    71       }
    72   
    73       ///Increments the left hand side by u
    74       xy<T>& operator +=(const xy<T>& u) {
    75         x += u.x;
    76         y += u.y;
    77         return *this;
    78       }
    79   
    80       ///Decrements the left hand side by u
    81       xy<T>& operator -=(const xy<T>& u) {
    82         x -= u.x;
    83         y -= u.y;
    84         return *this;
    85       }
    86 
    87       ///Multiplying the left hand side with a scalar
    88       xy<T>& operator *=(const T &u) {
    89         x *= u;
    90         y *= u;
    91         return *this;
    92       }
    93 
    94       ///Dividing the left hand side by a scalar
    95       xy<T>& operator /=(const T &u) {
    96         x /= u;
    97         y /= u;
    98         return *this;
    99       }
   100   
   101       ///Returns the scalar product of two vectors
   102       T operator *(const xy<T>& u) const {
   103         return x*u.x+y*u.y;
   104       }
   105   
   106       ///Returns the sum of two vectors
   107       xy<T> operator+(const xy<T> &u) const {
   108         xy<T> b=*this;
   109         return b+=u;
   110       }
   111 
   112       ///Returns the neg of the vectors
   113       xy<T> operator-() const {
   114         xy<T> b=*this;
   115         b.x=-b.x; b.y=-b.y;
   116         return b;
   117       }
   118 
   119       ///Returns the difference of two vectors
   120       xy<T> operator-(const xy<T> &u) const {
   121         xy<T> b=*this;
   122         return b-=u;
   123       }
   124 
   125       ///Returns a vector multiplied by a scalar
   126       xy<T> operator*(const T &u) const {
   127         xy<T> b=*this;
   128         return b*=u;
   129       }
   130 
   131       ///Returns a vector divided by a scalar
   132       xy<T> operator/(const T &u) const {
   133         xy<T> b=*this;
   134         return b/=u;
   135       }
   136 
   137       ///Testing equality
   138       bool operator==(const xy<T> &u) const {
   139         return (x==u.x) && (y==u.y);
   140       }
   141 
   142       ///Testing inequality
   143       bool operator!=(xy u) const {
   144         return  (x!=u.x) || (y!=u.y);
   145       }
   146 
   147     };
   148 
   149   ///Returns a vector multiplied by a scalar
   150 
   151   ///Returns a vector multiplied by a scalar
   152   ///\relates xy
   153   template<typename T> xy<T> operator*(const T &u,const xy<T> &x) {
   154     return x*u;
   155   }
   156 
   157   ///Read a plainvector from a stream
   158 
   159   ///Read a plainvector from a stream
   160   ///\relates xy
   161   ///
   162   template<typename T>
   163   inline std::istream& operator>>(std::istream &is, xy<T> &z) {
   164     char c;
   165     if (is >> c) {
   166       if (c != '(') is.putback(c);
   167     } else {
   168       is.clear();
   169     }
   170     if (!(is >> z.x)) return is;
   171     if (is >> c) {
   172       if (c != ',') is.putback(c);
   173     } else {
   174       is.clear();
   175     }
   176     if (!(is >> z.y)) return is;
   177     if (is >> c) {
   178       if (c != ')') is.putback(c);
   179     } else {
   180       is.clear();
   181     }
   182     return is;
   183   }
   184 
   185   ///Write a plainvector to a stream
   186 
   187   ///Write a plainvector to a stream
   188   ///\relates xy
   189   ///
   190   template<typename T>
   191   inline std::ostream& operator<<(std::ostream &os, const xy<T>& z)
   192   {
   193     os << "(" << z.x << ", " << z.y << ")";
   194     return os;
   195   }
   196 
   197   ///Rotate by 90 degrees
   198 
   199   ///Returns its parameter rotated by 90 degrees in positive direction.
   200   ///\relates xy
   201   ///
   202   template<typename T>
   203   inline xy<T> rot90(const xy<T> &z)
   204   {
   205     return xy<T>(-z.y,z.x);
   206   }
   207 
   208   ///Rotate by 270 degrees
   209 
   210   ///Returns its parameter rotated by 90 degrees in negative direction.
   211   ///\relates xy
   212   ///
   213   template<typename T>
   214   inline xy<T> rot270(const xy<T> &z)
   215   {
   216     return xy<T>(z.y,-z.x);
   217   }
   218 
   219   
   220 
   221   /// A class to calculate or store the bounding box of plainvectors.
   222 
   223   /// A class to calculate or store the bounding box of plainvectors.
   224   ///
   225   ///\author Attila Bernath
   226   template<typename T>
   227     class BoundingBox {
   228       xy<T> bottom_left, top_right;
   229       bool _empty;
   230     public:
   231       
   232       ///Default constructor: creates an empty bounding box
   233       BoundingBox() { _empty = true; }
   234 
   235       ///Constructing the instance from one point
   236       BoundingBox(xy<T> a) { bottom_left=top_right=a; _empty = false; }
   237 
   238       ///Were any points added?
   239       bool empty() const {
   240         return _empty;
   241       }
   242 
   243       ///Makes the BoundingBox empty
   244       void clear() {
   245         _empty=1;
   246       }
   247 
   248       ///Gives back the bottom left corner (if the bounding box is empty, then the return value is not defined) 
   249       xy<T> bottomLeft() const {
   250         return bottom_left;
   251       }
   252 
   253       ///Gives back the top right corner (if the bounding box is empty, then the return value is not defined) 
   254       xy<T> topRight() const {
   255         return top_right;
   256       }
   257 
   258       ///Gives back the bottom right corner (if the bounding box is empty, then the return value is not defined) 
   259       xy<T> bottomRight() const {
   260         return xy<T>(top_right.x,bottom_left.y);
   261       }
   262 
   263       ///Gives back the top left corner (if the bounding box is empty, then the return value is not defined) 
   264       xy<T> topLeft() const {
   265         return xy<T>(bottom_left.x,top_right.y);
   266       }
   267 
   268       ///Gives back the bottom of the box (if the bounding box is empty, then the return value is not defined) 
   269       T bottom() const {
   270         return bottom_left.y;
   271       }
   272 
   273       ///Gives back the top of the box (if the bounding box is empty, then the return value is not defined) 
   274       T top() const {
   275         return top_right.y;
   276       }
   277 
   278       ///Gives back the left side of the box (if the bounding box is empty, then the return value is not defined) 
   279       T left() const {
   280         return bottom_left.x;
   281       }
   282 
   283       ///Gives back the right side of the box (if the bounding box is empty, then the return value is not defined) 
   284       T right() const {
   285         return top_right.x;
   286       }
   287 
   288       ///Gives back the height of the box (if the bounding box is empty, then the return value is not defined) 
   289       T height() const {
   290         return top_right.y-bottom_left.y;
   291       }
   292 
   293       ///Gives back the width of the box (if the bounding box is empty, then the return value is not defined) 
   294       T width() const {
   295         return top_right.x-bottom_left.x;
   296       }
   297 
   298       ///Checks whether a point is inside a bounding box
   299       bool inside(const xy<T>& u){
   300         if (_empty)
   301           return false;
   302         else{
   303           return ((u.x-bottom_left.x)*(top_right.x-u.x) >= 0 &&
   304               (u.y-bottom_left.y)*(top_right.y-u.y) >= 0 );
   305         }
   306       }
   307   
   308       ///Increments a bounding box with a point
   309       BoundingBox& add(const xy<T>& u){
   310         if (_empty){
   311           bottom_left=top_right=u;
   312           _empty = false;
   313         }
   314         else{
   315           if (bottom_left.x > u.x) bottom_left.x = u.x;
   316           if (bottom_left.y > u.y) bottom_left.y = u.y;
   317           if (top_right.x < u.x) top_right.x = u.x;
   318           if (top_right.y < u.y) top_right.y = u.y;
   319         }
   320         return *this;
   321       }
   322   
   323 //       ///Sums a bounding box and a point
   324 //       BoundingBox operator +(const xy<T>& u){
   325 //         BoundingBox b = *this;
   326 //         return b += u;
   327 //       }
   328 
   329       ///Increments a bounding box with an other bounding box
   330       BoundingBox& add(const BoundingBox &u){
   331         if ( !u.empty() ){
   332           this->add(u.bottomLeft());
   333 	  this->add(u.topRight());
   334         }
   335         return *this;
   336       }
   337   
   338       ///Sums two bounding boxes
   339       BoundingBox operator +(const BoundingBox& u){
   340         BoundingBox b = *this;
   341         return b.add(u);
   342       }
   343 
   344 
   345       ///Intersection of two bounding boxes
   346       BoundingBox operator &(const BoundingBox& u){
   347         BoundingBox b;
   348 	b.bottom_left.x=std::max(this->bottom_left.x,u.bottom_left.x);
   349 	b.bottom_left.y=std::max(this->bottom_left.y,u.bottom_left.y);
   350 	b.top_right.x=std::min(this->top_right.x,u.top_right.x);
   351 	b.top_right.y=std::min(this->top_right.y,u.top_right.y);
   352 	b._empty = this->_empty || u._empty ||
   353 	  b.bottom_left.x>top_right.x && b.bottom_left.y>top_right.y;
   354         return b;
   355       }
   356 
   357     };//class Boundingbox
   358 
   359 
   360   ///Map of x-coordinates of an xy<>-map
   361 
   362   ///\ingroup maps
   363   ///
   364   template<class M>
   365   class XMap 
   366   {
   367     M& _map;
   368   public:
   369 
   370     typedef typename M::Value::Value Value;
   371     typedef typename M::Key Key;
   372     ///\e
   373     XMap(M& map) : _map(map) {}
   374     Value operator[](Key k) const {return _map[k].x;}
   375     void set(Key k,Value v) {_map.set(k,typename M::Value(v,_map[k].y));}
   376   };
   377     
   378   ///Returns an \ref XMap class
   379 
   380   ///This function just returns an \ref XMap class.
   381   ///
   382   ///\ingroup maps
   383   ///\relates XMap
   384   template<class M> 
   385   inline XMap<M> xMap(M &m) 
   386   {
   387     return XMap<M>(m);
   388   }
   389 
   390   template<class M> 
   391   inline XMap<M> xMap(const M &m) 
   392   {
   393     return XMap<M>(m);
   394   }
   395 
   396   ///Constant (read only) version of \ref XMap
   397 
   398   ///\ingroup maps
   399   ///
   400   template<class M>
   401   class ConstXMap 
   402   {
   403     const M& _map;
   404   public:
   405 
   406     typedef typename M::Value::Value Value;
   407     typedef typename M::Key Key;
   408     ///\e
   409     ConstXMap(const M &map) : _map(map) {}
   410     Value operator[](Key k) const {return _map[k].x;}
   411   };
   412     
   413   ///Returns a \ref ConstXMap class
   414 
   415   ///This function just returns an \ref ConstXMap class.
   416   ///
   417   ///\ingroup maps
   418   ///\relates ConstXMap
   419   template<class M> 
   420   inline ConstXMap<M> xMap(const M &m) 
   421   {
   422     return ConstXMap<M>(m);
   423   }
   424 
   425   ///Map of y-coordinates of an xy<>-map
   426     
   427   ///\ingroup maps
   428   ///
   429   template<class M>
   430   class YMap 
   431   {
   432     M& _map;
   433   public:
   434 
   435     typedef typename M::Value::Value Value;
   436     typedef typename M::Key Key;
   437     ///\e
   438     YMap(M& map) : _map(map) {}
   439     Value operator[](Key k) const {return _map[k].y;}
   440     void set(Key k,Value v) {_map.set(k,typename M::Value(_map[k].x,v));}
   441   };
   442 
   443   ///Returns an \ref YMap class
   444 
   445   ///This function just returns an \ref YMap class.
   446   ///
   447   ///\ingroup maps
   448   ///\relates YMap
   449   template<class M> 
   450   inline YMap<M> yMap(M &m) 
   451   {
   452     return YMap<M>(m);
   453   }
   454 
   455   template<class M> 
   456   inline YMap<M> yMap(const M &m) 
   457   {
   458     return YMap<M>(m);
   459   }
   460 
   461   ///Constant (read only) version of \ref YMap
   462 
   463   ///\ingroup maps
   464   ///
   465   template<class M>
   466   class ConstYMap 
   467   {
   468     const M& _map;
   469   public:
   470 
   471     typedef typename M::Value::Value Value;
   472     typedef typename M::Key Key;
   473     ///\e
   474     ConstYMap(const M &map) : _map(map) {}
   475     Value operator[](Key k) const {return _map[k].y;}
   476   };
   477     
   478   ///Returns a \ref ConstYMap class
   479 
   480   ///This function just returns an \ref ConstYMap class.
   481   ///
   482   ///\ingroup maps
   483   ///\relates ConstYMap
   484   template<class M> 
   485   inline ConstYMap<M> yMap(const M &m) 
   486   {
   487     return ConstYMap<M>(m);
   488   }
   489 
   490 
   491   ///Map of the \ref xy::normSquare() "normSquare()" of an \ref xy "xy"-map
   492 
   493   ///Map of the \ref xy::normSquare() "normSquare()" of an \ref xy "xy"-map
   494   ///\ingroup maps
   495   ///
   496   template<class M>
   497   class NormSquareMap 
   498   {
   499     const M& _map;
   500   public:
   501 
   502     typedef typename M::Value::Value Value;
   503     typedef typename M::Key Key;
   504     ///\e
   505     NormSquareMap(const M &map) : _map(map) {}
   506     Value operator[](Key k) const {return _map[k].normSquare();}
   507   };
   508     
   509   ///Returns a \ref NormSquareMap class
   510 
   511   ///This function just returns an \ref NormSquareMap class.
   512   ///
   513   ///\ingroup maps
   514   ///\relates NormSquareMap
   515   template<class M> 
   516   inline NormSquareMap<M> normSquareMap(const M &m) 
   517   {
   518     return NormSquareMap<M>(m);
   519   }
   520 
   521   /// @}
   522 
   523 
   524 } //namespace lemon
   525 
   526 #endif //LEMON_XY_H