lemon/xy.h
changeset 1435 8e85e6bbefdf
parent 1426 91eb70983697
child 1588 b79bcba43661
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/lemon/xy.h	Mon May 23 04:48:14 2005 +0000
     1.3 @@ -0,0 +1,518 @@
     1.4 +/* -*- C++ -*-
     1.5 + * lemon/xy.h - Part of LEMON, a generic C++ optimization library
     1.6 + *
     1.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     1.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
     1.9 + *
    1.10 + * Permission to use, modify and distribute this software is granted
    1.11 + * provided that this copyright notice appears in all copies. For
    1.12 + * precise terms see the accompanying LICENSE file.
    1.13 + *
    1.14 + * This software is provided "AS IS" with no warranty of any kind,
    1.15 + * express or implied, and with no claim as to its suitability for any
    1.16 + * purpose.
    1.17 + *
    1.18 + */
    1.19 +
    1.20 +#ifndef LEMON_XY_H
    1.21 +#define LEMON_XY_H
    1.22 +
    1.23 +#include <iostream>
    1.24 +#include <lemon/utility.h>
    1.25 +
    1.26 +///\ingroup misc
    1.27 +///\file
    1.28 +///\brief A simple two dimensional vector and a bounding box implementation 
    1.29 +///
    1.30 +/// The class \ref lemon::xy "xy" implements
    1.31 +///a two dimensional vector with the usual
    1.32 +/// operations.
    1.33 +///
    1.34 +/// The class \ref lemon::BoundingBox "BoundingBox" can be used to determine
    1.35 +/// the rectangular bounding box of a set of \ref lemon::xy "xy"'s.
    1.36 +///
    1.37 +///\author Attila Bernath
    1.38 +
    1.39 +
    1.40 +namespace lemon {
    1.41 +
    1.42 +  /// \addtogroup misc
    1.43 +  /// @{
    1.44 +
    1.45 +  /// A simple two dimensional vector (plainvector) implementation
    1.46 +
    1.47 +  /// A simple two dimensional vector (plainvector) implementation
    1.48 +  ///with the usual vector
    1.49 +  /// operators.
    1.50 +  ///
    1.51 +  ///\author Attila Bernath
    1.52 +  template<typename T>
    1.53 +    class xy {
    1.54 +
    1.55 +    public:
    1.56 +
    1.57 +      typedef T Value;
    1.58 +
    1.59 +      T x,y;     
    1.60 +      
    1.61 +      ///Default constructor
    1.62 +      xy() {}
    1.63 +
    1.64 +      ///Constructing the instance from coordinates
    1.65 +      xy(T a, T b) : x(a), y(b) { }
    1.66 +
    1.67 +
    1.68 +      ///Conversion constructor
    1.69 +      template<class TT> xy(const xy<TT> &p) : x(p.x), y(p.y) {}
    1.70 +
    1.71 +      ///Gives back the square of the norm of the vector
    1.72 +      T normSquare() const {
    1.73 +        return x*x+y*y;
    1.74 +      }
    1.75 +  
    1.76 +      ///Increments the left hand side by u
    1.77 +      xy<T>& operator +=(const xy<T>& u) {
    1.78 +        x += u.x;
    1.79 +        y += u.y;
    1.80 +        return *this;
    1.81 +      }
    1.82 +  
    1.83 +      ///Decrements the left hand side by u
    1.84 +      xy<T>& operator -=(const xy<T>& u) {
    1.85 +        x -= u.x;
    1.86 +        y -= u.y;
    1.87 +        return *this;
    1.88 +      }
    1.89 +
    1.90 +      ///Multiplying the left hand side with a scalar
    1.91 +      xy<T>& operator *=(const T &u) {
    1.92 +        x *= u;
    1.93 +        y *= u;
    1.94 +        return *this;
    1.95 +      }
    1.96 +
    1.97 +      ///Dividing the left hand side by a scalar
    1.98 +      xy<T>& operator /=(const T &u) {
    1.99 +        x /= u;
   1.100 +        y /= u;
   1.101 +        return *this;
   1.102 +      }
   1.103 +  
   1.104 +      ///Returns the scalar product of two vectors
   1.105 +      T operator *(const xy<T>& u) const {
   1.106 +        return x*u.x+y*u.y;
   1.107 +      }
   1.108 +  
   1.109 +      ///Returns the sum of two vectors
   1.110 +      xy<T> operator+(const xy<T> &u) const {
   1.111 +        xy<T> b=*this;
   1.112 +        return b+=u;
   1.113 +      }
   1.114 +
   1.115 +      ///Returns the neg of the vectors
   1.116 +      xy<T> operator-() const {
   1.117 +        xy<T> b=*this;
   1.118 +        b.x=-b.x; b.y=-b.y;
   1.119 +        return b;
   1.120 +      }
   1.121 +
   1.122 +      ///Returns the difference of two vectors
   1.123 +      xy<T> operator-(const xy<T> &u) const {
   1.124 +        xy<T> b=*this;
   1.125 +        return b-=u;
   1.126 +      }
   1.127 +
   1.128 +      ///Returns a vector multiplied by a scalar
   1.129 +      xy<T> operator*(const T &u) const {
   1.130 +        xy<T> b=*this;
   1.131 +        return b*=u;
   1.132 +      }
   1.133 +
   1.134 +      ///Returns a vector divided by a scalar
   1.135 +      xy<T> operator/(const T &u) const {
   1.136 +        xy<T> b=*this;
   1.137 +        return b/=u;
   1.138 +      }
   1.139 +
   1.140 +      ///Testing equality
   1.141 +      bool operator==(const xy<T> &u) const {
   1.142 +        return (x==u.x) && (y==u.y);
   1.143 +      }
   1.144 +
   1.145 +      ///Testing inequality
   1.146 +      bool operator!=(xy u) const {
   1.147 +        return  (x!=u.x) || (y!=u.y);
   1.148 +      }
   1.149 +
   1.150 +    };
   1.151 +
   1.152 +  ///Returns a vector multiplied by a scalar
   1.153 +
   1.154 +  ///Returns a vector multiplied by a scalar
   1.155 +  ///\relates xy
   1.156 +  template<typename T> xy<T> operator*(const T &u,const xy<T> &x) {
   1.157 +    return x*u;
   1.158 +  }
   1.159 +
   1.160 +  ///Read a plainvector from a stream
   1.161 +
   1.162 +  ///Read a plainvector from a stream
   1.163 +  ///\relates xy
   1.164 +  ///
   1.165 +  template<typename T>
   1.166 +  inline std::istream& operator>>(std::istream &is, xy<T> &z) {
   1.167 +    char c;
   1.168 +    if (is >> c) {
   1.169 +      if (c != '(') is.putback(c);
   1.170 +    } else {
   1.171 +      is.clear();
   1.172 +    }
   1.173 +    if (!(is >> z.x)) return is;
   1.174 +    if (is >> c) {
   1.175 +      if (c != ',') is.putback(c);
   1.176 +    } else {
   1.177 +      is.clear();
   1.178 +    }
   1.179 +    if (!(is >> z.y)) return is;
   1.180 +    if (is >> c) {
   1.181 +      if (c != ')') is.putback(c);
   1.182 +    } else {
   1.183 +      is.clear();
   1.184 +    }
   1.185 +    return is;
   1.186 +  }
   1.187 +
   1.188 +  ///Write a plainvector to a stream
   1.189 +
   1.190 +  ///Write a plainvector to a stream
   1.191 +  ///\relates xy
   1.192 +  ///
   1.193 +  template<typename T>
   1.194 +  inline std::ostream& operator<<(std::ostream &os, const xy<T>& z)
   1.195 +  {
   1.196 +    os << "(" << z.x << ", " << z.y << ")";
   1.197 +    return os;
   1.198 +  }
   1.199 +
   1.200 +  ///Rotate by 90 degrees
   1.201 +
   1.202 +  ///Returns its parameter rotated by 90 degrees in positive direction.
   1.203 +  ///\relates xy
   1.204 +  ///
   1.205 +  template<typename T>
   1.206 +  inline xy<T> rot90(const xy<T> &z)
   1.207 +  {
   1.208 +    return xy<T>(-z.y,z.x);
   1.209 +  }
   1.210 +
   1.211 +  ///Rotate by 270 degrees
   1.212 +
   1.213 +  ///Returns its parameter rotated by 90 degrees in negative direction.
   1.214 +  ///\relates xy
   1.215 +  ///
   1.216 +  template<typename T>
   1.217 +  inline xy<T> rot270(const xy<T> &z)
   1.218 +  {
   1.219 +    return xy<T>(z.y,-z.x);
   1.220 +  }
   1.221 +
   1.222 +  
   1.223 +
   1.224 +  /// A class to calculate or store the bounding box of plainvectors.
   1.225 +
   1.226 +  /// A class to calculate or store the bounding box of plainvectors.
   1.227 +  ///
   1.228 +  ///\author Attila Bernath
   1.229 +  template<typename T>
   1.230 +    class BoundingBox {
   1.231 +      xy<T> bottom_left, top_right;
   1.232 +      bool _empty;
   1.233 +    public:
   1.234 +      
   1.235 +      ///Default constructor: creates an empty bounding box
   1.236 +      BoundingBox() { _empty = true; }
   1.237 +
   1.238 +      ///Constructing the instance from one point
   1.239 +      BoundingBox(xy<T> a) { bottom_left=top_right=a; _empty = false; }
   1.240 +
   1.241 +      ///Were any points added?
   1.242 +      bool empty() const {
   1.243 +        return _empty;
   1.244 +      }
   1.245 +
   1.246 +      ///Makes the BoundingBox empty
   1.247 +      void clear() {
   1.248 +        _empty=1;
   1.249 +      }
   1.250 +
   1.251 +      ///Gives back the bottom left corner (if the bounding box is empty, then the return value is not defined) 
   1.252 +      xy<T> bottomLeft() const {
   1.253 +        return bottom_left;
   1.254 +      }
   1.255 +
   1.256 +      ///Gives back the top right corner (if the bounding box is empty, then the return value is not defined) 
   1.257 +      xy<T> topRight() const {
   1.258 +        return top_right;
   1.259 +      }
   1.260 +
   1.261 +      ///Gives back the bottom right corner (if the bounding box is empty, then the return value is not defined) 
   1.262 +      xy<T> bottomRight() const {
   1.263 +        return xy<T>(top_right.x,bottom_left.y);
   1.264 +      }
   1.265 +
   1.266 +      ///Gives back the top left corner (if the bounding box is empty, then the return value is not defined) 
   1.267 +      xy<T> topLeft() const {
   1.268 +        return xy<T>(bottom_left.x,top_right.y);
   1.269 +      }
   1.270 +
   1.271 +      ///Gives back the bottom of the box (if the bounding box is empty, then the return value is not defined) 
   1.272 +      T bottom() const {
   1.273 +        return bottom_left.y;
   1.274 +      }
   1.275 +
   1.276 +      ///Gives back the top of the box (if the bounding box is empty, then the return value is not defined) 
   1.277 +      T top() const {
   1.278 +        return top_right.y;
   1.279 +      }
   1.280 +
   1.281 +      ///Gives back the left side of the box (if the bounding box is empty, then the return value is not defined) 
   1.282 +      T left() const {
   1.283 +        return bottom_left.x;
   1.284 +      }
   1.285 +
   1.286 +      ///Gives back the right side of the box (if the bounding box is empty, then the return value is not defined) 
   1.287 +      T right() const {
   1.288 +        return top_right.x;
   1.289 +      }
   1.290 +
   1.291 +      ///Gives back the height of the box (if the bounding box is empty, then the return value is not defined) 
   1.292 +      T height() const {
   1.293 +        return top_right.y-bottom_left.y;
   1.294 +      }
   1.295 +
   1.296 +      ///Gives back the width of the box (if the bounding box is empty, then the return value is not defined) 
   1.297 +      T width() const {
   1.298 +        return top_right.x-bottom_left.x;
   1.299 +      }
   1.300 +
   1.301 +      ///Checks whether a point is inside a bounding box
   1.302 +      bool inside(const xy<T>& u){
   1.303 +        if (_empty)
   1.304 +          return false;
   1.305 +        else{
   1.306 +          return ((u.x-bottom_left.x)*(top_right.x-u.x) >= 0 &&
   1.307 +              (u.y-bottom_left.y)*(top_right.y-u.y) >= 0 );
   1.308 +        }
   1.309 +      }
   1.310 +  
   1.311 +      ///Increments a bounding box with a point
   1.312 +      BoundingBox& operator +=(const xy<T>& u){
   1.313 +        if (_empty){
   1.314 +          bottom_left=top_right=u;
   1.315 +          _empty = false;
   1.316 +        }
   1.317 +        else{
   1.318 +          if (bottom_left.x > u.x) bottom_left.x = u.x;
   1.319 +          if (bottom_left.y > u.y) bottom_left.y = u.y;
   1.320 +          if (top_right.x < u.x) top_right.x = u.x;
   1.321 +          if (top_right.y < u.y) top_right.y = u.y;
   1.322 +        }
   1.323 +        return *this;
   1.324 +      }
   1.325 +  
   1.326 +      ///Sums a bounding box and a point
   1.327 +      BoundingBox operator +(const xy<T>& u){
   1.328 +        BoundingBox b = *this;
   1.329 +        return b += u;
   1.330 +      }
   1.331 +
   1.332 +      ///Increments a bounding box with an other bounding box
   1.333 +      BoundingBox& operator +=(const BoundingBox &u){
   1.334 +        if ( !u.empty() ){
   1.335 +          *this += u.bottomLeft();
   1.336 +          *this += u.topRight();
   1.337 +        }
   1.338 +        return *this;
   1.339 +      }
   1.340 +  
   1.341 +      ///Sums two bounding boxes
   1.342 +      BoundingBox operator +(const BoundingBox& u){
   1.343 +        BoundingBox b = *this;
   1.344 +        return b += u;
   1.345 +      }
   1.346 +
   1.347 +    };//class Boundingbox
   1.348 +
   1.349 +
   1.350 +  ///Map of x-coordinates of an xy<>-map
   1.351 +
   1.352 +  ///\ingroup maps
   1.353 +  ///
   1.354 +  template<class M>
   1.355 +  class XMap 
   1.356 +  {
   1.357 +    typename SmartReference<M>::Type _map;
   1.358 +  public:
   1.359 +    typedef True NeedCopy;
   1.360 +
   1.361 +    typedef typename M::Value::Value Value;
   1.362 +    typedef typename M::Key Key;
   1.363 +    ///\e
   1.364 +    XMap(typename SmartParameter<M>::Type map) : _map(map) {}
   1.365 +    Value operator[](Key k) const {return _map[k].x;}
   1.366 +    void set(Key k,Value v) {_map.set(k,typename M::Value(v,_map[k].y));}
   1.367 +  };
   1.368 +    
   1.369 +  ///Returns an \ref XMap class
   1.370 +
   1.371 +  ///This function just returns an \ref XMap class.
   1.372 +  ///
   1.373 +  ///\ingroup maps
   1.374 +  ///\relates XMap
   1.375 +  template<class M> 
   1.376 +  inline XMap<M> xMap(M &m) 
   1.377 +  {
   1.378 +    return XMap<M>(m);
   1.379 +  }
   1.380 +
   1.381 +  template<class M> 
   1.382 +  inline XMap<M> xMap(const M &m) 
   1.383 +  {
   1.384 +    return XMap<M>(m);
   1.385 +  }
   1.386 +
   1.387 +  ///Constant (read only) version of \ref XMap
   1.388 +
   1.389 +  ///\ingroup maps
   1.390 +  ///
   1.391 +  template<class M>
   1.392 +  class ConstXMap 
   1.393 +  {
   1.394 +    typename SmartConstReference<M>::Type _map;
   1.395 +  public:
   1.396 +    typedef True NeedCopy;
   1.397 +
   1.398 +    typedef typename M::Value::Value Value;
   1.399 +    typedef typename M::Key Key;
   1.400 +    ///\e
   1.401 +    ConstXMap(const M &map) : _map(map) {}
   1.402 +    Value operator[](Key k) const {return _map[k].x;}
   1.403 +  };
   1.404 +    
   1.405 +  ///Returns a \ref ConstXMap class
   1.406 +
   1.407 +  ///This function just returns an \ref ConstXMap class.
   1.408 +  ///
   1.409 +  ///\ingroup maps
   1.410 +  ///\relates ConstXMap
   1.411 +  template<class M> 
   1.412 +  inline ConstXMap<M> xMap(const M &m) 
   1.413 +  {
   1.414 +    return ConstXMap<M>(m);
   1.415 +  }
   1.416 +
   1.417 +  ///Map of y-coordinates of an xy<>-map
   1.418 +    
   1.419 +  ///\ingroup maps
   1.420 +  ///
   1.421 +  template<class M>
   1.422 +  class YMap 
   1.423 +  {
   1.424 +    typename SmartReference<M>::Type _map;
   1.425 +  public:
   1.426 +    typedef True NeedCopy;
   1.427 +
   1.428 +    typedef typename M::Value::Value Value;
   1.429 +    typedef typename M::Key Key;
   1.430 +    ///\e
   1.431 +    YMap(typename SmartParameter<M>::Type map) : _map(map) {}
   1.432 +    Value operator[](Key k) const {return _map[k].y;}
   1.433 +    void set(Key k,Value v) {_map.set(k,typename M::Value(_map[k].x,v));}
   1.434 +  };
   1.435 +
   1.436 +  ///Returns an \ref YMap class
   1.437 +
   1.438 +  ///This function just returns an \ref YMap class.
   1.439 +  ///
   1.440 +  ///\ingroup maps
   1.441 +  ///\relates YMap
   1.442 +  template<class M> 
   1.443 +  inline YMap<M> yMap(M &m) 
   1.444 +  {
   1.445 +    return YMap<M>(m);
   1.446 +  }
   1.447 +
   1.448 +  template<class M> 
   1.449 +  inline YMap<M> yMap(const M &m) 
   1.450 +  {
   1.451 +    return YMap<M>(m);
   1.452 +  }
   1.453 +
   1.454 +  ///Constant (read only) version of \ref YMap
   1.455 +
   1.456 +  ///\ingroup maps
   1.457 +  ///
   1.458 +  template<class M>
   1.459 +  class ConstYMap 
   1.460 +  {
   1.461 +    typename SmartConstReference<M>::Type _map;
   1.462 +  public:
   1.463 +    typedef True NeedCopy;
   1.464 +
   1.465 +    typedef typename M::Value::Value Value;
   1.466 +    typedef typename M::Key Key;
   1.467 +    ///\e
   1.468 +    ConstYMap(const M &map) : _map(map) {}
   1.469 +    Value operator[](Key k) const {return _map[k].y;}
   1.470 +  };
   1.471 +    
   1.472 +  ///Returns a \ref ConstYMap class
   1.473 +
   1.474 +  ///This function just returns an \ref ConstYMap class.
   1.475 +  ///
   1.476 +  ///\ingroup maps
   1.477 +  ///\relates ConstYMap
   1.478 +  template<class M> 
   1.479 +  inline ConstYMap<M> yMap(const M &m) 
   1.480 +  {
   1.481 +    return ConstYMap<M>(m);
   1.482 +  }
   1.483 +
   1.484 +
   1.485 +  ///Map of the \ref xy::normSquare() "normSquare()" of an \ref xy "xy"-map
   1.486 +
   1.487 +  ///Map of the \ref xy::normSquare() "normSquare()" of an \ref xy "xy"-map
   1.488 +  ///\ingroup maps
   1.489 +  ///
   1.490 +  template<class M>
   1.491 +  class NormSquareMap 
   1.492 +  {
   1.493 +    typename SmartConstReference<M>::Type _map;
   1.494 +  public:
   1.495 +    typedef True NeedCopy;
   1.496 +
   1.497 +    typedef typename M::Value::Value Value;
   1.498 +    typedef typename M::Key Key;
   1.499 +    ///\e
   1.500 +    NormSquareMap(const M &map) : _map(map) {}
   1.501 +    Value operator[](Key k) const {return _map[k].normSquare();}
   1.502 +  };
   1.503 +    
   1.504 +  ///Returns a \ref NormSquareMap class
   1.505 +
   1.506 +  ///This function just returns an \ref NormSquareMap class.
   1.507 +  ///
   1.508 +  ///\ingroup maps
   1.509 +  ///\relates NormSquareMap
   1.510 +  template<class M> 
   1.511 +  inline NormSquareMap<M> normSquareMap(const M &m) 
   1.512 +  {
   1.513 +    return NormSquareMap<M>(m);
   1.514 +  }
   1.515 +
   1.516 +  /// @}
   1.517 +
   1.518 +
   1.519 +} //namespace lemon
   1.520 +
   1.521 +#endif //LEMON_XY_H