COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/xy.h @ 1962:c1c3a0fae8a1

Last change on this file since 1962:c1c3a0fae8a1 was 1956:a055123339d5, checked in by Alpar Juttner, 18 years ago

Unified copyright notices

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