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