lemon/bezier.h
author deba
Wed, 01 Mar 2006 10:25:30 +0000
changeset 1991 d7442141d9ef
parent 1875 98698b69a902
permissions -rw-r--r--
The graph adadptors can be alteration observed.
In most cases it uses the adapted graph alteration notifiers.
Only special case is now the UndirGraphAdaptor, where
we have to proxy the signals from the graph.

The SubBidirGraphAdaptor is removed, because it doest not
gives more feature than the EdgeSubGraphAdaptor<UndirGraphAdaptor<Graph>>.

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