COIN-OR::LEMON - Graph Library

source: lemon-0.x/src/lemon/xy.h @ 1396:56f9a4ba9149

Last change on this file since 1396:56f9a4ba9149 was 1392:b87aa8f0feb8, checked in by Balazs Dezso, 16 years ago

Changed input operator.

File size: 11.2 KB
Line 
1/* -*- C++ -*-
2 * src/lemon/xy.h - Part of LEMON, a generic C++ optimization library
3 *
4 * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
5 * (Egervary Research Group on Combinatorial Optimization, EGRES).
6 *
7 * Permission to use, modify and distribute this software is granted
8 * provided that this copyright notice appears in all copies. For
9 * precise terms see the accompanying LICENSE file.
10 *
11 * This software is provided "AS IS" with no warranty of any kind,
12 * express or implied, and with no claim as to its suitability for any
13 * purpose.
14 *
15 */
16
17#ifndef LEMON_XY_H
18#define LEMON_XY_H
19
20#include <iostream>
21
22///\ingroup misc
23///\file
24///\brief A simple two dimensional vector and a bounding box implementation
25///
26/// The class \ref lemon::xy "xy" implements
27///a two dimensional vector with the usual
28/// operations.
29///
30/// The class \ref lemon::BoundingBox "BoundingBox" can be used to determine
31/// the rectangular bounding box a set of \ref lemon::xy "xy"'s.
32///
33///\author Attila Bernath
34
35
36namespace lemon {
37
38  /// \addtogroup misc
39  /// @{
40
41  /// A simple two dimensional vector (plainvector) implementation
42
43  /// A simple two dimensional vector (plainvector) implementation
44  ///with the usual vector
45  /// operators.
46  ///
47  ///\author Attila Bernath
48  template<typename T>
49    class xy {
50
51    public:
52
53      typedef T Value;
54
55      T x,y;     
56     
57      ///Default constructor
58      xy() {}
59
60      ///Constructing the instance from coordinates
61      xy(T a, T b) : x(a), y(b) { }
62
63
64      ///Conversion constructor
65      template<class TT> xy(const xy<TT> &p) : x(p.x), y(p.y) {}
66
67      ///Gives back the square of the norm of the vector
68      T normSquare() const {
69        return x*x+y*y;
70      }
71 
72      ///Increments the left hand side by u
73      xy<T>& operator +=(const xy<T>& u) {
74        x += u.x;
75        y += u.y;
76        return *this;
77      }
78 
79      ///Decrements the left hand side by u
80      xy<T>& operator -=(const xy<T>& u) {
81        x -= u.x;
82        y -= u.y;
83        return *this;
84      }
85
86      ///Multiplying the left hand side with a scalar
87      xy<T>& operator *=(const T &u) {
88        x *= u;
89        y *= u;
90        return *this;
91      }
92
93      ///Dividing the left hand side by a scalar
94      xy<T>& operator /=(const T &u) {
95        x /= u;
96        y /= u;
97        return *this;
98      }
99 
100      ///Returns the scalar product of two vectors
101      T operator *(const xy<T>& u) const {
102        return x*u.x+y*u.y;
103      }
104 
105      ///Returns the sum of two vectors
106      xy<T> operator+(const xy<T> &u) const {
107        xy<T> b=*this;
108        return b+=u;
109      }
110
111      ///Returns the neg of the vectors
112      xy<T> operator-() const {
113        xy<T> b=*this;
114        b.x=-b.x; b.y=-b.y;
115        return b;
116      }
117
118      ///Returns the difference of two vectors
119      xy<T> operator-(const xy<T> &u) const {
120        xy<T> b=*this;
121        return b-=u;
122      }
123
124      ///Returns a vector multiplied by a scalar
125      xy<T> operator*(const T &u) const {
126        xy<T> b=*this;
127        return b*=u;
128      }
129
130      ///Returns a vector divided by a scalar
131      xy<T> operator/(const T &u) const {
132        xy<T> b=*this;
133        return b/=u;
134      }
135
136      ///Testing equality
137      bool operator==(const xy<T> &u) const {
138        return (x==u.x) && (y==u.y);
139      }
140
141      ///Testing inequality
142      bool operator!=(xy u) const {
143        return  (x!=u.x) || (y!=u.y);
144      }
145
146    };
147
148  ///Returns a vector multiplied by a scalar
149
150  ///Returns a vector multiplied by a scalar
151  ///\relates xy
152  template<typename T> xy<T> operator*(const T &u,const xy<T> &x) {
153    return x*u;
154  }
155
156  ///Read a plainvector from a stream
157
158  ///Read a plainvector from a stream
159  ///\relates xy
160  ///
161  template<typename T>
162  inline std::istream& operator>>(std::istream &is, xy<T> &z) {
163    char c;
164    if (is >> c) {
165      if (c != '(') is.putback(c);
166    } else {
167      is.clear();
168    }
169    if (!(is >> z.x)) return is;
170    if (is >> c) {
171      if (c != ',') is.putback(c);
172    } else {
173      is.clear();
174    }
175    if (!(is >> z.y)) return is;
176    if (is >> c) {
177      if (c != ')') is.putback(c);
178    } else {
179      is.clear();
180    }
181    return is;
182  }
183
184  ///Write a plainvector to a stream
185
186  ///Write a plainvector to a stream
187  ///\relates xy
188  ///
189  template<typename T>
190  inline std::ostream& operator<<(std::ostream &os, const xy<T>& z)
191  {
192    os << "(" << z.x << ", " << z.y << ")";
193    return os;
194  }
195
196  ///Rotate by 90 degrees
197
198  ///Returns its parameter rotated by 90 degrees in positive direction.
199  ///\relates xy
200  ///
201  template<typename T>
202  inline xy<T> rot90(const xy<T> &z)
203  {
204    return xy<T>(-z.y,z.x);
205  }
206
207  ///Rotate by 270 degrees
208
209  ///Returns its parameter rotated by 90 degrees in negative direction.
210  ///\relates xy
211  ///
212  template<typename T>
213  inline xy<T> rot270(const xy<T> &z)
214  {
215    return xy<T>(z.y,-z.x);
216  }
217
218 
219
220  /// A class to calculate or store the bounding box of plainvectors.
221
222  /// A class to calculate or store the bounding box of plainvectors.
223  ///
224  ///\author Attila Bernath
225  template<typename T>
226    class BoundingBox {
227      xy<T> bottom_left, top_right;
228      bool _empty;
229    public:
230     
231      ///Default constructor: an empty bounding box
232      BoundingBox() { _empty = true; }
233
234      ///Constructing the instance from one point
235      BoundingBox(xy<T> a) { bottom_left=top_right=a; _empty = false; }
236
237      ///Is there any point added
238      bool empty() const {
239        return _empty;
240      }
241
242      ///Makes the BoundingBox empty
243      void clear() {
244        _empty=1;
245      }
246
247      ///Gives back the bottom left corner (if the bounding box is empty, then the return value is not defined)
248      xy<T> bottomLeft() const {
249        return bottom_left;
250      }
251
252      ///Gives back the top right corner (if the bounding box is empty, then the return value is not defined)
253      xy<T> topRight() const {
254        return top_right;
255      }
256
257      ///Gives back the bottom right corner (if the bounding box is empty, then the return value is not defined)
258      xy<T> bottomRight() const {
259        return xy<T>(top_right.x,bottom_left.y);
260      }
261
262      ///Gives back the top left corner (if the bounding box is empty, then the return value is not defined)
263      xy<T> topLeft() const {
264        return xy<T>(bottom_left.x,top_right.y);
265      }
266
267      ///Gives back the bottom of the box (if the bounding box is empty, then the return value is not defined)
268      T bottom() const {
269        return bottom_left.y;
270      }
271
272      ///Gives back the top of the box (if the bounding box is empty, then the return value is not defined)
273      T top() const {
274        return top_right.y;
275      }
276
277      ///Gives back the left side of the box (if the bounding box is empty, then the return value is not defined)
278      T left() const {
279        return bottom_left.x;
280      }
281
282      ///Gives back the right side of the box (if the bounding box is empty, then the return value is not defined)
283      T right() const {
284        return top_right.x;
285      }
286
287      ///Gives back the height of the box (if the bounding box is empty, then the return value is not defined)
288      T height() const {
289        return top_right.y-bottom_left.y;
290      }
291
292      ///Gives back the width of the box (if the bounding box is empty, then the return value is not defined)
293      T width() const {
294        return top_right.x-bottom_left.x;
295      }
296
297      ///Checks whether a point is inside a bounding box
298      bool inside(const xy<T>& u){
299        if (_empty)
300          return false;
301        else{
302          return ((u.x-bottom_left.x)*(top_right.x-u.x) >= 0 &&
303                  (u.y-bottom_left.y)*(top_right.y-u.y) >= 0 );
304        }
305      }
306 
307      ///Increments a bounding box with a point
308      BoundingBox& operator +=(const xy<T>& u){
309        if (_empty){
310          bottom_left=top_right=u;
311          _empty = false;
312        }
313        else{
314          if (bottom_left.x > u.x) bottom_left.x = u.x;
315          if (bottom_left.y > u.y) bottom_left.y = u.y;
316          if (top_right.x < u.x) top_right.x = u.x;
317          if (top_right.y < u.y) top_right.y = u.y;
318        }
319        return *this;
320      }
321 
322      ///Sums a bounding box and a point
323      BoundingBox operator +(const xy<T>& u){
324        BoundingBox b = *this;
325        return b += u;
326      }
327
328      ///Increments a bounding box with an other bounding box
329      BoundingBox& operator +=(const BoundingBox &u){
330        if ( !u.empty() ){
331          *this += u.bottomLeft();
332          *this += u.topRight();
333        }
334        return *this;
335      }
336 
337      ///Sums two bounding boxes
338      BoundingBox operator +(const BoundingBox& u){
339        BoundingBox b = *this;
340        return b += u;
341      }
342
343    };//class Boundingbox
344
345
346  ///Map of x-coordinates of an xy<>-map
347
348  ///\ingroup maps
349  ///
350  template<class M>
351  class XMap
352  {
353    M &_map;
354  public:
355    typedef typename M::Value::Value Value;
356    typedef typename M::Key Key;
357    ///\e
358    XMap(M &map) : _map(map) {}
359    Value operator[](Key k) const {return _map[k].x;}
360    void set(Key k,Value v) {_map.set(k,typename M::Value(v,_map[k].y));}
361  };
362   
363  ///Returns an \ref XMap class
364
365  ///This function just returns an \ref XMap class.
366  ///
367  ///\ingroup maps
368  ///\relates XMap
369  template<class M>
370  inline XMap<M> xMap(M &m)
371  {
372    return XMap<M>(m);
373  }
374
375  ///Constant (read only) version of \ref XMap
376
377  ///\ingroup maps
378  ///
379  template<class M>
380  class ConstXMap
381  {
382    const M &_map;
383  public:
384    typedef typename M::Value::Value Value;
385    typedef typename M::Key Key;
386    ///\e
387    ConstXMap(const M &map) : _map(map) {}
388    Value operator[](Key k) const {return _map[k].x;}
389  };
390   
391  ///Returns a \ref ConstXMap class
392
393  ///This function just returns an \ref ConstXMap class.
394  ///
395  ///\ingroup maps
396  ///\relates ConstXMap
397  template<class M>
398  inline ConstXMap<M> xMap(const M &m)
399  {
400    return ConstXMap<M>(m);
401  }
402
403  ///Map of y-coordinates of an xy<>-map
404   
405  ///\ingroup maps
406  ///
407  template<class M>
408  class YMap
409  {
410    M &_map;
411  public:
412    typedef typename M::Value::Value Value;
413    typedef typename M::Key Key;
414    ///\e
415    YMap(M &map) : _map(map) {}
416    Value operator[](Key k) const {return _map[k].y;}
417    void set(Key k,Value v) {_map.set(k,typename M::Value(_map[k].x,v));}
418  };
419
420  ///Returns an \ref YMap class
421
422  ///This function just returns an \ref YMap class.
423  ///
424  ///\ingroup maps
425  ///\relates YMap
426  template<class M>
427  inline YMap<M> yMap(M &m)
428  {
429    return YMap<M>(m);
430  }
431
432  ///Constant (read only) version of \ref YMap
433
434  ///\ingroup maps
435  ///
436  template<class M>
437  class ConstYMap
438  {
439    const M &_map;
440  public:
441    typedef typename M::Value::Value Value;
442    typedef typename M::Key Key;
443    ///\e
444    ConstYMap(const M &map) : _map(map) {}
445    Value operator[](Key k) const {return _map[k].y;}
446  };
447   
448  ///Returns a \ref ConstYMap class
449
450  ///This function just returns an \ref ConstYMap class.
451  ///
452  ///\ingroup maps
453  ///\relates ConstYMap
454  template<class M>
455  inline ConstYMap<M> yMap(const M &m)
456  {
457    return ConstYMap<M>(m);
458  }
459
460
461  ///Map of the \ref xy::normSquare() "normSquare()" of an \ref xy "xy"-map
462
463  ///Map of the \ref xy::normSquare() "normSquare()" of an \ref xy "xy"-map
464  ///\ingroup maps
465  ///
466  template<class M>
467  class NormSquareMap
468  {
469    const M &_map;
470  public:
471    typedef typename M::Value::Value Value;
472    typedef typename M::Key Key;
473    ///\e
474    NormSquareMap(const M &map) : _map(map) {}
475    Value operator[](Key k) const {return _map[k].normSquare();}
476  };
477   
478  ///Returns a \ref NormSquareMap class
479
480  ///This function just returns an \ref NormSquareMap class.
481  ///
482  ///\ingroup maps
483  ///\relates NormSquareMap
484  template<class M>
485  inline NormSquareMap<M> normSquareMap(const M &m)
486  {
487    return NormSquareMap<M>(m);
488  }
489
490  /// @}
491
492
493} //namespace lemon
494
495#endif //LEMON_XY_H
Note: See TracBrowser for help on using the repository browser.