| 
alpar@906
 | 
     1  | 
/* -*- C++ -*-
  | 
| 
alpar@921
 | 
     2  | 
 * src/lemon/xy.h - Part of LEMON, a generic C++ optimization library
  | 
| 
alpar@906
 | 
     3  | 
 *
  | 
| 
alpar@906
 | 
     4  | 
 * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  | 
| 
alpar@906
 | 
     5  | 
 * (Egervary Combinatorial Optimization Research Group, EGRES).
  | 
| 
alpar@906
 | 
     6  | 
 *
  | 
| 
alpar@906
 | 
     7  | 
 * Permission to use, modify and distribute this software is granted
  | 
| 
alpar@906
 | 
     8  | 
 * provided that this copyright notice appears in all copies. For
  | 
| 
alpar@906
 | 
     9  | 
 * precise terms see the accompanying LICENSE file.
  | 
| 
alpar@906
 | 
    10  | 
 *
  | 
| 
alpar@906
 | 
    11  | 
 * This software is provided "AS IS" with no warranty of any kind,
  | 
| 
alpar@906
 | 
    12  | 
 * express or implied, and with no claim as to its suitability for any
  | 
| 
alpar@906
 | 
    13  | 
 * purpose.
  | 
| 
alpar@906
 | 
    14  | 
 *
  | 
| 
alpar@906
 | 
    15  | 
 */
  | 
| 
alpar@906
 | 
    16  | 
  | 
| 
alpar@921
 | 
    17  | 
#ifndef LEMON_XY_H
  | 
| 
alpar@921
 | 
    18  | 
#define LEMON_XY_H
  | 
| 
athos@201
 | 
    19  | 
  | 
| 
athos@201
 | 
    20  | 
#include <iostream>
  | 
| 
athos@201
 | 
    21  | 
  | 
| 
klao@491
 | 
    22  | 
///\ingroup misc
  | 
| 
alpar@249
 | 
    23  | 
///\file
  | 
| 
alpar@249
 | 
    24  | 
///\brief A simple two dimensional vector and a bounding box implementation 
  | 
| 
alpar@249
 | 
    25  | 
///
  | 
| 
alpar@921
 | 
    26  | 
/// The class \ref lemon::xy "xy" implements
  | 
| 
alpar@249
 | 
    27  | 
///a two dimensional vector with the usual
  | 
| 
alpar@249
 | 
    28  | 
/// operations.
  | 
| 
alpar@249
 | 
    29  | 
///
  | 
| 
alpar@921
 | 
    30  | 
/// The class \ref lemon::BoundingBox "BoundingBox" can be used to determine
  | 
| 
alpar@921
 | 
    31  | 
/// the rectangular bounding box a set of \ref lemon::xy "xy"'s.
  | 
| 
alpar@458
 | 
    32  | 
///
  | 
| 
alpar@458
 | 
    33  | 
///\author Attila Bernath
  | 
| 
alpar@249
 | 
    34  | 
  | 
| 
alpar@249
 | 
    35  | 
  | 
| 
alpar@921
 | 
    36  | 
namespace lemon {
 | 
| 
alpar@431
 | 
    37  | 
  | 
| 
alpar@431
 | 
    38  | 
  /// \addtogroup misc
  | 
| 
alpar@431
 | 
    39  | 
  /// @{
 | 
| 
alpar@431
 | 
    40  | 
  | 
| 
alpar@458
 | 
    41  | 
  /// A two dimensional vector (plainvector) implementation
  | 
| 
alpar@242
 | 
    42  | 
  | 
| 
alpar@458
 | 
    43  | 
  /// A two dimensional vector (plainvector) implementation
  | 
| 
alpar@458
 | 
    44  | 
  ///with the usual vector
  | 
| 
alpar@458
 | 
    45  | 
  /// operators.
  | 
| 
alpar@458
 | 
    46  | 
  ///
  | 
| 
alpar@458
 | 
    47  | 
  ///\author Attila Bernath
  | 
| 
athos@207
 | 
    48  | 
  template<typename T>
  | 
| 
athos@207
 | 
    49  | 
    class xy {
 | 
| 
athos@201
 | 
    50  | 
  | 
| 
athos@207
 | 
    51  | 
    public:
  | 
| 
athos@240
 | 
    52  | 
  | 
| 
alpar@987
 | 
    53  | 
      typedef T Value;
  | 
| 
alpar@964
 | 
    54  | 
  | 
| 
athos@240
 | 
    55  | 
      T x,y;     
  | 
| 
athos@207
 | 
    56  | 
      
  | 
| 
athos@207
 | 
    57  | 
      ///Default constructor: both coordinates become 0
  | 
| 
athos@240
 | 
    58  | 
      xy() : x(0), y(0) {}
 | 
| 
athos@201
 | 
    59  | 
  | 
| 
athos@240
 | 
    60  | 
      ///Constructing the instance from coordinates
  | 
| 
athos@514
 | 
    61  | 
      xy(T a, T b) : x(a), y(b) { }
 | 
| 
athos@201
 | 
    62  | 
  | 
| 
athos@201
 | 
    63  | 
  | 
| 
alpar@1049
 | 
    64  | 
      ///Conversion constructor
  | 
| 
alpar@1049
 | 
    65  | 
      template<class TT> xy(const xy<TT> &p) : x(p.x), y(p.y) {}
 | 
| 
alpar@1049
 | 
    66  | 
  | 
| 
athos@207
 | 
    67  | 
      ///Gives back the square of the norm of the vector
  | 
| 
athos@207
 | 
    68  | 
      T normSquare(){
 | 
| 
athos@240
 | 
    69  | 
	return x*x+y*y;
  | 
| 
athos@207
 | 
    70  | 
      };
  | 
| 
athos@201
 | 
    71  | 
  
  | 
| 
athos@207
 | 
    72  | 
      ///Increments the left hand side by u
  | 
| 
athos@207
 | 
    73  | 
      xy<T>& operator +=(const xy<T>& u){
 | 
| 
athos@240
 | 
    74  | 
	x += u.x;
  | 
| 
athos@240
 | 
    75  | 
	y += u.y;
  | 
| 
athos@207
 | 
    76  | 
	return *this;
  | 
| 
athos@207
 | 
    77  | 
      };
  | 
| 
athos@201
 | 
    78  | 
  
  | 
| 
athos@207
 | 
    79  | 
      ///Decrements the left hand side by u
  | 
| 
athos@207
 | 
    80  | 
      xy<T>& operator -=(const xy<T>& u){
 | 
| 
athos@240
 | 
    81  | 
	x -= u.x;
  | 
| 
athos@240
 | 
    82  | 
	y -= u.y;
  | 
| 
athos@207
 | 
    83  | 
	return *this;
  | 
| 
athos@207
 | 
    84  | 
      };
  | 
| 
athos@201
 | 
    85  | 
  | 
| 
athos@207
 | 
    86  | 
      ///Multiplying the left hand side with a scalar
  | 
| 
athos@207
 | 
    87  | 
      xy<T>& operator *=(const T &u){
 | 
| 
athos@240
 | 
    88  | 
	x *= u;
  | 
| 
athos@240
 | 
    89  | 
	y *= u;
  | 
| 
athos@207
 | 
    90  | 
	return *this;
  | 
| 
athos@207
 | 
    91  | 
      };
  | 
| 
athos@207
 | 
    92  | 
  | 
| 
athos@207
 | 
    93  | 
      ///Dividing the left hand side by a scalar
  | 
| 
athos@207
 | 
    94  | 
      xy<T>& operator /=(const T &u){
 | 
| 
athos@240
 | 
    95  | 
	x /= u;
  | 
| 
athos@240
 | 
    96  | 
	y /= u;
  | 
| 
athos@207
 | 
    97  | 
	return *this;
  | 
| 
athos@207
 | 
    98  | 
      };
  | 
| 
athos@201
 | 
    99  | 
  
  | 
| 
athos@207
 | 
   100  | 
      ///Returns the scalar product of two vectors
  | 
| 
athos@207
 | 
   101  | 
      T operator *(const xy<T>& u){
 | 
| 
athos@240
 | 
   102  | 
	return x*u.x+y*u.y;
  | 
| 
athos@207
 | 
   103  | 
      };
  | 
| 
athos@201
 | 
   104  | 
  
  | 
| 
athos@207
 | 
   105  | 
      ///Returns the sum of two vectors
  | 
| 
athos@207
 | 
   106  | 
      xy<T> operator+(const xy<T> &u) const {
 | 
| 
athos@207
 | 
   107  | 
	xy<T> b=*this;
  | 
| 
athos@207
 | 
   108  | 
	return b+=u;
  | 
| 
athos@207
 | 
   109  | 
      };
  | 
| 
athos@201
 | 
   110  | 
  | 
| 
alpar@1049
 | 
   111  | 
      ///Returns the neg of the vectors
  | 
| 
alpar@1049
 | 
   112  | 
      xy<T> operator-() const {
 | 
| 
alpar@1049
 | 
   113  | 
	xy<T> b=*this;
  | 
| 
alpar@1049
 | 
   114  | 
	b.x=-b.x; b.y=-b.y;
  | 
| 
alpar@1049
 | 
   115  | 
	return b;
  | 
| 
alpar@1049
 | 
   116  | 
      };
  | 
| 
alpar@1049
 | 
   117  | 
  | 
| 
athos@207
 | 
   118  | 
      ///Returns the difference of two vectors
  | 
| 
athos@207
 | 
   119  | 
      xy<T> operator-(const xy<T> &u) const {
 | 
| 
athos@207
 | 
   120  | 
	xy<T> b=*this;
  | 
| 
athos@207
 | 
   121  | 
	return b-=u;
  | 
| 
athos@207
 | 
   122  | 
      };
  | 
| 
athos@201
 | 
   123  | 
  | 
| 
athos@207
 | 
   124  | 
      ///Returns a vector multiplied by a scalar
  | 
| 
athos@207
 | 
   125  | 
      xy<T> operator*(const T &u) const {
 | 
| 
athos@207
 | 
   126  | 
	xy<T> b=*this;
  | 
| 
athos@207
 | 
   127  | 
	return b*=u;
  | 
| 
athos@207
 | 
   128  | 
      };
  | 
| 
athos@201
 | 
   129  | 
  | 
| 
athos@207
 | 
   130  | 
      ///Returns a vector divided by a scalar
  | 
| 
athos@207
 | 
   131  | 
      xy<T> operator/(const T &u) const {
 | 
| 
athos@207
 | 
   132  | 
	xy<T> b=*this;
  | 
| 
athos@207
 | 
   133  | 
	return b/=u;
  | 
| 
athos@207
 | 
   134  | 
      };
  | 
| 
athos@201
 | 
   135  | 
  | 
| 
athos@207
 | 
   136  | 
      ///Testing equality
  | 
| 
athos@207
 | 
   137  | 
      bool operator==(const xy<T> &u){
 | 
| 
athos@240
 | 
   138  | 
	return (x==u.x) && (y==u.y);
  | 
| 
athos@207
 | 
   139  | 
      };
  | 
| 
athos@201
 | 
   140  | 
  | 
| 
athos@207
 | 
   141  | 
      ///Testing inequality
  | 
| 
athos@207
 | 
   142  | 
      bool operator!=(xy u){
 | 
| 
athos@240
 | 
   143  | 
	return  (x!=u.x) || (y!=u.y);
  | 
| 
athos@207
 | 
   144  | 
      };
  | 
| 
athos@201
 | 
   145  | 
  | 
| 
athos@207
 | 
   146  | 
    };
  | 
| 
athos@201
 | 
   147  | 
  | 
| 
alpar@1071
 | 
   148  | 
  ///Returns a vector multiplied by a scalar
  | 
| 
alpar@1083
 | 
   149  | 
  | 
| 
alpar@1083
 | 
   150  | 
  ///Returns a vector multiplied by a scalar
  | 
| 
alpar@1083
 | 
   151  | 
  ///\relates xy
  | 
| 
alpar@1071
 | 
   152  | 
  template<typename T> xy<T> operator*(const T &u,const xy<T> &x) {
 | 
| 
alpar@1071
 | 
   153  | 
    return x*u;
  | 
| 
alpar@1071
 | 
   154  | 
  };
  | 
| 
alpar@1071
 | 
   155  | 
  | 
| 
alpar@814
 | 
   156  | 
  ///Read a plainvector from a stream
  | 
| 
alpar@814
 | 
   157  | 
  | 
| 
alpar@967
 | 
   158  | 
  ///Read a plainvector from a stream
  | 
| 
alpar@814
 | 
   159  | 
  ///\relates xy
  | 
| 
alpar@814
 | 
   160  | 
  ///
  | 
| 
athos@207
 | 
   161  | 
  template<typename T>
  | 
| 
athos@207
 | 
   162  | 
  inline
  | 
| 
athos@207
 | 
   163  | 
  std::istream& operator>>(std::istream &is, xy<T> &z)
  | 
| 
athos@207
 | 
   164  | 
  {
 | 
| 
athos@240
 | 
   165  | 
  | 
| 
athos@240
 | 
   166  | 
    is >> z.x >> z.y;
  | 
| 
athos@207
 | 
   167  | 
    return is;
  | 
| 
athos@207
 | 
   168  | 
  }
  | 
| 
athos@201
 | 
   169  | 
  | 
| 
alpar@814
 | 
   170  | 
  ///Write a plainvector to a stream
  | 
| 
alpar@814
 | 
   171  | 
  | 
| 
alpar@967
 | 
   172  | 
  ///Write a plainvector to a stream
  | 
| 
alpar@814
 | 
   173  | 
  ///\relates xy
  | 
| 
alpar@814
 | 
   174  | 
  ///
  | 
| 
athos@207
 | 
   175  | 
  template<typename T>
  | 
| 
athos@207
 | 
   176  | 
  inline
  | 
| 
athos@207
 | 
   177  | 
  std::ostream& operator<<(std::ostream &os, xy<T> z)
  | 
| 
athos@207
 | 
   178  | 
  {
 | 
| 
athos@240
 | 
   179  | 
    os << "(" << z.x << ", " << z.y << ")";
 | 
| 
athos@207
 | 
   180  | 
    return os;
  | 
| 
athos@207
 | 
   181  | 
  }
  | 
| 
athos@207
 | 
   182  | 
  | 
| 
athos@244
 | 
   183  | 
  | 
| 
alpar@458
 | 
   184  | 
  /// A class to calculate or store the bounding box of plainvectors.
  | 
| 
alpar@458
 | 
   185  | 
  | 
| 
alpar@458
 | 
   186  | 
  /// A class to calculate or store the bounding box of plainvectors.
  | 
| 
alpar@458
 | 
   187  | 
  ///
  | 
| 
alpar@458
 | 
   188  | 
  ///\author Attila Bernath
  | 
| 
athos@244
 | 
   189  | 
  template<typename T>
  | 
| 
athos@244
 | 
   190  | 
    class BoundingBox {
 | 
| 
athos@244
 | 
   191  | 
      xy<T> bottom_left, top_right;
  | 
| 
athos@244
 | 
   192  | 
      bool _empty;
  | 
| 
athos@244
 | 
   193  | 
    public:
  | 
| 
athos@244
 | 
   194  | 
      
  | 
| 
athos@244
 | 
   195  | 
      ///Default constructor: an empty bounding box
  | 
| 
athos@244
 | 
   196  | 
      BoundingBox() { _empty = true; }
 | 
| 
athos@244
 | 
   197  | 
  | 
| 
athos@244
 | 
   198  | 
      ///Constructing the instance from one point
  | 
| 
athos@244
 | 
   199  | 
      BoundingBox(xy<T> a) { bottom_left=top_right=a; _empty = false; }
 | 
| 
athos@244
 | 
   200  | 
  | 
| 
athos@244
 | 
   201  | 
      ///Is there any point added
  | 
| 
athos@244
 | 
   202  | 
      bool empty() const {
 | 
| 
athos@244
 | 
   203  | 
	return _empty;
  | 
| 
athos@244
 | 
   204  | 
      }
  | 
| 
athos@244
 | 
   205  | 
  | 
| 
athos@244
 | 
   206  | 
      ///Gives back the bottom left corner (if the bounding box is empty, then the return value is not defined) 
  | 
| 
athos@244
 | 
   207  | 
      xy<T> bottomLeft() const {
 | 
| 
athos@244
 | 
   208  | 
	return bottom_left;
  | 
| 
athos@244
 | 
   209  | 
      };
  | 
| 
athos@244
 | 
   210  | 
  | 
| 
athos@244
 | 
   211  | 
      ///Gives back the top right corner (if the bounding box is empty, then the return value is not defined) 
  | 
| 
athos@244
 | 
   212  | 
      xy<T> topRight() const {
 | 
| 
athos@244
 | 
   213  | 
	return top_right;
  | 
| 
athos@244
 | 
   214  | 
      };
  | 
| 
athos@244
 | 
   215  | 
  | 
| 
alpar@1045
 | 
   216  | 
      ///Gives back the bottom right corner (if the bounding box is empty, then the return value is not defined) 
  | 
| 
alpar@1045
 | 
   217  | 
      xy<T> bottomRight() const {
 | 
| 
alpar@1045
 | 
   218  | 
	return xy<T>(top_right.x,bottom_left.y);
  | 
| 
alpar@1045
 | 
   219  | 
      };
  | 
| 
alpar@1045
 | 
   220  | 
  | 
| 
alpar@1045
 | 
   221  | 
      ///Gives back the top left corner (if the bounding box is empty, then the return value is not defined) 
  | 
| 
alpar@1045
 | 
   222  | 
      xy<T> topLeft() const {
 | 
| 
alpar@1045
 | 
   223  | 
	return xy<T>(bottom_left.x,top_right.y);
  | 
| 
alpar@1045
 | 
   224  | 
      };
  | 
| 
alpar@1045
 | 
   225  | 
  | 
| 
alpar@1045
 | 
   226  | 
      ///Gives back the bottom of the box (if the bounding box is empty, then the return value is not defined) 
  | 
| 
alpar@1045
 | 
   227  | 
      T bottom() const {
 | 
| 
alpar@1045
 | 
   228  | 
	return bottom_left.y;
  | 
| 
alpar@1045
 | 
   229  | 
      };
  | 
| 
alpar@1045
 | 
   230  | 
  | 
| 
alpar@1045
 | 
   231  | 
      ///Gives back the top of the box (if the bounding box is empty, then the return value is not defined) 
  | 
| 
alpar@1045
 | 
   232  | 
      T top() const {
 | 
| 
alpar@1045
 | 
   233  | 
	return top_right.y;
  | 
| 
alpar@1045
 | 
   234  | 
      };
  | 
| 
alpar@1045
 | 
   235  | 
  | 
| 
alpar@1045
 | 
   236  | 
      ///Gives back the left side of the box (if the bounding box is empty, then the return value is not defined) 
  | 
| 
alpar@1045
 | 
   237  | 
      T left() const {
 | 
| 
alpar@1045
 | 
   238  | 
	return bottom_left.x;
  | 
| 
alpar@1045
 | 
   239  | 
      };
  | 
| 
alpar@1045
 | 
   240  | 
  | 
| 
alpar@1045
 | 
   241  | 
      ///Gives back the right side of the box (if the bounding box is empty, then the return value is not defined) 
  | 
| 
alpar@1045
 | 
   242  | 
      T right() const {
 | 
| 
alpar@1045
 | 
   243  | 
	return top_right.x;
  | 
| 
alpar@1045
 | 
   244  | 
      };
  | 
| 
alpar@1045
 | 
   245  | 
  | 
| 
athos@244
 | 
   246  | 
      ///Checks whether a point is inside a bounding box
  | 
| 
athos@244
 | 
   247  | 
      bool inside(const xy<T>& u){
 | 
| 
athos@244
 | 
   248  | 
	if (_empty)
  | 
| 
athos@244
 | 
   249  | 
	  return false;
  | 
| 
athos@244
 | 
   250  | 
	else{
 | 
| 
athos@244
 | 
   251  | 
	  return ((u.x-bottom_left.x)*(top_right.x-u.x) >= 0 &&
  | 
| 
athos@244
 | 
   252  | 
		  (u.y-bottom_left.y)*(top_right.y-u.y) >= 0 );
  | 
| 
athos@244
 | 
   253  | 
	}
  | 
| 
athos@244
 | 
   254  | 
      }
  | 
| 
athos@244
 | 
   255  | 
  
  | 
| 
athos@244
 | 
   256  | 
      ///Increments a bounding box with a point
  | 
| 
athos@244
 | 
   257  | 
      BoundingBox& operator +=(const xy<T>& u){
 | 
| 
athos@244
 | 
   258  | 
	if (_empty){
 | 
| 
athos@244
 | 
   259  | 
	  bottom_left=top_right=u;
  | 
| 
athos@244
 | 
   260  | 
	  _empty = false;
  | 
| 
athos@244
 | 
   261  | 
	}
  | 
| 
athos@244
 | 
   262  | 
	else{
 | 
| 
athos@244
 | 
   263  | 
	  if (bottom_left.x > u.x) bottom_left.x = u.x;
  | 
| 
athos@244
 | 
   264  | 
	  if (bottom_left.y > u.y) bottom_left.y = u.y;
  | 
| 
athos@244
 | 
   265  | 
	  if (top_right.x < u.x) top_right.x = u.x;
  | 
| 
athos@244
 | 
   266  | 
	  if (top_right.y < u.y) top_right.y = u.y;
  | 
| 
athos@244
 | 
   267  | 
	}
  | 
| 
athos@244
 | 
   268  | 
	return *this;
  | 
| 
athos@244
 | 
   269  | 
      };
  | 
| 
athos@244
 | 
   270  | 
  
  | 
| 
athos@244
 | 
   271  | 
      ///Sums a bounding box and a point
  | 
| 
athos@244
 | 
   272  | 
      BoundingBox operator +(const xy<T>& u){
 | 
| 
athos@244
 | 
   273  | 
	BoundingBox b = *this;
  | 
| 
athos@244
 | 
   274  | 
	return b += u;
  | 
| 
athos@244
 | 
   275  | 
      };
  | 
| 
athos@244
 | 
   276  | 
  | 
| 
athos@244
 | 
   277  | 
      ///Increments a bounding box with an other bounding box
  | 
| 
athos@244
 | 
   278  | 
      BoundingBox& operator +=(const BoundingBox &u){
 | 
| 
athos@244
 | 
   279  | 
	if ( !u.empty() ){
 | 
| 
athos@244
 | 
   280  | 
	  *this += u.bottomLeft();
  | 
| 
athos@244
 | 
   281  | 
	  *this += u.topRight();
  | 
| 
athos@244
 | 
   282  | 
	}
  | 
| 
athos@244
 | 
   283  | 
	return *this;
  | 
| 
athos@244
 | 
   284  | 
      };
  | 
| 
athos@244
 | 
   285  | 
  
  | 
| 
athos@244
 | 
   286  | 
      ///Sums two bounding boxes
  | 
| 
athos@244
 | 
   287  | 
      BoundingBox operator +(const BoundingBox& u){
 | 
| 
athos@244
 | 
   288  | 
	BoundingBox b = *this;
  | 
| 
athos@244
 | 
   289  | 
	return b += u;
  | 
| 
athos@244
 | 
   290  | 
      };
  | 
| 
athos@244
 | 
   291  | 
  | 
| 
athos@244
 | 
   292  | 
    };//class Boundingbox
  | 
| 
athos@244
 | 
   293  | 
  | 
| 
athos@244
 | 
   294  | 
  | 
| 
alpar@431
 | 
   295  | 
  /// @}
  | 
| 
athos@244
 | 
   296  | 
  | 
| 
athos@244
 | 
   297  | 
  | 
| 
alpar@921
 | 
   298  | 
} //namespace lemon
  | 
| 
athos@201
 | 
   299  | 
  | 
| 
alpar@921
 | 
   300  | 
#endif //LEMON_XY_H
  |