lemon/dim2.h
author Alpar Juttner <alpar@cs.elte.hu>
Thu, 25 Feb 2021 09:46:12 +0100
changeset 1209 4a170261cc54
parent 714 98a30824fe36
child 1210 da87dbdf3daf
permissions -rw-r--r--
Merge #638
     1 /* -*- mode: C++; indent-tabs-mode: nil; -*-
     2  *
     3  * This file is a part of LEMON, a generic C++ optimization library.
     4  *
     5  * Copyright (C) 2003-2009
     6  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     7  * (Egervary Research Group on Combinatorial Optimization, EGRES).
     8  *
     9  * Permission to use, modify and distribute this software is granted
    10  * provided that this copyright notice appears in all copies. For
    11  * precise terms see the accompanying LICENSE file.
    12  *
    13  * This software is provided "AS IS" with no warranty of any kind,
    14  * express or implied, and with no claim as to its suitability for any
    15  * purpose.
    16  *
    17  */
    18 
    19 #ifndef LEMON_DIM2_H
    20 #define LEMON_DIM2_H
    21 
    22 #include <iostream>
    23 #include <algorithm>
    24 
    25 ///\ingroup geomdat
    26 ///\file
    27 ///\brief A simple two dimensional vector and a bounding box implementation
    28 
    29 namespace lemon {
    30 
    31   ///Tools for handling two dimensional coordinates
    32 
    33   ///This namespace is a storage of several
    34   ///tools for handling two dimensional coordinates
    35   namespace dim2 {
    36 
    37   /// \addtogroup geomdat
    38   /// @{
    39 
    40   /// Two dimensional vector (plain vector)
    41 
    42   /// A simple two dimensional vector (plain vector) implementation
    43   /// with the usual vector operations.
    44   template<typename T>
    45     class Point {
    46 
    47     public:
    48 
    49       typedef T Value;
    50 
    51       ///First coordinate
    52       T x;
    53       ///Second coordinate
    54       T y;
    55 
    56       ///Default constructor
    57       Point() {}
    58 
    59       ///Construct an instance from coordinates
    60       Point(T a, T b) : x(a), y(b) { }
    61 
    62       ///Returns the dimension of the vector (i.e. returns 2).
    63 
    64       ///The dimension of the vector.
    65       ///This function always returns 2.
    66       int size() const { return 2; }
    67 
    68       ///Subscripting operator
    69 
    70       ///\c p[0] is \c p.x and \c p[1] is \c p.y
    71       ///
    72       T& operator[](int idx) { return idx == 0 ? x : y; }
    73 
    74       ///Const subscripting operator
    75 
    76       ///\c p[0] is \c p.x and \c p[1] is \c p.y
    77       ///
    78       const T& operator[](int idx) const { return idx == 0 ? x : y; }
    79 
    80       ///Conversion constructor
    81       template<class TT> Point(const Point<TT> &p) : x(p.x), y(p.y) {}
    82 
    83       ///Give back the square of the norm of the vector
    84       T normSquare() const {
    85         return x*x+y*y;
    86       }
    87 
    88       ///Increment the left hand side by \c u
    89       Point<T>& operator +=(const Point<T>& u) {
    90         x += u.x;
    91         y += u.y;
    92         return *this;
    93       }
    94 
    95       ///Decrement the left hand side by \c u
    96       Point<T>& operator -=(const Point<T>& u) {
    97         x -= u.x;
    98         y -= u.y;
    99         return *this;
   100       }
   101 
   102       ///Multiply the left hand side with a scalar
   103       Point<T>& operator *=(const T &u) {
   104         x *= u;
   105         y *= u;
   106         return *this;
   107       }
   108 
   109       ///Divide the left hand side by a scalar
   110       Point<T>& operator /=(const T &u) {
   111         x /= u;
   112         y /= u;
   113         return *this;
   114       }
   115 
   116       ///Return the scalar product of two vectors
   117       T operator *(const Point<T>& u) const {
   118         return x*u.x+y*u.y;
   119       }
   120 
   121       ///Return the sum of two vectors
   122       Point<T> operator+(const Point<T> &u) const {
   123         Point<T> b=*this;
   124         return b+=u;
   125       }
   126 
   127       ///Return the negative of the vector
   128       Point<T> operator-() const {
   129         Point<T> b=*this;
   130         b.x=-b.x; b.y=-b.y;
   131         return b;
   132       }
   133 
   134       ///Return the difference of two vectors
   135       Point<T> operator-(const Point<T> &u) const {
   136         Point<T> b=*this;
   137         return b-=u;
   138       }
   139 
   140       ///Return a vector multiplied by a scalar
   141       Point<T> operator*(const T &u) const {
   142         Point<T> b=*this;
   143         return b*=u;
   144       }
   145 
   146       ///Return a vector divided by a scalar
   147       Point<T> operator/(const T &u) const {
   148         Point<T> b=*this;
   149         return b/=u;
   150       }
   151 
   152       ///Test equality
   153       bool operator==(const Point<T> &u) const {
   154         return (x==u.x) && (y==u.y);
   155       }
   156 
   157       ///Test inequality
   158       bool operator!=(Point u) const {
   159         return  (x!=u.x) || (y!=u.y);
   160       }
   161 
   162     };
   163 
   164   ///Return a Point
   165 
   166   ///Return a Point.
   167   ///\relates Point
   168   template <typename T>
   169   inline Point<T> makePoint(const T& x, const T& y) {
   170     return Point<T>(x, y);
   171   }
   172 
   173   ///Return a vector multiplied by a scalar
   174 
   175   ///Return a vector multiplied by a scalar.
   176   ///\relates Point
   177   template<typename T> Point<T> operator*(const T &u,const Point<T> &x) {
   178     return x*u;
   179   }
   180 
   181   ///Read a plain vector from a stream
   182 
   183   ///Read a plain vector from a stream.
   184   ///\relates Point
   185   ///
   186   template<typename T>
   187   inline std::istream& operator>>(std::istream &is, Point<T> &z) {
   188     char c;
   189     if (is >> c) {
   190       if (c != '(') is.putback(c);
   191     } else {
   192       is.clear();
   193     }
   194     if (!(is >> z.x)) return is;
   195     if (is >> c) {
   196       if (c != ',') is.putback(c);
   197     } else {
   198       is.clear();
   199     }
   200     if (!(is >> z.y)) return is;
   201     if (is >> c) {
   202       if (c != ')') is.putback(c);
   203     } else {
   204       is.clear();
   205     }
   206     return is;
   207   }
   208 
   209   ///Write a plain vector to a stream
   210 
   211   ///Write a plain vector to a stream.
   212   ///\relates Point
   213   ///
   214   template<typename T>
   215   inline std::ostream& operator<<(std::ostream &os, const Point<T>& z)
   216   {
   217     os << "(" << z.x << "," << z.y << ")";
   218     return os;
   219   }
   220 
   221   ///Rotate by 90 degrees
   222 
   223   ///Returns the parameter rotated by 90 degrees in positive direction.
   224   ///\relates Point
   225   ///
   226   template<typename T>
   227   inline Point<T> rot90(const Point<T> &z)
   228   {
   229     return Point<T>(-z.y,z.x);
   230   }
   231 
   232   ///Rotate by 180 degrees
   233 
   234   ///Returns the parameter rotated by 180 degrees.
   235   ///\relates Point
   236   ///
   237   template<typename T>
   238   inline Point<T> rot180(const Point<T> &z)
   239   {
   240     return Point<T>(-z.x,-z.y);
   241   }
   242 
   243   ///Rotate by 270 degrees
   244 
   245   ///Returns the parameter rotated by 90 degrees in negative direction.
   246   ///\relates Point
   247   ///
   248   template<typename T>
   249   inline Point<T> rot270(const Point<T> &z)
   250   {
   251     return Point<T>(z.y,-z.x);
   252   }
   253 
   254 
   255 
   256   /// Bounding box of plain vectors (points).
   257 
   258   /// A class to calculate or store the bounding box of plain vectors
   259   /// (\ref Point "points").
   260   template<typename T>
   261   class Box {
   262       Point<T> _bottom_left, _top_right;
   263       bool _empty;
   264     public:
   265 
   266       ///Default constructor: creates an empty box
   267       Box() { _empty = true; }
   268 
   269       ///Construct a box from one point
   270       Box(Point<T> a) {
   271         _bottom_left = _top_right = a;
   272         _empty = false;
   273       }
   274 
   275       ///Construct a box from two points
   276 
   277       ///Construct a box from two points.
   278       ///\param a The bottom left corner.
   279       ///\param b The top right corner.
   280       ///\warning The coordinates of the bottom left corner must be no more
   281       ///than those of the top right one.
   282       Box(Point<T> a,Point<T> b)
   283       {
   284         _bottom_left = a;
   285         _top_right = b;
   286         _empty = false;
   287       }
   288 
   289       ///Construct a box from four numbers
   290 
   291       ///Construct a box from four numbers.
   292       ///\param l The left side of the box.
   293       ///\param b The bottom of the box.
   294       ///\param r The right side of the box.
   295       ///\param t The top of the box.
   296       ///\warning The left side must be no more than the right side and
   297       ///bottom must be no more than the top.
   298       Box(T l,T b,T r,T t)
   299       {
   300         _bottom_left=Point<T>(l,b);
   301         _top_right=Point<T>(r,t);
   302         _empty = false;
   303       }
   304 
   305       ///Return \c true if the box is empty.
   306 
   307       ///Return \c true if the box is empty (i.e. return \c false
   308       ///if at least one point was added to the box or the coordinates of
   309       ///the box were set).
   310       ///
   311       ///The coordinates of an empty box are not defined.
   312       bool empty() const {
   313         return _empty;
   314       }
   315 
   316       ///Make the box empty
   317       void clear() {
   318         _empty = true;
   319       }
   320 
   321       ///Give back the bottom left corner of the box
   322 
   323       ///Give back the bottom left corner of the box.
   324       ///If the box is empty, then the return value is not defined.
   325       Point<T> bottomLeft() const {
   326         return _bottom_left;
   327       }
   328 
   329       ///Set the bottom left corner of the box
   330 
   331       ///Set the bottom left corner of the box.
   332       ///\pre The box must not be empty.
   333       void bottomLeft(Point<T> p) {
   334         _bottom_left = p;
   335       }
   336 
   337       ///Give back the top right corner of the box
   338 
   339       ///Give back the top right corner of the box.
   340       ///If the box is empty, then the return value is not defined.
   341       Point<T> topRight() const {
   342         return _top_right;
   343       }
   344 
   345       ///Set the top right corner of the box
   346 
   347       ///Set the top right corner of the box.
   348       ///\pre The box must not be empty.
   349       void topRight(Point<T> p) {
   350         _top_right = p;
   351       }
   352 
   353       ///Give back the bottom right corner of the box
   354 
   355       ///Give back the bottom right corner of the box.
   356       ///If the box is empty, then the return value is not defined.
   357       Point<T> bottomRight() const {
   358         return Point<T>(_top_right.x,_bottom_left.y);
   359       }
   360 
   361       ///Set the bottom right corner of the box
   362 
   363       ///Set the bottom right corner of the box.
   364       ///\pre The box must not be empty.
   365       void bottomRight(Point<T> p) {
   366         _top_right.x = p.x;
   367         _bottom_left.y = p.y;
   368       }
   369 
   370       ///Give back the top left corner of the box
   371 
   372       ///Give back the top left corner of the box.
   373       ///If the box is empty, then the return value is not defined.
   374       Point<T> topLeft() const {
   375         return Point<T>(_bottom_left.x,_top_right.y);
   376       }
   377 
   378       ///Set the top left corner of the box
   379 
   380       ///Set the top left corner of the box.
   381       ///\pre The box must not be empty.
   382       void topLeft(Point<T> p) {
   383         _top_right.y = p.y;
   384         _bottom_left.x = p.x;
   385       }
   386 
   387       ///Give back the bottom of the box
   388 
   389       ///Give back the bottom of the box.
   390       ///If the box is empty, then the return value is not defined.
   391       T bottom() const {
   392         return _bottom_left.y;
   393       }
   394 
   395       ///Set the bottom of the box
   396 
   397       ///Set the bottom of the box.
   398       ///\pre The box must not be empty.
   399       void bottom(T t) {
   400         _bottom_left.y = t;
   401       }
   402 
   403       ///Give back the top of the box
   404 
   405       ///Give back the top of the box.
   406       ///If the box is empty, then the return value is not defined.
   407       T top() const {
   408         return _top_right.y;
   409       }
   410 
   411       ///Set the top of the box
   412 
   413       ///Set the top of the box.
   414       ///\pre The box must not be empty.
   415       void top(T t) {
   416         _top_right.y = t;
   417       }
   418 
   419       ///Give back the left side of the box
   420 
   421       ///Give back the left side of the box.
   422       ///If the box is empty, then the return value is not defined.
   423       T left() const {
   424         return _bottom_left.x;
   425       }
   426 
   427       ///Set the left side of the box
   428 
   429       ///Set the left side of the box.
   430       ///\pre The box must not be empty.
   431       void left(T t) {
   432         _bottom_left.x = t;
   433       }
   434 
   435       /// Give back the right side of the box
   436 
   437       /// Give back the right side of the box.
   438       ///If the box is empty, then the return value is not defined.
   439       T right() const {
   440         return _top_right.x;
   441       }
   442 
   443       ///Set the right side of the box
   444 
   445       ///Set the right side of the box.
   446       ///\pre The box must not be empty.
   447       void right(T t) {
   448         _top_right.x = t;
   449       }
   450 
   451       ///Give back the height of the box
   452 
   453       ///Give back the height of the box.
   454       ///If the box is empty, then the return value is not defined.
   455       T height() const {
   456         return _top_right.y-_bottom_left.y;
   457       }
   458 
   459       ///Give back the width of the box
   460 
   461       ///Give back the width of the box.
   462       ///If the box is empty, then the return value is not defined.
   463       T width() const {
   464         return _top_right.x-_bottom_left.x;
   465       }
   466 
   467       ///Checks whether a point is inside the box
   468       bool inside(const Point<T>& u) const {
   469         if (_empty)
   470           return false;
   471         else {
   472           return ( (u.x-_bottom_left.x)*(_top_right.x-u.x) >= 0 &&
   473                    (u.y-_bottom_left.y)*(_top_right.y-u.y) >= 0 );
   474         }
   475       }
   476 
   477       ///Increments the box with a point
   478 
   479       ///Increments the box with a point.
   480       ///
   481       Box& add(const Point<T>& u){
   482         if (_empty) {
   483           _bottom_left = _top_right = u;
   484           _empty = false;
   485         }
   486         else {
   487           if (_bottom_left.x > u.x) _bottom_left.x = u.x;
   488           if (_bottom_left.y > u.y) _bottom_left.y = u.y;
   489           if (_top_right.x < u.x) _top_right.x = u.x;
   490           if (_top_right.y < u.y) _top_right.y = u.y;
   491         }
   492         return *this;
   493       }
   494 
   495       ///Increments the box to contain another box
   496 
   497       ///Increments the box to contain another box.
   498       ///
   499       Box& add(const Box &u){
   500         if ( !u.empty() ){
   501           add(u._bottom_left);
   502           add(u._top_right);
   503         }
   504         return *this;
   505       }
   506 
   507       ///Intersection of two boxes
   508 
   509       ///Intersection of two boxes.
   510       ///
   511       Box operator&(const Box& u) const {
   512         Box b;
   513         if (_empty || u._empty) {
   514           b._empty = true;
   515         } else {
   516           b._bottom_left.x = std::max(_bottom_left.x, u._bottom_left.x);
   517           b._bottom_left.y = std::max(_bottom_left.y, u._bottom_left.y);
   518           b._top_right.x = std::min(_top_right.x, u._top_right.x);
   519           b._top_right.y = std::min(_top_right.y, u._top_right.y);
   520           b._empty = b._bottom_left.x > b._top_right.x ||
   521                      b._bottom_left.y > b._top_right.y;
   522         }
   523         return b;
   524       }
   525 
   526   };//class Box
   527 
   528 
   529   ///Read a box from a stream
   530 
   531   ///Read a box from a stream.
   532   ///\relates Box
   533   template<typename T>
   534   inline std::istream& operator>>(std::istream &is, Box<T>& b) {
   535     char c;
   536     Point<T> p;
   537     if (is >> c) {
   538       if (c != '(') is.putback(c);
   539     } else {
   540       is.clear();
   541     }
   542     if (!(is >> p)) return is;
   543     b.bottomLeft(p);
   544     if (is >> c) {
   545       if (c != ',') is.putback(c);
   546     } else {
   547       is.clear();
   548     }
   549     if (!(is >> p)) return is;
   550     b.topRight(p);
   551     if (is >> c) {
   552       if (c != ')') is.putback(c);
   553     } else {
   554       is.clear();
   555     }
   556     return is;
   557   }
   558 
   559   ///Write a box to a stream
   560 
   561   ///Write a box to a stream.
   562   ///\relates Box
   563   template<typename T>
   564   inline std::ostream& operator<<(std::ostream &os, const Box<T>& b)
   565   {
   566     os << "(" << b.bottomLeft() << "," << b.topRight() << ")";
   567     return os;
   568   }
   569 
   570   ///Map of x-coordinates of a <tt>Point</tt>-map
   571 
   572   ///Map of x-coordinates of a \ref Point "Point"-map.
   573   ///
   574   template<class M>
   575   class XMap
   576   {
   577     M& _map;
   578   public:
   579 
   580     typedef typename M::Value::Value Value;
   581     typedef typename M::Key Key;
   582     ///\e
   583     XMap(M& map) : _map(map) {}
   584     Value operator[](Key k) const {return _map[k].x;}
   585     void set(Key k,Value v) {_map.set(k,typename M::Value(v,_map[k].y));}
   586   };
   587 
   588   ///Returns an XMap class
   589 
   590   ///This function just returns an XMap class.
   591   ///\relates XMap
   592   template<class M>
   593   inline XMap<M> xMap(M &m)
   594   {
   595     return XMap<M>(m);
   596   }
   597 
   598   template<class M>
   599   inline XMap<M> xMap(const M &m)
   600   {
   601     return XMap<M>(m);
   602   }
   603 
   604   ///Constant (read only) version of XMap
   605 
   606   ///Constant (read only) version of XMap.
   607   ///
   608   template<class M>
   609   class ConstXMap
   610   {
   611     const M& _map;
   612   public:
   613 
   614     typedef typename M::Value::Value Value;
   615     typedef typename M::Key Key;
   616     ///\e
   617     ConstXMap(const M &map) : _map(map) {}
   618     Value operator[](Key k) const {return _map[k].x;}
   619   };
   620 
   621   ///Returns a ConstXMap class
   622 
   623   ///This function just returns a ConstXMap class.
   624   ///\relates ConstXMap
   625   template<class M>
   626   inline ConstXMap<M> xMap(const M &m)
   627   {
   628     return ConstXMap<M>(m);
   629   }
   630 
   631   ///Map of y-coordinates of a <tt>Point</tt>-map
   632 
   633   ///Map of y-coordinates of a \ref Point "Point"-map.
   634   ///
   635   template<class M>
   636   class YMap
   637   {
   638     M& _map;
   639   public:
   640 
   641     typedef typename M::Value::Value Value;
   642     typedef typename M::Key Key;
   643     ///\e
   644     YMap(M& map) : _map(map) {}
   645     Value operator[](Key k) const {return _map[k].y;}
   646     void set(Key k,Value v) {_map.set(k,typename M::Value(_map[k].x,v));}
   647   };
   648 
   649   ///Returns a YMap class
   650 
   651   ///This function just returns a YMap class.
   652   ///\relates YMap
   653   template<class M>
   654   inline YMap<M> yMap(M &m)
   655   {
   656     return YMap<M>(m);
   657   }
   658 
   659   template<class M>
   660   inline YMap<M> yMap(const M &m)
   661   {
   662     return YMap<M>(m);
   663   }
   664 
   665   ///Constant (read only) version of YMap
   666 
   667   ///Constant (read only) version of YMap.
   668   ///
   669   template<class M>
   670   class ConstYMap
   671   {
   672     const M& _map;
   673   public:
   674 
   675     typedef typename M::Value::Value Value;
   676     typedef typename M::Key Key;
   677     ///\e
   678     ConstYMap(const M &map) : _map(map) {}
   679     Value operator[](Key k) const {return _map[k].y;}
   680   };
   681 
   682   ///Returns a ConstYMap class
   683 
   684   ///This function just returns a ConstYMap class.
   685   ///\relates ConstYMap
   686   template<class M>
   687   inline ConstYMap<M> yMap(const M &m)
   688   {
   689     return ConstYMap<M>(m);
   690   }
   691 
   692 
   693   ///\brief Map of the normSquare() of a <tt>Point</tt>-map
   694   ///
   695   ///Map of the \ref Point::normSquare() "normSquare()"
   696   ///of a \ref Point "Point"-map.
   697   template<class M>
   698   class NormSquareMap
   699   {
   700     const M& _map;
   701   public:
   702 
   703     typedef typename M::Value::Value Value;
   704     typedef typename M::Key Key;
   705     ///\e
   706     NormSquareMap(const M &map) : _map(map) {}
   707     Value operator[](Key k) const {return _map[k].normSquare();}
   708   };
   709 
   710   ///Returns a NormSquareMap class
   711 
   712   ///This function just returns a NormSquareMap class.
   713   ///\relates NormSquareMap
   714   template<class M>
   715   inline NormSquareMap<M> normSquareMap(const M &m)
   716   {
   717     return NormSquareMap<M>(m);
   718   }
   719 
   720   /// @}
   721 
   722   } //namespce dim2
   723 
   724 } //namespace lemon
   725 
   726 #endif //LEMON_DIM2_H