00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef LEMON_BEZIER_H
00018 #define LEMON_BEZIER_H
00019
00027
00028 #include<lemon/xy.h>
00029
00030 namespace lemon {
00031
00032 class BezierBase {
00033 public:
00034 typedef xy<double> xy;
00035 protected:
00036 static xy conv(xy x,xy y,double t) {return (1-t)*x+t*y;}
00037 };
00038
00039 class Bezier1 : public BezierBase
00040 {
00041 public:
00042 xy p1,p2;
00043
00044 Bezier1() {}
00045 Bezier1(xy _p1, xy _p2) :p1(_p1), p2(_p2) {}
00046
00047 xy operator()(double t) const
00048 {
00049
00050 return conv(p1,p2,t);
00051 }
00052 Bezier1 before(double t) const
00053 {
00054 return Bezier1(p1,conv(p1,p2,t));
00055 }
00056
00057 Bezier1 after(double t) const
00058 {
00059 return Bezier1(conv(p1,p2,t),p2);
00060 }
00061 Bezier1 revert() { return Bezier1(p2,p1);}
00062 Bezier1 operator()(double a,double b) { return before(b).after(a/b); }
00063 xy grad() { return p2-p1; }
00064 xy grad(double t) { return grad(); }
00065
00066 };
00067
00068 class Bezier2 : public BezierBase
00069 {
00070 public:
00071 xy p1,p2,p3;
00072
00073 Bezier2() {}
00074 Bezier2(xy _p1, xy _p2, xy _p3) :p1(_p1), p2(_p2), p3(_p3) {}
00075 Bezier2(const Bezier1 &b) : p1(b.p1), p2(conv(b.p1,b.p2,.5)), p3(b.p2) {}
00076 xy operator()(double t) const
00077 {
00078
00079 return ((1-t)*(1-t))*p1+(2*(1-t)*t)*p2+(t*t)*p3;
00080 }
00081 Bezier2 before(double t) const
00082 {
00083 xy q(conv(p1,p2,t));
00084 xy r(conv(p2,p3,t));
00085 return Bezier2(p1,q,conv(q,r,t));
00086 }
00087
00088 Bezier2 after(double t) const
00089 {
00090 xy q(conv(p1,p2,t));
00091 xy r(conv(p2,p3,t));
00092 return Bezier2(conv(q,r,t),r,p3);
00093 }
00094 Bezier2 revert() { return Bezier2(p3,p2,p1);}
00095 Bezier2 operator()(double a,double b) { return before(b).after(a/b); }
00096 Bezier1 grad() { return Bezier1(2.0*(p2-p1),2.0*(p3-p2)); }
00097 xy grad(double t) { return grad()(t); }
00098 };
00099
00100 class Bezier3 : public BezierBase
00101 {
00102 public:
00103 xy p1,p2,p3,p4;
00104
00105 Bezier3() {}
00106 Bezier3(xy _p1, xy _p2, xy _p3, xy _p4) :p1(_p1), p2(_p2), p3(_p3), p4(_p4) {}
00107 Bezier3(const Bezier1 &b) : p1(b.p1), p2(conv(b.p1,b.p2,1.0/3.0)),
00108 p3(conv(b.p1,b.p2,2.0/3.0)), p4(b.p2) {}
00109 Bezier3(const Bezier2 &b) : p1(b.p1), p2(conv(b.p1,b.p2,2.0/3.0)),
00110 p3(conv(b.p2,b.p3,1.0/3.0)), p4(b.p3) {}
00111
00112 xy operator()(double t) const
00113 {
00114
00115 return ((1-t)*(1-t)*(1-t))*p1+(3*t*(1-t)*(1-t))*p2+
00116 (3*t*t*(1-t))*p3+(t*t*t)*p4;
00117 }
00118 Bezier3 before(double t) const
00119 {
00120 xy p(conv(p1,p2,t));
00121 xy q(conv(p2,p3,t));
00122 xy r(conv(p3,p4,t));
00123 xy a(conv(p,q,t));
00124 xy b(conv(q,r,t));
00125 xy c(conv(a,b,t));
00126 return Bezier3(p1,p,a,c);
00127 }
00128
00129 Bezier3 after(double t) const
00130 {
00131 xy p(conv(p1,p2,t));
00132 xy q(conv(p2,p3,t));
00133 xy r(conv(p3,p4,t));
00134 xy a(conv(p,q,t));
00135 xy b(conv(q,r,t));
00136 xy c(conv(a,b,t));
00137 return Bezier3(c,b,r,p4);
00138 }
00139 Bezier3 revert() { return Bezier3(p4,p3,p2,p1);}
00140 Bezier3 operator()(double a,double b) { return before(b).after(a/b); }
00141 Bezier2 grad() { return Bezier2(3.0*(p2-p1),3.0*(p3-p2),3.0*(p4-p3)); }
00142 xy grad(double t) { return grad()(t); }
00143 };
00144
00145 }
00146
00147 #endif // LEMON_BEZIER_H