Commit c3f88428 by Steve Tonneau

### bernstein polynoms for higher order bezier eval

parent e60540df
 /** * \file bezier_curve.h * \brief class allowing to create a Bezier curve of dimension 1 <= n <= 3. * \author Steve T. * \version 0.1 * \date 06/17/2013 */ #ifndef _CLASS_BERNSTEIN #define _CLASS_BERNSTEIN #include "curve_abc.h" #include "MathDefs.h" #include #include #include namespace spline { /// /// \brief Computes factorial of a number /// unsigned int fact(const unsigned int n) { assert(n>=0); int res = 1; for (int i=2 ; i <= n ; ++i) res *= i; return res; } /// /// \brief Computes a binomal coefficient /// unsigned int bin(const unsigned int n, const unsigned int k) { return fact(n) / (fact(k) * fact(n - k)); } /// \class Bernstein /// \brief Computes a Bernstein polynome /// template struct Bern{ Bern(const unsigned int m, const unsigned int i) :m_minus_i(m - i) ,i_(i) ,bin_m_i_(bin(m,i)) {} ~Bern(){} Numeric operator()(const Numeric u) const { assert(u >= 0. && u <= 1.); return bin_m_i_*(pow(u, i_)) *pow((1-u),m_minus_i); } Numeric m_minus_i; Numeric i_; Numeric bin_m_i_; }; /// /// \brief Computes all Bernstein polynomes for a certain degree /// template std::vector > makeBernstein(const unsigned int n) { std::vector > res; for(unsigned int i = 0; i<= n; ++i) res.push_back(Bern(n, i)); return res; } } // namespace spline #endif //_CLASS_BERNSTEIN
 ... ... @@ -11,10 +11,12 @@ #define _CLASS_BEZIERCURVE #include "curve_abc.h" #include "bernstein.h" #include "MathDefs.h" #include #include namespace spline { ... ... @@ -27,7 +29,8 @@ struct bezier_curve : public curve_abc { typedef Point point_t; typedef Time time_t; typedef Numeric num_t; typedef Numeric num_t; typedef std::vector > t_point_t; /* Constructors - destructors */ public: ... ... @@ -39,11 +42,13 @@ struct bezier_curve : public curve_abc : minBound_(minBound) , maxBound_(maxBound) , size_(std::distance(PointsBegin, PointsEnd)) , bernstein_(spline::makeBernstein(size_-1)) { assert(bernstein_.size() == size_); In it(PointsBegin); if(Safe && (size_<=1 || minBound == maxBound)) { throw std::out_of_range("TODO"); // TODO throw std::out_of_range("can't create bezier min bound is higher than max bound"); // TODO } for(; it != PointsEnd; ++it) { ... ... @@ -58,8 +63,8 @@ struct bezier_curve : public curve_abc } private: bezier_curve(const bezier_curve&); bezier_curve& operator=(const bezier_curve&); // bezier_curve(const bezier_curve&); // bezier_curve& operator=(const bezier_curve&); /* Constructors - destructors */ /*Operations*/ ... ... @@ -72,7 +77,7 @@ struct bezier_curve : public curve_abc num_t nT = (t - minBound_) / (maxBound_ - minBound_); if(Safe &! (0 <= nT && nT <= 1)) { throw std::out_of_range("TODO"); // TODO throw std::out_of_range("can't evaluate bezier curve, out of range"); // TODO } else { ... ... @@ -87,15 +92,33 @@ struct bezier_curve : public curve_abc + 2 * pts_[1] * nT * dt + pts_[2] * nT * nT; break; default : case 4 : return pts_[0] * dt * dt * dt + 3 * pts_[1] * nT * dt * dt + 3 * pts_[2] * nT * nT * dt + pts_[3] * nT * nT *nT; default : return evalBernstein(dt); break; } } } /// /// \brief Evaluates all Bernstein polynomes for a certain degree /// point_t evalBernstein(const Numeric u) const { point_t res = point_t::Zero(); typename t_point_t::const_iterator pts_it = pts_.begin(); for(typename std::vector >::const_iterator cit = bernstein_.begin(); cit !=bernstein_.end(); ++cit, ++pts_it) { res += cit->operator()(u) * (*pts_it); } return res; } /*Operations*/ /*Helpers*/ ... ... @@ -104,12 +127,14 @@ struct bezier_curve : public curve_abc /*Helpers*/ public: const int size_; const time_t minBound_, maxBound_; const time_t minBound_, maxBound_; const std::size_t size_; const std::vector > bernstein_; private: typedef std::vector > T_Vector; T_Vector pts_; private: t_point_t pts_; //storing bernstein polynoms, even in low dimension }; } #endif //_CLASS_BEZIERCURVE ... ...
 ... ... @@ -181,30 +181,40 @@ void BezierCurveTest(bool& error) res1 = cf4(2); ComparePoints(d, res1, errMsg + "3(1) ", error); //testing bernstein polynomes std::string errMsg2("In test BezierCurveTest ; Bernstein polynoms do not evaluate as analytical evaluation"); for(double d = 0.; d <1.; d+=0.1) { ComparePoints( cf3.evalBernstein(d) , cf3 (d), errMsg2, error); } bool error_in(true); try { cf(-0.4); } catch(...) { error = false; error_in = false; } if(error) if(error_in) { std::cout << "Evaluation of bezier cf error, -0.4 should be an out of range value\n"; error = true; } error = true; error_in = true; try { cf(1.1); } catch(...) { error = false; error_in = false; } if(error) if(error_in) { std::cout << "Evaluation of bezier cf error, 1.1 should be an out of range value\n"; error = true; } if(cf.max() != 1) { ... ...
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!