COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/xy.h @ 1999:2ff283124dfc

Last change on this file since 1999:2ff283124dfc was 1999:2ff283124dfc, checked in by Balazs Dezso, 14 years ago

Clarifing alteration observing system
It is directly connected now to a container

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