bezier_curve.h 3.73 KB
Newer Older
1
/**
2
* \file bezier_curve.h
3 4 5 6 7 8 9 10 11 12
* \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_BEZIERCURVE
#define _CLASS_BEZIERCURVE

stonneau's avatar
stonneau committed
13
#include "curve_abc.h"
14
#include "bernstein.h"
15 16 17 18

#include "MathDefs.h"

#include <vector>
19
#include <stdexcept>
20 21 22

namespace spline
{
23
/// \class BezierCurve
24 25 26
/// \brief Represents a Bezier curve of arbitrary dimension and order.
/// For degree lesser than 4, the evaluation is analitycal.Otherwise
/// the bernstein polynoms are used to evaluate the spline at a given location.
27
///
28
template<typename Time= double, typename Numeric=Time, std::size_t Dim=3, bool Safe=false
29 30 31 32 33
, typename Point= Eigen::Matrix<Numeric, Dim, 1> >
struct bezier_curve : public  curve_abc<Time, Numeric, Dim, Safe, Point>
{
	typedef Point 	point_t;
	typedef Time 	time_t;
34 35
    typedef Numeric	num_t;
    typedef std::vector<point_t,Eigen::aligned_allocator<point_t> > t_point_t;
36

37 38
/* Constructors - destructors */
	public:
39 40
	///\brief Constructor
	///\param PointsBegin, PointsEnd : the points parametering the Bezier curve
41
    ///
42
	template<typename In>
stonneau's avatar
stonneau committed
43
	bezier_curve(In PointsBegin, In PointsEnd, const time_t minBound=0, const time_t maxBound=1)
44 45 46
	: minBound_(minBound)
	, maxBound_(maxBound)
	, size_(std::distance(PointsBegin, PointsEnd))
47
    , bernstein_(spline::makeBernstein<num_t>(size_-1))
48
	{
49
        assert(bernstein_.size() == size_);
50 51 52
		In it(PointsBegin);
		if(Safe && (size_<=1 || minBound == maxBound))
		{
53
            throw std::out_of_range("can't create bezier min bound is higher than max bound"); // TODO
54 55 56 57 58 59
		}
		for(; it != PointsEnd; ++it)
		{
			pts_.push_back(*it);
		}
	}
60

61
	///\brief Destructor
stonneau's avatar
stonneau committed
62
	~bezier_curve()
63 64 65
	{
		// NOTHING
	}
66 67

	private:
68 69
//	bezier_curve(const bezier_curve&);
//  bezier_curve& operator=(const bezier_curve&);
70 71 72 73 74 75
/* Constructors - destructors */

/*Operations*/
	public:
	///  \brief Evaluation of the cubic spline at time t.
	///  \param t : the time when to evaluate the spine
76
	///  \param return : the value x(t)
77
    virtual point_t operator()(const time_t t) const
78 79 80 81
	{
		num_t nT = (t - minBound_) / (maxBound_ - minBound_);
		if(Safe &! (0 <= nT && nT <= 1))
		{
82
            throw std::out_of_range("can't evaluate bezier curve, out of range"); // TODO
83
        }
84 85 86 87 88 89 90 91 92 93 94 95 96
		else
		{
			num_t dt = (1 - nT);
			switch(size_)
			{	
				case 2 :
					return pts_[0] * dt +  nT * pts_[1];
				break;
				case 3 :
					return 	pts_[0] * dt * dt 
                       				+ 2 * pts_[1] * nT * dt
						+ pts_[2] * nT * nT;
				break;
97
                case 4 :
98 99 100 101
					return 	pts_[0] * dt * dt * dt
						+ 3 * pts_[1] * nT * dt * dt 
						+ 3 * pts_[2] * nT * nT * dt 
						+ pts_[3] * nT * nT *nT;
102 103
                default :
                    return evalBernstein(dt);
104 105 106 107
				break;
			}
		}
	}
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123

    ///
    /// \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<Bern<Numeric> >::const_iterator cit = bernstein_.begin();
            cit !=bernstein_.end(); ++cit, ++pts_it)
        {
            res += cit->operator()(u) * (*pts_it);
        }
        return res;
    }

124
/*Operations*/
125 126

/*Helpers*/
stonneau's avatar
stonneau committed
127 128
	virtual time_t min() const{return minBound_;}
	virtual time_t max() const{return maxBound_;}
129 130 131
/*Helpers*/

	public:
132 133 134
    const time_t minBound_, maxBound_;
    const std::size_t size_;
    const std::vector<Bern<Numeric> > bernstein_;
135
	
136 137 138 139
    private:
    t_point_t  pts_;

    //storing bernstein polynoms, even in low dimension
140
};
141 142 143
}
#endif //_CLASS_BEZIERCURVE