lemon/bits/bezier.h
author deba
Tue, 17 Oct 2006 10:50:57 +0000
changeset 2247 269a0dcee70b
parent 2178 0d7c0f96a5ee
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@2178
     1
/* -*- C++ -*-
alpar@2178
     2
 *
alpar@2178
     3
 * This file is a part of LEMON, a generic C++ optimization library
alpar@2178
     4
 *
alpar@2178
     5
 * Copyright (C) 2003-2006
alpar@2178
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
alpar@2178
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
alpar@2178
     8
 *
alpar@2178
     9
 * Permission to use, modify and distribute this software is granted
alpar@2178
    10
 * provided that this copyright notice appears in all copies. For
alpar@2178
    11
 * precise terms see the accompanying LICENSE file.
alpar@2178
    12
 *
alpar@2178
    13
 * This software is provided "AS IS" with no warranty of any kind,
alpar@2178
    14
 * express or implied, and with no claim as to its suitability for any
alpar@2178
    15
 * purpose.
alpar@2178
    16
 *
alpar@2178
    17
 */
alpar@2178
    18
alpar@2178
    19
#ifndef LEMON_BEZIER_H
alpar@2178
    20
#define LEMON_BEZIER_H
alpar@2178
    21
alpar@2178
    22
///\ingroup misc
alpar@2178
    23
///\file
alpar@2178
    24
///\brief Classes to compute with Bezier curves.
alpar@2178
    25
///
alpar@2178
    26
///Up to now this file is used internally by \ref graph_to_eps.h
alpar@2178
    27
///
alpar@2178
    28
///\author Alpar Juttner
alpar@2178
    29
alpar@2207
    30
#include<lemon/dim2.h>
alpar@2178
    31
alpar@2178
    32
namespace lemon {
alpar@2207
    33
  namespace dim2 {
alpar@2178
    34
alpar@2178
    35
class BezierBase {
alpar@2178
    36
public:
alpar@2207
    37
  typedef Point<double> Point;
alpar@2178
    38
protected:
alpar@2207
    39
  static Point conv(Point x,Point y,double t) {return (1-t)*x+t*y;}
alpar@2178
    40
};
alpar@2178
    41
alpar@2178
    42
class Bezier1 : public BezierBase
alpar@2178
    43
{
alpar@2178
    44
public:
alpar@2207
    45
  Point p1,p2;
alpar@2178
    46
alpar@2178
    47
  Bezier1() {}
alpar@2207
    48
  Bezier1(Point _p1, Point _p2) :p1(_p1), p2(_p2) {}
alpar@2178
    49
  
alpar@2207
    50
  Point operator()(double t) const
alpar@2178
    51
  {
alpar@2178
    52
    //    return conv(conv(p1,p2,t),conv(p2,p3,t),t);
alpar@2178
    53
    return conv(p1,p2,t);
alpar@2178
    54
  }
alpar@2178
    55
  Bezier1 before(double t) const
alpar@2178
    56
  {
alpar@2178
    57
    return Bezier1(p1,conv(p1,p2,t));
alpar@2178
    58
  }
alpar@2178
    59
  
alpar@2178
    60
  Bezier1 after(double t) const
alpar@2178
    61
  {
alpar@2178
    62
    return Bezier1(conv(p1,p2,t),p2);
alpar@2178
    63
  }
alpar@2178
    64
alpar@2178
    65
  Bezier1 revert() const { return Bezier1(p2,p1);}
alpar@2178
    66
  Bezier1 operator()(double a,double b) const { return before(b).after(a/b); }
alpar@2207
    67
  Point grad() const { return p2-p1; }
alpar@2207
    68
  Point norm() const { return rot90(p2-p1); }
alpar@2207
    69
  Point grad(double) const { return grad(); }
alpar@2207
    70
  Point norm(double t) const { return rot90(grad(t)); }
alpar@2178
    71
};
alpar@2178
    72
alpar@2178
    73
class Bezier2 : public BezierBase
alpar@2178
    74
{
alpar@2178
    75
public:
alpar@2207
    76
  Point p1,p2,p3;
alpar@2178
    77
alpar@2178
    78
  Bezier2() {}
alpar@2207
    79
  Bezier2(Point _p1, Point _p2, Point _p3) :p1(_p1), p2(_p2), p3(_p3) {}
alpar@2178
    80
  Bezier2(const Bezier1 &b) : p1(b.p1), p2(conv(b.p1,b.p2,.5)), p3(b.p2) {}
alpar@2207
    81
  Point operator()(double t) const
alpar@2178
    82
  {
alpar@2178
    83
    //    return conv(conv(p1,p2,t),conv(p2,p3,t),t);
alpar@2178
    84
    return ((1-t)*(1-t))*p1+(2*(1-t)*t)*p2+(t*t)*p3;
alpar@2178
    85
  }
alpar@2178
    86
  Bezier2 before(double t) const
alpar@2178
    87
  {
alpar@2207
    88
    Point q(conv(p1,p2,t));
alpar@2207
    89
    Point r(conv(p2,p3,t));
alpar@2178
    90
    return Bezier2(p1,q,conv(q,r,t));
alpar@2178
    91
  }
alpar@2178
    92
  
alpar@2178
    93
  Bezier2 after(double t) const
alpar@2178
    94
  {
alpar@2207
    95
    Point q(conv(p1,p2,t));
alpar@2207
    96
    Point r(conv(p2,p3,t));
alpar@2178
    97
    return Bezier2(conv(q,r,t),r,p3);
alpar@2178
    98
  }
alpar@2178
    99
  Bezier2 revert() const { return Bezier2(p3,p2,p1);}
alpar@2178
   100
  Bezier2 operator()(double a,double b) const { return before(b).after(a/b); }
alpar@2178
   101
  Bezier1 grad() const { return Bezier1(2.0*(p2-p1),2.0*(p3-p2)); }
alpar@2178
   102
  Bezier1 norm() const { return Bezier1(2.0*rot90(p2-p1),2.0*rot90(p3-p2)); }
alpar@2207
   103
  Point grad(double t) const { return grad()(t); }
alpar@2207
   104
  Point norm(double t) const { return rot90(grad(t)); }
alpar@2178
   105
};
alpar@2178
   106
alpar@2178
   107
class Bezier3 : public BezierBase
alpar@2178
   108
{
alpar@2178
   109
public:
alpar@2207
   110
  Point p1,p2,p3,p4;
alpar@2178
   111
alpar@2178
   112
  Bezier3() {}
alpar@2207
   113
  Bezier3(Point _p1, Point _p2, Point _p3, Point _p4)
alpar@2207
   114
    : p1(_p1), p2(_p2), p3(_p3), p4(_p4) {}
alpar@2178
   115
  Bezier3(const Bezier1 &b) : p1(b.p1), p2(conv(b.p1,b.p2,1.0/3.0)), 
alpar@2178
   116
			      p3(conv(b.p1,b.p2,2.0/3.0)), p4(b.p2) {}
alpar@2178
   117
  Bezier3(const Bezier2 &b) : p1(b.p1), p2(conv(b.p1,b.p2,2.0/3.0)),
alpar@2178
   118
			      p3(conv(b.p2,b.p3,1.0/3.0)), p4(b.p3) {}
alpar@2178
   119
  
alpar@2207
   120
  Point operator()(double t) const 
alpar@2178
   121
    {
alpar@2178
   122
      //    return Bezier2(conv(p1,p2,t),conv(p2,p3,t),conv(p3,p4,t))(t);
alpar@2178
   123
      return ((1-t)*(1-t)*(1-t))*p1+(3*t*(1-t)*(1-t))*p2+
alpar@2178
   124
	(3*t*t*(1-t))*p3+(t*t*t)*p4;
alpar@2178
   125
    }
alpar@2178
   126
  Bezier3 before(double t) const
alpar@2178
   127
    {
alpar@2207
   128
      Point p(conv(p1,p2,t));
alpar@2207
   129
      Point q(conv(p2,p3,t));
alpar@2207
   130
      Point r(conv(p3,p4,t));
alpar@2207
   131
      Point a(conv(p,q,t));
alpar@2207
   132
      Point b(conv(q,r,t));
alpar@2207
   133
      Point c(conv(a,b,t));
alpar@2178
   134
      return Bezier3(p1,p,a,c);
alpar@2178
   135
    }
alpar@2178
   136
  
alpar@2178
   137
  Bezier3 after(double t) const
alpar@2178
   138
    {
alpar@2207
   139
      Point p(conv(p1,p2,t));
alpar@2207
   140
      Point q(conv(p2,p3,t));
alpar@2207
   141
      Point r(conv(p3,p4,t));
alpar@2207
   142
      Point a(conv(p,q,t));
alpar@2207
   143
      Point b(conv(q,r,t));
alpar@2207
   144
      Point c(conv(a,b,t));
alpar@2178
   145
      return Bezier3(c,b,r,p4);
alpar@2178
   146
    }
alpar@2178
   147
  Bezier3 revert() const { return Bezier3(p4,p3,p2,p1);}
alpar@2178
   148
  Bezier3 operator()(double a,double b) const { return before(b).after(a/b); }
alpar@2178
   149
  Bezier2 grad() const { return Bezier2(3.0*(p2-p1),3.0*(p3-p2),3.0*(p4-p3)); }
alpar@2178
   150
  Bezier2 norm() const { return Bezier2(3.0*rot90(p2-p1),
alpar@2178
   151
				  3.0*rot90(p3-p2),
alpar@2178
   152
				  3.0*rot90(p4-p3)); }
alpar@2207
   153
  Point grad(double t) const { return grad()(t); }
alpar@2207
   154
  Point norm(double t) const { return rot90(grad(t)); }
alpar@2178
   155
alpar@2178
   156
  template<class R,class F,class S,class D>
alpar@2178
   157
  R recSplit(F &_f,const S &_s,D _d) const 
alpar@2178
   158
  {
alpar@2207
   159
    const Point a=(p1+p2)/2;
alpar@2207
   160
    const Point b=(p2+p3)/2;
alpar@2207
   161
    const Point c=(p3+p4)/2;
alpar@2207
   162
    const Point d=(a+b)/2;
alpar@2207
   163
    const Point e=(b+c)/2;
alpar@2207
   164
    const Point f=(d+e)/2;
alpar@2178
   165
    R f1=_f(Bezier3(p1,a,d,e),_d);
alpar@2178
   166
    R f2=_f(Bezier3(e,d,c,p4),_d);
alpar@2178
   167
    return _s(f1,f2);
alpar@2178
   168
  }
alpar@2178
   169
  
alpar@2178
   170
};
alpar@2178
   171
alpar@2207
   172
alpar@2207
   173
} //END OF NAMESPACE dim2
alpar@2207
   174
} //END OF NAMESPACE lemon
alpar@2178
   175
alpar@2178
   176
#endif // LEMON_BEZIER_H