lemon/dim2.h
author deba
Tue, 17 Oct 2006 10:50:57 +0000
changeset 2247 269a0dcee70b
parent 2214 a886e48e0d91
child 2391 14a343be7a5a
permissions -rw-r--r--
Update the Path concept
Concept check for paths

DirPath renamed to Path
The interface updated to the new lemon interface
Make difference between the empty path and the path from one node
Builder interface have not been changed
// I wanted but there was not accordance about it

UPath is removed
It was a buggy implementation, it could not iterate on the
nodes in the right order
Right way to use undirected paths => path of edges in undirected graphs

The tests have been modified to the current implementation
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@1956
     5
 * Copyright (C) 2003-2006
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
alpar@458
    55
  ///with the usual vector
alpar@458
    56
  /// operators.
alpar@458
    57
  ///
athos@207
    58
  template<typename T>
alpar@2207
    59
    class Point {
athos@201
    60
athos@207
    61
    public:
athos@240
    62
alpar@987
    63
      typedef T Value;
alpar@964
    64
alpar@1974
    65
      ///First co-ordinate
alpar@1974
    66
      T x;
alpar@1974
    67
      ///Second co-ordinate
alpar@1974
    68
      T y;     
athos@207
    69
      
alpar@1257
    70
      ///Default constructor
alpar@2207
    71
      Point() {}
athos@201
    72
alpar@2157
    73
      ///Construct an instance from coordinates
alpar@2207
    74
      Point(T a, T b) : x(a), y(b) { }
athos@201
    75
deba@2217
    76
      ///The dimension of the vector.
deba@2217
    77
deba@2217
    78
      ///This class give back always 2.
deba@2217
    79
      ///
deba@2212
    80
      int size() const { return 2; }
deba@2212
    81
deba@2212
    82
      ///Subscripting operator
deba@2217
    83
deba@2217
    84
      ///\c p[0] is \c p.x and \c p[1] is \c p.y
deba@2217
    85
      ///
deba@2212
    86
      T& operator[](int idx) { return idx == 0 ? x : y; }
deba@2212
    87
deba@2212
    88
      ///Const subscripting operator
deba@2217
    89
deba@2217
    90
      ///\c p[0] is \c p.x and \c p[1] is \c p.y
deba@2217
    91
      ///
deba@2212
    92
      const T& operator[](int idx) const { return idx == 0 ? x : y; }
athos@201
    93
alpar@1049
    94
      ///Conversion constructor
alpar@2207
    95
      template<class TT> Point(const Point<TT> &p) : x(p.x), y(p.y) {}
alpar@1049
    96
alpar@2157
    97
      ///Give back the square of the norm of the vector
alpar@1257
    98
      T normSquare() const {
ladanyi@1426
    99
        return x*x+y*y;
alpar@1391
   100
      }
athos@201
   101
  
alpar@2157
   102
      ///Increment the left hand side by u
alpar@2207
   103
      Point<T>& operator +=(const Point<T>& u) {
ladanyi@1426
   104
        x += u.x;
ladanyi@1426
   105
        y += u.y;
ladanyi@1426
   106
        return *this;
alpar@1391
   107
      }
athos@201
   108
  
alpar@2157
   109
      ///Decrement the left hand side by u
alpar@2207
   110
      Point<T>& operator -=(const Point<T>& u) {
ladanyi@1426
   111
        x -= u.x;
ladanyi@1426
   112
        y -= u.y;
ladanyi@1426
   113
        return *this;
alpar@1391
   114
      }
athos@201
   115
alpar@2157
   116
      ///Multiply the left hand side with a scalar
alpar@2207
   117
      Point<T>& operator *=(const T &u) {
ladanyi@1426
   118
        x *= u;
ladanyi@1426
   119
        y *= u;
ladanyi@1426
   120
        return *this;
alpar@1391
   121
      }
athos@207
   122
alpar@2157
   123
      ///Divide the left hand side by a scalar
alpar@2207
   124
      Point<T>& operator /=(const T &u) {
ladanyi@1426
   125
        x /= u;
ladanyi@1426
   126
        y /= u;
ladanyi@1426
   127
        return *this;
alpar@1391
   128
      }
athos@201
   129
  
alpar@2157
   130
      ///Return the scalar product of two vectors
alpar@2207
   131
      T operator *(const Point<T>& u) const {
ladanyi@1426
   132
        return x*u.x+y*u.y;
alpar@1391
   133
      }
athos@201
   134
  
alpar@2157
   135
      ///Return the sum of two vectors
alpar@2207
   136
      Point<T> operator+(const Point<T> &u) const {
alpar@2207
   137
        Point<T> b=*this;
ladanyi@1426
   138
        return b+=u;
alpar@1391
   139
      }
athos@201
   140
alpar@2157
   141
      ///Return the neg of the vectors
alpar@2207
   142
      Point<T> operator-() const {
alpar@2207
   143
        Point<T> b=*this;
ladanyi@1426
   144
        b.x=-b.x; b.y=-b.y;
ladanyi@1426
   145
        return b;
alpar@1391
   146
      }
alpar@1049
   147
alpar@2157
   148
      ///Return the difference of two vectors
alpar@2207
   149
      Point<T> operator-(const Point<T> &u) const {
alpar@2207
   150
        Point<T> b=*this;
ladanyi@1426
   151
        return b-=u;
alpar@1391
   152
      }
athos@201
   153
alpar@2157
   154
      ///Return a vector multiplied by a scalar
alpar@2207
   155
      Point<T> operator*(const T &u) const {
alpar@2207
   156
        Point<T> b=*this;
ladanyi@1426
   157
        return b*=u;
alpar@1391
   158
      }
athos@201
   159
alpar@2157
   160
      ///Return a vector divided by a scalar
alpar@2207
   161
      Point<T> operator/(const T &u) const {
alpar@2207
   162
        Point<T> b=*this;
ladanyi@1426
   163
        return b/=u;
alpar@1391
   164
      }
athos@201
   165
alpar@2157
   166
      ///Test equality
alpar@2207
   167
      bool operator==(const Point<T> &u) const {
ladanyi@1426
   168
        return (x==u.x) && (y==u.y);
alpar@1391
   169
      }
athos@201
   170
alpar@2157
   171
      ///Test inequality
alpar@2207
   172
      bool operator!=(Point u) const {
ladanyi@1426
   173
        return  (x!=u.x) || (y!=u.y);
alpar@1391
   174
      }
athos@201
   175
athos@207
   176
    };
athos@201
   177
alpar@2207
   178
  ///Return an Point 
deba@1999
   179
alpar@2207
   180
  ///Return an Point
alpar@2207
   181
  ///\relates Point
deba@1999
   182
  template <typename T>
deba@2212
   183
  inline Point<T> makePoint(const T& x, const T& y) {
alpar@2207
   184
    return Point<T>(x, y);
deba@1999
   185
  }
deba@1999
   186
alpar@2157
   187
  ///Return a vector multiplied by a scalar
alpar@1083
   188
alpar@2157
   189
  ///Return a vector multiplied by a scalar
alpar@2207
   190
  ///\relates Point
alpar@2207
   191
  template<typename T> Point<T> operator*(const T &u,const Point<T> &x) {
alpar@1071
   192
    return x*u;
alpar@1391
   193
  }
alpar@1071
   194
alpar@814
   195
  ///Read a plainvector from a stream
alpar@814
   196
alpar@967
   197
  ///Read a plainvector from a stream
alpar@2207
   198
  ///\relates Point
alpar@814
   199
  ///
athos@207
   200
  template<typename T>
alpar@2207
   201
  inline std::istream& operator>>(std::istream &is, Point<T> &z) {
deba@1392
   202
    char c;
deba@1392
   203
    if (is >> c) {
deba@1392
   204
      if (c != '(') is.putback(c);
deba@1392
   205
    } else {
deba@1392
   206
      is.clear();
deba@1392
   207
    }
deba@1392
   208
    if (!(is >> z.x)) return is;
deba@1392
   209
    if (is >> c) {
deba@1392
   210
      if (c != ',') is.putback(c);
deba@1392
   211
    } else {
deba@1392
   212
      is.clear();
deba@1392
   213
    }
deba@1392
   214
    if (!(is >> z.y)) return is;
deba@1392
   215
    if (is >> c) {
deba@1392
   216
      if (c != ')') is.putback(c);
deba@1392
   217
    } else {
deba@1392
   218
      is.clear();
deba@1392
   219
    }
athos@207
   220
    return is;
athos@207
   221
  }
athos@201
   222
alpar@814
   223
  ///Write a plainvector to a stream
alpar@814
   224
alpar@967
   225
  ///Write a plainvector to a stream
alpar@2207
   226
  ///\relates Point
alpar@814
   227
  ///
athos@207
   228
  template<typename T>
alpar@2207
   229
  inline std::ostream& operator<<(std::ostream &os, const Point<T>& z)
athos@207
   230
  {
athos@240
   231
    os << "(" << z.x << ", " << z.y << ")";
athos@207
   232
    return os;
athos@207
   233
  }
athos@207
   234
alpar@1202
   235
  ///Rotate by 90 degrees
alpar@1202
   236
alpar@1202
   237
  ///Returns its parameter rotated by 90 degrees in positive direction.
alpar@2207
   238
  ///\relates Point
alpar@1202
   239
  ///
alpar@1202
   240
  template<typename T>
alpar@2207
   241
  inline Point<T> rot90(const Point<T> &z)
alpar@1202
   242
  {
alpar@2207
   243
    return Point<T>(-z.y,z.x);
alpar@1202
   244
  }
alpar@1202
   245
alpar@2157
   246
  ///Rotate by 180 degrees
alpar@2157
   247
alpar@2157
   248
  ///Returns its parameter rotated by 180 degrees.
alpar@2207
   249
  ///\relates Point
alpar@2157
   250
  ///
alpar@2157
   251
  template<typename T>
alpar@2207
   252
  inline Point<T> rot180(const Point<T> &z)
alpar@2157
   253
  {
alpar@2207
   254
    return Point<T>(-z.x,-z.y);
alpar@2157
   255
  }
alpar@2157
   256
alpar@1202
   257
  ///Rotate by 270 degrees
alpar@1202
   258
alpar@1202
   259
  ///Returns its parameter rotated by 90 degrees in negative direction.
alpar@2207
   260
  ///\relates Point
alpar@1202
   261
  ///
alpar@1202
   262
  template<typename T>
alpar@2207
   263
  inline Point<T> rot270(const Point<T> &z)
alpar@1202
   264
  {
alpar@2207
   265
    return Point<T>(z.y,-z.x);
alpar@1202
   266
  }
alpar@1202
   267
alpar@1202
   268
  
athos@244
   269
alpar@458
   270
  /// A class to calculate or store the bounding box of plainvectors.
alpar@458
   271
alpar@458
   272
  /// A class to calculate or store the bounding box of plainvectors.
alpar@458
   273
  ///
alpar@458
   274
  ///\author Attila Bernath
athos@244
   275
  template<typename T>
athos@244
   276
    class BoundingBox {
alpar@2207
   277
      Point<T> bottom_left, top_right;
athos@244
   278
      bool _empty;
athos@244
   279
    public:
athos@244
   280
      
ladanyi@1426
   281
      ///Default constructor: creates an empty bounding box
athos@244
   282
      BoundingBox() { _empty = true; }
athos@244
   283
alpar@2157
   284
      ///Construct an instance from one point
alpar@2207
   285
      BoundingBox(Point<T> a) { bottom_left=top_right=a; _empty = false; }
athos@244
   286
ladanyi@1426
   287
      ///Were any points added?
athos@244
   288
      bool empty() const {
ladanyi@1426
   289
        return _empty;
athos@244
   290
      }
athos@244
   291
alpar@2157
   292
      ///Make the BoundingBox empty
alpar@1391
   293
      void clear() {
ladanyi@1426
   294
        _empty=1;
alpar@1391
   295
      }
alpar@1391
   296
alpar@2157
   297
      ///Give back the bottom left corner
alpar@2157
   298
alpar@2157
   299
      ///Give back the bottom left corner.
alpar@2157
   300
      ///If the bounding box is empty, then the return value is not defined.
alpar@2207
   301
      Point<T> bottomLeft() const {
ladanyi@1426
   302
        return bottom_left;
alpar@1391
   303
      }
athos@244
   304
alpar@2157
   305
      ///Set the bottom left corner
alpar@2157
   306
alpar@2157
   307
      ///Set the bottom left corner.
alpar@2157
   308
      ///It should only bee used for non-empty box.
alpar@2207
   309
      void bottomLeft(Point<T> p) {
alpar@1927
   310
	bottom_left = p;
alpar@1927
   311
      }
alpar@1927
   312
alpar@2157
   313
      ///Give back the top right corner
alpar@2157
   314
alpar@2157
   315
      ///Give back the top right corner.
alpar@2157
   316
      ///If the bounding box is empty, then the return value is not defined.
alpar@2207
   317
      Point<T> topRight() const {
ladanyi@1426
   318
        return top_right;
alpar@1391
   319
      }
athos@244
   320
alpar@2157
   321
      ///Set the top right corner
alpar@2157
   322
alpar@2157
   323
      ///Set the top right corner.
alpar@2157
   324
      ///It should only bee used for non-empty box.
alpar@2207
   325
      void topRight(Point<T> p) {
alpar@1927
   326
	top_right = p;
alpar@1927
   327
      }
alpar@1927
   328
alpar@2157
   329
      ///Give back the bottom right corner
alpar@2157
   330
alpar@2157
   331
      ///Give back the bottom right corner.
alpar@2157
   332
      ///If the bounding box is empty, then the return value is not defined.
alpar@2207
   333
      Point<T> bottomRight() const {
alpar@2207
   334
        return Point<T>(top_right.x,bottom_left.y);
alpar@1391
   335
      }
alpar@1045
   336
alpar@2157
   337
      ///Set the bottom right corner
alpar@2157
   338
alpar@2157
   339
      ///Set the bottom right corner.
alpar@2157
   340
      ///It should only bee used for non-empty box.
alpar@2207
   341
      void bottomRight(Point<T> p) {
alpar@1927
   342
	top_right.x = p.x;
alpar@1927
   343
	bottom_left.y = p.y;
alpar@1927
   344
      }
alpar@2157
   345
 
alpar@2157
   346
      ///Give back the top left corner
alpar@1927
   347
alpar@2157
   348
      ///Give back the top left corner.
alpar@2157
   349
      ///If the bounding box is empty, then the return value is not defined.
alpar@2207
   350
      Point<T> topLeft() const {
alpar@2207
   351
        return Point<T>(bottom_left.x,top_right.y);
alpar@1391
   352
      }
alpar@1045
   353
alpar@2157
   354
      ///Set the top left corner
alpar@2157
   355
alpar@2157
   356
      ///Set the top left corner.
alpar@2157
   357
      ///It should only bee used for non-empty box.
alpar@2207
   358
      void topLeft(Point<T> p) {
alpar@1927
   359
	top_right.y = p.y;
alpar@1927
   360
	bottom_left.x = p.x;
alpar@1927
   361
      }
alpar@1927
   362
alpar@2157
   363
      ///Give back the bottom of the box
alpar@2157
   364
alpar@2157
   365
      ///Give back the bottom of the box.
alpar@2157
   366
      ///If the bounding box is empty, then the return value is not defined.
alpar@1045
   367
      T bottom() const {
ladanyi@1426
   368
        return bottom_left.y;
alpar@1391
   369
      }
alpar@1045
   370
alpar@2157
   371
      ///Set the bottom of the box
alpar@2157
   372
alpar@2157
   373
      ///Set the bottom of the box.
alpar@2157
   374
      ///It should only bee used for non-empty box.
alpar@1927
   375
      void bottom(T t) {
alpar@1927
   376
	bottom_left.y = t;
alpar@1927
   377
      }
alpar@1927
   378
alpar@2157
   379
      ///Give back the top of the box
alpar@2157
   380
alpar@2157
   381
      ///Give back the top of the box.
alpar@2157
   382
      ///If the bounding box is empty, then the return value is not defined.
alpar@1045
   383
      T top() const {
ladanyi@1426
   384
        return top_right.y;
alpar@1391
   385
      }
alpar@1045
   386
alpar@2157
   387
      ///Set the top of the box
alpar@2157
   388
alpar@2157
   389
      ///Set the top of the box.
alpar@2157
   390
      ///It should only bee used for non-empty box.
alpar@1927
   391
      void top(T t) {
alpar@1927
   392
	top_right.y = t;
alpar@1927
   393
      }
alpar@1927
   394
alpar@2157
   395
      ///Give back the left side of the box
alpar@2157
   396
alpar@2157
   397
      ///Give back the left side of the box.
alpar@2157
   398
      ///If the bounding box is empty, then the return value is not defined.
alpar@1045
   399
      T left() const {
ladanyi@1426
   400
        return bottom_left.x;
alpar@1391
   401
      }
alpar@2157
   402
 
alpar@2157
   403
      ///Set the left side of the box
alpar@1045
   404
alpar@2157
   405
      ///Set the left side of the box.
alpar@2157
   406
      ///It should only bee used for non-empty box
alpar@1927
   407
      void left(T t) {
alpar@1927
   408
	bottom_left.x = t;
alpar@1927
   409
      }
alpar@1927
   410
alpar@2157
   411
      /// Give back the right side of the box
alpar@2157
   412
alpar@2157
   413
      /// Give back the right side of the box.
alpar@2157
   414
      ///If the bounding box is empty, then the return value is not defined.
alpar@1045
   415
      T right() const {
ladanyi@1426
   416
        return top_right.x;
alpar@1391
   417
      }
alpar@1045
   418
alpar@2157
   419
      ///Set the right side of the box
alpar@2157
   420
alpar@2157
   421
      ///Set the right side of the box.
alpar@2157
   422
      ///It should only bee used for non-empty box
alpar@1927
   423
      void right(T t) {
alpar@1927
   424
	top_right.x = t;
alpar@1927
   425
      }
alpar@1927
   426
alpar@2157
   427
      ///Give back the height of the box
alpar@2157
   428
alpar@2157
   429
      ///Give back the height of the box.
alpar@2157
   430
      ///If the bounding box is empty, then the return value is not defined.
alpar@1102
   431
      T height() const {
ladanyi@1426
   432
        return top_right.y-bottom_left.y;
alpar@1391
   433
      }
alpar@1102
   434
alpar@2157
   435
      ///Give back the width of the box
alpar@2157
   436
alpar@2157
   437
      ///Give back the width of the box.
alpar@2157
   438
      ///If the bounding box is empty, then the return value is not defined.
alpar@1102
   439
      T width() const {
ladanyi@1426
   440
        return top_right.x-bottom_left.x;
alpar@1391
   441
      }
alpar@1102
   442
athos@244
   443
      ///Checks whether a point is inside a bounding box
alpar@2207
   444
      bool inside(const Point<T>& u){
ladanyi@1426
   445
        if (_empty)
ladanyi@1426
   446
          return false;
ladanyi@1426
   447
        else{
ladanyi@1426
   448
          return ((u.x-bottom_left.x)*(top_right.x-u.x) >= 0 &&
ladanyi@1426
   449
              (u.y-bottom_left.y)*(top_right.y-u.y) >= 0 );
ladanyi@1426
   450
        }
athos@244
   451
      }
athos@244
   452
  
athos@244
   453
      ///Increments a bounding box with a point
alpar@2207
   454
      BoundingBox& add(const Point<T>& u){
ladanyi@1426
   455
        if (_empty){
ladanyi@1426
   456
          bottom_left=top_right=u;
ladanyi@1426
   457
          _empty = false;
ladanyi@1426
   458
        }
ladanyi@1426
   459
        else{
ladanyi@1426
   460
          if (bottom_left.x > u.x) bottom_left.x = u.x;
ladanyi@1426
   461
          if (bottom_left.y > u.y) bottom_left.y = u.y;
ladanyi@1426
   462
          if (top_right.x < u.x) top_right.x = u.x;
ladanyi@1426
   463
          if (top_right.y < u.y) top_right.y = u.y;
ladanyi@1426
   464
        }
ladanyi@1426
   465
        return *this;
alpar@1391
   466
      }
alpar@2214
   467
    
alpar@2214
   468
      ///Increments a bounding to contain another bounding box
alpar@1588
   469
      BoundingBox& add(const BoundingBox &u){
ladanyi@1426
   470
        if ( !u.empty() ){
alpar@1588
   471
          this->add(u.bottomLeft());
alpar@1588
   472
	  this->add(u.topRight());
ladanyi@1426
   473
        }
ladanyi@1426
   474
        return *this;
alpar@1391
   475
      }
athos@244
   476
  
alpar@1588
   477
      ///Intersection of two bounding boxes
alpar@1588
   478
      BoundingBox operator &(const BoundingBox& u){
alpar@1588
   479
        BoundingBox b;
alpar@1588
   480
	b.bottom_left.x=std::max(this->bottom_left.x,u.bottom_left.x);
alpar@1588
   481
	b.bottom_left.y=std::max(this->bottom_left.y,u.bottom_left.y);
alpar@1588
   482
	b.top_right.x=std::min(this->top_right.x,u.top_right.x);
alpar@1588
   483
	b.top_right.y=std::min(this->top_right.y,u.top_right.y);
alpar@1588
   484
	b._empty = this->_empty || u._empty ||
alpar@1588
   485
	  b.bottom_left.x>top_right.x && b.bottom_left.y>top_right.y;
alpar@1588
   486
        return b;
alpar@1391
   487
      }
athos@244
   488
athos@244
   489
    };//class Boundingbox
athos@244
   490
athos@244
   491
alpar@2207
   492
  ///Map of x-coordinates of a dim2::Point<>-map
alpar@1317
   493
alpar@1317
   494
  ///\ingroup maps
alpar@2214
   495
  ///Map of x-coordinates of a dim2::Point<>-map
alpar@1317
   496
  ///
alpar@1317
   497
  template<class M>
alpar@1317
   498
  class XMap 
alpar@1317
   499
  {
deba@1706
   500
    M& _map;
alpar@1317
   501
  public:
deba@1420
   502
alpar@1317
   503
    typedef typename M::Value::Value Value;
alpar@1317
   504
    typedef typename M::Key Key;
alpar@1317
   505
    ///\e
deba@1706
   506
    XMap(M& map) : _map(map) {}
alpar@1317
   507
    Value operator[](Key k) const {return _map[k].x;}
alpar@1352
   508
    void set(Key k,Value v) {_map.set(k,typename M::Value(v,_map[k].y));}
alpar@1317
   509
  };
alpar@1317
   510
    
alpar@1317
   511
  ///Returns an \ref XMap class
alpar@1317
   512
alpar@1317
   513
  ///This function just returns an \ref XMap class.
alpar@1317
   514
  ///
alpar@1317
   515
  ///\ingroup maps
alpar@1317
   516
  ///\relates XMap
alpar@1317
   517
  template<class M> 
alpar@1317
   518
  inline XMap<M> xMap(M &m) 
alpar@1317
   519
  {
alpar@1317
   520
    return XMap<M>(m);
alpar@1317
   521
  }
alpar@1317
   522
deba@1420
   523
  template<class M> 
deba@1420
   524
  inline XMap<M> xMap(const M &m) 
deba@1420
   525
  {
deba@1420
   526
    return XMap<M>(m);
deba@1420
   527
  }
deba@1420
   528
alpar@1317
   529
  ///Constant (read only) version of \ref XMap
alpar@1317
   530
alpar@1317
   531
  ///\ingroup maps
alpar@2214
   532
  ///Constant (read only) version of \ref XMap
alpar@1317
   533
  ///
alpar@1317
   534
  template<class M>
alpar@1317
   535
  class ConstXMap 
alpar@1317
   536
  {
deba@1706
   537
    const M& _map;
alpar@1317
   538
  public:
deba@1420
   539
alpar@1317
   540
    typedef typename M::Value::Value Value;
alpar@1317
   541
    typedef typename M::Key Key;
alpar@1317
   542
    ///\e
alpar@1317
   543
    ConstXMap(const M &map) : _map(map) {}
alpar@1317
   544
    Value operator[](Key k) const {return _map[k].x;}
alpar@1317
   545
  };
alpar@1317
   546
    
alpar@1317
   547
  ///Returns a \ref ConstXMap class
alpar@1317
   548
alpar@1317
   549
  ///This function just returns an \ref ConstXMap class.
alpar@1317
   550
  ///
alpar@1317
   551
  ///\ingroup maps
alpar@1317
   552
  ///\relates ConstXMap
alpar@1317
   553
  template<class M> 
alpar@1317
   554
  inline ConstXMap<M> xMap(const M &m) 
alpar@1317
   555
  {
alpar@1317
   556
    return ConstXMap<M>(m);
alpar@1317
   557
  }
alpar@1317
   558
alpar@2207
   559
  ///Map of y-coordinates of a dim2::Point<>-map
alpar@1317
   560
    
alpar@1317
   561
  ///\ingroup maps
alpar@2214
   562
  ///Map of y-coordinates of a dim2::Point<>-map
alpar@1317
   563
  ///
alpar@1317
   564
  template<class M>
alpar@1317
   565
  class YMap 
alpar@1317
   566
  {
deba@1706
   567
    M& _map;
alpar@1317
   568
  public:
deba@1420
   569
alpar@1317
   570
    typedef typename M::Value::Value Value;
alpar@1317
   571
    typedef typename M::Key Key;
alpar@1317
   572
    ///\e
deba@1706
   573
    YMap(M& map) : _map(map) {}
alpar@1317
   574
    Value operator[](Key k) const {return _map[k].y;}
alpar@1352
   575
    void set(Key k,Value v) {_map.set(k,typename M::Value(_map[k].x,v));}
alpar@1317
   576
  };
alpar@1317
   577
alpar@1317
   578
  ///Returns an \ref YMap class
alpar@1317
   579
alpar@1317
   580
  ///This function just returns an \ref YMap class.
alpar@1317
   581
  ///
alpar@1317
   582
  ///\ingroup maps
alpar@1317
   583
  ///\relates YMap
alpar@1317
   584
  template<class M> 
alpar@1317
   585
  inline YMap<M> yMap(M &m) 
alpar@1317
   586
  {
alpar@1317
   587
    return YMap<M>(m);
alpar@1317
   588
  }
alpar@1317
   589
deba@1420
   590
  template<class M> 
deba@1420
   591
  inline YMap<M> yMap(const M &m) 
deba@1420
   592
  {
deba@1420
   593
    return YMap<M>(m);
deba@1420
   594
  }
deba@1420
   595
alpar@1317
   596
  ///Constant (read only) version of \ref YMap
alpar@1317
   597
alpar@1317
   598
  ///\ingroup maps
alpar@2214
   599
  ///Constant (read only) version of \ref YMap
alpar@1317
   600
  ///
alpar@1317
   601
  template<class M>
alpar@1317
   602
  class ConstYMap 
alpar@1317
   603
  {
deba@1706
   604
    const M& _map;
alpar@1317
   605
  public:
deba@1420
   606
alpar@1317
   607
    typedef typename M::Value::Value Value;
alpar@1317
   608
    typedef typename M::Key Key;
alpar@1317
   609
    ///\e
alpar@1317
   610
    ConstYMap(const M &map) : _map(map) {}
alpar@1317
   611
    Value operator[](Key k) const {return _map[k].y;}
alpar@1317
   612
  };
alpar@1317
   613
    
alpar@1317
   614
  ///Returns a \ref ConstYMap class
alpar@1317
   615
alpar@1317
   616
  ///This function just returns an \ref ConstYMap class.
alpar@1317
   617
  ///
alpar@1317
   618
  ///\ingroup maps
alpar@1317
   619
  ///\relates ConstYMap
alpar@1317
   620
  template<class M> 
alpar@1317
   621
  inline ConstYMap<M> yMap(const M &m) 
alpar@1317
   622
  {
alpar@1317
   623
    return ConstYMap<M>(m);
alpar@1317
   624
  }
alpar@1317
   625
alpar@1317
   626
alpar@2214
   627
    ///\brief Map of the \ref Point::normSquare() "normSquare()"
alpar@2214
   628
    ///of an \ref Point "Point"-map
alpar@2214
   629
    ///
alpar@2214
   630
    ///Map of the \ref Point::normSquare() "normSquare()"
alpar@2214
   631
    ///of an \ref Point "Point"-map
alpar@2214
   632
    ///\ingroup maps
alpar@2214
   633
    ///
alpar@1352
   634
  template<class M>
alpar@1352
   635
  class NormSquareMap 
alpar@1352
   636
  {
deba@1706
   637
    const M& _map;
alpar@1352
   638
  public:
deba@1420
   639
alpar@1352
   640
    typedef typename M::Value::Value Value;
alpar@1352
   641
    typedef typename M::Key Key;
alpar@1352
   642
    ///\e
alpar@1352
   643
    NormSquareMap(const M &map) : _map(map) {}
alpar@1352
   644
    Value operator[](Key k) const {return _map[k].normSquare();}
alpar@1352
   645
  };
alpar@1352
   646
    
alpar@1352
   647
  ///Returns a \ref NormSquareMap class
alpar@1352
   648
alpar@1352
   649
  ///This function just returns an \ref NormSquareMap class.
alpar@1352
   650
  ///
alpar@1352
   651
  ///\ingroup maps
alpar@1352
   652
  ///\relates NormSquareMap
alpar@1352
   653
  template<class M> 
alpar@1352
   654
  inline NormSquareMap<M> normSquareMap(const M &m) 
alpar@1352
   655
  {
alpar@1352
   656
    return NormSquareMap<M>(m);
alpar@1352
   657
  }
alpar@1352
   658
alpar@431
   659
  /// @}
athos@244
   660
alpar@2207
   661
  } //namespce dim2
alpar@2207
   662
  
alpar@921
   663
} //namespace lemon
athos@201
   664
alpar@2207
   665
#endif //LEMON_DIM2_H