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