lemon/dim2.h
author deba
Thu, 20 Mar 2008 16:25:47 +0000
changeset 2596 9c00e972cdfd
parent 2553 bfced05fa852
permissions -rw-r--r--
Back porting commit 81563e019fa4
alpar@906
     1
/* -*- C++ -*-
alpar@906
     2
 *
alpar@1956
     3
 * This file is a part of LEMON, a generic C++ optimization library
alpar@1956
     4
 *
alpar@2553
     5
 * Copyright (C) 2003-2008
alpar@1956
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
alpar@1359
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
alpar@906
     8
 *
alpar@906
     9
 * Permission to use, modify and distribute this software is granted
alpar@906
    10
 * provided that this copyright notice appears in all copies. For
alpar@906
    11
 * precise terms see the accompanying LICENSE file.
alpar@906
    12
 *
alpar@906
    13
 * This software is provided "AS IS" with no warranty of any kind,
alpar@906
    14
 * express or implied, and with no claim as to its suitability for any
alpar@906
    15
 * purpose.
alpar@906
    16
 *
alpar@906
    17
 */
alpar@906
    18
alpar@2207
    19
#ifndef LEMON_DIM2_H
alpar@2207
    20
#define LEMON_DIM2_H
athos@201
    21
athos@201
    22
#include <iostream>
deba@1993
    23
#include <lemon/bits/utility.h>
athos@201
    24
klao@491
    25
///\ingroup misc
alpar@249
    26
///\file
alpar@249
    27
///\brief A simple two dimensional vector and a bounding box implementation 
alpar@249
    28
///
alpar@2207
    29
/// The class \ref lemon::dim2::Point "dim2::Point" implements
alpar@249
    30
///a two dimensional vector with the usual
alpar@249
    31
/// operations.
alpar@249
    32
///
alpar@2207
    33
/// The class \ref lemon::dim2::BoundingBox "dim2::BoundingBox"
alpar@2207
    34
/// can be used to determine
alpar@2207
    35
/// the rectangular bounding box of a set of
alpar@2207
    36
/// \ref lemon::dim2::Point "dim2::Point"'s.
alpar@458
    37
///
alpar@458
    38
///\author Attila Bernath
alpar@249
    39
alpar@249
    40
alpar@921
    41
namespace lemon {
alpar@431
    42
alpar@2207
    43
  ///Tools for handling two dimensional coordinates
alpar@2207
    44
alpar@2207
    45
  ///This namespace is a storage of several
alpar@2207
    46
  ///tools for handling two dimensional coordinates
alpar@2207
    47
  namespace dim2 {
alpar@2207
    48
alpar@431
    49
  /// \addtogroup misc
alpar@431
    50
  /// @{
alpar@431
    51
alpar@1257
    52
  /// A simple two dimensional vector (plainvector) implementation
alpar@242
    53
alpar@1257
    54
  /// A simple two dimensional vector (plainvector) implementation
kpeter@2562
    55
  /// with the usual vector operations.
athos@207
    56
  template<typename T>
alpar@2207
    57
    class Point {
athos@201
    58
athos@207
    59
    public:
athos@240
    60
alpar@987
    61
      typedef T Value;
alpar@964
    62
kpeter@2562
    63
      ///First coordinate
alpar@1974
    64
      T x;
kpeter@2562
    65
      ///Second coordinate
alpar@1974
    66
      T y;     
athos@207
    67
      
alpar@1257
    68
      ///Default constructor
alpar@2207
    69
      Point() {}
athos@201
    70
alpar@2157
    71
      ///Construct an instance from coordinates
alpar@2207
    72
      Point(T a, T b) : x(a), y(b) { }
athos@201
    73
deba@2217
    74
      ///The dimension of the vector.
deba@2217
    75
kpeter@2562
    76
      ///This function always returns 2.
deba@2217
    77
      ///
deba@2212
    78
      int size() const { return 2; }
deba@2212
    79
deba@2212
    80
      ///Subscripting operator
deba@2217
    81
deba@2217
    82
      ///\c p[0] is \c p.x and \c p[1] is \c p.y
deba@2217
    83
      ///
deba@2212
    84
      T& operator[](int idx) { return idx == 0 ? x : y; }
deba@2212
    85
deba@2212
    86
      ///Const subscripting operator
deba@2217
    87
deba@2217
    88
      ///\c p[0] is \c p.x and \c p[1] is \c p.y
deba@2217
    89
      ///
deba@2212
    90
      const T& operator[](int idx) const { return idx == 0 ? x : y; }
athos@201
    91
alpar@1049
    92
      ///Conversion constructor
alpar@2207
    93
      template<class TT> Point(const Point<TT> &p) : x(p.x), y(p.y) {}
alpar@1049
    94
alpar@2157
    95
      ///Give back the square of the norm of the vector
alpar@1257
    96
      T normSquare() const {
ladanyi@1426
    97
        return x*x+y*y;
alpar@1391
    98
      }
athos@201
    99
  
kpeter@2562
   100
      ///Increment the left hand side by \c u
alpar@2207
   101
      Point<T>& operator +=(const Point<T>& u) {
ladanyi@1426
   102
        x += u.x;
ladanyi@1426
   103
        y += u.y;
ladanyi@1426
   104
        return *this;
alpar@1391
   105
      }
athos@201
   106
  
kpeter@2562
   107
      ///Decrement the left hand side by \c u
alpar@2207
   108
      Point<T>& operator -=(const Point<T>& u) {
ladanyi@1426
   109
        x -= u.x;
ladanyi@1426
   110
        y -= u.y;
ladanyi@1426
   111
        return *this;
alpar@1391
   112
      }
athos@201
   113
alpar@2157
   114
      ///Multiply the left hand side with a scalar
alpar@2207
   115
      Point<T>& operator *=(const T &u) {
ladanyi@1426
   116
        x *= u;
ladanyi@1426
   117
        y *= u;
ladanyi@1426
   118
        return *this;
alpar@1391
   119
      }
athos@207
   120
alpar@2157
   121
      ///Divide the left hand side by a scalar
alpar@2207
   122
      Point<T>& operator /=(const T &u) {
ladanyi@1426
   123
        x /= u;
ladanyi@1426
   124
        y /= u;
ladanyi@1426
   125
        return *this;
alpar@1391
   126
      }
athos@201
   127
  
alpar@2157
   128
      ///Return the scalar product of two vectors
alpar@2207
   129
      T operator *(const Point<T>& u) const {
ladanyi@1426
   130
        return x*u.x+y*u.y;
alpar@1391
   131
      }
athos@201
   132
  
alpar@2157
   133
      ///Return the sum of two vectors
alpar@2207
   134
      Point<T> operator+(const Point<T> &u) const {
alpar@2207
   135
        Point<T> b=*this;
ladanyi@1426
   136
        return b+=u;
alpar@1391
   137
      }
athos@201
   138
kpeter@2562
   139
      ///Return the negative of the vector
alpar@2207
   140
      Point<T> operator-() const {
alpar@2207
   141
        Point<T> b=*this;
ladanyi@1426
   142
        b.x=-b.x; b.y=-b.y;
ladanyi@1426
   143
        return b;
alpar@1391
   144
      }
alpar@1049
   145
alpar@2157
   146
      ///Return the difference of two vectors
alpar@2207
   147
      Point<T> operator-(const Point<T> &u) const {
alpar@2207
   148
        Point<T> b=*this;
ladanyi@1426
   149
        return b-=u;
alpar@1391
   150
      }
athos@201
   151
alpar@2157
   152
      ///Return a vector multiplied by a scalar
alpar@2207
   153
      Point<T> operator*(const T &u) const {
alpar@2207
   154
        Point<T> b=*this;
ladanyi@1426
   155
        return b*=u;
alpar@1391
   156
      }
athos@201
   157
alpar@2157
   158
      ///Return a vector divided by a scalar
alpar@2207
   159
      Point<T> operator/(const T &u) const {
alpar@2207
   160
        Point<T> b=*this;
ladanyi@1426
   161
        return b/=u;
alpar@1391
   162
      }
athos@201
   163
alpar@2157
   164
      ///Test equality
alpar@2207
   165
      bool operator==(const Point<T> &u) const {
ladanyi@1426
   166
        return (x==u.x) && (y==u.y);
alpar@1391
   167
      }
athos@201
   168
alpar@2157
   169
      ///Test inequality
alpar@2207
   170
      bool operator!=(Point u) const {
ladanyi@1426
   171
        return  (x!=u.x) || (y!=u.y);
alpar@1391
   172
      }
athos@201
   173
athos@207
   174
    };
athos@201
   175
kpeter@2562
   176
  ///Return a Point 
deba@1999
   177
kpeter@2562
   178
  ///Return a Point.
alpar@2207
   179
  ///\relates Point
deba@1999
   180
  template <typename T>
deba@2212
   181
  inline Point<T> makePoint(const T& x, const T& y) {
alpar@2207
   182
    return Point<T>(x, y);
deba@1999
   183
  }
deba@1999
   184
alpar@2157
   185
  ///Return a vector multiplied by a scalar
alpar@1083
   186
alpar@2157
   187
  ///Return a vector multiplied by a scalar
alpar@2207
   188
  ///\relates Point
alpar@2207
   189
  template<typename T> Point<T> operator*(const T &u,const Point<T> &x) {
alpar@1071
   190
    return x*u;
alpar@1391
   191
  }
alpar@1071
   192
alpar@814
   193
  ///Read a plainvector from a stream
alpar@814
   194
alpar@967
   195
  ///Read a plainvector from a stream
alpar@2207
   196
  ///\relates Point
alpar@814
   197
  ///
athos@207
   198
  template<typename T>
alpar@2207
   199
  inline std::istream& operator>>(std::istream &is, Point<T> &z) {
deba@1392
   200
    char c;
deba@1392
   201
    if (is >> c) {
deba@1392
   202
      if (c != '(') is.putback(c);
deba@1392
   203
    } else {
deba@1392
   204
      is.clear();
deba@1392
   205
    }
deba@1392
   206
    if (!(is >> z.x)) return is;
deba@1392
   207
    if (is >> c) {
deba@1392
   208
      if (c != ',') is.putback(c);
deba@1392
   209
    } else {
deba@1392
   210
      is.clear();
deba@1392
   211
    }
deba@1392
   212
    if (!(is >> z.y)) return is;
deba@1392
   213
    if (is >> c) {
deba@1392
   214
      if (c != ')') is.putback(c);
deba@1392
   215
    } else {
deba@1392
   216
      is.clear();
deba@1392
   217
    }
athos@207
   218
    return is;
athos@207
   219
  }
athos@201
   220
alpar@814
   221
  ///Write a plainvector to a stream
alpar@814
   222
alpar@967
   223
  ///Write a plainvector to a stream
alpar@2207
   224
  ///\relates Point
alpar@814
   225
  ///
athos@207
   226
  template<typename T>
alpar@2207
   227
  inline std::ostream& operator<<(std::ostream &os, const Point<T>& z)
athos@207
   228
  {
athos@240
   229
    os << "(" << z.x << ", " << z.y << ")";
athos@207
   230
    return os;
athos@207
   231
  }
athos@207
   232
alpar@1202
   233
  ///Rotate by 90 degrees
alpar@1202
   234
alpar@1202
   235
  ///Returns its parameter rotated by 90 degrees in positive direction.
alpar@2207
   236
  ///\relates Point
alpar@1202
   237
  ///
alpar@1202
   238
  template<typename T>
alpar@2207
   239
  inline Point<T> rot90(const Point<T> &z)
alpar@1202
   240
  {
alpar@2207
   241
    return Point<T>(-z.y,z.x);
alpar@1202
   242
  }
alpar@1202
   243
alpar@2157
   244
  ///Rotate by 180 degrees
alpar@2157
   245
alpar@2157
   246
  ///Returns its parameter rotated by 180 degrees.
alpar@2207
   247
  ///\relates Point
alpar@2157
   248
  ///
alpar@2157
   249
  template<typename T>
alpar@2207
   250
  inline Point<T> rot180(const Point<T> &z)
alpar@2157
   251
  {
alpar@2207
   252
    return Point<T>(-z.x,-z.y);
alpar@2157
   253
  }
alpar@2157
   254
alpar@1202
   255
  ///Rotate by 270 degrees
alpar@1202
   256
alpar@1202
   257
  ///Returns its parameter rotated by 90 degrees in negative direction.
alpar@2207
   258
  ///\relates Point
alpar@1202
   259
  ///
alpar@1202
   260
  template<typename T>
alpar@2207
   261
  inline Point<T> rot270(const Point<T> &z)
alpar@1202
   262
  {
alpar@2207
   263
    return Point<T>(z.y,-z.x);
alpar@1202
   264
  }
alpar@1202
   265
alpar@1202
   266
  
athos@244
   267
alpar@458
   268
  /// A class to calculate or store the bounding box of plainvectors.
alpar@458
   269
alpar@458
   270
  /// A class to calculate or store the bounding box of plainvectors.
alpar@458
   271
  ///
alpar@458
   272
  ///\author Attila Bernath
alpar@2451
   273
    template<typename T>
athos@244
   274
    class BoundingBox {
alpar@2207
   275
      Point<T> bottom_left, top_right;
athos@244
   276
      bool _empty;
athos@244
   277
    public:
athos@244
   278
      
ladanyi@1426
   279
      ///Default constructor: creates an empty bounding box
athos@244
   280
      BoundingBox() { _empty = true; }
athos@244
   281
alpar@2157
   282
      ///Construct an instance from one point
alpar@2207
   283
      BoundingBox(Point<T> a) { bottom_left=top_right=a; _empty = false; }
alpar@2451
   284
      
alpar@2451
   285
      ///Construct an instance from two points
alpar@2451
   286
      
kpeter@2562
   287
      ///Construct an instance from two points.
kpeter@2562
   288
      ///\param a The bottom left corner.
kpeter@2562
   289
      ///\param b The top right corner.
kpeter@2562
   290
      ///\warning The coordinates of the bottom left corner must be no more
kpeter@2562
   291
      ///than those of the top right one.
alpar@2451
   292
      BoundingBox(Point<T> a,Point<T> b)
alpar@2451
   293
      {
alpar@2451
   294
	bottom_left=a;
alpar@2451
   295
	top_right=b;
alpar@2451
   296
	_empty = false;
alpar@2451
   297
      }
alpar@2451
   298
      
alpar@2451
   299
      ///Construct an instance from four numbers
athos@244
   300
kpeter@2562
   301
      ///Construct an instance from four numbers.
kpeter@2562
   302
      ///\param l The left side of the box.
kpeter@2562
   303
      ///\param b The bottom of the box.
kpeter@2562
   304
      ///\param r The right side of the box.
kpeter@2562
   305
      ///\param t The top of the box.
kpeter@2562
   306
      ///\warning The left side must be no more than the right side and
kpeter@2562
   307
      ///bottom must be no more than the top. 
alpar@2451
   308
      BoundingBox(T l,T b,T r,T t)
alpar@2451
   309
      {
alpar@2451
   310
	bottom_left=Point<T>(l,b);
alpar@2451
   311
	top_right=Point<T>(r,t);
alpar@2451
   312
	_empty = false;
alpar@2451
   313
      }
alpar@2451
   314
      
kpeter@2562
   315
      ///Return \c true if the bounding box is empty.
kpeter@2562
   316
      
kpeter@2562
   317
      ///Return \c true if the bounding box is empty (i.e. return \c false
kpeter@2562
   318
      ///if at least one point was added to the box or the coordinates of
kpeter@2562
   319
      ///the box were set).
kpeter@2562
   320
      ///
kpeter@2562
   321
      ///The coordinates of an empty bounding box are not defined. 
athos@244
   322
      bool empty() const {
ladanyi@1426
   323
        return _empty;
athos@244
   324
      }
alpar@2451
   325
      
alpar@2157
   326
      ///Make the BoundingBox empty
alpar@1391
   327
      void clear() {
ladanyi@1426
   328
        _empty=1;
alpar@1391
   329
      }
alpar@1391
   330
kpeter@2562
   331
      ///Give back the bottom left corner of the box
alpar@2157
   332
kpeter@2562
   333
      ///Give back the bottom left corner of the box.
alpar@2157
   334
      ///If the bounding box is empty, then the return value is not defined.
alpar@2207
   335
      Point<T> bottomLeft() const {
ladanyi@1426
   336
        return bottom_left;
alpar@1391
   337
      }
athos@244
   338
kpeter@2562
   339
      ///Set the bottom left corner of the box
alpar@2157
   340
kpeter@2562
   341
      ///Set the bottom left corner of the box.
kpeter@2562
   342
      ///It should only be used for non-empty box.
alpar@2207
   343
      void bottomLeft(Point<T> p) {
alpar@1927
   344
	bottom_left = p;
alpar@1927
   345
      }
alpar@1927
   346
kpeter@2562
   347
      ///Give back the top right corner of the box
alpar@2157
   348
kpeter@2562
   349
      ///Give back the top right corner of the box.
alpar@2157
   350
      ///If the bounding box is empty, then the return value is not defined.
alpar@2207
   351
      Point<T> topRight() const {
ladanyi@1426
   352
        return top_right;
alpar@1391
   353
      }
athos@244
   354
kpeter@2562
   355
      ///Set the top right corner of the box
alpar@2157
   356
kpeter@2562
   357
      ///Set the top right corner of the box.
kpeter@2562
   358
      ///It should only be used for non-empty box.
alpar@2207
   359
      void topRight(Point<T> p) {
alpar@1927
   360
	top_right = p;
alpar@1927
   361
      }
alpar@1927
   362
kpeter@2562
   363
      ///Give back the bottom right corner of the box
alpar@2157
   364
kpeter@2562
   365
      ///Give back the bottom right corner of the box.
alpar@2157
   366
      ///If the bounding box is empty, then the return value is not defined.
alpar@2207
   367
      Point<T> bottomRight() const {
alpar@2207
   368
        return Point<T>(top_right.x,bottom_left.y);
alpar@1391
   369
      }
alpar@1045
   370
kpeter@2562
   371
      ///Set the bottom right corner of the box
alpar@2157
   372
kpeter@2562
   373
      ///Set the bottom right corner of the box.
kpeter@2562
   374
      ///It should only be used for non-empty box.
alpar@2207
   375
      void bottomRight(Point<T> p) {
alpar@1927
   376
	top_right.x = p.x;
alpar@1927
   377
	bottom_left.y = p.y;
alpar@1927
   378
      }
alpar@2157
   379
 
kpeter@2562
   380
      ///Give back the top left corner of the box
alpar@1927
   381
kpeter@2562
   382
      ///Give back the top left corner of the box.
alpar@2157
   383
      ///If the bounding box is empty, then the return value is not defined.
alpar@2207
   384
      Point<T> topLeft() const {
alpar@2207
   385
        return Point<T>(bottom_left.x,top_right.y);
alpar@1391
   386
      }
alpar@1045
   387
kpeter@2562
   388
      ///Set the top left corner of the box
alpar@2157
   389
kpeter@2562
   390
      ///Set the top left corner of the box.
kpeter@2562
   391
      ///It should only be used for non-empty box.
alpar@2207
   392
      void topLeft(Point<T> p) {
alpar@1927
   393
	top_right.y = p.y;
alpar@1927
   394
	bottom_left.x = p.x;
alpar@1927
   395
      }
alpar@1927
   396
alpar@2157
   397
      ///Give back the bottom of the box
alpar@2157
   398
alpar@2157
   399
      ///Give back the bottom of the box.
alpar@2157
   400
      ///If the bounding box is empty, then the return value is not defined.
alpar@1045
   401
      T bottom() const {
ladanyi@1426
   402
        return bottom_left.y;
alpar@1391
   403
      }
alpar@1045
   404
alpar@2157
   405
      ///Set the bottom of the box
alpar@2157
   406
alpar@2157
   407
      ///Set the bottom of the box.
kpeter@2562
   408
      ///It should only be used for non-empty box.
alpar@1927
   409
      void bottom(T t) {
alpar@1927
   410
	bottom_left.y = t;
alpar@1927
   411
      }
alpar@1927
   412
alpar@2157
   413
      ///Give back the top of the box
alpar@2157
   414
alpar@2157
   415
      ///Give back the top of the box.
alpar@2157
   416
      ///If the bounding box is empty, then the return value is not defined.
alpar@1045
   417
      T top() const {
ladanyi@1426
   418
        return top_right.y;
alpar@1391
   419
      }
alpar@1045
   420
alpar@2157
   421
      ///Set the top of the box
alpar@2157
   422
alpar@2157
   423
      ///Set the top of the box.
kpeter@2562
   424
      ///It should only be used for non-empty box.
alpar@1927
   425
      void top(T t) {
alpar@1927
   426
	top_right.y = t;
alpar@1927
   427
      }
alpar@1927
   428
alpar@2157
   429
      ///Give back the left side of the box
alpar@2157
   430
alpar@2157
   431
      ///Give back the left side of the box.
alpar@2157
   432
      ///If the bounding box is empty, then the return value is not defined.
alpar@1045
   433
      T left() const {
ladanyi@1426
   434
        return bottom_left.x;
alpar@1391
   435
      }
alpar@2157
   436
 
alpar@2157
   437
      ///Set the left side of the box
alpar@1045
   438
alpar@2157
   439
      ///Set the left side of the box.
kpeter@2562
   440
      ///It should only be used for non-empty box.
alpar@1927
   441
      void left(T t) {
alpar@1927
   442
	bottom_left.x = t;
alpar@1927
   443
      }
alpar@1927
   444
alpar@2157
   445
      /// Give back the right side of the box
alpar@2157
   446
alpar@2157
   447
      /// Give back the right side of the box.
alpar@2157
   448
      ///If the bounding box is empty, then the return value is not defined.
alpar@1045
   449
      T right() const {
ladanyi@1426
   450
        return top_right.x;
alpar@1391
   451
      }
alpar@1045
   452
alpar@2157
   453
      ///Set the right side of the box
alpar@2157
   454
alpar@2157
   455
      ///Set the right side of the box.
kpeter@2562
   456
      ///It should only be used for non-empty box.
alpar@1927
   457
      void right(T t) {
alpar@1927
   458
	top_right.x = t;
alpar@1927
   459
      }
alpar@1927
   460
alpar@2157
   461
      ///Give back the height of the box
alpar@2157
   462
alpar@2157
   463
      ///Give back the height of the box.
alpar@2157
   464
      ///If the bounding box is empty, then the return value is not defined.
alpar@1102
   465
      T height() const {
ladanyi@1426
   466
        return top_right.y-bottom_left.y;
alpar@1391
   467
      }
alpar@1102
   468
alpar@2157
   469
      ///Give back the width of the box
alpar@2157
   470
alpar@2157
   471
      ///Give back the width of the box.
alpar@2157
   472
      ///If the bounding box is empty, then the return value is not defined.
alpar@1102
   473
      T width() const {
ladanyi@1426
   474
        return top_right.x-bottom_left.x;
alpar@1391
   475
      }
alpar@1102
   476
athos@244
   477
      ///Checks whether a point is inside a bounding box
kpeter@2562
   478
      bool inside(const Point<T>& u) const {
ladanyi@1426
   479
        if (_empty)
ladanyi@1426
   480
          return false;
ladanyi@1426
   481
        else{
ladanyi@1426
   482
          return ((u.x-bottom_left.x)*(top_right.x-u.x) >= 0 &&
ladanyi@1426
   483
              (u.y-bottom_left.y)*(top_right.y-u.y) >= 0 );
ladanyi@1426
   484
        }
athos@244
   485
      }
athos@244
   486
  
athos@244
   487
      ///Increments a bounding box with a point
kpeter@2562
   488
kpeter@2562
   489
      ///Increments a bounding box with a point.
kpeter@2562
   490
      ///
alpar@2207
   491
      BoundingBox& add(const Point<T>& u){
ladanyi@1426
   492
        if (_empty){
ladanyi@1426
   493
          bottom_left=top_right=u;
ladanyi@1426
   494
          _empty = false;
ladanyi@1426
   495
        }
ladanyi@1426
   496
        else{
ladanyi@1426
   497
          if (bottom_left.x > u.x) bottom_left.x = u.x;
ladanyi@1426
   498
          if (bottom_left.y > u.y) bottom_left.y = u.y;
ladanyi@1426
   499
          if (top_right.x < u.x) top_right.x = u.x;
ladanyi@1426
   500
          if (top_right.y < u.y) top_right.y = u.y;
ladanyi@1426
   501
        }
ladanyi@1426
   502
        return *this;
alpar@1391
   503
      }
alpar@2214
   504
    
kpeter@2562
   505
      ///Increments a bounding box to contain another bounding box
kpeter@2562
   506
      
kpeter@2562
   507
      ///Increments a bounding box to contain another bounding box.
kpeter@2562
   508
      ///
alpar@1588
   509
      BoundingBox& add(const BoundingBox &u){
ladanyi@1426
   510
        if ( !u.empty() ){
alpar@1588
   511
          this->add(u.bottomLeft());
alpar@1588
   512
	  this->add(u.topRight());
ladanyi@1426
   513
        }
ladanyi@1426
   514
        return *this;
alpar@1391
   515
      }
athos@244
   516
  
alpar@1588
   517
      ///Intersection of two bounding boxes
kpeter@2562
   518
kpeter@2562
   519
      ///Intersection of two bounding boxes.
kpeter@2562
   520
      ///
kpeter@2562
   521
      BoundingBox operator&(const BoundingBox& u) const {
alpar@1588
   522
        BoundingBox b;
kpeter@2562
   523
        if (this->_empty || u._empty) {
kpeter@2562
   524
	  b._empty = true;
kpeter@2562
   525
	} else {
kpeter@2562
   526
	  b.bottom_left.x=std::max(this->bottom_left.x,u.bottom_left.x);
kpeter@2562
   527
	  b.bottom_left.y=std::max(this->bottom_left.y,u.bottom_left.y);
kpeter@2562
   528
	  b.top_right.x=std::min(this->top_right.x,u.top_right.x);
kpeter@2562
   529
	  b.top_right.y=std::min(this->top_right.y,u.top_right.y);
kpeter@2562
   530
	  b._empty = b.bottom_left.x > b.top_right.x ||
kpeter@2562
   531
	             b.bottom_left.y > b.top_right.y;
kpeter@2562
   532
	} 
alpar@1588
   533
        return b;
alpar@1391
   534
      }
athos@244
   535
athos@244
   536
    };//class Boundingbox
athos@244
   537
athos@244
   538
kpeter@2562
   539
  ///Map of x-coordinates of a \ref Point "Point"-map
alpar@1317
   540
alpar@1317
   541
  ///\ingroup maps
kpeter@2562
   542
  ///Map of x-coordinates of a \ref Point "Point"-map.
alpar@1317
   543
  ///
alpar@1317
   544
  template<class M>
alpar@1317
   545
  class XMap 
alpar@1317
   546
  {
deba@1706
   547
    M& _map;
alpar@1317
   548
  public:
deba@1420
   549
alpar@1317
   550
    typedef typename M::Value::Value Value;
alpar@1317
   551
    typedef typename M::Key Key;
alpar@1317
   552
    ///\e
deba@1706
   553
    XMap(M& map) : _map(map) {}
alpar@1317
   554
    Value operator[](Key k) const {return _map[k].x;}
alpar@1352
   555
    void set(Key k,Value v) {_map.set(k,typename M::Value(v,_map[k].y));}
alpar@1317
   556
  };
alpar@1317
   557
    
alpar@1317
   558
  ///Returns an \ref XMap class
alpar@1317
   559
alpar@1317
   560
  ///This function just returns an \ref XMap class.
alpar@1317
   561
  ///
alpar@1317
   562
  ///\ingroup maps
alpar@1317
   563
  ///\relates XMap
alpar@1317
   564
  template<class M> 
alpar@1317
   565
  inline XMap<M> xMap(M &m) 
alpar@1317
   566
  {
alpar@1317
   567
    return XMap<M>(m);
alpar@1317
   568
  }
alpar@1317
   569
deba@1420
   570
  template<class M> 
deba@1420
   571
  inline XMap<M> xMap(const M &m) 
deba@1420
   572
  {
deba@1420
   573
    return XMap<M>(m);
deba@1420
   574
  }
deba@1420
   575
alpar@1317
   576
  ///Constant (read only) version of \ref XMap
alpar@1317
   577
alpar@1317
   578
  ///\ingroup maps
alpar@2214
   579
  ///Constant (read only) version of \ref XMap
alpar@1317
   580
  ///
alpar@1317
   581
  template<class M>
alpar@1317
   582
  class ConstXMap 
alpar@1317
   583
  {
deba@1706
   584
    const M& _map;
alpar@1317
   585
  public:
deba@1420
   586
alpar@1317
   587
    typedef typename M::Value::Value Value;
alpar@1317
   588
    typedef typename M::Key Key;
alpar@1317
   589
    ///\e
alpar@1317
   590
    ConstXMap(const M &map) : _map(map) {}
alpar@1317
   591
    Value operator[](Key k) const {return _map[k].x;}
alpar@1317
   592
  };
alpar@1317
   593
    
alpar@1317
   594
  ///Returns a \ref ConstXMap class
alpar@1317
   595
kpeter@2562
   596
  ///This function just returns a \ref ConstXMap class.
alpar@1317
   597
  ///
alpar@1317
   598
  ///\ingroup maps
alpar@1317
   599
  ///\relates ConstXMap
alpar@1317
   600
  template<class M> 
alpar@1317
   601
  inline ConstXMap<M> xMap(const M &m) 
alpar@1317
   602
  {
alpar@1317
   603
    return ConstXMap<M>(m);
alpar@1317
   604
  }
alpar@1317
   605
kpeter@2562
   606
  ///Map of y-coordinates of a \ref Point "Point"-map
alpar@1317
   607
    
alpar@1317
   608
  ///\ingroup maps
kpeter@2562
   609
  ///Map of y-coordinates of a \ref Point "Point"-map.
alpar@1317
   610
  ///
alpar@1317
   611
  template<class M>
alpar@1317
   612
  class YMap 
alpar@1317
   613
  {
deba@1706
   614
    M& _map;
alpar@1317
   615
  public:
deba@1420
   616
alpar@1317
   617
    typedef typename M::Value::Value Value;
alpar@1317
   618
    typedef typename M::Key Key;
alpar@1317
   619
    ///\e
deba@1706
   620
    YMap(M& map) : _map(map) {}
alpar@1317
   621
    Value operator[](Key k) const {return _map[k].y;}
alpar@1352
   622
    void set(Key k,Value v) {_map.set(k,typename M::Value(_map[k].x,v));}
alpar@1317
   623
  };
alpar@1317
   624
kpeter@2562
   625
  ///Returns a \ref YMap class
alpar@1317
   626
kpeter@2562
   627
  ///This function just returns a \ref YMap class.
alpar@1317
   628
  ///
alpar@1317
   629
  ///\ingroup maps
alpar@1317
   630
  ///\relates YMap
alpar@1317
   631
  template<class M> 
alpar@1317
   632
  inline YMap<M> yMap(M &m) 
alpar@1317
   633
  {
alpar@1317
   634
    return YMap<M>(m);
alpar@1317
   635
  }
alpar@1317
   636
deba@1420
   637
  template<class M> 
deba@1420
   638
  inline YMap<M> yMap(const M &m) 
deba@1420
   639
  {
deba@1420
   640
    return YMap<M>(m);
deba@1420
   641
  }
deba@1420
   642
alpar@1317
   643
  ///Constant (read only) version of \ref YMap
alpar@1317
   644
alpar@1317
   645
  ///\ingroup maps
alpar@2214
   646
  ///Constant (read only) version of \ref YMap
alpar@1317
   647
  ///
alpar@1317
   648
  template<class M>
alpar@1317
   649
  class ConstYMap 
alpar@1317
   650
  {
deba@1706
   651
    const M& _map;
alpar@1317
   652
  public:
deba@1420
   653
alpar@1317
   654
    typedef typename M::Value::Value Value;
alpar@1317
   655
    typedef typename M::Key Key;
alpar@1317
   656
    ///\e
alpar@1317
   657
    ConstYMap(const M &map) : _map(map) {}
alpar@1317
   658
    Value operator[](Key k) const {return _map[k].y;}
alpar@1317
   659
  };
alpar@1317
   660
    
alpar@1317
   661
  ///Returns a \ref ConstYMap class
alpar@1317
   662
kpeter@2562
   663
  ///This function just returns a \ref ConstYMap class.
alpar@1317
   664
  ///
alpar@1317
   665
  ///\ingroup maps
alpar@1317
   666
  ///\relates ConstYMap
alpar@1317
   667
  template<class M> 
alpar@1317
   668
  inline ConstYMap<M> yMap(const M &m) 
alpar@1317
   669
  {
alpar@1317
   670
    return ConstYMap<M>(m);
alpar@1317
   671
  }
alpar@1317
   672
alpar@1317
   673
kpeter@2562
   674
  ///\brief Map of the \ref Point::normSquare() "normSquare()"
kpeter@2562
   675
  ///of a \ref Point "Point"-map
kpeter@2562
   676
  ///
kpeter@2562
   677
  ///Map of the \ref Point::normSquare() "normSquare()"
kpeter@2562
   678
  ///of a \ref Point "Point"-map.
kpeter@2562
   679
  ///\ingroup maps
alpar@2214
   680
    ///
alpar@1352
   681
  template<class M>
alpar@1352
   682
  class NormSquareMap 
alpar@1352
   683
  {
deba@1706
   684
    const M& _map;
alpar@1352
   685
  public:
deba@1420
   686
alpar@1352
   687
    typedef typename M::Value::Value Value;
alpar@1352
   688
    typedef typename M::Key Key;
alpar@1352
   689
    ///\e
alpar@1352
   690
    NormSquareMap(const M &map) : _map(map) {}
alpar@1352
   691
    Value operator[](Key k) const {return _map[k].normSquare();}
alpar@1352
   692
  };
alpar@1352
   693
    
alpar@1352
   694
  ///Returns a \ref NormSquareMap class
alpar@1352
   695
kpeter@2562
   696
  ///This function just returns a \ref NormSquareMap class.
alpar@1352
   697
  ///
alpar@1352
   698
  ///\ingroup maps
alpar@1352
   699
  ///\relates NormSquareMap
alpar@1352
   700
  template<class M> 
alpar@1352
   701
  inline NormSquareMap<M> normSquareMap(const M &m) 
alpar@1352
   702
  {
alpar@1352
   703
    return NormSquareMap<M>(m);
alpar@1352
   704
  }
alpar@1352
   705
alpar@431
   706
  /// @}
athos@244
   707
alpar@2207
   708
  } //namespce dim2
alpar@2207
   709
  
alpar@921
   710
} //namespace lemon
athos@201
   711
alpar@2207
   712
#endif //LEMON_DIM2_H