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