lemon/dim2.h
changeset 2575 e866e288cba6
parent 2553 bfced05fa852
equal deleted inserted replaced
6:aca570b2a406 7:1e12486dfca4
    50   /// @{
    50   /// @{
    51 
    51 
    52   /// A simple two dimensional vector (plainvector) implementation
    52   /// A simple two dimensional vector (plainvector) implementation
    53 
    53 
    54   /// A simple two dimensional vector (plainvector) implementation
    54   /// A simple two dimensional vector (plainvector) implementation
    55   ///with the usual vector
    55   /// with the usual vector operations.
    56   /// operators.
       
    57   ///
       
    58   template<typename T>
    56   template<typename T>
    59     class Point {
    57     class Point {
    60 
    58 
    61     public:
    59     public:
    62 
    60 
    63       typedef T Value;
    61       typedef T Value;
    64 
    62 
    65       ///First co-ordinate
    63       ///First coordinate
    66       T x;
    64       T x;
    67       ///Second co-ordinate
    65       ///Second coordinate
    68       T y;     
    66       T y;     
    69       
    67       
    70       ///Default constructor
    68       ///Default constructor
    71       Point() {}
    69       Point() {}
    72 
    70 
    73       ///Construct an instance from coordinates
    71       ///Construct an instance from coordinates
    74       Point(T a, T b) : x(a), y(b) { }
    72       Point(T a, T b) : x(a), y(b) { }
    75 
    73 
    76       ///The dimension of the vector.
    74       ///The dimension of the vector.
    77 
    75 
    78       ///This class give back always 2.
    76       ///This function always returns 2.
    79       ///
    77       ///
    80       int size() const { return 2; }
    78       int size() const { return 2; }
    81 
    79 
    82       ///Subscripting operator
    80       ///Subscripting operator
    83 
    81 
    97       ///Give back the square of the norm of the vector
    95       ///Give back the square of the norm of the vector
    98       T normSquare() const {
    96       T normSquare() const {
    99         return x*x+y*y;
    97         return x*x+y*y;
   100       }
    98       }
   101   
    99   
   102       ///Increment the left hand side by u
   100       ///Increment the left hand side by \c u
   103       Point<T>& operator +=(const Point<T>& u) {
   101       Point<T>& operator +=(const Point<T>& u) {
   104         x += u.x;
   102         x += u.x;
   105         y += u.y;
   103         y += u.y;
   106         return *this;
   104         return *this;
   107       }
   105       }
   108   
   106   
   109       ///Decrement the left hand side by u
   107       ///Decrement the left hand side by \c u
   110       Point<T>& operator -=(const Point<T>& u) {
   108       Point<T>& operator -=(const Point<T>& u) {
   111         x -= u.x;
   109         x -= u.x;
   112         y -= u.y;
   110         y -= u.y;
   113         return *this;
   111         return *this;
   114       }
   112       }
   136       Point<T> operator+(const Point<T> &u) const {
   134       Point<T> operator+(const Point<T> &u) const {
   137         Point<T> b=*this;
   135         Point<T> b=*this;
   138         return b+=u;
   136         return b+=u;
   139       }
   137       }
   140 
   138 
   141       ///Return the neg of the vectors
   139       ///Return the negative of the vector
   142       Point<T> operator-() const {
   140       Point<T> operator-() const {
   143         Point<T> b=*this;
   141         Point<T> b=*this;
   144         b.x=-b.x; b.y=-b.y;
   142         b.x=-b.x; b.y=-b.y;
   145         return b;
   143         return b;
   146       }
   144       }
   173         return  (x!=u.x) || (y!=u.y);
   171         return  (x!=u.x) || (y!=u.y);
   174       }
   172       }
   175 
   173 
   176     };
   174     };
   177 
   175 
   178   ///Return an Point 
   176   ///Return a Point 
   179 
   177 
   180   ///Return an Point
   178   ///Return a Point.
   181   ///\relates Point
   179   ///\relates Point
   182   template <typename T>
   180   template <typename T>
   183   inline Point<T> makePoint(const T& x, const T& y) {
   181   inline Point<T> makePoint(const T& x, const T& y) {
   184     return Point<T>(x, y);
   182     return Point<T>(x, y);
   185   }
   183   }
   284       ///Construct an instance from one point
   282       ///Construct an instance from one point
   285       BoundingBox(Point<T> a) { bottom_left=top_right=a; _empty = false; }
   283       BoundingBox(Point<T> a) { bottom_left=top_right=a; _empty = false; }
   286       
   284       
   287       ///Construct an instance from two points
   285       ///Construct an instance from two points
   288       
   286       
   289       ///Construct an instance from two points
   287       ///Construct an instance from two points.
   290       ///\warning The coordinates of the bottom-left corner must be no more
   288       ///\param a The bottom left corner.
   291       ///than those of the top-right one
   289       ///\param b The top right corner.
       
   290       ///\warning The coordinates of the bottom left corner must be no more
       
   291       ///than those of the top right one.
   292       BoundingBox(Point<T> a,Point<T> b)
   292       BoundingBox(Point<T> a,Point<T> b)
   293       {
   293       {
   294 	bottom_left=a;
   294 	bottom_left=a;
   295 	top_right=b;
   295 	top_right=b;
   296 	_empty = false;
   296 	_empty = false;
   297       }
   297       }
   298       
   298       
   299       ///Construct an instance from four numbers
   299       ///Construct an instance from four numbers
   300 
   300 
   301       ///Construct an instance from four numbers
   301       ///Construct an instance from four numbers.
   302       ///\warning The coordinates of the bottom-left corner must be no more
   302       ///\param l The left side of the box.
   303       ///than those of the top-right one
   303       ///\param b The bottom of the box.
       
   304       ///\param r The right side of the box.
       
   305       ///\param t The top of the box.
       
   306       ///\warning The left side must be no more than the right side and
       
   307       ///bottom must be no more than the top. 
   304       BoundingBox(T l,T b,T r,T t)
   308       BoundingBox(T l,T b,T r,T t)
   305       {
   309       {
   306 	bottom_left=Point<T>(l,b);
   310 	bottom_left=Point<T>(l,b);
   307 	top_right=Point<T>(r,t);
   311 	top_right=Point<T>(r,t);
   308 	_empty = false;
   312 	_empty = false;
   309       }
   313       }
   310       
   314       
   311       ///Were any points added?
   315       ///Return \c true if the bounding box is empty.
       
   316       
       
   317       ///Return \c true if the bounding box is empty (i.e. return \c false
       
   318       ///if at least one point was added to the box or the coordinates of
       
   319       ///the box were set).
       
   320       ///
       
   321       ///The coordinates of an empty bounding box are not defined. 
   312       bool empty() const {
   322       bool empty() const {
   313         return _empty;
   323         return _empty;
   314       }
   324       }
   315       
   325       
   316       ///Make the BoundingBox empty
   326       ///Make the BoundingBox empty
   317       void clear() {
   327       void clear() {
   318         _empty=1;
   328         _empty=1;
   319       }
   329       }
   320 
   330 
   321       ///Give back the bottom left corner
   331       ///Give back the bottom left corner of the box
   322 
   332 
   323       ///Give back the bottom left corner.
   333       ///Give back the bottom left corner of the box.
   324       ///If the bounding box is empty, then the return value is not defined.
   334       ///If the bounding box is empty, then the return value is not defined.
   325       Point<T> bottomLeft() const {
   335       Point<T> bottomLeft() const {
   326         return bottom_left;
   336         return bottom_left;
   327       }
   337       }
   328 
   338 
   329       ///Set the bottom left corner
   339       ///Set the bottom left corner of the box
   330 
   340 
   331       ///Set the bottom left corner.
   341       ///Set the bottom left corner of the box.
   332       ///It should only bee used for non-empty box.
   342       ///It should only be used for non-empty box.
   333       void bottomLeft(Point<T> p) {
   343       void bottomLeft(Point<T> p) {
   334 	bottom_left = p;
   344 	bottom_left = p;
   335       }
   345       }
   336 
   346 
   337       ///Give back the top right corner
   347       ///Give back the top right corner of the box
   338 
   348 
   339       ///Give back the top right corner.
   349       ///Give back the top right corner of the box.
   340       ///If the bounding box is empty, then the return value is not defined.
   350       ///If the bounding box is empty, then the return value is not defined.
   341       Point<T> topRight() const {
   351       Point<T> topRight() const {
   342         return top_right;
   352         return top_right;
   343       }
   353       }
   344 
   354 
   345       ///Set the top right corner
   355       ///Set the top right corner of the box
   346 
   356 
   347       ///Set the top right corner.
   357       ///Set the top right corner of the box.
   348       ///It should only bee used for non-empty box.
   358       ///It should only be used for non-empty box.
   349       void topRight(Point<T> p) {
   359       void topRight(Point<T> p) {
   350 	top_right = p;
   360 	top_right = p;
   351       }
   361       }
   352 
   362 
   353       ///Give back the bottom right corner
   363       ///Give back the bottom right corner of the box
   354 
   364 
   355       ///Give back the bottom right corner.
   365       ///Give back the bottom right corner of the box.
   356       ///If the bounding box is empty, then the return value is not defined.
   366       ///If the bounding box is empty, then the return value is not defined.
   357       Point<T> bottomRight() const {
   367       Point<T> bottomRight() const {
   358         return Point<T>(top_right.x,bottom_left.y);
   368         return Point<T>(top_right.x,bottom_left.y);
   359       }
   369       }
   360 
   370 
   361       ///Set the bottom right corner
   371       ///Set the bottom right corner of the box
   362 
   372 
   363       ///Set the bottom right corner.
   373       ///Set the bottom right corner of the box.
   364       ///It should only bee used for non-empty box.
   374       ///It should only be used for non-empty box.
   365       void bottomRight(Point<T> p) {
   375       void bottomRight(Point<T> p) {
   366 	top_right.x = p.x;
   376 	top_right.x = p.x;
   367 	bottom_left.y = p.y;
   377 	bottom_left.y = p.y;
   368       }
   378       }
   369  
   379  
   370       ///Give back the top left corner
   380       ///Give back the top left corner of the box
   371 
   381 
   372       ///Give back the top left corner.
   382       ///Give back the top left corner of the box.
   373       ///If the bounding box is empty, then the return value is not defined.
   383       ///If the bounding box is empty, then the return value is not defined.
   374       Point<T> topLeft() const {
   384       Point<T> topLeft() const {
   375         return Point<T>(bottom_left.x,top_right.y);
   385         return Point<T>(bottom_left.x,top_right.y);
   376       }
   386       }
   377 
   387 
   378       ///Set the top left corner
   388       ///Set the top left corner of the box
   379 
   389 
   380       ///Set the top left corner.
   390       ///Set the top left corner of the box.
   381       ///It should only bee used for non-empty box.
   391       ///It should only be used for non-empty box.
   382       void topLeft(Point<T> p) {
   392       void topLeft(Point<T> p) {
   383 	top_right.y = p.y;
   393 	top_right.y = p.y;
   384 	bottom_left.x = p.x;
   394 	bottom_left.x = p.x;
   385       }
   395       }
   386 
   396 
   393       }
   403       }
   394 
   404 
   395       ///Set the bottom of the box
   405       ///Set the bottom of the box
   396 
   406 
   397       ///Set the bottom of the box.
   407       ///Set the bottom of the box.
   398       ///It should only bee used for non-empty box.
   408       ///It should only be used for non-empty box.
   399       void bottom(T t) {
   409       void bottom(T t) {
   400 	bottom_left.y = t;
   410 	bottom_left.y = t;
   401       }
   411       }
   402 
   412 
   403       ///Give back the top of the box
   413       ///Give back the top of the box
   409       }
   419       }
   410 
   420 
   411       ///Set the top of the box
   421       ///Set the top of the box
   412 
   422 
   413       ///Set the top of the box.
   423       ///Set the top of the box.
   414       ///It should only bee used for non-empty box.
   424       ///It should only be used for non-empty box.
   415       void top(T t) {
   425       void top(T t) {
   416 	top_right.y = t;
   426 	top_right.y = t;
   417       }
   427       }
   418 
   428 
   419       ///Give back the left side of the box
   429       ///Give back the left side of the box
   425       }
   435       }
   426  
   436  
   427       ///Set the left side of the box
   437       ///Set the left side of the box
   428 
   438 
   429       ///Set the left side of the box.
   439       ///Set the left side of the box.
   430       ///It should only bee used for non-empty box
   440       ///It should only be used for non-empty box.
   431       void left(T t) {
   441       void left(T t) {
   432 	bottom_left.x = t;
   442 	bottom_left.x = t;
   433       }
   443       }
   434 
   444 
   435       /// Give back the right side of the box
   445       /// Give back the right side of the box
   441       }
   451       }
   442 
   452 
   443       ///Set the right side of the box
   453       ///Set the right side of the box
   444 
   454 
   445       ///Set the right side of the box.
   455       ///Set the right side of the box.
   446       ///It should only bee used for non-empty box
   456       ///It should only be used for non-empty box.
   447       void right(T t) {
   457       void right(T t) {
   448 	top_right.x = t;
   458 	top_right.x = t;
   449       }
   459       }
   450 
   460 
   451       ///Give back the height of the box
   461       ///Give back the height of the box
   463       T width() const {
   473       T width() const {
   464         return top_right.x-bottom_left.x;
   474         return top_right.x-bottom_left.x;
   465       }
   475       }
   466 
   476 
   467       ///Checks whether a point is inside a bounding box
   477       ///Checks whether a point is inside a bounding box
   468       bool inside(const Point<T>& u){
   478       bool inside(const Point<T>& u) const {
   469         if (_empty)
   479         if (_empty)
   470           return false;
   480           return false;
   471         else{
   481         else{
   472           return ((u.x-bottom_left.x)*(top_right.x-u.x) >= 0 &&
   482           return ((u.x-bottom_left.x)*(top_right.x-u.x) >= 0 &&
   473               (u.y-bottom_left.y)*(top_right.y-u.y) >= 0 );
   483               (u.y-bottom_left.y)*(top_right.y-u.y) >= 0 );
   474         }
   484         }
   475       }
   485       }
   476   
   486   
   477       ///Increments a bounding box with a point
   487       ///Increments a bounding box with a point
       
   488 
       
   489       ///Increments a bounding box with a point.
       
   490       ///
   478       BoundingBox& add(const Point<T>& u){
   491       BoundingBox& add(const Point<T>& u){
   479         if (_empty){
   492         if (_empty){
   480           bottom_left=top_right=u;
   493           bottom_left=top_right=u;
   481           _empty = false;
   494           _empty = false;
   482         }
   495         }
   487           if (top_right.y < u.y) top_right.y = u.y;
   500           if (top_right.y < u.y) top_right.y = u.y;
   488         }
   501         }
   489         return *this;
   502         return *this;
   490       }
   503       }
   491     
   504     
   492       ///Increments a bounding to contain another bounding box
   505       ///Increments a bounding box to contain another bounding box
       
   506       
       
   507       ///Increments a bounding box to contain another bounding box.
       
   508       ///
   493       BoundingBox& add(const BoundingBox &u){
   509       BoundingBox& add(const BoundingBox &u){
   494         if ( !u.empty() ){
   510         if ( !u.empty() ){
   495           this->add(u.bottomLeft());
   511           this->add(u.bottomLeft());
   496 	  this->add(u.topRight());
   512 	  this->add(u.topRight());
   497         }
   513         }
   498         return *this;
   514         return *this;
   499       }
   515       }
   500   
   516   
   501       ///Intersection of two bounding boxes
   517       ///Intersection of two bounding boxes
   502       BoundingBox operator &(const BoundingBox& u){
   518 
       
   519       ///Intersection of two bounding boxes.
       
   520       ///
       
   521       BoundingBox operator&(const BoundingBox& u) const {
   503         BoundingBox b;
   522         BoundingBox b;
   504 	b.bottom_left.x=std::max(this->bottom_left.x,u.bottom_left.x);
   523         if (this->_empty || u._empty) {
   505 	b.bottom_left.y=std::max(this->bottom_left.y,u.bottom_left.y);
   524 	  b._empty = true;
   506 	b.top_right.x=std::min(this->top_right.x,u.top_right.x);
   525 	} else {
   507 	b.top_right.y=std::min(this->top_right.y,u.top_right.y);
   526 	  b.bottom_left.x=std::max(this->bottom_left.x,u.bottom_left.x);
   508 	b._empty = this->_empty || u._empty ||
   527 	  b.bottom_left.y=std::max(this->bottom_left.y,u.bottom_left.y);
   509 	  b.bottom_left.x>top_right.x && b.bottom_left.y>top_right.y;
   528 	  b.top_right.x=std::min(this->top_right.x,u.top_right.x);
       
   529 	  b.top_right.y=std::min(this->top_right.y,u.top_right.y);
       
   530 	  b._empty = b.bottom_left.x > b.top_right.x ||
       
   531 	             b.bottom_left.y > b.top_right.y;
       
   532 	} 
   510         return b;
   533         return b;
   511       }
   534       }
   512 
   535 
   513     };//class Boundingbox
   536     };//class Boundingbox
   514 
   537 
   515 
   538 
   516   ///Map of x-coordinates of a dim2::Point<>-map
   539   ///Map of x-coordinates of a \ref Point "Point"-map
   517 
   540 
   518   ///\ingroup maps
   541   ///\ingroup maps
   519   ///Map of x-coordinates of a dim2::Point<>-map
   542   ///Map of x-coordinates of a \ref Point "Point"-map.
   520   ///
   543   ///
   521   template<class M>
   544   template<class M>
   522   class XMap 
   545   class XMap 
   523   {
   546   {
   524     M& _map;
   547     M& _map;
   568     Value operator[](Key k) const {return _map[k].x;}
   591     Value operator[](Key k) const {return _map[k].x;}
   569   };
   592   };
   570     
   593     
   571   ///Returns a \ref ConstXMap class
   594   ///Returns a \ref ConstXMap class
   572 
   595 
   573   ///This function just returns an \ref ConstXMap class.
   596   ///This function just returns a \ref ConstXMap class.
   574   ///
   597   ///
   575   ///\ingroup maps
   598   ///\ingroup maps
   576   ///\relates ConstXMap
   599   ///\relates ConstXMap
   577   template<class M> 
   600   template<class M> 
   578   inline ConstXMap<M> xMap(const M &m) 
   601   inline ConstXMap<M> xMap(const M &m) 
   579   {
   602   {
   580     return ConstXMap<M>(m);
   603     return ConstXMap<M>(m);
   581   }
   604   }
   582 
   605 
   583   ///Map of y-coordinates of a dim2::Point<>-map
   606   ///Map of y-coordinates of a \ref Point "Point"-map
   584     
   607     
   585   ///\ingroup maps
   608   ///\ingroup maps
   586   ///Map of y-coordinates of a dim2::Point<>-map
   609   ///Map of y-coordinates of a \ref Point "Point"-map.
   587   ///
   610   ///
   588   template<class M>
   611   template<class M>
   589   class YMap 
   612   class YMap 
   590   {
   613   {
   591     M& _map;
   614     M& _map;
   597     YMap(M& map) : _map(map) {}
   620     YMap(M& map) : _map(map) {}
   598     Value operator[](Key k) const {return _map[k].y;}
   621     Value operator[](Key k) const {return _map[k].y;}
   599     void set(Key k,Value v) {_map.set(k,typename M::Value(_map[k].x,v));}
   622     void set(Key k,Value v) {_map.set(k,typename M::Value(_map[k].x,v));}
   600   };
   623   };
   601 
   624 
   602   ///Returns an \ref YMap class
   625   ///Returns a \ref YMap class
   603 
   626 
   604   ///This function just returns an \ref YMap class.
   627   ///This function just returns a \ref YMap class.
   605   ///
   628   ///
   606   ///\ingroup maps
   629   ///\ingroup maps
   607   ///\relates YMap
   630   ///\relates YMap
   608   template<class M> 
   631   template<class M> 
   609   inline YMap<M> yMap(M &m) 
   632   inline YMap<M> yMap(M &m) 
   635     Value operator[](Key k) const {return _map[k].y;}
   658     Value operator[](Key k) const {return _map[k].y;}
   636   };
   659   };
   637     
   660     
   638   ///Returns a \ref ConstYMap class
   661   ///Returns a \ref ConstYMap class
   639 
   662 
   640   ///This function just returns an \ref ConstYMap class.
   663   ///This function just returns a \ref ConstYMap class.
   641   ///
   664   ///
   642   ///\ingroup maps
   665   ///\ingroup maps
   643   ///\relates ConstYMap
   666   ///\relates ConstYMap
   644   template<class M> 
   667   template<class M> 
   645   inline ConstYMap<M> yMap(const M &m) 
   668   inline ConstYMap<M> yMap(const M &m) 
   646   {
   669   {
   647     return ConstYMap<M>(m);
   670     return ConstYMap<M>(m);
   648   }
   671   }
   649 
   672 
   650 
   673 
   651     ///\brief Map of the \ref Point::normSquare() "normSquare()"
   674   ///\brief Map of the \ref Point::normSquare() "normSquare()"
   652     ///of an \ref Point "Point"-map
   675   ///of a \ref Point "Point"-map
   653     ///
   676   ///
   654     ///Map of the \ref Point::normSquare() "normSquare()"
   677   ///Map of the \ref Point::normSquare() "normSquare()"
   655     ///of an \ref Point "Point"-map
   678   ///of a \ref Point "Point"-map.
   656     ///\ingroup maps
   679   ///\ingroup maps
   657     ///
   680     ///
   658   template<class M>
   681   template<class M>
   659   class NormSquareMap 
   682   class NormSquareMap 
   660   {
   683   {
   661     const M& _map;
   684     const M& _map;
   668     Value operator[](Key k) const {return _map[k].normSquare();}
   691     Value operator[](Key k) const {return _map[k].normSquare();}
   669   };
   692   };
   670     
   693     
   671   ///Returns a \ref NormSquareMap class
   694   ///Returns a \ref NormSquareMap class
   672 
   695 
   673   ///This function just returns an \ref NormSquareMap class.
   696   ///This function just returns a \ref NormSquareMap class.
   674   ///
   697   ///
   675   ///\ingroup maps
   698   ///\ingroup maps
   676   ///\relates NormSquareMap
   699   ///\relates NormSquareMap
   677   template<class M> 
   700   template<class M> 
   678   inline NormSquareMap<M> normSquareMap(const M &m) 
   701   inline NormSquareMap<M> normSquareMap(const M &m)