COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/dim2.h @ 2216:1e45cdeea3cc

Last change on this file since 2216:1e45cdeea3cc was 2214:a886e48e0d91, checked in by Alpar Juttner, 18 years ago

Doc improvements

File size: 15.3 KB
RevLine 
[906]1/* -*- C++ -*-
2 *
[1956]3 * This file is a part of LEMON, a generic C++ optimization library
4 *
5 * Copyright (C) 2003-2006
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
[1359]7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
[906]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
[2207]19#ifndef LEMON_DIM2_H
20#define LEMON_DIM2_H
[201]21
22#include <iostream>
[1993]23#include <lemon/bits/utility.h>
[201]24
[491]25///\ingroup misc
[249]26///\file
27///\brief A simple two dimensional vector and a bounding box implementation
28///
[2207]29/// The class \ref lemon::dim2::Point "dim2::Point" implements
[249]30///a two dimensional vector with the usual
31/// operations.
32///
[2207]33/// The class \ref lemon::dim2::BoundingBox "dim2::BoundingBox"
34/// can be used to determine
35/// the rectangular bounding box of a set of
36/// \ref lemon::dim2::Point "dim2::Point"'s.
[458]37///
38///\author Attila Bernath
[249]39
40
[921]41namespace lemon {
[431]42
[2207]43  ///Tools for handling two dimensional coordinates
44
45  ///This namespace is a storage of several
46  ///tools for handling two dimensional coordinates
47  namespace dim2 {
48
[431]49  /// \addtogroup misc
50  /// @{
51
[1257]52  /// A simple two dimensional vector (plainvector) implementation
[242]53
[1257]54  /// A simple two dimensional vector (plainvector) implementation
[458]55  ///with the usual vector
56  /// operators.
57  ///
[207]58  template<typename T>
[2207]59    class Point {
[201]60
[207]61    public:
[240]62
[987]63      typedef T Value;
[964]64
[1974]65      ///First co-ordinate
66      T x;
67      ///Second co-ordinate
68      T y;     
[207]69     
[1257]70      ///Default constructor
[2207]71      Point() {}
[201]72
[2157]73      ///Construct an instance from coordinates
[2207]74      Point(T a, T b) : x(a), y(b) { }
[201]75
[2212]76      ///Size of vector
77      int size() const { return 2; }
78
79      ///Subscripting operator
80      T& operator[](int idx) { return idx == 0 ? x : y; }
81
82      ///Const subscripting operator
83      const T& operator[](int idx) const { return idx == 0 ? x : y; }
[201]84
[1049]85      ///Conversion constructor
[2207]86      template<class TT> Point(const Point<TT> &p) : x(p.x), y(p.y) {}
[1049]87
[2157]88      ///Give back the square of the norm of the vector
[1257]89      T normSquare() const {
[1426]90        return x*x+y*y;
[1391]91      }
[201]92 
[2157]93      ///Increment the left hand side by u
[2207]94      Point<T>& operator +=(const Point<T>& u) {
[1426]95        x += u.x;
96        y += u.y;
97        return *this;
[1391]98      }
[201]99 
[2157]100      ///Decrement the left hand side by u
[2207]101      Point<T>& operator -=(const Point<T>& u) {
[1426]102        x -= u.x;
103        y -= u.y;
104        return *this;
[1391]105      }
[201]106
[2157]107      ///Multiply the left hand side with a scalar
[2207]108      Point<T>& operator *=(const T &u) {
[1426]109        x *= u;
110        y *= u;
111        return *this;
[1391]112      }
[207]113
[2157]114      ///Divide the left hand side by a scalar
[2207]115      Point<T>& operator /=(const T &u) {
[1426]116        x /= u;
117        y /= u;
118        return *this;
[1391]119      }
[201]120 
[2157]121      ///Return the scalar product of two vectors
[2207]122      T operator *(const Point<T>& u) const {
[1426]123        return x*u.x+y*u.y;
[1391]124      }
[201]125 
[2157]126      ///Return the sum of two vectors
[2207]127      Point<T> operator+(const Point<T> &u) const {
128        Point<T> b=*this;
[1426]129        return b+=u;
[1391]130      }
[201]131
[2157]132      ///Return the neg of the vectors
[2207]133      Point<T> operator-() const {
134        Point<T> b=*this;
[1426]135        b.x=-b.x; b.y=-b.y;
136        return b;
[1391]137      }
[1049]138
[2157]139      ///Return the difference of two vectors
[2207]140      Point<T> operator-(const Point<T> &u) const {
141        Point<T> b=*this;
[1426]142        return b-=u;
[1391]143      }
[201]144
[2157]145      ///Return a vector multiplied by a scalar
[2207]146      Point<T> operator*(const T &u) const {
147        Point<T> b=*this;
[1426]148        return b*=u;
[1391]149      }
[201]150
[2157]151      ///Return a vector divided by a scalar
[2207]152      Point<T> operator/(const T &u) const {
153        Point<T> b=*this;
[1426]154        return b/=u;
[1391]155      }
[201]156
[2157]157      ///Test equality
[2207]158      bool operator==(const Point<T> &u) const {
[1426]159        return (x==u.x) && (y==u.y);
[1391]160      }
[201]161
[2157]162      ///Test inequality
[2207]163      bool operator!=(Point u) const {
[1426]164        return  (x!=u.x) || (y!=u.y);
[1391]165      }
[201]166
[207]167    };
[201]168
[2207]169  ///Return an Point
[1999]170
[2207]171  ///Return an Point
172  ///\relates Point
[1999]173  template <typename T>
[2212]174  inline Point<T> makePoint(const T& x, const T& y) {
[2207]175    return Point<T>(x, y);
[1999]176  }
177
[2157]178  ///Return a vector multiplied by a scalar
[1083]179
[2157]180  ///Return a vector multiplied by a scalar
[2207]181  ///\relates Point
182  template<typename T> Point<T> operator*(const T &u,const Point<T> &x) {
[1071]183    return x*u;
[1391]184  }
[1071]185
[814]186  ///Read a plainvector from a stream
187
[967]188  ///Read a plainvector from a stream
[2207]189  ///\relates Point
[814]190  ///
[207]191  template<typename T>
[2207]192  inline std::istream& operator>>(std::istream &is, Point<T> &z) {
[1392]193    char c;
194    if (is >> c) {
195      if (c != '(') is.putback(c);
196    } else {
197      is.clear();
198    }
199    if (!(is >> z.x)) return is;
200    if (is >> c) {
201      if (c != ',') is.putback(c);
202    } else {
203      is.clear();
204    }
205    if (!(is >> z.y)) return is;
206    if (is >> c) {
207      if (c != ')') is.putback(c);
208    } else {
209      is.clear();
210    }
[207]211    return is;
212  }
[201]213
[814]214  ///Write a plainvector to a stream
215
[967]216  ///Write a plainvector to a stream
[2207]217  ///\relates Point
[814]218  ///
[207]219  template<typename T>
[2207]220  inline std::ostream& operator<<(std::ostream &os, const Point<T>& z)
[207]221  {
[240]222    os << "(" << z.x << ", " << z.y << ")";
[207]223    return os;
224  }
225
[1202]226  ///Rotate by 90 degrees
227
228  ///Returns its parameter rotated by 90 degrees in positive direction.
[2207]229  ///\relates Point
[1202]230  ///
231  template<typename T>
[2207]232  inline Point<T> rot90(const Point<T> &z)
[1202]233  {
[2207]234    return Point<T>(-z.y,z.x);
[1202]235  }
236
[2157]237  ///Rotate by 180 degrees
238
239  ///Returns its parameter rotated by 180 degrees.
[2207]240  ///\relates Point
[2157]241  ///
242  template<typename T>
[2207]243  inline Point<T> rot180(const Point<T> &z)
[2157]244  {
[2207]245    return Point<T>(-z.x,-z.y);
[2157]246  }
247
[1202]248  ///Rotate by 270 degrees
249
250  ///Returns its parameter rotated by 90 degrees in negative direction.
[2207]251  ///\relates Point
[1202]252  ///
253  template<typename T>
[2207]254  inline Point<T> rot270(const Point<T> &z)
[1202]255  {
[2207]256    return Point<T>(z.y,-z.x);
[1202]257  }
258
259 
[244]260
[458]261  /// A class to calculate or store the bounding box of plainvectors.
262
263  /// A class to calculate or store the bounding box of plainvectors.
264  ///
265  ///\author Attila Bernath
[244]266  template<typename T>
267    class BoundingBox {
[2207]268      Point<T> bottom_left, top_right;
[244]269      bool _empty;
270    public:
271     
[1426]272      ///Default constructor: creates an empty bounding box
[244]273      BoundingBox() { _empty = true; }
274
[2157]275      ///Construct an instance from one point
[2207]276      BoundingBox(Point<T> a) { bottom_left=top_right=a; _empty = false; }
[244]277
[1426]278      ///Were any points added?
[244]279      bool empty() const {
[1426]280        return _empty;
[244]281      }
282
[2157]283      ///Make the BoundingBox empty
[1391]284      void clear() {
[1426]285        _empty=1;
[1391]286      }
287
[2157]288      ///Give back the bottom left corner
289
290      ///Give back the bottom left corner.
291      ///If the bounding box is empty, then the return value is not defined.
[2207]292      Point<T> bottomLeft() const {
[1426]293        return bottom_left;
[1391]294      }
[244]295
[2157]296      ///Set the bottom left corner
297
298      ///Set the bottom left corner.
299      ///It should only bee used for non-empty box.
[2207]300      void bottomLeft(Point<T> p) {
[1927]301        bottom_left = p;
302      }
303
[2157]304      ///Give back the top right corner
305
306      ///Give back the top right corner.
307      ///If the bounding box is empty, then the return value is not defined.
[2207]308      Point<T> topRight() const {
[1426]309        return top_right;
[1391]310      }
[244]311
[2157]312      ///Set the top right corner
313
314      ///Set the top right corner.
315      ///It should only bee used for non-empty box.
[2207]316      void topRight(Point<T> p) {
[1927]317        top_right = p;
318      }
319
[2157]320      ///Give back the bottom right corner
321
322      ///Give back the bottom right corner.
323      ///If the bounding box is empty, then the return value is not defined.
[2207]324      Point<T> bottomRight() const {
325        return Point<T>(top_right.x,bottom_left.y);
[1391]326      }
[1045]327
[2157]328      ///Set the bottom right corner
329
330      ///Set the bottom right corner.
331      ///It should only bee used for non-empty box.
[2207]332      void bottomRight(Point<T> p) {
[1927]333        top_right.x = p.x;
334        bottom_left.y = p.y;
335      }
[2157]336 
337      ///Give back the top left corner
[1927]338
[2157]339      ///Give back the top left corner.
340      ///If the bounding box is empty, then the return value is not defined.
[2207]341      Point<T> topLeft() const {
342        return Point<T>(bottom_left.x,top_right.y);
[1391]343      }
[1045]344
[2157]345      ///Set the top left corner
346
347      ///Set the top left corner.
348      ///It should only bee used for non-empty box.
[2207]349      void topLeft(Point<T> p) {
[1927]350        top_right.y = p.y;
351        bottom_left.x = p.x;
352      }
353
[2157]354      ///Give back the bottom of the box
355
356      ///Give back the bottom of the box.
357      ///If the bounding box is empty, then the return value is not defined.
[1045]358      T bottom() const {
[1426]359        return bottom_left.y;
[1391]360      }
[1045]361
[2157]362      ///Set the bottom of the box
363
364      ///Set the bottom of the box.
365      ///It should only bee used for non-empty box.
[1927]366      void bottom(T t) {
367        bottom_left.y = t;
368      }
369
[2157]370      ///Give back the top of the box
371
372      ///Give back the top of the box.
373      ///If the bounding box is empty, then the return value is not defined.
[1045]374      T top() const {
[1426]375        return top_right.y;
[1391]376      }
[1045]377
[2157]378      ///Set the top of the box
379
380      ///Set the top of the box.
381      ///It should only bee used for non-empty box.
[1927]382      void top(T t) {
383        top_right.y = t;
384      }
385
[2157]386      ///Give back the left side of the box
387
388      ///Give back the left side of the box.
389      ///If the bounding box is empty, then the return value is not defined.
[1045]390      T left() const {
[1426]391        return bottom_left.x;
[1391]392      }
[2157]393 
394      ///Set the left side of the box
[1045]395
[2157]396      ///Set the left side of the box.
397      ///It should only bee used for non-empty box
[1927]398      void left(T t) {
399        bottom_left.x = t;
400      }
401
[2157]402      /// Give back the right side of the box
403
404      /// Give back the right side of the box.
405      ///If the bounding box is empty, then the return value is not defined.
[1045]406      T right() const {
[1426]407        return top_right.x;
[1391]408      }
[1045]409
[2157]410      ///Set the right side of the box
411
412      ///Set the right side of the box.
413      ///It should only bee used for non-empty box
[1927]414      void right(T t) {
415        top_right.x = t;
416      }
417
[2157]418      ///Give back the height of the box
419
420      ///Give back the height of the box.
421      ///If the bounding box is empty, then the return value is not defined.
[1102]422      T height() const {
[1426]423        return top_right.y-bottom_left.y;
[1391]424      }
[1102]425
[2157]426      ///Give back the width of the box
427
428      ///Give back the width of the box.
429      ///If the bounding box is empty, then the return value is not defined.
[1102]430      T width() const {
[1426]431        return top_right.x-bottom_left.x;
[1391]432      }
[1102]433
[244]434      ///Checks whether a point is inside a bounding box
[2207]435      bool inside(const Point<T>& u){
[1426]436        if (_empty)
437          return false;
438        else{
439          return ((u.x-bottom_left.x)*(top_right.x-u.x) >= 0 &&
440              (u.y-bottom_left.y)*(top_right.y-u.y) >= 0 );
441        }
[244]442      }
443 
444      ///Increments a bounding box with a point
[2207]445      BoundingBox& add(const Point<T>& u){
[1426]446        if (_empty){
447          bottom_left=top_right=u;
448          _empty = false;
449        }
450        else{
451          if (bottom_left.x > u.x) bottom_left.x = u.x;
452          if (bottom_left.y > u.y) bottom_left.y = u.y;
453          if (top_right.x < u.x) top_right.x = u.x;
454          if (top_right.y < u.y) top_right.y = u.y;
455        }
456        return *this;
[1391]457      }
[2214]458   
459      ///Increments a bounding to contain another bounding box
[1588]460      BoundingBox& add(const BoundingBox &u){
[1426]461        if ( !u.empty() ){
[1588]462          this->add(u.bottomLeft());
463          this->add(u.topRight());
[1426]464        }
465        return *this;
[1391]466      }
[244]467 
[1588]468      ///Intersection of two bounding boxes
469      BoundingBox operator &(const BoundingBox& u){
470        BoundingBox b;
471        b.bottom_left.x=std::max(this->bottom_left.x,u.bottom_left.x);
472        b.bottom_left.y=std::max(this->bottom_left.y,u.bottom_left.y);
473        b.top_right.x=std::min(this->top_right.x,u.top_right.x);
474        b.top_right.y=std::min(this->top_right.y,u.top_right.y);
475        b._empty = this->_empty || u._empty ||
476          b.bottom_left.x>top_right.x && b.bottom_left.y>top_right.y;
477        return b;
[1391]478      }
[244]479
480    };//class Boundingbox
481
482
[2207]483  ///Map of x-coordinates of a dim2::Point<>-map
[1317]484
485  ///\ingroup maps
[2214]486  ///Map of x-coordinates of a dim2::Point<>-map
[1317]487  ///
488  template<class M>
489  class XMap
490  {
[1706]491    M& _map;
[1317]492  public:
[1420]493
[1317]494    typedef typename M::Value::Value Value;
495    typedef typename M::Key Key;
496    ///\e
[1706]497    XMap(M& map) : _map(map) {}
[1317]498    Value operator[](Key k) const {return _map[k].x;}
[1352]499    void set(Key k,Value v) {_map.set(k,typename M::Value(v,_map[k].y));}
[1317]500  };
501   
502  ///Returns an \ref XMap class
503
504  ///This function just returns an \ref XMap class.
505  ///
506  ///\ingroup maps
507  ///\relates XMap
508  template<class M>
509  inline XMap<M> xMap(M &m)
510  {
511    return XMap<M>(m);
512  }
513
[1420]514  template<class M>
515  inline XMap<M> xMap(const M &m)
516  {
517    return XMap<M>(m);
518  }
519
[1317]520  ///Constant (read only) version of \ref XMap
521
522  ///\ingroup maps
[2214]523  ///Constant (read only) version of \ref XMap
[1317]524  ///
525  template<class M>
526  class ConstXMap
527  {
[1706]528    const M& _map;
[1317]529  public:
[1420]530
[1317]531    typedef typename M::Value::Value Value;
532    typedef typename M::Key Key;
533    ///\e
534    ConstXMap(const M &map) : _map(map) {}
535    Value operator[](Key k) const {return _map[k].x;}
536  };
537   
538  ///Returns a \ref ConstXMap class
539
540  ///This function just returns an \ref ConstXMap class.
541  ///
542  ///\ingroup maps
543  ///\relates ConstXMap
544  template<class M>
545  inline ConstXMap<M> xMap(const M &m)
546  {
547    return ConstXMap<M>(m);
548  }
549
[2207]550  ///Map of y-coordinates of a dim2::Point<>-map
[1317]551   
552  ///\ingroup maps
[2214]553  ///Map of y-coordinates of a dim2::Point<>-map
[1317]554  ///
555  template<class M>
556  class YMap
557  {
[1706]558    M& _map;
[1317]559  public:
[1420]560
[1317]561    typedef typename M::Value::Value Value;
562    typedef typename M::Key Key;
563    ///\e
[1706]564    YMap(M& map) : _map(map) {}
[1317]565    Value operator[](Key k) const {return _map[k].y;}
[1352]566    void set(Key k,Value v) {_map.set(k,typename M::Value(_map[k].x,v));}
[1317]567  };
568
569  ///Returns an \ref YMap class
570
571  ///This function just returns an \ref YMap class.
572  ///
573  ///\ingroup maps
574  ///\relates YMap
575  template<class M>
576  inline YMap<M> yMap(M &m)
577  {
578    return YMap<M>(m);
579  }
580
[1420]581  template<class M>
582  inline YMap<M> yMap(const M &m)
583  {
584    return YMap<M>(m);
585  }
586
[1317]587  ///Constant (read only) version of \ref YMap
588
589  ///\ingroup maps
[2214]590  ///Constant (read only) version of \ref YMap
[1317]591  ///
592  template<class M>
593  class ConstYMap
594  {
[1706]595    const M& _map;
[1317]596  public:
[1420]597
[1317]598    typedef typename M::Value::Value Value;
599    typedef typename M::Key Key;
600    ///\e
601    ConstYMap(const M &map) : _map(map) {}
602    Value operator[](Key k) const {return _map[k].y;}
603  };
604   
605  ///Returns a \ref ConstYMap class
606
607  ///This function just returns an \ref ConstYMap class.
608  ///
609  ///\ingroup maps
610  ///\relates ConstYMap
611  template<class M>
612  inline ConstYMap<M> yMap(const M &m)
613  {
614    return ConstYMap<M>(m);
615  }
616
617
[2214]618    ///\brief Map of the \ref Point::normSquare() "normSquare()"
619    ///of an \ref Point "Point"-map
620    ///
621    ///Map of the \ref Point::normSquare() "normSquare()"
622    ///of an \ref Point "Point"-map
623    ///\ingroup maps
624    ///
[1352]625  template<class M>
626  class NormSquareMap
627  {
[1706]628    const M& _map;
[1352]629  public:
[1420]630
[1352]631    typedef typename M::Value::Value Value;
632    typedef typename M::Key Key;
633    ///\e
634    NormSquareMap(const M &map) : _map(map) {}
635    Value operator[](Key k) const {return _map[k].normSquare();}
636  };
637   
638  ///Returns a \ref NormSquareMap class
639
640  ///This function just returns an \ref NormSquareMap class.
641  ///
642  ///\ingroup maps
643  ///\relates NormSquareMap
644  template<class M>
645  inline NormSquareMap<M> normSquareMap(const M &m)
646  {
647    return NormSquareMap<M>(m);
648  }
649
[431]650  /// @}
[244]651
[2207]652  } //namespce dim2
653 
[921]654} //namespace lemon
[201]655
[2207]656#endif //LEMON_DIM2_H
Note: See TracBrowser for help on using the repository browser.