X-Git-Url: http://git.tdb.fi/?p=libs%2Fmath.git;a=blobdiff_plain;f=source%2Finterpolate%2Fbezierspline.h;fp=source%2Finterpolate%2Fbezierspline.h;h=c6e295a3dc40072aa9804de0977d280d181bfa19;hp=0000000000000000000000000000000000000000;hb=c854dd42c57b0430558baed5151449c83e24507f;hpb=92480ec2f41502e3cbdfe1fe3ca703c4521ff747 diff --git a/source/interpolate/bezierspline.h b/source/interpolate/bezierspline.h new file mode 100644 index 0000000..c6e295a --- /dev/null +++ b/source/interpolate/bezierspline.h @@ -0,0 +1,88 @@ +#ifndef MSP_INTERPOLATE_BEZIERSPLINE_H_ +#define MSP_INTERPOLATE_BEZIERSPLINE_H_ + +#include +#include "spline.h" + +namespace Msp { +namespace Interpolate { + +template +struct Bernstein +{ + static Polynomial b(unsigned); +}; + +/** +A spline composed of bezier curves. Each segment has D-1 control points +between the knots which determine the shape of the curve. Bezier splines +with 2- or 3-dimensional values are commonly used in graphics. +*/ +template +class BezierSpline: public Spline +{ +public: + using typename Spline::Knot; + + BezierSpline(const std::vector &); +}; + +template +inline Polynomial Bernstein::b(unsigned k) +{ + if(k>D) + throw std::invalid_argument("Bernstein::b"); + + LinAl::Vector coeff; + + int c = ((D-k)%2 ? -1 : 1); + for(unsigned i=0; i<=D-k; ++i) + { + coeff[i] = c; + c = c*-1*static_cast(D-k-i)/static_cast(i+1); + } + + unsigned n = 1; + for(unsigned i=0; i(coeff); +} + +template +inline BezierSpline::BezierSpline(const std::vector &k): + Spline(k.front()) +{ + typedef SplineValue SV; + + if((k.size()-1)%D) + throw std::invalid_argument("BezierSpline::BezierSpline"); + + Polynomial b[D+1]; + for(unsigned i=0; i<=D; ++i) + b[i] = Bernstein::b(i); + + for(unsigned i=0; i+D t(LinAl::Vector(T(1)/dx, -k[i].x/dx)); + Polynomial p[N]; + for(unsigned j=0; jadd_segment(p, k[i+D].x); + } +} + +} // namespace Interpolate +} // namespace Msp + +#endif