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