COIN-OR::LEMON - Graph Library

source: lemon-0.x/src/lemon/xy.h @ 1391:5b46af577b23

Last change on this file since 1391:5b46af577b23 was 1391:5b46af577b23, checked in by Alpar Juttner, 15 years ago
  • BoundingBox::clear() added
  • More "-pedantic" code
File size: 10.9 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
163  std::istream& operator>>(std::istream &is, xy<T> &z)
164  {
165
166    is >> z.x >> z.y;
167    return is;
168  }
169
170  ///Write a plainvector to a stream
171
172  ///Write a plainvector to a stream
173  ///\relates xy
174  ///
175  template<typename T>
176  inline
177  std::ostream& operator<<(std::ostream &os, xy<T> z)
178  {
179    os << "(" << z.x << ", " << z.y << ")";
180    return os;
181  }
182
183  ///Rotate by 90 degrees
184
185  ///Returns its parameter rotated by 90 degrees in positive direction.
186  ///\relates xy
187  ///
188  template<typename T>
189  inline xy<T> rot90(const xy<T> &z)
190  {
191    return xy<T>(-z.y,z.x);
192  }
193
194  ///Rotate by 270 degrees
195
196  ///Returns its parameter rotated by 90 degrees in negative direction.
197  ///\relates xy
198  ///
199  template<typename T>
200  inline xy<T> rot270(const xy<T> &z)
201  {
202    return xy<T>(z.y,-z.x);
203  }
204
205 
206
207  /// A class to calculate or store the bounding box of plainvectors.
208
209  /// A class to calculate or store the bounding box of plainvectors.
210  ///
211  ///\author Attila Bernath
212  template<typename T>
213    class BoundingBox {
214      xy<T> bottom_left, top_right;
215      bool _empty;
216    public:
217     
218      ///Default constructor: an empty bounding box
219      BoundingBox() { _empty = true; }
220
221      ///Constructing the instance from one point
222      BoundingBox(xy<T> a) { bottom_left=top_right=a; _empty = false; }
223
224      ///Is there any point added
225      bool empty() const {
226        return _empty;
227      }
228
229      ///Makes the BoundingBox empty
230      void clear() {
231        _empty=1;
232      }
233
234      ///Gives back the bottom left corner (if the bounding box is empty, then the return value is not defined)
235      xy<T> bottomLeft() const {
236        return bottom_left;
237      }
238
239      ///Gives back the top right corner (if the bounding box is empty, then the return value is not defined)
240      xy<T> topRight() const {
241        return top_right;
242      }
243
244      ///Gives back the bottom right corner (if the bounding box is empty, then the return value is not defined)
245      xy<T> bottomRight() const {
246        return xy<T>(top_right.x,bottom_left.y);
247      }
248
249      ///Gives back the top left corner (if the bounding box is empty, then the return value is not defined)
250      xy<T> topLeft() const {
251        return xy<T>(bottom_left.x,top_right.y);
252      }
253
254      ///Gives back the bottom of the box (if the bounding box is empty, then the return value is not defined)
255      T bottom() const {
256        return bottom_left.y;
257      }
258
259      ///Gives back the top of the box (if the bounding box is empty, then the return value is not defined)
260      T top() const {
261        return top_right.y;
262      }
263
264      ///Gives back the left side of the box (if the bounding box is empty, then the return value is not defined)
265      T left() const {
266        return bottom_left.x;
267      }
268
269      ///Gives back the right side of the box (if the bounding box is empty, then the return value is not defined)
270      T right() const {
271        return top_right.x;
272      }
273
274      ///Gives back the height of the box (if the bounding box is empty, then the return value is not defined)
275      T height() const {
276        return top_right.y-bottom_left.y;
277      }
278
279      ///Gives back the width of the box (if the bounding box is empty, then the return value is not defined)
280      T width() const {
281        return top_right.x-bottom_left.x;
282      }
283
284      ///Checks whether a point is inside a bounding box
285      bool inside(const xy<T>& u){
286        if (_empty)
287          return false;
288        else{
289          return ((u.x-bottom_left.x)*(top_right.x-u.x) >= 0 &&
290                  (u.y-bottom_left.y)*(top_right.y-u.y) >= 0 );
291        }
292      }
293 
294      ///Increments a bounding box with a point
295      BoundingBox& operator +=(const xy<T>& u){
296        if (_empty){
297          bottom_left=top_right=u;
298          _empty = false;
299        }
300        else{
301          if (bottom_left.x > u.x) bottom_left.x = u.x;
302          if (bottom_left.y > u.y) bottom_left.y = u.y;
303          if (top_right.x < u.x) top_right.x = u.x;
304          if (top_right.y < u.y) top_right.y = u.y;
305        }
306        return *this;
307      }
308 
309      ///Sums a bounding box and a point
310      BoundingBox operator +(const xy<T>& u){
311        BoundingBox b = *this;
312        return b += u;
313      }
314
315      ///Increments a bounding box with an other bounding box
316      BoundingBox& operator +=(const BoundingBox &u){
317        if ( !u.empty() ){
318          *this += u.bottomLeft();
319          *this += u.topRight();
320        }
321        return *this;
322      }
323 
324      ///Sums two bounding boxes
325      BoundingBox operator +(const BoundingBox& u){
326        BoundingBox b = *this;
327        return b += u;
328      }
329
330    };//class Boundingbox
331
332
333  ///Map of x-coordinates of an xy<>-map
334
335  ///\ingroup maps
336  ///
337  template<class M>
338  class XMap
339  {
340    M &_map;
341  public:
342    typedef typename M::Value::Value Value;
343    typedef typename M::Key Key;
344    ///\e
345    XMap(M &map) : _map(map) {}
346    Value operator[](Key k) const {return _map[k].x;}
347    void set(Key k,Value v) {_map.set(k,typename M::Value(v,_map[k].y));}
348  };
349   
350  ///Returns an \ref XMap class
351
352  ///This function just returns an \ref XMap class.
353  ///
354  ///\ingroup maps
355  ///\relates XMap
356  template<class M>
357  inline XMap<M> xMap(M &m)
358  {
359    return XMap<M>(m);
360  }
361
362  ///Constant (read only) version of \ref XMap
363
364  ///\ingroup maps
365  ///
366  template<class M>
367  class ConstXMap
368  {
369    const M &_map;
370  public:
371    typedef typename M::Value::Value Value;
372    typedef typename M::Key Key;
373    ///\e
374    ConstXMap(const M &map) : _map(map) {}
375    Value operator[](Key k) const {return _map[k].x;}
376  };
377   
378  ///Returns a \ref ConstXMap class
379
380  ///This function just returns an \ref ConstXMap class.
381  ///
382  ///\ingroup maps
383  ///\relates ConstXMap
384  template<class M>
385  inline ConstXMap<M> xMap(const M &m)
386  {
387    return ConstXMap<M>(m);
388  }
389
390  ///Map of y-coordinates of an xy<>-map
391   
392  ///\ingroup maps
393  ///
394  template<class M>
395  class YMap
396  {
397    M &_map;
398  public:
399    typedef typename M::Value::Value Value;
400    typedef typename M::Key Key;
401    ///\e
402    YMap(M &map) : _map(map) {}
403    Value operator[](Key k) const {return _map[k].y;}
404    void set(Key k,Value v) {_map.set(k,typename M::Value(_map[k].x,v));}
405  };
406
407  ///Returns an \ref YMap class
408
409  ///This function just returns an \ref YMap class.
410  ///
411  ///\ingroup maps
412  ///\relates YMap
413  template<class M>
414  inline YMap<M> yMap(M &m)
415  {
416    return YMap<M>(m);
417  }
418
419  ///Constant (read only) version of \ref YMap
420
421  ///\ingroup maps
422  ///
423  template<class M>
424  class ConstYMap
425  {
426    const M &_map;
427  public:
428    typedef typename M::Value::Value Value;
429    typedef typename M::Key Key;
430    ///\e
431    ConstYMap(const M &map) : _map(map) {}
432    Value operator[](Key k) const {return _map[k].y;}
433  };
434   
435  ///Returns a \ref ConstYMap class
436
437  ///This function just returns an \ref ConstYMap class.
438  ///
439  ///\ingroup maps
440  ///\relates ConstYMap
441  template<class M>
442  inline ConstYMap<M> yMap(const M &m)
443  {
444    return ConstYMap<M>(m);
445  }
446
447
448  ///Map of the \ref xy::normSquare() "normSquare()" of an \ref xy "xy"-map
449
450  ///Map of the \ref xy::normSquare() "normSquare()" of an \ref xy "xy"-map
451  ///\ingroup maps
452  ///
453  template<class M>
454  class NormSquareMap
455  {
456    const M &_map;
457  public:
458    typedef typename M::Value::Value Value;
459    typedef typename M::Key Key;
460    ///\e
461    NormSquareMap(const M &map) : _map(map) {}
462    Value operator[](Key k) const {return _map[k].normSquare();}
463  };
464   
465  ///Returns a \ref NormSquareMap class
466
467  ///This function just returns an \ref NormSquareMap class.
468  ///
469  ///\ingroup maps
470  ///\relates NormSquareMap
471  template<class M>
472  inline NormSquareMap<M> normSquareMap(const M &m)
473  {
474    return NormSquareMap<M>(m);
475  }
476
477  /// @}
478
479
480} //namespace lemon
481
482#endif //LEMON_XY_H
Note: See TracBrowser for help on using the repository browser.