COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/xy.h @ 1993:2115143eceea

Last change on this file since 1993:2115143eceea was 1993:2115143eceea, checked in by Balazs Dezso, 14 years ago

utility, invalid and traits moved to bits

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