diff --git a/include/curves/CMakeLists.txt b/include/curves/CMakeLists.txt
index c0f87f95b9555d1cbb879217c9f7ee0596bea727..8fefd30f211302e469c04d014d14f40909e44d9b 100644
--- a/include/curves/CMakeLists.txt
+++ b/include/curves/CMakeLists.txt
@@ -1,16 +1,17 @@
 SET(${PROJECT_NAME}_HEADERS
   bernstein.h
-  bezier_polynom_conversion.h
+  curve_conversion.h
   curve_abc.h
   exact_cubic.h
   MathDefs.h
-  polynom.h
-  spline_deriv_constraint.h
+  polynomial.h
   bezier_curve.h
   cubic_spline.h
   curve_constraint.h
   quintic_spline.h
   linear_variable.h
+  cubic_hermite_spline.h
+  piecewise_polynomial_curve.h
   )
 
 INSTALL(FILES
diff --git a/include/curves/MathDefs.h b/include/curves/MathDefs.h
index 628898e60bf97ac176b28584fcbc8674ae8c65c8..18cced66cf22e1f7c39943e695a388b693daa5a7 100644
--- a/include/curves/MathDefs.h
+++ b/include/curves/MathDefs.h
@@ -35,7 +35,9 @@ void PseudoInverse(_Matrix_Type_& pinvmat)
 	for (long i=0; i<m_sigma.rows(); ++i)
 	{
 		if (m_sigma(i) > pinvtoler)
+		{
 			m_sigma_inv(i,i)=1.0/m_sigma(i);
+		}
 	}
 	pinvmat = (svd.matrixV()*m_sigma_inv*svd.matrixU().transpose());
 }
diff --git a/include/curves/bernstein.h b/include/curves/bernstein.h
index 800ac3447c861899370eca24181d370e7ae03482..31c8aedff57f86da23f6b43ac24b89bed0b5a7de 100644
--- a/include/curves/bernstein.h
+++ b/include/curves/bernstein.h
@@ -20,23 +20,20 @@
 
 namespace curves
 {
-///
-/// \brief Computes factorial of a number.
-///
-inline unsigned int fact(const unsigned int n)
-{
-    unsigned int res = 1;
-    for (unsigned int i=2 ; i <= n ; ++i)
-       res *= i;
-    return res;
-}
-
-///
-/// \brief Computes a binomal coefficient.
+/// \brief Computes a binomial coefficient.
+/// \param n : an unsigned integer.
+/// \param k : an unsigned integer.
+/// \return \f$\binom{n}{k}f$
 ///
 inline unsigned int bin(const unsigned  int n, const unsigned  int k)
 {
-    return fact(n) / (fact(k) * fact(n - k));
+    if(k >  n)
+        throw std::runtime_error("binomial coefficient higher than degree");
+    if(k == 0)
+        return 1;
+    if(k > n/2)
+        return bin(n,n-k);
+    return n * bin(n-1,k-1) / k;
 }
 
 /// \class Bernstein.
@@ -62,8 +59,6 @@ Numeric i_;
 Numeric bin_m_i_;
 };
 
-
-///
 /// \brief Computes all Bernstein polynomes for a certain degree.
 ///
 template <typename Numeric>
diff --git a/include/curves/bezier_curve.h b/include/curves/bezier_curve.h
index d5d6bf124e435bf0d8d94ba10394793be2ffa11f..56210193005728412381f4faaf3966de25f41005 100644
--- a/include/curves/bezier_curve.h
+++ b/include/curves/bezier_curve.h
@@ -44,60 +44,16 @@ struct bezier_curve : public curve_abc<Time, Numeric, Dim, Safe, Point>
 	public:
 
     /// \brief Constructor.
-    /// Given the first and last point of a control points set, automatically create the bezier curve.
-    /// \param PointsBegin  : an iterator pointing to the first element of a control point container.
-    /// \param PointsEnd    : an iterator pointing to the last element of a control point container.
-    ///
-	template<typename In>
-    bezier_curve(In PointsBegin, In PointsEnd)
-    : T_(1.)
-    , mult_T_(1.)
-	, size_(std::distance(PointsBegin, PointsEnd))
-    , degree_(size_-1)
-    , bernstein_(curves::makeBernstein<num_t>((unsigned int)degree_))
-    {
-        assert(bernstein_.size() == size_);
-		In it(PointsBegin);
-        if(Safe && (size_<1 || T_ <= 0.))
-            throw std::out_of_range("can't create bezier min bound is higher than max bound"); // TODO
-        for(; it != PointsEnd; ++it)
-            pts_.push_back(*it);
-    }
-
-    /// \brief Constructor.
-    /// Given the first and last point of a control points set, automatically create the bezier curve.
-    /// \param PointsBegin   : an iterator pointing to the first element of a control point container.
-    /// \param PointsEnd     : an iterator pointing to the last element of a control point container.
-    /// \param T             : upper bound of curve parameter which is between \f$[0;T]\f$ (default \f$[0;1]\f$).
-    ///
-    template<typename In>
-    bezier_curve(In PointsBegin, In PointsEnd, const time_t T)
-    : T_(T)
-    , mult_T_(1.)
-    , size_(std::distance(PointsBegin, PointsEnd))
-    , degree_(size_-1)
-    , bernstein_(curves::makeBernstein<num_t>((unsigned int)degree_))
-    {
-        assert(bernstein_.size() == size_);
-        In it(PointsBegin);
-        if(Safe && (size_<1 || T_ <= 0.))
-            throw std::out_of_range("can't create bezier min bound is higher than max bound"); // TODO
-        for(; it != PointsEnd; ++it)
-            pts_.push_back(*it);
-    }
-
-
-
-    /// \brief Constructor.
-    /// Given the first and last point of a control points set, automatically create the bezier curve.
+    /// Given the first and last point of a control points set, create the bezier curve.
     /// \param PointsBegin   : an iterator pointing to the first element of a control point container.
     /// \param PointsEnd     : an iterator pointing to the last element of a control point container.
     /// \param T             : upper bound of time which is between \f$[0;T]\f$ (default \f$[0;1]\f$).
-    /// \param mult_T        : 
+    /// \param mult_T        : ... (default value is 1.0).
     ///
     template<typename In>
-    bezier_curve(In PointsBegin, In PointsEnd, const time_t T, const time_t mult_T)
-    : T_(T)
+    bezier_curve(In PointsBegin, In PointsEnd, const time_t T_min=0., const time_t T_max=1., const time_t mult_T=1.)
+    : T_min_(T_min)
+    , T_max_(T_max)
     , mult_T_(mult_T)
     , size_(std::distance(PointsBegin, PointsEnd))
     , degree_(size_-1)
@@ -105,10 +61,14 @@ struct bezier_curve : public curve_abc<Time, Numeric, Dim, Safe, Point>
     {
         assert(bernstein_.size() == size_);
         In it(PointsBegin);
-        if(Safe && (size_<1 || T_ <= 0.))
+        if(Safe && (size_<1 || T_max_ <= T_min_))
+        {
             throw std::out_of_range("can't create bezier min bound is higher than max bound"); // TODO
+        }
         for(; it != PointsEnd; ++it)
-            pts_.push_back(*it);
+        {
+            control_points_.push_back(*it);
+        }
     }
 
     /// \brief Constructor
@@ -119,18 +79,24 @@ struct bezier_curve : public curve_abc<Time, Numeric, Dim, Safe, Point>
     /// \param constraints : constraints applying on start / end velocities and acceleration.
     ///
     template<typename In>
-    bezier_curve(In PointsBegin, In PointsEnd, const curve_constraints_t& constraints, const time_t T=1.)
-    : T_(T)
-    , mult_T_(1.)
+    bezier_curve(In PointsBegin, In PointsEnd, const curve_constraints_t& constraints, 
+                const time_t T_min=0., const time_t T_max=1., const time_t mult_T=1.)
+    : T_min_(T_min)
+    , T_max_(T_max)
+    , mult_T_(mult_T)
     , size_(std::distance(PointsBegin, PointsEnd)+4)
     , degree_(size_-1)
     , bernstein_(curves::makeBernstein<num_t>((unsigned int)degree_))
     {
-        if(Safe && (size_<1 || T_ <= 0.))
+        if(Safe && (size_<1 || T_max_ <= T_min_))
+        {
             throw std::out_of_range("can't create bezier min bound is higher than max bound");
+        }
         t_point_t updatedList = add_constraints<In>(PointsBegin, PointsEnd, constraints);
         for(cit_point_t cit = updatedList.begin(); cit != updatedList.end(); ++cit)
-            pts_.push_back(*cit);
+        {
+            control_points_.push_back(*cit);
+        }
     }
 
 	///\brief Destructor
@@ -148,141 +114,179 @@ struct bezier_curve : public curve_abc<Time, Numeric, Dim, Safe, Point>
 	public:
 	///  \brief Evaluation of the bezier curve at time t.
 	///  \param t : time when to evaluate the curve.
-	///  \return Point corresponding on curve at time t.
+	///  \return \f$x(t)\f$ point corresponding on curve at time t.
     virtual point_t operator()(const time_t t) const
+    {
+        if(Safe &! (T_min_ <= t && t <= T_max_))
+        {
+            throw std::out_of_range("can't evaluate bezier curve, out of range"); // TODO
+        }
+        if (size_ == 1)
+        {
+          return mult_T_*control_points_[0];
+        }else
         {
-            if(Safe &! (0 <= t && t <= T_))
-                throw std::out_of_range("can't evaluate bezier curve, out of range"); // TODO
-            if (size_ == 1){
-              return mult_T_*pts_[0];
-            }else{
-              return evalHorner(t);
-            }
+          return evalHorner(t);
+        }
 	}
 
-    ///  \brief Compute the derivative curve at order N.
-    ///  Computes the derivative at order N, \f$\frac{d^Nx(t)}{dt^N}\f$ of bezier curve of parametric equation x(t).
-    ///  \param order : order of the derivative.
-    ///  \return Derivative \f$\frac{dx(t)}{dt}\f$.
+    ///  \brief Compute the derived curve at order N.
+    ///  Computes the derivative order N, \f$\frac{d^Nx(t)}{dt^N}\f$ of bezier curve of parametric equation x(t).
+    ///  \param order : order of derivative.
+    ///  \return \f$\frac{d^Nx(t)}{dt^N}\f$ derivative order N of the curve.
     bezier_curve_t compute_derivate(const std::size_t order) const
     {
-        if(order == 0) return *this;
+        if(order == 0) 
+        {
+            return *this;
+        }
         t_point_t derived_wp;
-        for(typename t_point_t::const_iterator pit =  pts_.begin(); pit != pts_.end()-1; ++pit)
+        for(typename t_point_t::const_iterator pit =  control_points_.begin(); pit != control_points_.end()-1; ++pit)
             derived_wp.push_back((num_t)degree_ * (*(pit+1) - (*pit)));
         if(derived_wp.empty())
             derived_wp.push_back(point_t::Zero(Dim));
-        bezier_curve_t deriv(derived_wp.begin(), derived_wp.end(),T_, mult_T_ * (1./T_) );
+        bezier_curve_t deriv(derived_wp.begin(), derived_wp.end(),T_min_, T_max_, mult_T_ * (1./(T_max_-T_min_)) );
         return deriv.compute_derivate(order-1);
     }
 
     ///  \brief Compute the primitive of the curve at order N.
-    ///  Computes the primitive at order N of bezier curve of parametric equation \f$x(t)\f$. At order \f$N=1\f$, 
-    ///  the primitve \f$X(t)\f$ of \f$x(t)\f$ is such as \f$\frac{dX(t)}{dt} = x(t)\f$.
+    ///  Computes the primitive at order N of bezier curve of parametric equation \f$x(t)\f$. <br>
+    ///  At order \f$N=1\f$, the primitve \f$X(t)\f$ of \f$x(t)\f$ is such as \f$\frac{dX(t)}{dt} = x(t)\f$.
     ///  \param order : order of the primitive.
-    ///  \return Primitive of x(t).
+    ///  \return primitive at order N of x(t).
     bezier_curve_t compute_primitive(const std::size_t order) const
     {
-        if(order == 0) return *this;
+        if(order == 0) 
+        {
+            return *this;
+        }
         num_t new_degree = (num_t)(degree_+1);
         t_point_t n_wp;
         point_t current_sum =  point_t::Zero(Dim);
         // recomputing waypoints q_i from derivative waypoints p_i. q_0 is the given constant.
         // then q_i = (sum( j = 0 -> j = i-1) p_j) /n+1
         n_wp.push_back(current_sum);
-        for(typename t_point_t::const_iterator pit =  pts_.begin(); pit != pts_.end(); ++pit)
+        for(typename t_point_t::const_iterator pit =  control_points_.begin(); pit != control_points_.end(); ++pit)
         {
             current_sum += *pit;
             n_wp.push_back(current_sum / new_degree);
         }
-        bezier_curve_t integ(n_wp.begin(), n_wp.end(),T_, mult_T_*T_);
+        bezier_curve_t integ(n_wp.begin(), n_wp.end(),T_min_, T_max_, mult_T_*(T_max_-T_min_));
         return integ.compute_primitive(order-1);
     }
 
-    ///  \brief Evaluate the derivative at order N of the curve.
-    ///  If the derivative is to be evaluated several times, it is
-    ///  rather recommended to compute the derivative curve using compute_derivate.
-    ///  \param order : order of the derivative
+    ///  \brief Evaluate the derivative order N of curve at time t.
+    ///  If derivative is to be evaluated several times, it is
+    ///  rather recommended to compute derived curve using compute_derivate.
+    ///  \param order : order of derivative.
     ///  \param t : time when to evaluate the curve.
-    ///  \return Point corresponding on derivative curve at time t.
+    ///  \return \f$\frac{d^Nx(t)}{dt^N}\f$ point corresponding on derived curve of order N at time t.
+    ///
     virtual point_t derivate(const time_t t, const std::size_t order) const
     {
-        bezier_curve_t deriv =compute_derivate(order);
+        bezier_curve_t deriv = compute_derivate(order);
         return deriv(t);
     }
 
     /// \brief Evaluate all Bernstein polynomes for a certain degree.
-    /// Warning: the horner scheme is about 100 times faster than this method.
-    /// This method will probably be removed in the future.
-    /// \param t : unNormalized time
-    /// \return Point corresponding on curve at time t.
+    /// A bezier curve with N control points is represented by : \f$x(t) = \sum_{i=0}^{N} B_i^N(t) P_i\f$
+    /// with \f$ B_i^N(t) = \binom{N}{i}t^i (1-t)^{N-i} \f$.<br/>
+    /// Warning: the horner scheme is about 100 times faster than this method.<br>
+    /// This method will probably be removed in the future as the computation of bernstein polynomial is very costly.
+    /// \param t : time when to evaluate the curve.
+    /// \return \f$x(t)\f$ point corresponding on curve at time t.
     ///
     point_t evalBernstein(const Numeric t) const
     {
-        const Numeric u = t/T_;
+        const Numeric u = (t-T_min_)/(T_max_-T_min_);
         point_t res = point_t::Zero(Dim);
-        typename t_point_t::const_iterator pts_it = pts_.begin();
+        typename t_point_t::const_iterator control_points_it = control_points_.begin();
         for(typename std::vector<Bern<Numeric> >::const_iterator cit = bernstein_.begin();
-            cit !=bernstein_.end(); ++cit, ++pts_it)
-            res += cit->operator()(u) * (*pts_it);
+            cit !=bernstein_.end(); ++cit, ++control_points_it)
+        {
+            res += cit->operator()(u) * (*control_points_it);
+        }
         return res*mult_T_;
     }
 
-    /// \brief Evaluate all Bernstein polynomes for a certain degree using horner's scheme.
-    /// \param t : unNormalized time
-    /// \return Point corresponding on curve at time t.
+    /// \brief Evaluate all Bernstein polynomes for a certain degree using Horner's scheme.
+    /// A bezier curve with N control points is expressed as : \f$x(t) = \sum_{i=0}^{N} B_i^N(t) P_i\f$.<br>
+    /// To evaluate the position on curve at time t,we can apply the Horner's scheme : <br>
+    /// \f$ x(t) = (1-t)^N(\sum_{i=0}^{N} \binom{N}{i} \frac{1-t}{t}^i P_i) \f$.<br>
+    /// Horner's scheme : for a polynom of degree N expressed by : <br>
+    /// \f$x(t) = a_0 + a_1t + a_2t^2 + ... + a_nt^n\f$
+    /// where \f$number of additions = N\f$ / f$number of multiplication = N!\f$<br>
+    /// Using Horner's method, the polynom is transformed into : <br>
+    /// \f$x(t) = a_0 + t(a_1 + t(a_2+t(...))\f$ with N additions and multiplications.
+    /// \param t : time when to evaluate the curve.
+    /// \return \f$x(t)\f$ point corresponding on curve at time t.
     ///
     point_t evalHorner(const Numeric t) const
     {
-        const Numeric u = t/T_;
-        typename t_point_t::const_iterator pts_it = pts_.begin();
+        const Numeric u = (t-T_min_)/(T_max_-T_min_);
+        typename t_point_t::const_iterator control_points_it = control_points_.begin();
         Numeric u_op, bc, tn;
         u_op = 1.0 - u;
         bc = 1;
         tn = 1;
-        point_t tmp =(*pts_it)*u_op; ++pts_it;
-        for(unsigned int i=1; i<degree_; i++, ++pts_it)
+        point_t tmp =(*control_points_it)*u_op; ++control_points_it;
+        for(unsigned int i=1; i<degree_; i++, ++control_points_it)
         {
             tn = tn*u;
             bc = bc*((num_t)(degree_-i+1))/i;
-            tmp = (tmp + tn*bc*(*pts_it))*u_op;
+            tmp = (tmp + tn*bc*(*control_points_it))*u_op;
         }
-        return (tmp + tn*u*(*pts_it))*mult_T_;
+        return (tmp + tn*u*(*control_points_it))*mult_T_;
     }
 
-    const t_point_t& waypoints() const {return pts_;}
+    const t_point_t& waypoints() const {return control_points_;}
 
     /// \brief Evaluate the curve value at time t using deCasteljau algorithm.
-    /// \param t : unNormalized time
-    /// \return Point corresponding on curve at time t.
+    /// The algorithm will compute the \f$N-1\f$ centroids of parameters \f${t,1-t}\f$ of consecutive \f$N\f$ control points 
+    /// of bezier curve, and perform it iteratively until getting one point in the list which will be the evaluation of bezier
+    /// curve at time \f$t\f$.
+    /// \param t : time when to evaluate the curve.
+    /// \return \f$x(t)\f$ point corresponding on curve at time t.
     ///
     point_t evalDeCasteljau(const Numeric t) const {
         // normalize time :
-        const Numeric u = t/T_;
+        const Numeric u = (t-T_min_)/(T_max_-T_min_);
         t_point_t pts = deCasteljauReduction(waypoints(),u);
-        while(pts.size() > 1){
+        while(pts.size() > 1)
+        {
             pts = deCasteljauReduction(pts,u);
         }
         return pts[0]*mult_T_;
     }
 
+
     t_point_t deCasteljauReduction(const Numeric t) const{
-        return deCasteljauReduction(waypoints(),t/T_);
+        const Numeric u = (t-T_min_)/(T_max_-T_min_);
+        return deCasteljauReduction(waypoints(),u);
     }
 
     /// \brief Compute de Casteljau's reduction of the given list of points at time t.
+    /// For the list \f$pts\f$ of N points, compute a new list of points of size N-1 :<br>
+    /// \f$<br>( pts[0]*(1-t)+pts[1], pts[1]*(1-t)+pts[2], ..., pts[0]*(N-2)+pts[N-1] )\f$<br>
+    /// with t the time when to evaluate bezier curve.<br>\ The new list contains centroid of 
+    /// parameters \f${t,1-t}\f$ of consecutive points in the list.
     /// \param pts : list of points.
-    /// \param u   : NORMALIZED time.
-    /// \return Reduced list of point (size of pts - 1).
+    /// \param u   : NORMALIZED time when to evaluate the curve.
+    /// \return reduced list of point (size of pts - 1).
     ///
     t_point_t deCasteljauReduction(const t_point_t& pts, const Numeric u) const{
         if(u < 0 || u > 1)
+        {
             throw std::out_of_range("In deCasteljau reduction : u is not in [0;1]");
+        }
         if(pts.size() == 1)
+        {
             return pts;
+        }
 
         t_point_t new_pts;
-        for(cit_point_t cit = pts.begin() ; cit != (pts.end() - 1) ; ++cit){
+        for(cit_point_t cit = pts.begin() ; cit != (pts.end() - 1) ; ++cit)
+        {
             new_pts.push_back((1-u) * (*cit) + u*(*(cit+1)));
         }
         return new_pts;
@@ -291,38 +295,49 @@ struct bezier_curve : public curve_abc<Time, Numeric, Dim, Safe, Point>
     /// \brief Split the bezier curve in 2 at time t.
     /// \param t : list of points.
     /// \param u : unNormalized time.
-    /// \return A pair containing the first element of both bezier curve obtained.
+    /// \return pair containing the first element of both bezier curve obtained.
     ///
     std::pair<bezier_curve_t,bezier_curve_t> split(const Numeric t){
-        if (t == T_)
+        if (t == T_max_)
+        {
             throw std::runtime_error("can't split curve, interval range is equal to original curve");
+        }
         t_point_t wps_first(size_),wps_second(size_);
-        const double u = t/T_;
-        wps_first[0] = pts_.front();
-        wps_second[degree_] = pts_.back();
+        const Numeric u = (t-T_min_)/(T_max_-T_min_);
+        wps_first[0] = control_points_.front();
+        wps_second[degree_] = control_points_.back();
         t_point_t casteljau_pts = waypoints();
         size_t id = 1;
-        while(casteljau_pts.size() > 1){
+        while(casteljau_pts.size() > 1)
+        {
             casteljau_pts = deCasteljauReduction(casteljau_pts,u);
             wps_first[id] = casteljau_pts.front();
             wps_second[degree_-id] = casteljau_pts.back();
             ++id;
         }
 
-        bezier_curve_t c_first(wps_first.begin(), wps_first.end(), t,mult_T_);
-        bezier_curve_t c_second(wps_second.begin(), wps_second.end(), T_-t,mult_T_);
+        bezier_curve_t c_first(wps_first.begin(), wps_first.end(),T_min_,t,mult_T_);
+        bezier_curve_t c_second(wps_second.begin(), wps_second.end(),t, T_max_,mult_T_);
         return std::make_pair(c_first,c_second);
     }
 
     bezier_curve_t extract(const Numeric t1, const Numeric t2){
-        if(t1 < 0. || t1 > T_ || t2 < 0. || t2 > T_)
+        if(t1 < T_min_ || t1 > T_max_ || t2 < T_min_ || t2 > T_max_)
+        {
             throw std::out_of_range("In Extract curve : times out of bounds");
-        if(t1 == 0. &&  t2 == T_)
-            return bezier_curve_t(waypoints().begin(), waypoints().end(), T_,mult_T_);
-        if(t1 == 0.)
+        }
+        if(t1 == T_min_ &&  t2 == T_max_)
+        {
+            return bezier_curve_t(waypoints().begin(), waypoints().end(), T_min_, T_max_, mult_T_);
+        }
+        if(t1 == T_min_)
+        {
             return split(t2).first;
-        if(t2 == T_)
+        }
+        if(t2 == T_max_)
+        {
             return split(t1).second;
+        }
 
         std::pair<bezier_curve_t,bezier_curve_t> c_split = this->split(t1);
         return c_split.second.split(t2-t1).first;
@@ -333,19 +348,23 @@ struct bezier_curve : public curve_abc<Time, Numeric, Dim, Safe, Point>
     t_point_t add_constraints(In PointsBegin, In PointsEnd, const curve_constraints_t& constraints)
     {
         t_point_t res;
+        num_t T = T_max_ - T_min_;
+        num_t T_square = T*T;
         point_t P0, P1, P2, P_n_2, P_n_1, PN;
         P0 = *PointsBegin; PN = *(PointsEnd-1);
-        P1    = P0+ constraints.init_vel / (num_t)degree_;
-        P_n_1 = PN -constraints.end_vel  / (num_t)degree_;
-        P2    = constraints.init_acc / (num_t)(degree_ * (degree_-1)) + 2* P1    - P0;
-        P_n_2 = constraints.end_acc  / (num_t)(degree_ * (degree_-1)) + 2* P_n_1 - PN;
+        P1    = P0+ constraints.init_vel * T / (num_t)degree_;
+        P_n_1 = PN- constraints.end_vel * T / (num_t)degree_;
+        P2    = constraints.init_acc * T_square / (num_t)(degree_ * (degree_-1)) + 2* P1    - P0;
+        P_n_2 = constraints.end_acc * T_square / (num_t)(degree_ * (degree_-1)) + 2* P_n_1 - PN;
 
         res.push_back(P0);
         res.push_back(P1);
         res.push_back(P2);
 
         for(In it = PointsBegin+1; it != PointsEnd-1; ++it)
+        {
             res.push_back(*it);
+        }
 
         res.push_back(P_n_2);
         res.push_back(P_n_1);
@@ -357,26 +376,31 @@ struct bezier_curve : public curve_abc<Time, Numeric, Dim, Safe, Point>
 
 /*Helpers*/
     public:
-    virtual time_t min() const{return 0.;}
-    virtual time_t max() const{return T_;}
+    /// \brief Get the minimum time for which the curve is defined
+    /// \return \f$t_{min}\f$, lower bound of time range.
+    virtual time_t min() const{return T_min_;}
+    /// \brief Get the maximum time for which the curve is defined.
+    /// \return \f$t_{max}\f$, upper bound of time range.
+    virtual time_t max() const{return T_max_;}
 /*Helpers*/
 
 	public:
-    /*const*/ time_t T_;
+    /// Starting time of cubic hermite spline : T_min_ is equal to first time of control points.
+    /*const*/ time_t T_min_;
+    /// Ending time of cubic hermite spline : T_max_ is equal to last time of control points.
+    /*const*/ time_t T_max_;
     /*const*/ time_t mult_T_;
     /*const*/ std::size_t size_;
     /*const*/ std::size_t degree_;
     /*const*/ std::vector<Bern<Numeric> > bernstein_;
-	
-    private:
-    t_point_t  pts_;
+    /*const*/ t_point_t  control_points_;
 
     public:
     static bezier_curve_t zero(const time_t T=1.)
     {
         std::vector<point_t> ts;
         ts.push_back(point_t::Zero(Dim));
-        return bezier_curve_t(ts.begin(), ts.end(),T);
+        return bezier_curve_t(ts.begin(), ts.end(),0.,T);
     }
 };
 } // namespace curve
diff --git a/include/curves/bezier_polynom_conversion.h b/include/curves/bezier_polynomial_conversion.h
similarity index 61%
rename from include/curves/bezier_polynom_conversion.h
rename to include/curves/bezier_polynomial_conversion.h
index 6829f98d0846be4359807dd6562b25f1b79bddf4..c45461dc98555c2f7e7ffca8f07fc97455da273a 100644
--- a/include/curves/bezier_polynom_conversion.h
+++ b/include/curves/bezier_polynomial_conversion.h
@@ -24,17 +24,17 @@
 namespace curves
 {
 /// \brief Provides methods for converting a curve from a bernstein representation
-/// to a polynom representation.
+/// to a polynomial representation.
 ///
 
-/// \brief Converts a Bezier curve to a polynom.
-/// \param bezier: the Bezier curve to convert.
-/// \return The equivalent polynom.
-template<typename Bezier, typename Polynom>
-Polynom from_bezier(const Bezier& curve)
+/// \brief Converts a Bezier curve to a polynomial.
+/// \param bezier   : the Bezier curve to convert.
+/// \return the equivalent polynomial.
+template<typename Bezier, typename Polynomial>
+Polynomial from_bezier(const Bezier& curve)
 {
-    typedef typename Polynom::t_point_t    t_point_t;
-    typedef typename Polynom::num_t    num_t;
+    typedef typename Polynomial::t_point_t    t_point_t;
+    typedef typename Polynomial::num_t    num_t;
     assert (curve.min() == 0.);
     assert (curve.max() == 1.);
     t_point_t coefficients;
@@ -47,14 +47,15 @@ Polynom from_bezier(const Bezier& curve)
         fact *= (num_t)i;
         coefficients.push_back(current(0.)/fact);
     }
-    return Polynom(coefficients,curve.min(),curve.max());
+    return Polynomial(coefficients,curve.min(),curve.max());
 }
 
-///\brief Converts a polynom to a Bezier curve
-///\param polynom: the polynom to be converted from
-///\return the equivalent Bezier curve
-/*template<typename Bezier, typename Polynom>
-Bezier from_polynom(const Polynom& polynom)
+/*
+/// \brief Converts a polynomial to a Bezier curve.
+/// \param polynomial : the polynomial to convert.
+/// \return the equivalent Bezier curve.
+template<typename Bezier, typename Polynomial>
+Bezier from_polynomial(const Polynomial& polynomial)
 {
     typedef Bezier::point_t 	point_t;
     typedef Bezier::time_t 	time_t;
@@ -63,7 +64,8 @@ Bezier from_polynom(const Polynom& polynom)
     typedef Bezier::t_point_t    t_point_t;
     typedef Bezier::cit_point_t    cit_point_t;
     typedef Bezier::bezier_curve_t   bezier_curve_t;
-}*/
+}
+*/
 } // namespace curves
 #endif //_BEZIER_POLY_CONVERSION
 
diff --git a/include/curves/cubic_hermite_spline.h b/include/curves/cubic_hermite_spline.h
new file mode 100644
index 0000000000000000000000000000000000000000..dd2118d5e1992d630626ce3e6fb9516e45518bff
--- /dev/null
+++ b/include/curves/cubic_hermite_spline.h
@@ -0,0 +1,371 @@
+/**
+* \file cubic_hermite_spline.h
+* \brief class allowing to create a cubic hermite spline of any dimension.
+* \author Justin Carpentier <jcarpent@laas.fr> modified by Jason Chemin <jchemin@laas.fr>
+* \date 05/2019
+*/
+
+#ifndef _CLASS_CUBICHERMITESPLINE
+#define _CLASS_CUBICHERMITESPLINE
+
+#include "curve_abc.h"
+#include "curve_constraint.h"
+
+#include "MathDefs.h"
+
+#include <vector>
+#include <stdexcept>
+
+#include <iostream>
+
+namespace curves
+{
+/// \class CubicHermiteSpline.
+/// \brief Represents a set of cubic hermite splines defining a continuous function \f$p(t)\f$.
+/// A hermite cubic spline is a minimal degree polynom interpolating a function in two 
+/// points \f$P_i\f$ and \f$P_{i+1}\f$ with its tangent \f$m_i\f$ and \f$m_{i+1}\f$.<br>
+/// A hermite cubic spline :
+/// - crosses each of the waypoint given in its initialization (\f$P_0\f$, \f$P_1\f$,...,\f$P_N\f$).
+/// - has its derivatives on \f$P_i\f$ and \f$P_{i+1}\f$ are \f$p'(t_{P_i}) = m_i\f$ and \f$p'(t_{P_{i+1}}) = m_{i+1}\f$.
+///
+template<typename Time= double, typename Numeric=Time, std::size_t Dim=3, bool Safe=false
+, typename Point= Eigen::Matrix<Numeric, Dim, 1>
+, typename Tangent= Eigen::Matrix<Numeric, Dim, 1>
+>
+struct cubic_hermite_spline : public curve_abc<Time, Numeric, Dim, Safe, Point>
+{
+    typedef std::pair<Point, Tangent> pair_point_tangent_t; 
+    typedef std::vector< pair_point_tangent_t ,Eigen::aligned_allocator<Point> > t_pair_point_tangent_t;
+    typedef std::vector<Time> vector_time_t;
+    typedef Numeric num_t;
+
+    /*Attributes*/
+    public:
+    /// Vector of pair < Point, Tangent >.
+    t_pair_point_tangent_t control_points_;
+    /// Vector of Time corresponding to time of each N control points : time at \f$P_0, P_1, P_2, ..., P_N\f$.
+    /// Exemple : \f$( 0., 0.5, 0.9, ..., 4.5 )\f$ with values corresponding to times for \f$P_0, P_1, P_2, ..., P_N\f$ respectively.
+    vector_time_t time_control_points_;
+
+    /// Vector of Time corresponding to time duration of each subspline.<br>
+    /// For N control points with time \f$T_{P_0}, T_{P_1}, T_{P_2}, ..., T_{P_N}\f$ respectively,
+    /// duration of each subspline is : ( T_{P_1}-T_{P_0}, T_{P_2}-T_{P_1}, ..., T_{P_N}-T_{P_{N-1} )<br>
+    /// It contains \f$N-1\f$ durations. 
+    vector_time_t duration_splines_;
+    /// Starting time of cubic hermite spline : T_min_ is equal to first time of control points.
+    /*const*/ Time T_min_;
+    /// Ending time of cubic hermite spline : T_max_ is equal to last time of control points.
+    /*const*/ Time T_max_;
+    /// Number of control points (pairs).
+    std::size_t size_;
+    /// Degree (Cubic so degree 3)
+    static const std::size_t degree_ = 3;
+    /*Attributes*/
+    
+    public:
+	/// \brief Constructor.
+	/// \param wayPointsBegin : an iterator pointing to the first element of a pair(position, derivative) container.
+	/// \param wayPointsEns   : an iterator pointing to the last  element of a pair(position, derivative) container.
+    /// \param time_control_points : vector containing time for each waypoint.
+    ///
+	template<typename In>
+	cubic_hermite_spline(In PairsBegin, In PairsEnd, const vector_time_t & time_control_points)
+	{
+		// Check size of pairs container.
+        std::size_t const size(std::distance(PairsBegin, PairsEnd));
+        size_ = size;
+        if(Safe && size < 1)
+        {
+            throw std::length_error("can not create cubic_hermite_spline, number of pairs is inferior to 2.");
+        }
+        // Push all pairs in controlPoints
+        In it(PairsBegin);
+        for(; it != PairsEnd; ++it)
+        {
+            control_points_.push_back(*it);
+        }
+        setTime(time_control_points);
+	}
+
+	/// \brief Destructor.
+    virtual ~cubic_hermite_spline(){}
+
+    /*Operations*/
+	public:
+    ///  \brief Evaluation of the cubic hermite spline at time t.
+    ///  \param t : time when to evaluate the spline.
+    ///  \return \f$p(t)\f$ point corresponding on spline at time t.
+    ///
+	virtual Point operator()(const Time t) const
+    {
+        if(Safe &! (T_min_ <= t && t <= T_max_))
+        {
+			throw std::out_of_range("can't evaluate cubic hermite spline, out of range");
+        }
+        if (size_ == 1)
+        {
+			return control_points_.front().first;
+        }
+        else
+        {
+			return evalCubicHermiteSpline(t, 0);
+        }
+    }
+
+    ///  \brief Evaluate the derivative of order N of spline at time t.
+    ///  \param t : time when to evaluate the spline.
+    ///  \param order : order of derivative.
+    ///  \return \f$\frac{d^Np(t)}{dt^N}\f$ point corresponding on derivative spline of order N at time t.
+    ///
+    virtual Point derivate(const Time t, const std::size_t order) const
+    {   
+        return evalCubicHermiteSpline(t, order);
+    }
+
+    /// \brief Set time of each control point of cubic hermite spline.
+    /// Set duration of each spline, Exemple : \f$( 0., 0.5, 0.9, ..., 4.5 )\f$ with 
+    /// values corresponding to times for \f$P_0, P_1, P_2, ..., P_N\f$ respectively.<br>
+    /// \param time_control_points : Vector containing time for each control point.
+    ///
+    void setTime(const vector_time_t & time_control_points)
+    {
+        time_control_points_ = time_control_points;
+        T_min_ = time_control_points_.front();
+        T_max_ = time_control_points_.back();
+        if (time_control_points.size() != size())
+        {
+            throw std::length_error("size of time control points should be equal to number of control points");
+        }
+        computeDurationSplines();
+        if (!checkDurationSplines())
+        {
+            throw std::logic_error("time_splines not monotonous, all spline duration should be superior to 0");
+        }
+    }
+
+    /// \brief Get vector of pair (positition, derivative) corresponding to control points.
+    /// \return vector containing control points.
+    ///
+    t_pair_point_tangent_t getControlPoints()
+    {
+        return control_points_;
+    }
+
+    /// \brief Get vector of Time corresponding to Time for each control point.
+    /// \return vector containing time of each control point.
+    ///
+    vector_time_t getTime()
+    {
+        return time_control_points_;
+    }
+
+    /// \brief Get number of control points contained in the trajectory.
+    /// \return number of control points.
+    ///
+    std::size_t size() const { return size_; }
+
+    /// \brief Get number of intervals (subsplines) contained in the trajectory.
+    /// \return number of intervals (subsplines).
+    ///
+    std::size_t numIntervals() const { return size()-1; }
+
+
+    /// \brief Evaluate value of cubic hermite spline or its derivate at specified order at time \f$t\f$.
+    /// A cubic hermite spline on unit interval \f$[0,1]\f$ and given two control points defined by 
+    /// their position and derivative \f$\{p_0,m_0\}\f$ and \f$\{p_1,m_1\}\f$, is defined by the polynom : <br>
+    ///     \f$p(t)=h_{00}(t)P_0 + h_{10}(t)m_0 + h_{01}(t)p_1 + h_{11}(t)m_1\f$<br>
+    /// To extend this formula to a cubic hermite spline on any arbitrary interval, 
+    /// we define \f$\alpha=(t-t_0)/(t_1-t_0) \in [0, 1]\f$ where \f$t \in [t_0, t_1]\f$.<br>
+    /// Polynom \f$p(t) \in [t_0, t_1]\f$ becomes \f$p(\alpha) \in [0, 1]\f$
+    /// and \f$p(\alpha) = p((t-t_0)/(t_1-t_0))\f$.
+    /// \param t : time when to evaluate the curve.
+    /// \param order_derivative : Order of derivate of cubic hermite spline (set value to 0 if you do not want derivate)
+    /// \return point corresponding \f$p(t)\f$ on spline at time t or its derivate order N \f$\frac{d^Np(t)}{dt^N}\f$.
+    ///
+    Point evalCubicHermiteSpline(const Numeric t, std::size_t order_derivative) const
+    {
+        const std::size_t id = findInterval(t);
+        // ID is on the last control point
+        if(id == size_-1)
+        {
+            if (order_derivative==0)
+            {
+                return control_points_.back().first;
+            }
+            else if (order_derivative==1)
+            {
+                return control_points_.back().second;
+            }
+            else
+            {
+                return control_points_.back().first*0.; // To modify, create a new Tangent ininitialized with 0.
+            }
+        }
+        const pair_point_tangent_t Pair0 = control_points_.at(id);
+        const pair_point_tangent_t Pair1 = control_points_.at(id+1);
+        const Time & t0 = time_control_points_[id];
+        const Time & t1 = time_control_points_[id+1]; 
+        // Polynom for a cubic hermite spline defined on [0., 1.] is : 
+        //      p(t) = h00(t)*p0 + h10(t)*m0 + h01(t)*p1 + h11(t)*m1 with t in [0., 1.]
+        //
+        // For a cubic hermite spline defined on [t0, t1], we define alpha=(t-t0)/(t1-t0) in [0., 1.].
+        // Polynom p(t) defined on [t0, t1] becomes p(alpha) defined on [0., 1.]
+        //      p(alpha) = p((t-t0)/(t1-t0))
+        //
+        const Time dt = (t1-t0);
+        const Time alpha = (t - t0)/dt;
+        assert(0. <= alpha <= 1. && "alpha must be in [0,1]");
+        Numeric h00, h10, h01, h11;
+        evalCoeffs(alpha,h00,h10,h01,h11,order_derivative);
+        //std::cout << "for val t="<<t<<" alpha="<<alpha<<" coef : h00="<<h00<<" h10="<<h10<<" h01="<<h01<<" h11="<<h11<<std::endl;
+        Point p_ = (h00 * Pair0.first + h10 * dt * Pair0.second + h01 * Pair1.first + h11 * dt * Pair1.second);
+        // if derivative, divide by dt^order_derivative
+        for (std::size_t i=0; i<order_derivative; i++)
+        {
+            p_ /= dt;
+        }
+        return p_;
+    }
+
+    /// \brief Evaluate coefficient for polynom of cubic hermite spline.
+    /// Coefficients of polynom :<br>
+    ///  - \f$h00(t)=2t^3-3t^2+1\f$;
+    ///  - \f$h10(t)=t^3-2t^2+t\f$;
+    ///  - \f$h01(t)=-2t^3+3t^2\f$;
+    ///  - \f$h11(t)=t^3-t^2\f$.<br>
+    /// From it, we can calculate their derivate order N : 
+    /// \f$\frac{d^Nh00(t)}{dt^N}\f$, \f$\frac{d^Nh10(t)}{dt^N}\f$,\f$\frac{d^Nh01(t)}{dt^N}\f$, \f$\frac{d^Nh11(t)}{dt^N}\f$.
+    /// \param t : time to calculate coefficients.
+    /// \param h00 : variable to store value of coefficient.
+    /// \param h10 : variable to store value of coefficient.
+    /// \param h01 : variable to store value of coefficient.
+    /// \param h11 : variable to store value of coefficient.
+    /// \param order_derivative : order of derivative.
+    ///
+    static void evalCoeffs(const Numeric t, Numeric & h00, Numeric & h10, Numeric & h01, Numeric & h11, std::size_t order_derivative)
+    {
+        Numeric t_square = t*t;
+        Numeric t_cube = t_square*t;
+        if (order_derivative==0)
+        {
+            h00 =  2*t_cube     -3*t_square     +1.;
+            h10 =  t_cube       -2*t_square     +t;
+            h01 = -2*t_cube     +3*t_square;
+            h11 =  t_cube       -t_square;
+        }
+        else if (order_derivative==1)
+        {
+            h00 =  6*t_square   -6*t;
+            h10 =  3*t_square   -4*t    +1.;
+            h01 = -6*t_square   +6*t;
+            h11 =  3*t_square   -2*t;
+        }
+        else if (order_derivative==2)
+        {
+            h00 =  12*t     -6.;
+            h10 =  6*t      -4.;  
+            h01 = -12*t     +6.;
+            h11 =  6*t      -2.;
+        }
+        else if (order_derivative==3)
+        {
+            h00 =  12.;
+            h10 =  6.;  
+            h01 = -12.;
+            h11 =  6.;
+        }
+        else 
+        {
+            h00 =  0.;
+            h10 =  0.;  
+            h01 =  0.;
+            h11 =  0.;
+        }
+    }
+
+    private:
+    /// \brief Get index of the interval (subspline) corresponding to time t for the interpolation.
+    /// \param t : time where to look for interval.
+    /// \return Index of interval for time t.
+    ///
+    std::size_t findInterval(const Numeric t) const
+    {
+        // time before first control point time.
+        if(t < time_control_points_[0])
+        {
+            return 0;
+        }
+        // time is after last control point time
+        if(t > time_control_points_[size_-1])
+        {
+            return size_-1;
+        }
+
+        std::size_t left_id = 0;
+        std::size_t right_id = size_-1;
+        while(left_id <= right_id)
+        {
+            const std::size_t middle_id = left_id + (right_id - left_id)/2;
+            if(time_control_points_.at(middle_id) < t)
+            {
+                left_id = middle_id+1;
+            }
+            else if(time_control_points_.at(middle_id) > t)
+            {
+                right_id = middle_id-1;
+            }
+            else
+            {
+                return middle_id;
+            }
+        }
+        return left_id-1;
+    }
+
+    /// \brief compute duration of each spline.
+    /// For N control points with time \f$T_{P_0}, T_{P_1}, T_{P_2}, ..., T_{P_N}\f$ respectively,
+    /// Duration of each subspline is : ( T_{P_1}-T_{P_0}, T_{P_2}-T_{P_1}, ..., T_{P_N}-T_{P_{N-1} ).
+    ///
+    void computeDurationSplines() {
+        duration_splines_.clear();
+        Time actual_time;
+        Time prev_time = *(time_control_points_.begin());
+        std::size_t i = 0;
+        for (i=0; i<size()-1; i++)
+        {
+            actual_time = time_control_points_.at(i+1);
+            duration_splines_.push_back(actual_time-prev_time);
+            prev_time = actual_time;
+        }
+    }
+
+    /// \brief Check if duration of each subspline is strictly positive.
+    /// \return true if all duration of strictly positive, false otherwise.
+    ///
+    bool checkDurationSplines() const
+    {
+        std::size_t i = 0;
+        bool is_positive = true;
+        while (is_positive && i<duration_splines_.size())
+        {
+            is_positive = (duration_splines_.at(i)>0.);
+            i++;
+        }
+        return is_positive;
+    }
+	/*Operations*/	
+
+    /*Helpers*/
+	public:
+    /// \brief Get the minimum time for which the curve is defined
+    /// \return \f$t_{min}\f$, lower bound of time range.
+    Time virtual min() const{return time_control_points_.front();}
+    /// \brief Get the maximum time for which the curve is defined.
+    /// \return \f$t_{max}\f$, upper bound of time range.
+    Time virtual max() const{return time_control_points_.back();}
+	/*Helpers*/
+
+};
+
+} // namespace curve
+#endif //_CLASS_CUBICHERMITESPLINE
\ No newline at end of file
diff --git a/include/curves/cubic_spline.h b/include/curves/cubic_spline.h
index 4e2efed0e94f9240d8d5e86ef86be7d3957c074a..20def8256486cfd0f4cb893c95e2b0934c64896c 100644
--- a/include/curves/cubic_spline.h
+++ b/include/curves/cubic_spline.h
@@ -16,15 +16,16 @@
 
 #include "MathDefs.h"
 
-#include "polynom.h"
+#include "polynomial.h"
 
 #include <stdexcept>
 
 namespace curves
 {
 /// \brief Creates coefficient vector of a cubic spline defined on the interval
-/// \f$[t_{min}, t_{max}]\f$. It follows the equation : 
-/// \f$ x(t) = a + b(t - t_{min}) + c(t - t_{min})^2 + d(t - t_{min})^3 \f$ where \f$ t \in [t_{min}, t_{max}] \f$.
+/// \f$[t_{min}, t_{max}]\f$. It follows the equation : <br>
+/// \f$ x(t) = a + b(t - t_{min}) + c(t - t_{min})^2 + d(t - t_{min})^3 \f$ where \f$ t \in [t_{min}, t_{max}] \f$
+/// with a, b, c and d the control points.
 ///
 template<typename Point, typename T_Point>
 T_Point make_cubic_vector(Point const& a, Point const& b, Point const& c, Point const &d)
@@ -35,11 +36,11 @@ T_Point make_cubic_vector(Point const& a, Point const& b, Point const& c, Point
 }
 
 template<typename Time, typename Numeric, std::size_t Dim, bool Safe, typename Point, typename T_Point>
-polynom<Time,Numeric,Dim,Safe,Point,T_Point> create_cubic(Point const& a, Point const& b, Point const& c, Point const &d,
+polynomial<Time,Numeric,Dim,Safe,Point,T_Point> create_cubic(Point const& a, Point const& b, Point const& c, Point const &d,
                const Time t_min, const Time t_max)
 {
     T_Point coeffs = make_cubic_vector<Point, T_Point>(a,b,c,d);
-    return polynom<Time,Numeric,Dim,Safe,Point,T_Point>(coeffs.begin(),coeffs.end(), t_min, t_max);
+    return polynomial<Time,Numeric,Dim,Safe,Point,T_Point>(coeffs.begin(),coeffs.end(), t_min, t_max);
 }
 } // namespace curves
 #endif //_STRUCT_CUBICSPLINE
diff --git a/include/curves/curve_abc.h b/include/curves/curve_abc.h
index a943eb8911214e942ecebaef070dabb54d653932..d6afacb9b3c342e037434eff4a07ec94779e4671 100644
--- a/include/curves/curve_abc.h
+++ b/include/curves/curve_abc.h
@@ -18,9 +18,9 @@
 
 namespace curves
 {
-/// \struct curve_abc
-/// \brief Represents a curve of dimension Dim
-/// is Safe is false, no verification is made on the evaluation of the curve.
+/// \struct curve_abc.
+/// \brief Represents a curve of dimension Dim.
+/// If value of parameter Safe is false, no verification is made on the evaluation of the curve.
 template<typename Time= double, typename Numeric=Time, std::size_t Dim=3, bool Safe=false
 , typename Point= Eigen::Matrix<Numeric, Dim, 1> >
 struct  curve_abc : std::unary_function<Time, Point>
@@ -30,33 +30,35 @@ struct  curve_abc : std::unary_function<Time, Point>
 
 /* Constructors - destructors */
 	public:
-	///\brief Constructor
+	/// \brief Constructor.
     curve_abc(){}
 
-	///\brief Destructor
+	/// \brief Destructor.
     virtual ~curve_abc(){}
 /* Constructors - destructors */
 
 /*Operations*/
 	public:
 	///  \brief Evaluation of the cubic spline at time t.
-	///  \param t : the time when to evaluate the spine
-	///  \param return : the value x(t)
+	///  \param t : time when to evaluate the spine
+	///  \return \f$x(t)\f$, point corresponding on curve at time t.
     virtual point_t operator()(const time_t t) const = 0;
 
 
-    ///  \brief Evaluation of the derivative spline at time t.
-    ///  \param t : the time when to evaluate the spline
-    ///  \param order : order of the derivative
-    ///  \param return : the value x(t)
+    /// \brief Evaluate the derivative of order N of curve at time t.
+    /// \param t : time when to evaluate the spline.
+    /// \param order : order of derivative.
+    /// \return \f$\frac{d^Nx(t)}{dt^N}\f$, point corresponding on derivative curve of order N at time t.
     virtual point_t derivate(const time_t t, const std::size_t order) const = 0;
 /*Operations*/
 
 /*Helpers*/
 	public:
-	///  \brief Returns the minimum time for wich curve is defined
+	/// \brief Get the minimum time for which the curve is defined.
+	/// \return \f$t_{min}\f$, lower bound of time range.
 	virtual time_t min() const = 0;
-	///  \brief Returns the maximum time for wich curve is defined
+	/// \brief Get the maximum time for which the curve is defined.
+	/// \return \f$t_{max}\f$, upper bound of time range.
 	virtual time_t max() const = 0;
 
     std::pair<time_t, time_t> timeRange() {return std::make_pair(min(), max());}
diff --git a/include/curves/curve_constraint.h b/include/curves/curve_constraint.h
index d3710c9fb40e396bce15fcc55989d7f2bb074623..eb88d1cd7026a9ea65aead04ddc442ecd932a911 100644
--- a/include/curves/curve_constraint.h
+++ b/include/curves/curve_constraint.h
@@ -26,11 +26,12 @@ struct curve_constraints
     curve_constraints():
         init_vel(point_t::Zero()),init_acc(init_vel),end_vel(init_vel),end_acc(init_vel){}
 
-   ~curve_constraints(){}
-    point_t init_vel;
-    point_t init_acc;
-    point_t end_vel;
-    point_t end_acc;
+	~curve_constraints(){}
+
+	point_t init_vel;
+	point_t init_acc;
+	point_t end_vel;
+	point_t end_acc;
 };
 } // namespace curves
 #endif //_CLASS_CUBICZEROVELACC
diff --git a/include/curves/curve_conversion.h b/include/curves/curve_conversion.h
new file mode 100644
index 0000000000000000000000000000000000000000..98bf1ca8b3b867851138c05727d63ed32e8d3705
--- /dev/null
+++ b/include/curves/curve_conversion.h
@@ -0,0 +1,117 @@
+#ifndef _CLASS_CURVE_CONVERSION
+#define _CLASS_CURVE_CONVERSION
+
+#include "curve_abc.h"
+#include "bernstein.h"
+#include "curve_constraint.h"
+
+#include "MathDefs.h"
+
+#include <vector>
+#include <stdexcept>
+
+#include <iostream>
+
+namespace curves
+{
+
+/// \brief Converts a cubic hermite spline or a bezier curve to a polynomial.
+/// \param curve   : the bezier curve/cubic hermite spline defined between [Tmin,Tmax] to convert.
+/// \return the equivalent polynomial.
+template<typename Polynomial, typename curveTypeToConvert>
+Polynomial polynomial_from_curve(const curveTypeToConvert& curve)
+{
+    typedef typename Polynomial::t_point_t    t_point_t;
+    typedef typename Polynomial::num_t    num_t;
+    t_point_t coefficients;
+    curveTypeToConvert current (curve);
+    coefficients.push_back(curve(curve.min()));
+    num_t T = curve.max()-curve.min();
+    num_t T_div = 1.0;
+    num_t fact = 1;
+    for(std::size_t i = 1; i<= curve.degree_; ++i)
+    {
+        fact *= (num_t)i;
+        coefficients.push_back(current.derivate(current.min(),i)/fact);
+    }
+    return Polynomial(coefficients,curve.min(),curve.max());
+}
+
+
+/// \brief Converts a cubic hermite spline or polynomial to a cubic bezier curve.
+/// \param curve   : the polynomial of order 3 or less/cubic hermite spline defined between [Tmin,Tmax] to convert.
+/// \return the equivalent cubic bezier curve.
+template<typename Bezier, typename curveTypeToConvert>
+Bezier bezier_from_curve(const curveTypeToConvert& curve)
+{
+    typedef typename Bezier::point_t point_t;
+    typedef typename Bezier::t_point_t t_point_t;
+    typedef typename Bezier::num_t    num_t;
+    curveTypeToConvert current (curve);
+    
+    num_t T_min = current.min();
+    num_t T_max = current.max();
+    num_t T = T_max-T_min;
+
+    // Positions and derivatives
+    point_t p0 = current(T_min);
+    point_t p1 = current(T_max);
+    point_t m0 = current.derivate(T_min,1);
+    point_t m1 = current.derivate(T_max,1);
+
+    // Convert to bezier control points
+    // for t in [Tmin,Tmax] and T=Tmax-Tmin : x'(0)=3(b_p1-b_p0)/T and x'(1)=3(b_p3-b_p2)/T
+    // so : m0=3(b_p1-b_p0)/T and m1=3(b_p3-b_p2)/T
+    // <=> b_p1=T(m0/3)+b_p0 and b_p2=-T(m1/3)+b_p3
+    point_t b_p0 = p0;
+    point_t b_p3 = p1;
+    point_t b_p1 = T*m0/3+b_p0;
+    point_t b_p2 = -T*m1/3+b_p3;
+
+
+    t_point_t control_points;
+    control_points.push_back(b_p0);
+    control_points.push_back(b_p1);
+    control_points.push_back(b_p2);
+    control_points.push_back(b_p3);
+
+    return Bezier(control_points.begin(), control_points.end(), current.min(), current.max());
+}
+
+/// \brief Converts a polynomial of order 3 or less/cubic bezier curve to a cubic hermite spline.
+/// \param curve   : the polynomial of order 3 or less/cubic bezier curve defined between [Tmin,Tmax] to convert.
+/// \return the equivalent cubic hermite spline.
+template<typename Hermite, typename curveTypeToConvert>
+Hermite hermite_from_curve(const curveTypeToConvert& curve)
+{
+    typedef typename Hermite::pair_point_tangent_t pair_point_tangent_t;
+    typedef typename Hermite::t_pair_point_tangent_t t_pair_point_tangent_t;
+    typedef typename Hermite::point_t point_t;
+    typedef typename Hermite::num_t    num_t;
+    curveTypeToConvert current (curve);
+
+    num_t T_min = current.min();
+    num_t T_max = current.max();
+    num_t T = T_max-T_min;
+
+    // Positions and derivatives
+    point_t p0 = current(T_min);
+    point_t p1 = current(T_max);
+    point_t m0 = current.derivate(T_min,1);
+    point_t m1 = current.derivate(T_max,1);
+
+    pair_point_tangent_t pair0(p0,m0);
+    pair_point_tangent_t pair1(p1,m1);
+    t_pair_point_tangent_t control_points;
+    control_points.push_back(pair0);
+    control_points.push_back(pair1);
+
+    std::vector< double > time_control_points;
+    time_control_points.push_back(T_min);
+    time_control_points.push_back(T_max);
+
+    return Hermite(control_points.begin(), control_points.end(), time_control_points);
+}
+
+} // namespace curve
+#endif //_CLASS_CURVE_CONVERSION
\ No newline at end of file
diff --git a/include/curves/exact_cubic.h b/include/curves/exact_cubic.h
index 693109c02c72b580fb0fdbcf7dc3f47e9620632b..cbbcbf52ed934813c02792c4bcf87ecce7322e40 100644
--- a/include/curves/exact_cubic.h
+++ b/include/curves/exact_cubic.h
@@ -23,6 +23,7 @@
 #include "curve_abc.h"
 #include "cubic_spline.h"
 #include "quintic_spline.h"
+#include "curve_constraint.h"
 
 #include "MathDefs.h"
 
@@ -37,12 +38,13 @@ namespace curves
 ///
 template<typename Time= double, typename Numeric=Time, std::size_t Dim=3, bool Safe=false
 , typename Point= Eigen::Matrix<Numeric, Dim, 1>, typename T_Point =std::vector<Point,Eigen::aligned_allocator<Point> >
-, typename SplineBase=polynom<Time, Numeric, Dim, Safe, Point, T_Point> >
+, typename SplineBase=polynomial<Time, Numeric, Dim, Safe, Point, T_Point> >
 struct exact_cubic : public curve_abc<Time, Numeric, Dim, Safe, Point>
 {
 	typedef Point 	point_t;
     typedef T_Point t_point_t;
     typedef Eigen::Matrix<Numeric, Eigen::Dynamic, Eigen::Dynamic> MatrixX;
+    typedef Eigen::Matrix<Numeric, 3, 3> Matrix3;
 	typedef Time 	time_t;
 	typedef Numeric	num_t;
     typedef SplineBase spline_t;
@@ -50,6 +52,7 @@ struct exact_cubic : public curve_abc<Time, Numeric, Dim, Safe, Point>
     typedef typename t_spline_t::iterator it_spline_t;
     typedef typename t_spline_t::const_iterator cit_spline_t;
     typedef curve_abc<Time, Numeric, Dim, Safe, Point> curve_abc_t;
+    typedef curve_constraints<point_t> spline_constraints;
 
 	/* Constructors - destructors */
 	public:
@@ -61,6 +64,14 @@ struct exact_cubic : public curve_abc<Time, Numeric, Dim, Safe, Point>
 	exact_cubic(In wayPointsBegin, In wayPointsEnd)
         : curve_abc_t(), subSplines_(computeWayPoints<In>(wayPointsBegin, wayPointsEnd)) {}
 
+    /// \brief Constructor.
+    /// \param wayPointsBegin : an iterator pointing to the first element of a waypoint container.
+    /// \param wayPointsEns   : an iterator pointing to the last element of a waypoint container.
+    /// \param constraints    : constraints on the init and end velocity / accelerations of the spline.
+    ///
+    template<typename In>
+    exact_cubic(In wayPointsBegin, In wayPointsEnd, const spline_constraints& constraints)
+        : curve_abc_t(), subSplines_(computeWayPoints<In>(wayPointsBegin, wayPointsEnd, constraints)) {}
 
     /// \brief Constructor.
     /// \param subSplines: vector of subsplines.
@@ -74,14 +85,30 @@ struct exact_cubic : public curve_abc<Time, Numeric, Dim, Safe, Point>
 	/// \brief Destructor.
     virtual ~exact_cubic(){}
 
+    std::size_t getNumberSplines()
+    {
+        return subSplines_.size();
+    }
+
+    spline_t getSplineAt(std::size_t index)
+    {
+        return subSplines_.at(index);
+    }
+
     private:
+    /// \brief Compute polynom of exact cubic spline from waypoints.
+    /// Compute the coefficients of polynom as in paper : "Task-Space Trajectories via Cubic Spline Optimization".<br>
+    /// \f$x_i(t)=a_i+b_i(t-t_i)+c_i(t-t_i)^2\f$<br>
+    /// with \f$a=x\f$, \f$H_1b=H_2x\f$, \f$c=H_3x+H_4b\f$, \f$d=H_5x+H_6b\f$.<br>
+    /// The matrices \f$H\f$ are defined as in the paper in Appendix A.
+    ///
     template<typename In>
     t_spline_t computeWayPoints(In wayPointsBegin, In wayPointsEnd) const
     {
         std::size_t const size(std::distance(wayPointsBegin, wayPointsEnd));
         if(Safe && size < 1)
         {
-            throw; // TODO
+            throw std::length_error("size of waypoints must be superior to 0") ; // TODO
         }
         t_spline_t subSplines; subSplines.reserve(size);
 
@@ -103,6 +130,7 @@ struct exact_cubic : public curve_abc<Time, Numeric, Dim, Safe, Point>
         In it(wayPointsBegin), next(wayPointsBegin);
         ++next;
 
+        // Fill the matrices H as specified in the paper.
         for(std::size_t i(0); next != wayPointsEnd; ++next, ++it, ++i)
         {
             num_t const dTi((*next).first  - (*it).first);
@@ -131,25 +159,94 @@ struct exact_cubic : public curve_abc<Time, Numeric, Dim, Safe, Point>
                 h2(i+1, i+2) =  6 / dTi_1sqr;
             }
             x.row(i)= (*it).second.transpose();
-            }
+        }
         // adding last x
         x.row(size-1)= (*it).second.transpose();
-        a= x;
+        // Compute coefficients of polynom.
+        a = x;
         PseudoInverse(h1);
         b = h1 * h2 * x; //h1 * b = h2 * x => b = (h1)^-1 * h2 * x
         c = h3 * x + h4 * b;
         d = h5 * x + h6 * b;
+        // create splines along waypoints.
         it= wayPointsBegin, next=wayPointsBegin; ++ next;
         for(int i=0; next != wayPointsEnd; ++i, ++it, ++next)
         {
             subSplines.push_back(
                 create_cubic<Time,Numeric,Dim,Safe,Point,T_Point>(a.row(i), b.row(i), c.row(i), d.row(i),(*it).first, (*next).first));
         }
+        /*
         subSplines.push_back(
                 create_cubic<Time,Numeric,Dim,Safe,Point,T_Point>(a.row(size-1), b.row(size-1), c.row(size-1), d.row(size-1), (*it).first, (*it).first));
+        */
         return subSplines;
     }
 
+    template<typename In>
+    t_spline_t computeWayPoints(In wayPointsBegin, In wayPointsEnd, const spline_constraints& constraints) const
+    {
+        std::size_t const size(std::distance(wayPointsBegin, wayPointsEnd));
+        if(Safe && size < 1) 
+        {
+            throw std::length_error("number of waypoints should be superior to one"); // TODO
+        }
+        t_spline_t subSplines; 
+        subSplines.reserve(size-1);
+        spline_constraints cons = constraints;
+        In it(wayPointsBegin), next(wayPointsBegin), end(wayPointsEnd-1);
+        ++next;
+        for(std::size_t i(0); next != end; ++next, ++it, ++i)
+        {
+            compute_one_spline<In>(it, next, cons, subSplines);
+        }
+        compute_end_spline<In>(it, next,cons, subSplines);
+        return subSplines;
+    }
+
+    template<typename In>
+    void compute_one_spline(In wayPointsBegin, In wayPointsNext, spline_constraints& constraints, t_spline_t& subSplines) const
+    {
+        const point_t& a0 = wayPointsBegin->second, a1 = wayPointsNext->second;
+        const point_t& b0 = constraints.init_vel , c0 = constraints.init_acc / 2.;
+        const num_t& init_t = wayPointsBegin->first, end_t = wayPointsNext->first;
+        const num_t dt = end_t - init_t, dt_2 = dt * dt, dt_3 = dt_2 * dt;
+        const point_t d0 = (a1 - a0 - b0 * dt - c0 * dt_2) / dt_3;
+        subSplines.push_back(create_cubic<Time,Numeric,Dim,Safe,Point,T_Point>
+                             (a0,b0,c0,d0,init_t, end_t));
+        constraints.init_vel = subSplines.back().derivate(end_t, 1);
+        constraints.init_acc = subSplines.back().derivate(end_t, 2);
+    }
+
+    template<typename In>
+    void compute_end_spline(In wayPointsBegin, In wayPointsNext, spline_constraints& constraints, t_spline_t& subSplines) const
+    {
+        const point_t& a0 = wayPointsBegin->second, a1 = wayPointsNext->second;
+        const point_t& b0 = constraints.init_vel, b1 = constraints.end_vel,
+                       c0 = constraints.init_acc / 2., c1 = constraints.end_acc;
+        const num_t& init_t = wayPointsBegin->first, end_t = wayPointsNext->first;
+        const num_t dt = end_t - init_t, dt_2 = dt * dt, dt_3 = dt_2 * dt, dt_4 = dt_3 * dt, dt_5 = dt_4 * dt;
+        //solving a system of four linear eq with 4 unknows: d0, e0
+        const point_t alpha_0 = a1 - a0 - b0 *dt -    c0 * dt_2;
+        const point_t alpha_1 = b1 -      b0     - 2 *c0 * dt;
+        const point_t alpha_2 = c1 -               2 *c0;
+        const num_t x_d_0 = dt_3, x_d_1 = 3*dt_2, x_d_2 = 6*dt;
+        const num_t x_e_0 = dt_4, x_e_1 = 4*dt_3, x_e_2 = 12*dt_2;
+        const num_t x_f_0 = dt_5, x_f_1 = 5*dt_4, x_f_2 = 20*dt_3;
+
+        point_t d, e, f;
+        MatrixX rhs = MatrixX::Zero(3,Dim);
+        rhs.row(0) = alpha_0; rhs.row(1) = alpha_1; rhs.row(2) = alpha_2;
+        Matrix3 eq  = Matrix3::Zero(3,3);
+        eq(0,0) = x_d_0; eq(0,1) = x_e_0; eq(0,2) = x_f_0;
+        eq(1,0) = x_d_1; eq(1,1) = x_e_1; eq(1,2) = x_f_1;
+        eq(2,0) = x_d_2; eq(2,1) = x_e_2; eq(2,2) = x_f_2;
+        rhs = eq.inverse().eval() * rhs;
+        d = rhs.row(0); e = rhs.row(1); f = rhs.row(2);
+
+        subSplines.push_back(create_quintic<Time,Numeric,Dim,Safe,Point,T_Point>
+                             (a0,b0,c0,d,e,f, init_t, end_t));
+    }
+
     private:
     //exact_cubic& operator=(const exact_cubic&);
 	/* Constructors - destructors */
@@ -158,32 +255,42 @@ struct exact_cubic : public curve_abc<Time, Numeric, Dim, Safe, Point>
 	public:
 	///  \brief Evaluation of the cubic spline at time t.
     ///  \param t : time when to evaluate the spline
-	///  \return Point corresponding on spline at time t.
+	///  \return \f$x(t)\f$ point corresponding on spline at time t.
     ///
     virtual point_t operator()(const time_t t) const
     {
-        if(Safe && (t < subSplines_.front().min() || t > subSplines_.back().max())){throw std::out_of_range("TODO");}
+        if(Safe && (t < subSplines_.front().min() || t > subSplines_.back().max()))
+        {
+            throw std::out_of_range("time t to evaluate should be in range [Tmin, Tmax] of the spline");
+        }
         for(cit_spline_t it = subSplines_.begin(); it != subSplines_.end(); ++ it)
         {
             if( (t >= (it->min()) && t <= (it->max())) || it+1 == subSplines_.end())
+            {
                 return it->operator()(t);
+            }
         }
         // this should not happen
         throw std::runtime_error("Exact cubic evaluation failed; t is outside bounds");
     }
 
-    ///  \brief Evaluation of the derivative spline at time t.
+    ///  \brief Evaluate the derivative of order N of spline at time t.
     ///  \param t : time when to evaluate the spline.
-    ///  \param order : order of the derivative.
-    ///  \return Point corresponding on derivative spline at time t.
+    ///  \param order : order of derivative.
+    ///  \return \f$\frac{d^Nx(t)}{dt^N}\f$ point corresponding on derivative spline of order N at time t.
     ///
     virtual point_t derivate(const time_t t, const std::size_t order) const
     {
-        if(Safe && (t < subSplines_.front().min() || t > subSplines_.back().max())){throw std::out_of_range("TODO");}
+        if(Safe && (t < subSplines_.front().min() || t > subSplines_.back().max()))
+        {
+            throw std::out_of_range("time t to evaluate should be in range [Tmin, Tmax] of the spline");
+        }
         for(cit_spline_t it = subSplines_.begin(); it != subSplines_.end(); ++ it)
         {
             if( (t >= (it->min()) && t <= (it->max())) || it+1 == subSplines_.end())
+            {
                 return it->derivate(t, order);
+            }
         }
         // this should not happen
         throw std::runtime_error("Exact cubic evaluation failed; t is outside bounds");
@@ -192,7 +299,11 @@ struct exact_cubic : public curve_abc<Time, Numeric, Dim, Safe, Point>
 
 	/*Helpers*/
 	public:
+    /// \brief Get the minimum time for which the curve is defined
+    /// \return \f$t_{min}\f$ lower bound of time range.
     num_t virtual min() const{return subSplines_.front().min();}
+    /// \brief Get the maximum time for which the curve is defined.
+    /// \return \f$t_{max}\f$ upper bound of time range.
     num_t virtual max() const{return subSplines_.back().max();}
 	/*Helpers*/
 
diff --git a/include/curves/helpers/effector_spline.h b/include/curves/helpers/effector_spline.h
index 9d9cd4216a63b14c83515aa334203cabbbcb68de..2a8fb59784816f2d28fb3e25d25ec1c9b49b7b77 100644
--- a/include/curves/helpers/effector_spline.h
+++ b/include/curves/helpers/effector_spline.h
@@ -20,7 +20,7 @@
 #ifndef _CLASS_EFFECTORSPLINE
 #define _CLASS_EFFECTORSPLINE
 
-#include "curves/spline_deriv_constraint.h"
+#include "curves/exact_cubic.h"
 
 namespace curves
 {
@@ -32,26 +32,24 @@ typedef Eigen::Matrix<Numeric, 3, 1> Point;
 typedef std::vector<Point,Eigen::aligned_allocator<Point> > T_Point;
 typedef std::pair<double, Point> Waypoint;
 typedef std::vector<Waypoint> T_Waypoint;
-typedef spline_deriv_constraint<Time, Numeric, 3, true, Point, T_Point> spline_deriv_constraint_t;
-typedef spline_deriv_constraint_t::spline_constraints spline_constraints_t;
-typedef spline_deriv_constraint_t::exact_cubic_t exact_cubic_t;
-typedef spline_deriv_constraint_t::t_spline_t t_spline_t;
-typedef spline_deriv_constraint_t::spline_t spline_t;
+typedef exact_cubic<Time, Numeric, 3, true, Point, T_Point> exact_cubic_t;
+typedef exact_cubic_t::spline_constraints spline_constraints_t;
+typedef exact_cubic_t::t_spline_t t_spline_t;
+typedef exact_cubic_t::spline_t spline_t;
 
+/// \brief Compute time such that the equation from source to offsetpoint is necessarily a line.
 Waypoint compute_offset(const Waypoint& source, const Point& normal, const Numeric offset, const Time time_offset)
 {
-    //compute time such that the equation from source to offsetpoint is necessarily a line
     Numeric norm = normal.norm();
     assert(norm>0.);
     return std::make_pair(source.first + time_offset,(source.second + normal / norm* offset));
 }
 
-
+/// \brief Compute spline from land way point to end point.
+/// Constraints are null velocity and acceleration.
 spline_t make_end_spline(const Point& normal, const Point& from, const Numeric offset,
                          const Time init_time, const Time time_offset)
 {
-    // compute spline from land way point to end point
-    // constraints are null velocity and acceleration
     Numeric norm = normal.norm();
     assert(norm>0.);
     Point n = normal / norm;
@@ -68,9 +66,9 @@ spline_t make_end_spline(const Point& normal, const Point& from, const Numeric o
     return spline_t(points.begin(), points.end(), init_time, init_time+time_offset);
 }
 
+/// \brief Compute end velocity : along landing normal and respecting time.
 spline_constraints_t compute_required_offset_velocity_acceleration(const spline_t& end_spline, const Time /*time_offset*/)
 {
-    //computing end velocity: along landing normal and respecting time
     spline_constraints_t constraints;
     constraints.end_acc = end_spline.derivate(end_spline.min(),2);
     constraints.end_vel = end_spline.derivate(end_spline.min(),1);
@@ -112,7 +110,7 @@ exact_cubic_t* effector_spline(
     //specifying end velocity constraint such that landing will be in straight line
     spline_t end_spline=make_end_spline(land_normal,landWaypoint.second,land_offset,landWaypoint.first,land_offset_duration);
     spline_constraints_t constraints = compute_required_offset_velocity_acceleration(end_spline,land_offset_duration);
-    spline_deriv_constraint_t all_but_end(waypoints.begin(), waypoints.end(),constraints);
+    exact_cubic_t all_but_end(waypoints.begin(), waypoints.end(),constraints);
     t_spline_t splines = all_but_end.subSplines_;
     splines.push_back(end_spline);
     return new exact_cubic_t(splines);
diff --git a/include/curves/helpers/effector_spline_rotation.h b/include/curves/helpers/effector_spline_rotation.h
index 9d7ff42239394273ba0bd11ffa70678f79db0c10..38e9266975fdbcc3543249ba59d2eb5de56d7b9a 100644
--- a/include/curves/helpers/effector_spline_rotation.h
+++ b/include/curves/helpers/effector_spline_rotation.h
@@ -37,7 +37,7 @@ typedef curve_abc<Time, Numeric, 4, false, quat_t> curve_abc_quat_t;
 typedef std::pair<Numeric, quat_t > waypoint_quat_t;
 typedef std::vector<waypoint_quat_t> t_waypoint_quat_t;
 typedef Eigen::Matrix<Numeric, 1, 1> point_one_dim_t;
-typedef spline_deriv_constraint <Numeric, Numeric, 1, false, point_one_dim_t> spline_deriv_constraint_one_dim;
+typedef exact_cubic <Numeric, Numeric, 1, false, point_one_dim_t> exact_cubic_constraint_one_dim;
 typedef std::pair<Numeric, point_one_dim_t > waypoint_one_dim_t;
 typedef std::vector<waypoint_one_dim_t> t_waypoint_one_dim_t;
 
@@ -60,7 +60,7 @@ class rotation_spline: public curve_abc_quat_t
         quat_from_ = from.quat_from_;
         quat_to_ = from.quat_to_;
         min_ =from.min_; max_ = from.max_;
-        time_reparam_ = spline_deriv_constraint_one_dim(from.time_reparam_);
+        time_reparam_ = exact_cubic_constraint_one_dim(from.time_reparam_);
         return *this;
     }
     /* Copy Constructors / operator=*/
@@ -80,13 +80,13 @@ class rotation_spline: public curve_abc_quat_t
         throw std::runtime_error("TODO quaternion spline does not implement derivate");
     }
 
-    spline_deriv_constraint_one_dim computeWayPoints() const
+    /// \brief Initialize time reparametrization for spline.
+    exact_cubic_constraint_one_dim computeWayPoints() const
     {
-        // initializing time reparametrization for spline
         t_waypoint_one_dim_t waypoints;
         waypoints.push_back(std::make_pair(0,point_one_dim_t::Zero()));
         waypoints.push_back(std::make_pair(1,point_one_dim_t::Ones()));
-        return spline_deriv_constraint_one_dim(waypoints.begin(), waypoints.end());
+        return exact_cubic_constraint_one_dim(waypoints.begin(), waypoints.end());
     }
 
     virtual time_t min() const{return min_;}
@@ -97,7 +97,7 @@ class rotation_spline: public curve_abc_quat_t
     Eigen::Quaterniond quat_to_;   //const
     double min_;                   //const
     double max_;                   //const
-    spline_deriv_constraint_one_dim time_reparam_; //const
+    exact_cubic_constraint_one_dim time_reparam_; //const
 };
 
 
@@ -223,7 +223,9 @@ class effector_spline_rotation
     exact_cubic_quat_t quat_spline(InQuat quatWayPointsBegin, InQuat quatWayPointsEnd) const
     {
         if(std::distance(quatWayPointsBegin, quatWayPointsEnd) < 1)
+        {
             return simple_quat_spline();
+        }
         exact_cubic_quat_t::t_spline_t splines;
         InQuat it(quatWayPointsBegin);
         Time init = time_lift_offset_;
diff --git a/include/curves/linear_variable.h b/include/curves/linear_variable.h
index 5a1dc4961e2fa0f14060d95f9dc4bafc253e31bc..14ea20ed19a520e9b68ed19dd95115283b310dbd 100644
--- a/include/curves/linear_variable.h
+++ b/include/curves/linear_variable.h
@@ -75,13 +75,16 @@ struct variables{
     variables& operator+=(const variables& w1)
     {
         if(variables_.size() == 0)
+        {
             variables_ = w1.variables_;
-        else if (w1.variables_.size() !=0)
+        } else if (w1.variables_.size() !=0)
         {
             assert(variables_.size() == w1.variables_.size());
             CIT_var_t cit = w1.variables_.begin();
             for(IT_var_t it = variables_.begin(); it != variables_.end(); ++it, ++cit)
+            {
                 (*it)+=(*cit);
+            }
         }
         return *this;
     }
@@ -89,13 +92,16 @@ struct variables{
     variables& operator-=(const variables& w1)
     {
         if(variables_.size() == 0)
+        {
             variables_ = w1.variables_;
-        else if (w1.variables_.size() !=0)
+        } else if (w1.variables_.size() !=0)
         {
             assert(variables_.size() == w1.variables_.size());
             CIT_var_t cit = w1.variables_.begin();
             for(IT_var_t it = variables_.begin(); it != variables_.end(); ++it, ++cit)
+            {
                 (*it)-=(*cit);
+            }
         }
         return *this;
     }
@@ -137,14 +143,20 @@ template<typename V>
 variables<V> operator+(const variables<V>& w1, const variables<V>& w2)
 {
     if(w2.variables_.size() == 0)
+    {
         return w1;
+    }
     if(w1.variables_.size() == 0)
+    {
         return w2;
+    }
     variables<V> res;
     assert(w2.variables_.size() == w1.variables_.size());
     typename variables<V>::CIT_var_t cit = w1.variables_.begin();
     for(typename variables<V>::CIT_var_t cit2 = w2.variables_.begin(); cit2 != w2.variables_.end(); ++cit, ++cit2)
+    {
         res.variables_.push_back((*cit)+(*cit2));
+    }
     return res;
 }
 
@@ -152,14 +164,20 @@ template<typename V>
 variables<V> operator-(const variables<V>& w1, const variables<V>& w2)
 {
     if(w2.variables_.size() == 0)
+    {
         return w1;
+    }
     if(w1.variables_.size() == 0)
+    {
         return w2;
+    }
     variables<V> res;
     assert(w2.variables_.size() == w1.variables_.size());
     typename variables<V>::CIT_var_t cit = w1.variables_.begin();
     for(typename variables<V>::CIT_var_t cit2 = w2.variables_.begin(); cit2 != w2.variables_.end(); ++cit, ++cit2)
+    {
         res.variables_.push_back((*cit)-(*cit2));
+    }
     return res;
 }
 
@@ -167,10 +185,14 @@ template<typename V>
 variables<V> operator*(const double k, const variables<V>& w)
 {
     if(w.variables_.size() == 0)
+    {
         return w;
+    }
     variables<V> res;
     for(typename variables<V>::CIT_var_t cit = w.variables_.begin(); cit != w.variables_.end(); ++cit)
+    {
         res.variables_.push_back(k*(*cit));
+    }
     return res;
 }
 
@@ -178,10 +200,14 @@ template<typename V>
 variables<V> operator*(const variables<V>& w,const double k)
 {
     if(w.variables_.size() == 0)
+    {
         return w;
+    }
     variables<V> res;
     for(typename variables<V>::CIT_var_t cit = w.variables_.begin(); cit != w.variables_.end(); ++cit)
+    {
         res.variables_.push_back((*cit)*k);
+    }
     return res;
 }
 
@@ -189,10 +215,14 @@ template<typename V>
 variables<V> operator/(const variables<V>& w,const double k)
 {
     if(w.variables_.size() == 0)
+    {
         return w;
+    }
     variables<V> res;
     for(typename variables<V>::CIT_var_t cit = w.variables_.begin(); cit != w.variables_.end(); ++cit)
+    {
         res.variables_.push_back((*cit)/k);
+    }
     return res;
 }
 
diff --git a/include/curves/optimization/OptimizeSpline.h b/include/curves/optimization/OptimizeSpline.h
index 1107a582fceaec594cab7aec490d2f76201425cd..85fbb644750ed000830be72f588b28be3a8e88cf 100644
--- a/include/curves/optimization/OptimizeSpline.h
+++ b/include/curves/optimization/OptimizeSpline.h
@@ -125,7 +125,7 @@ inline exact_cubic<Time, Numeric, Dim, Safe, Point>*
 	int const size((int)std::distance(wayPointsBegin, wayPointsEnd));
 	if(Safe && size < 1)
 	{
-		throw; // TODO
+		throw std::length_error("can not generate optimizedCurve, number of waypoints should be superior to one");; // TODO
 	}
 	// refer to the paper to understand all this.
 	MatrixX h1 = MatrixX::Zero(size, size);
@@ -258,7 +258,7 @@ inline exact_cubic<Time, Numeric, Dim, Safe, Point>*
 		for(int j = 0; j<Dim; ++j)
 		{
 			int id = i + j;
-			h3x_h4x.block(id, j*size		   , 1, size) = h3.row(i%3);
+			h3x_h4x.block(id, j*size		  , 1, size) = h3.row(i%3);
 			h3x_h4x.block(id, j*size + ptOff  , 1, size) = h4.row(i%3);
 			h3x_h4x.block(id, j*size + ptptOff, 1, size) = MatrixX::Ones(1, size) * -2;
 		}
@@ -430,56 +430,67 @@ inline exact_cubic<Time, Numeric, Dim, Safe, Point>*
 	/* Append 'numcon' empty constraints.
 		The constraints will initially have no bounds. */
 	if ( r == MSK_RES_OK )
+	{
 		r = MSK_appendcons(task,numcon);
+	}
 
 	/* Append 'numvar' variables.
 		The variables will initially be fixed at zero (x=0). */
 	if ( r == MSK_RES_OK )
+	{
 		r = MSK_appendvars(task,numvar);
+	}
 
 	for(int j=0; j<numvar && r == MSK_RES_OK; ++j)
 	{
-	/* Set the linear term c_j in the objective.*/   
-      if(r == MSK_RES_OK) 
-        r = MSK_putcj(task,j,0); 
-
+		/* Set the linear term c_j in the objective.*/   
+		if(r == MSK_RES_OK) 
+		{
+        	r = MSK_putcj(task,j,0); 
+		}
 		/* Set the bounds on variable j.
 		blx[j] <= x_j <= bux[j] */
 		if(r == MSK_RES_OK)
-		r = MSK_putvarbound(task,
-							j,           /* Index of variable.*/
-							bkx[j],      /* Bound key.*/
-							blx[j],      /* Numerical value of lower bound.*/
-							bux[j]);     /* Numerical value of upper bound.*/
-
+		{
+			r = MSK_putvarbound(task,
+								j,           /* Index of variable.*/
+								bkx[j],      /* Bound key.*/
+								blx[j],      /* Numerical value of lower bound.*/
+								bux[j]);     /* Numerical value of upper bound.*/
+		}
 		/* Input column j of A */   
 		if(r == MSK_RES_OK)
-		r = MSK_putacol(task,
-						j,                 /* Variable (column) index.*/
-						aptre[j]-aptrb[j], /* Number of non-zeros in column j.*/
-						asub+aptrb[j],     /* Pointer to row indexes of column j.*/
-						aval+aptrb[j]);    /* Pointer to Values of column j.*/
+		{
+			r = MSK_putacol(task,
+							j,                 /* Variable (column) index.*/
+							aptre[j]-aptrb[j], /* Number of non-zeros in column j.*/
+							asub+aptrb[j],     /* Pointer to row indexes of column j.*/
+							aval+aptrb[j]);    /* Pointer to Values of column j.*/
+		}
 	}
 
 	/* Set the bounds on constraints.
 		for i=1, ...,numcon : blc[i] <= constraint i <= buc[i] */
 	for(int i=0; i<numcon && r == MSK_RES_OK; ++i)
+	{
 		r = MSK_putconbound(task,
 							i,           /* Index of constraint.*/
 							bkc[i],      /* Bound key.*/
 							blc[i],      /* Numerical value of lower bound.*/
 							buc[i]);     /* Numerical value of upper bound.*/
+	}
 
 	/* Maximize objective function. */
 	if (r == MSK_RES_OK)
+	{
 		r = MSK_putobjsense(task, MSK_OBJECTIVE_SENSE_MINIMIZE);
+	}
 
 
 	if ( r==MSK_RES_OK ) 
     {  
-    /* Input the Q for the objective. */ 
- 
-    r = MSK_putqobj(task,numqz,qsubi,qsubj,qval); 
+	    /* Input the Q for the objective. */ 
+	    r = MSK_putqobj(task,numqz,qsubi,qsubj,qval); 
     } 
 
 	if ( r==MSK_RES_OK )
diff --git a/include/curves/piecewise_polynomial_curve.h b/include/curves/piecewise_polynomial_curve.h
new file mode 100644
index 0000000000000000000000000000000000000000..203bbd5b934f32e0fcfc4aa47dbfbd3c6eb6750f
--- /dev/null
+++ b/include/curves/piecewise_polynomial_curve.h
@@ -0,0 +1,195 @@
+/**
+* \file piecewise_polynomial_curve.h
+* \brief class allowing to create a piecewise polynomial curve.
+* \author Jason C.
+* \date 05/2019
+*/
+
+#ifndef _CLASS_PIECEWISE_CURVE
+#define _CLASS_PIECEWISE_CURVE
+
+#include "curve_abc.h"
+#include "polynomial.h"
+#include "curve_conversion.h"
+
+namespace curves
+{
+/// \class PiecewiseCurve.
+/// \brief Represent a piecewise polynomial curve. We can add some new polynomials to the curve,
+///        but the starting time of the polynomial to add should be equal to the ending time of the 
+///        piecewise_polynomial_curve.<br>\ Example : A piecewise polynomial curve composed of three polynomials pol_0, 
+///        pol_1 and pol_2 where pol_0 is defined between \f$[T0_{min},T0_{max}]\f$, pol_1 between 
+///        \f$[T0_{max},T1_{max}]\f$ and pol_2 between \f$[T1_{max},T2_{max}]\f$.
+///        On the piecewise polynomial curve, pol_0 is located between \f$[T0_{min},T0_{max}[\f$,
+///        pol_1 between \f$[T0_{max},T1_{max}[\f$ and pol_2 between \f$[T1_{max},T2_{max}]\f$.
+///
+template<typename Time= double, typename Numeric=Time, std::size_t Dim=3, bool Safe=false,
+     typename Point= Eigen::Matrix<Numeric, Dim, 1>, 
+     typename T_Point= std::vector<Point,Eigen::aligned_allocator<Point> > 
+     >
+struct piecewise_polynomial_curve : public curve_abc<Time, Numeric, Dim, Safe, Point>
+{
+
+	typedef Point 	point_t;
+	typedef T_Point t_point_t;
+	typedef Time 	time_t;
+    typedef Numeric	num_t;
+
+    //typedef polynomial  <double, double, 3, true, point_t, t_point_t> polynomial_t;
+    typedef polynomial  <double, double, 3, true, point_t, t_point_t> polynomial_t;
+    typedef typename std::vector < polynomial_t > t_polynomial_t;
+    typedef std::vector<Time> t_vector_time_t;
+
+	public:
+
+	/// \brief Constructor.
+    /// Initialize a piecewise polynomial curve by giving the first polynomial curve.
+    /// \param pol   : a polynomial curve.
+    ///
+	piecewise_polynomial_curve(const polynomial_t& pol)
+	{
+		size_ = 0;
+		add_polynomial_curve(pol);
+        time_polynomial_curves_.push_back(pol.min());
+        T_min_ = pol.min();
+	}
+
+	virtual ~piecewise_polynomial_curve(){}
+
+	virtual Point operator()(const Time t) const
+    {
+        if(Safe &! (T_min_ <= t && t <= T_max_))
+        {
+        	//std::cout<<"[Min,Max]=["<<T_min_<<","<<T_max_<<"]"<<" t="<<t<<std::endl;
+			throw std::out_of_range("can't evaluate piecewise curve, out of range");
+        }
+        return polynomial_curves_.at(find_interval(t))(t);
+    }
+
+    ///  \brief Evaluate the derivative of order N of curve at time t.
+    ///  \param t : time when to evaluate the spline.
+    ///  \param order : order of derivative.
+    ///  \return \f$\frac{d^Np(t)}{dt^N}\f$ point corresponding on derivative spline of order N at time t.
+    ///
+    virtual Point derivate(const Time t, const std::size_t order) const
+    {   
+        if(Safe &! (T_min_ <= t && t <= T_max_))
+        {
+			throw std::out_of_range("can't evaluate piecewise curve, out of range");
+        }
+        return (polynomial_curves_.at(find_interval(t))).derivate(t, order);
+    }
+
+    ///  \brief Add a new polynomial to piecewise curve, which should be defined in \f$[T_{min},T_{max}]\f$ where \f$T_{min}\f$
+    ///         is equal to \f$T_{max}\f$ of the actual piecewise curve.
+    ///  \param pol : polynomial to add.
+    ///
+	void add_polynomial_curve(polynomial_t pol)
+	{
+		// Check time continuity : Beginning time of pol must be equal to T_max_ of actual piecewise curve.
+		if (size_!=0 && pol.min()!=T_max_)
+		{
+			throw std::out_of_range("Can not add new Polynom to PiecewiseCurve : time discontinuity between T_max_ and pol.min()");
+		}
+		polynomial_curves_.push_back(pol);
+		size_ = polynomial_curves_.size();
+		T_max_ = pol.max();
+		time_polynomial_curves_.push_back(T_max_);
+	}
+
+    ///  \brief Check if the curve is continuous of order given.
+    ///  \param order : order of continuity we want to check.
+    ///  \return True if the curve is continuous of order given.
+    ///
+	bool is_continuous(const std::size_t order)
+	{
+        double margin = 0.001;
+		bool isContinuous = true;
+    	std::size_t i=0;
+    	point_t value_end, value_start;
+    	while (isContinuous && i<(size_-1))
+    	{
+    		polynomial_t current = polynomial_curves_.at(i);
+    		polynomial_t next = polynomial_curves_.at(i+1);
+
+    		if (order == 0)
+    		{
+    			value_end = current(current.max());
+				value_start = next(next.min());
+    		}
+    		else
+    		{
+				value_end = current.derivate(current.max(),order);
+				value_start = next.derivate(next.min(),order);
+			}
+
+    		if ((value_end-value_start).norm() > margin)
+    		{
+    			isContinuous = false;
+    		}
+    		i++;
+    	}
+    	return isContinuous;
+	}
+
+	private:
+
+	/// \brief Get index of the interval corresponding to time t for the interpolation.
+    /// \param t : time where to look for interval.
+    /// \return Index of interval for time t.
+    ///
+    std::size_t find_interval(const Numeric t) const
+    {	
+        // time before first control point time.
+        if(t < time_polynomial_curves_[0])
+        {
+            return 0;
+        }
+        // time is after last control point time
+        if(t > time_polynomial_curves_[size_-1])
+        {
+            return size_-1;
+        }
+
+        std::size_t left_id = 0;
+        std::size_t right_id = size_-1;
+        while(left_id <= right_id)
+        {
+            const std::size_t middle_id = left_id + (right_id - left_id)/2;
+            if(time_polynomial_curves_.at(middle_id) < t)
+            {
+                left_id = middle_id+1;
+            }
+            else if(time_polynomial_curves_.at(middle_id) > t)
+            {
+                right_id = middle_id-1;
+            }
+            else
+            {
+                return middle_id;
+            }
+        }
+        return left_id-1;
+    }
+
+    /*Helpers*/
+	public:
+    /// \brief Get the minimum time for which the curve is defined
+    /// \return \f$t_{min}\f$, lower bound of time range.
+    Time virtual min() const{return T_min_;}
+    /// \brief Get the maximum time for which the curve is defined.
+    /// \return \f$t_{max}\f$, upper bound of time range.
+    Time virtual max() const{return T_max_;}
+	/*Helpers*/
+
+    /* Variables */
+	t_polynomial_t polynomial_curves_; // for curves 0/1/2 : [ curve0, curve1, curve2 ]
+	t_vector_time_t time_polynomial_curves_; // for curves 0/1/2 : [ Tmin0, Tmax0,Tmax1,Tmax2 ]
+	std::size_t size_; // Number of segments in piecewise curve = size of polynomial_curves_
+	Time T_min_, T_max_;
+};
+
+} // end namespace
+
+
+#endif // _CLASS_PIECEWISE_CURVE
\ No newline at end of file
diff --git a/include/curves/polynom.h b/include/curves/polynomial.h
similarity index 54%
rename from include/curves/polynom.h
rename to include/curves/polynomial.h
index 2fd55ae14a0a1194b1d6b3a39be8460cd0e1503c..b6ef4c3d876785df075ce82d0121c8fdfeb2dea4 100644
--- a/include/curves/polynom.h
+++ b/include/curves/polynomial.h
@@ -1,18 +1,18 @@
 /**
-* \file polynom.h
+* \file polynomial.h
 * \brief Definition of a cubic spline.
 * \author Steve T.
 * \version 0.1
 * \date 06/17/2013
 *
-* This file contains definitions for the polynom struct.
+* This file contains definitions for the polynomial struct.
 * It allows the creation and evaluation of natural
 * smooth splines of arbitrary dimension and order
 */
 
 
-#ifndef _STRUCT_POLYNOM
-#define _STRUCT_POLYNOM
+#ifndef _STRUCT_POLYNOMIAL
+#define _STRUCT_POLYNOMIAL
 
 #include "MathDefs.h"
 
@@ -25,14 +25,15 @@
 
 namespace curves
 {
-/// \class polynom
-/// \brief Represents a polynomf arbitrary order defined on the interval
-/// [tBegin, tEnd]. It follows the equation
-/// x(t) = a + b(t - t_min_) + ... + d(t - t_min_)^N, where N is the order
+/// \class polynomial.
+/// \brief Represents a polynomial of an arbitrary order defined on the interval
+/// \f$[t_{min}, t_{max}]\f$. It follows the equation :<br>
+/// \f$ x(t) = a + b(t - t_{min}) + ... + d(t - t_{min})^N \f$<br> 
+/// where N is the order and \f$ t \in [t_{min}, t_{max}] \f$.
 ///
 template<typename Time= double, typename Numeric=Time, std::size_t Dim=3, bool Safe=false,
          typename Point= Eigen::Matrix<Numeric, Dim, 1>, typename T_Point =std::vector<Point,Eigen::aligned_allocator<Point> > >
-struct polynom : public curve_abc<Time, Numeric, Dim, Safe, Point>
+struct polynomial : public curve_abc<Time, Numeric, Dim, Safe, Point>
 {
     typedef Point 	point_t;
     typedef T_Point t_point_t;
@@ -44,26 +45,26 @@ struct polynom : public curve_abc<Time, Numeric, Dim, Safe, Point>
 
 /* Constructors - destructors */
     public:
-    ///\brief Constructor
-    ///\param coefficients : a reference to an Eigen matrix where each column is a coefficient,
+    /// \brief Constructor.
+    /// \param coefficients : a reference to an Eigen matrix where each column is a coefficient,
     /// from the zero order coefficient, up to the highest order. Spline order is given
     /// by the number of the columns -1.
-    ///\param min: LOWER bound on interval definition of the spline
-    ///\param max: UPPER bound on interval definition of the spline
-    polynom(const coeff_t& coefficients, const time_t min, const time_t max)
+    /// \param min  : LOWER bound on interval definition of the curve.
+    /// \param max  : UPPER bound on interval definition of the curve.
+    polynomial(const coeff_t& coefficients, const time_t min, const time_t max)
         : curve_abc_t(),
           coefficients_(coefficients), dim_(Dim), order_(coefficients_.cols()-1), t_min_(min), t_max_(max)
     {
         safe_check();
     }
 
-    ///\brief Constructor
-    ///\param coefficients : a container containing all coefficients of the spline, starting
-    /// with the zero order coefficient, up to the highest order. Spline order is given
-    /// by the size of the coefficients
-    ///\param min: LOWER bound on interval definition of the spline
-    ///\param max: UPPER bound on interval definition of the spline
-    polynom(const T_Point& coefficients, const time_t min, const time_t max)
+    /// \brief Constructor
+    /// \param coefficients : a container containing all coefficients of the spline, starting
+    ///  with the zero order coefficient, up to the highest order. Spline order is given
+    ///  by the size of the coefficients.
+    /// \param min  : LOWER bound on interval definition of the spline.
+    /// \param max  : UPPER bound on interval definition of the spline.
+    polynomial(const T_Point& coefficients, const time_t min, const time_t max)
         : curve_abc_t(),
           coefficients_(init_coeffs(coefficients.begin(), coefficients.end())),
           dim_(Dim), order_(coefficients_.cols()-1), t_min_(min), t_max_(max)
@@ -71,33 +72,33 @@ struct polynom : public curve_abc<Time, Numeric, Dim, Safe, Point>
         safe_check();
     }
 
-    ///\brief Constructor
-    ///\param zeroOrderCoefficient : an iterator pointing to the first element of a structure containing the coefficients
-    /// it corresponds to the zero degree coefficient
-    ///\param out   : an iterator pointing to the last element of a structure ofcoefficients
-    ///\param min: LOWER bound on interval definition of the spline
-    ///\param max: UPPER bound on interval definition of the spline
+    /// \brief Constructor.
+    /// \param zeroOrderCoefficient : an iterator pointing to the first element of a structure containing the coefficients
+    ///  it corresponds to the zero degree coefficient.
+    /// \param out   : an iterator pointing to the last element of a structure ofcoefficients.
+    /// \param min   : LOWER bound on interval definition of the spline.
+    /// \param max   : UPPER bound on interval definition of the spline.
     template<typename In>
-    polynom(In zeroOrderCoefficient, In out, const time_t min, const time_t max)
+    polynomial(In zeroOrderCoefficient, In out, const time_t min, const time_t max)
         :coefficients_(init_coeffs(zeroOrderCoefficient, out)),
           dim_(Dim), order_(coefficients_.cols()-1), t_min_(min), t_max_(max)
     {
         safe_check();
     }
 
-    ///\brief Destructor
-    ~polynom()
+    /// \brief Destructor
+    ~polynomial()
     {
         // NOTHING
     }
 
 
-    polynom(const polynom& other)
+    polynomial(const polynomial& other)
         : coefficients_(other.coefficients_),
           dim_(other.dim_), order_(other.order_), t_min_(other.t_min_), t_max_(other.t_max_){}
 
 
-    //polynom& operator=(const polynom& other);
+    //polynomial& operator=(const polynomial& other);
 
     private:
     void safe_check()
@@ -105,9 +106,13 @@ struct polynom : public curve_abc<Time, Numeric, Dim, Safe, Point>
         if(Safe)
         {
             if(t_min_ > t_max_)
-                std::out_of_range("TODO");
+            {
+                std::out_of_range("Tmin should be inferior to Tmax");
+            }
             if(coefficients_.size() != int(order_+1))
+            {
                 std::runtime_error("Spline order and coefficients do not match");
+            }
         }
     }
 
@@ -117,7 +122,7 @@ struct polynom : public curve_abc<Time, Numeric, Dim, Safe, Point>
     public:
     /*///  \brief Evaluation of the cubic spline at time t.
     ///  \param t : the time when to evaluate the spine
-    ///  \param return : the value x(t)
+    ///  \param return \f$x(t)\f$, point corresponding on curve at time t.
     virtual point_t operator()(const time_t t) const
     {
         if((t < t_min_ || t > t_max_) && Safe){ throw std::out_of_range("TODO");}
@@ -131,31 +136,41 @@ struct polynom : public curve_abc<Time, Numeric, Dim, Safe, Point>
 
 
     ///  \brief Evaluation of the cubic spline at time t using horner's scheme.
-    ///  \param t : the time when to evaluate the spine
-    ///  \param return : the value x(t)
+    ///  \param t : time when to evaluate the spline.
+    ///  \return \f$x(t)\f$ point corresponding on spline at time t.
     virtual point_t operator()(const time_t t) const
     {
-        if((t < t_min_ || t > t_max_) && Safe){ throw std::out_of_range("TODO");}
+        if((t < t_min_ || t > t_max_) && Safe)
+        { 
+            throw std::out_of_range("error in polynomial : time t to evaluate should be in range [Tmin, Tmax] of the curve");
+        }
         time_t const dt (t-t_min_);
         point_t h = coefficients_.col(order_);
         for(int i=(int)(order_-1); i>=0; i--)
+        {
             h = dt*h + coefficients_.col(i);
+        }
         return h;
     }
 
 
-    ///  \brief Evaluation of the derivative spline at time t.
-    ///  \param t : the time when to evaluate the spline
-    ///  \param order : order of the derivative
-    ///  \param return : the value x(t)
+    ///  \brief Evaluation of the derivative of order N of spline at time t.
+    ///  \param t : the time when to evaluate the spline.
+    ///  \param order : order of derivative.
+    ///  \return \f$\frac{d^Nx(t)}{dt^N}\f$ point corresponding on derivative spline at time t.
     virtual point_t derivate(const time_t t, const std::size_t order) const
     {
-        if((t < t_min_ || t > t_max_) && Safe){ throw std::out_of_range("TODO");}
+        if((t < t_min_ || t > t_max_) && Safe)
+        { 
+            throw std::out_of_range("error in polynomial : time t to evaluate derivative should be in range [Tmin, Tmax] of the curve");
+        }
         time_t const dt (t-t_min_);
         time_t cdt(1);
         point_t currentPoint_ = point_t::Zero();
-        for(int i = (int)(order); i < (int)(order_+1); ++i, cdt*=dt)
+        for(int i = (int)(order); i < (int)(order_+1); ++i, cdt*=dt) 
+        {
             currentPoint_ += cdt *coefficients_.col(i) * fact(i, order);
+        }
         return currentPoint_;
     }
 
@@ -164,7 +179,9 @@ struct polynom : public curve_abc<Time, Numeric, Dim, Safe, Point>
     {
         num_t res(1);
         for(std::size_t i = 0; i < order; ++i)
+        {
             res *= (num_t)(n-i);
+        }
         return res;
     }
 
@@ -172,9 +189,11 @@ struct polynom : public curve_abc<Time, Numeric, Dim, Safe, Point>
 
 /*Helpers*/
     public:
-    ///  \brief Returns the minimum time for wich curve is defined
+    /// \brief Get the minimum time for which the curve is defined
+    /// \return \f$t_{min}\f$ lower bound of time range.
     num_t virtual min() const {return t_min_;}
-    ///  \brief Returns the maximum time for wich curve is defined
+    /// \brief Get the maximum time for which the curve is defined.
+    /// \return \f$t_{max}\f$ upper bound of time range.
     num_t virtual max() const {return t_max_;}
 /*Helpers*/
 
@@ -195,10 +214,12 @@ struct polynom : public curve_abc<Time, Numeric, Dim, Safe, Point>
         std::size_t size = std::distance(zeroOrderCoefficient, highestOrderCoefficient);
         coeff_t res = coeff_t(Dim, size); int i = 0;
         for(In cit = zeroOrderCoefficient; cit != highestOrderCoefficient; ++cit, ++i)
+        {
             res.col(i) = *cit;
+        }
         return res;
     }
-}; //class polynom
+}; //class polynomial
 } // namespace curves
-#endif //_STRUCT_POLYNOM
+#endif //_STRUCT_POLYNOMIAL
 
diff --git a/include/curves/quintic_spline.h b/include/curves/quintic_spline.h
index 3ff0cf585a4f70976ccb35ea2cac46625ca84a3b..4bfa35a48a3f0bcef05dd3cb38d6f341b61bd96c 100644
--- a/include/curves/quintic_spline.h
+++ b/include/curves/quintic_spline.h
@@ -16,15 +16,15 @@
 
 #include "MathDefs.h"
 
-#include "polynom.h"
+#include "polynomial.h"
 
 #include <stdexcept>
 
 namespace curves
 {
 /// \brief Creates coefficient vector of a quintic spline defined on the interval
-/// \f$[t_{min}, t_{max}]\f$. It follows the equation :
-/// \f$ x(t) = a + b(t - t_{min}) + c(t - t_{min})^2 + d(t - t_{min})^3 + e(t - t_{min})^4  + f(t - t_{min})^5 \f$ 
+/// \f$[t_{min}, t_{max}]\f$. It follows the equation :<br>
+/// \f$ x(t) = a + b(t - t_{min}) + c(t - t_{min})^2 + d(t - t_{min})^3 + e(t - t_{min})^4  + f(t - t_{min})^5 \f$ <br>
 /// where \f$ t \in [t_{min}, t_{max}] \f$.
 ///
 template<typename Point, typename T_Point>
@@ -38,11 +38,11 @@ T_Point make_quintic_vector(Point const& a, Point const& b, Point const& c,
 }
 
 template<typename Time, typename Numeric, std::size_t Dim, bool Safe, typename Point, typename T_Point>
-polynom<Time,Numeric,Dim,Safe,Point,T_Point> create_quintic(Point const& a, Point const& b, Point const& c, Point const &d, Point const &e, Point const &f,
+polynomial<Time,Numeric,Dim,Safe,Point,T_Point> create_quintic(Point const& a, Point const& b, Point const& c, Point const &d, Point const &e, Point const &f,
                const Time t_min, const Time t_max)
 {
     T_Point coeffs = make_quintic_vector<Point, T_Point>(a,b,c,d,e,f);
-    return polynom<Time,Numeric,Dim,Safe,Point,T_Point>(coeffs.begin(),coeffs.end(), t_min, t_max);
+    return polynomial<Time,Numeric,Dim,Safe,Point,T_Point>(coeffs.begin(),coeffs.end(), t_min, t_max);
 }
 } // namespace curves
 #endif //_STRUCT_QUINTIC_SPLINE
diff --git a/include/curves/spline_deriv_constraint.h b/include/curves/spline_deriv_constraint.h
deleted file mode 100644
index 9f5c332371a37d89713e7d187cdbe6e3e587c87c..0000000000000000000000000000000000000000
--- a/include/curves/spline_deriv_constraint.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/**
-* \file exact_cubic.h
-* \brief class allowing to create an Exact cubic spline.
-* \author Steve T.
-* \version 0.1
-* \date 06/17/2013
-*
-* This file contains definitions for the ExactCubic class.
-* Given a set of waypoints (x_i*) and timestep (t_i), it provides the unique set of
-* cubic splines fulfulling those 4 restrictions :
-* - x_i(t_i) = x_i* ; this means that the curve passes trough each waypoint
-* - x_i(t_i+1) = x_i+1* ;
-* - its derivative is continous at t_i+1
-* - its acceleration is continous at t_i+1
-* more details in paper "Task-Space Trajectories via Cubic Spline Optimization"
-* By J. Zico Kolter and Andrew Y.ng (ICRA 2009)
-*/
-
-
-#ifndef _CLASS_CUBICZEROVELACC
-#define _CLASS_CUBICZEROVELACC
-
-#include "exact_cubic.h"
-#include "curve_constraint.h"
-
-#include "MathDefs.h"
-
-#include <functional>
-#include <vector>
-
-namespace curves
-{
-/// \class spline_deriv_constraint.
-/// \brief Represents a set of cubic splines defining a continuous function 
-/// crossing each of the waypoint given in its initialization. Additional constraints
-/// are used to increase the order of the last spline, to start and finish
-/// trajectory with user defined velocity and acceleration.
-///
-template<typename Time= double, typename Numeric=Time, std::size_t Dim=3, bool Safe=false,
-         typename Point= Eigen::Matrix<Numeric, Dim, 1>,
-         typename T_Point =std::vector<Point,Eigen::aligned_allocator<Point> >,
-         typename SplineBase=polynom<Time, Numeric, Dim, Safe, Point, T_Point> >
-struct spline_deriv_constraint : public exact_cubic<Time, Numeric, Dim, Safe, Point, T_Point, SplineBase>
-{
-    typedef Point 	point_t;
-    typedef T_Point t_point_t;
-    typedef Eigen::Matrix<Numeric, Eigen::Dynamic, Eigen::Dynamic> MatrixX;
-    typedef Eigen::Matrix<Numeric, 3, 3> Matrix3;
-    typedef Time 	time_t;
-    typedef Numeric	num_t;
-    typedef polynom<time_t, Numeric, Dim, Safe, point_t, t_point_t> spline_t;
-    typedef exact_cubic<time_t, Numeric, Dim, Safe, point_t, t_point_t> exact_cubic_t;
-    typedef typename std::vector<spline_t> t_spline_t;
-    typedef typename t_spline_t::iterator it_spline_t;
-    typedef typename t_spline_t::const_iterator cit_spline_t;
-    typedef curve_constraints<point_t> spline_constraints;
-
-	/* Constructors - destructors */
-	public:
-	/// \brief Constructor.
-	/// \param wayPointsBegin : an iterator pointing to the first element of a waypoint container.
-    /// \param wayPointsEnd   : an iterator pointing to the last element of a waypoint container.
-    /// \param constraints    : constraints on the init and end velocity / accelerations of the spline.
-    ///
-    template<typename In>
-    spline_deriv_constraint(In wayPointsBegin, In wayPointsEnd, const spline_constraints& constraints = spline_constraints())
-        : exact_cubic_t(computeWayPoints<In>(wayPointsBegin, wayPointsEnd, constraints)) {}
-
-	///\brief Destructor
-    virtual ~spline_deriv_constraint(){}
-
-    ///\brief Copy Constructor
-    spline_deriv_constraint(const spline_deriv_constraint& other)
-        : exact_cubic_t(other.subSplines_) {}
-
-    private:
-    template<typename In>
-    void compute_one_spline(In wayPointsBegin, In wayPointsNext, spline_constraints& constraints, t_spline_t& subSplines) const
-    {
-        const point_t& a0 = wayPointsBegin->second, a1 = wayPointsNext->second;
-        const point_t& b0 = constraints.init_vel , c0 = constraints.init_acc / 2.;
-        const num_t& init_t = wayPointsBegin->first, end_t = wayPointsNext->first;
-        const num_t dt = end_t - init_t, dt_2 = dt * dt, dt_3 = dt_2 * dt;
-        const point_t d0 = (a1 - a0 - b0 * dt - c0 * dt_2) / dt_3;
-        subSplines.push_back(create_cubic<Time,Numeric,Dim,Safe,Point,T_Point>
-                             (a0,b0,c0,d0,init_t, end_t));
-        constraints.init_vel = subSplines.back().derivate(end_t, 1);
-        constraints.init_acc = subSplines.back().derivate(end_t, 2);
-    }
-
-    template<typename In>
-    void compute_end_spline(In wayPointsBegin, In wayPointsNext, spline_constraints& constraints, t_spline_t& subSplines) const
-    {
-        const point_t& a0 = wayPointsBegin->second, a1 = wayPointsNext->second;
-        const point_t& b0 = constraints.init_vel, b1 = constraints.end_vel,
-                       c0 = constraints.init_acc / 2., c1 = constraints.end_acc;
-        const num_t& init_t = wayPointsBegin->first, end_t = wayPointsNext->first;
-        const num_t dt = end_t - init_t, dt_2 = dt * dt, dt_3 = dt_2 * dt, dt_4 = dt_3 * dt, dt_5 = dt_4 * dt;
-        //solving a system of four linear eq with 4 unknows: d0, e0
-        const point_t alpha_0 = a1 - a0 - b0 *dt -    c0 * dt_2;
-        const point_t alpha_1 = b1 -      b0     - 2 *c0 * dt;
-        const point_t alpha_2 = c1 -               2 *c0;
-        const num_t x_d_0 = dt_3, x_d_1 = 3*dt_2, x_d_2 = 6*dt;
-        const num_t x_e_0 = dt_4, x_e_1 = 4*dt_3, x_e_2 = 12*dt_2;
-        const num_t x_f_0 = dt_5, x_f_1 = 5*dt_4, x_f_2 = 20*dt_3;
-
-        point_t d, e, f;
-        MatrixX rhs = MatrixX::Zero(3,Dim);
-        rhs.row(0) = alpha_0; rhs.row(1) = alpha_1; rhs.row(2) = alpha_2;
-        Matrix3 eq  = Matrix3::Zero(3,3);
-        eq(0,0) = x_d_0; eq(0,1) = x_e_0; eq(0,2) = x_f_0;
-        eq(1,0) = x_d_1; eq(1,1) = x_e_1; eq(1,2) = x_f_1;
-        eq(2,0) = x_d_2; eq(2,1) = x_e_2; eq(2,2) = x_f_2;
-        rhs = eq.inverse().eval() * rhs;
-        d = rhs.row(0); e = rhs.row(1); f = rhs.row(2);
-
-        subSplines.push_back(create_quintic<Time,Numeric,Dim,Safe,Point,T_Point>
-                             (a0,b0,c0,d,e,f, init_t, end_t));
-    }
-
-    private:
-    template<typename In>
-    t_spline_t computeWayPoints(In wayPointsBegin, In wayPointsEnd, const spline_constraints& constraints) const
-    {
-        std::size_t const size(std::distance(wayPointsBegin, wayPointsEnd));
-        if(Safe && size < 1) throw; // TODO
-        t_spline_t subSplines; subSplines.reserve(size-1);
-        spline_constraints cons = constraints;
-        In it(wayPointsBegin), next(wayPointsBegin), end(wayPointsEnd-1);
-        ++next;
-        for(std::size_t i(0); next != end; ++next, ++it, ++i)
-            compute_one_spline<In>(it, next, cons, subSplines);
-        compute_end_spline<In>(it, next,cons, subSplines);
-        return subSplines;
-    }
-
-    private:
-    /* Constructors - destructors */
-};
-} // namespace curves
-#endif //_CLASS_CUBICZEROVELACC
-
diff --git a/python/curves_python.cpp b/python/curves_python.cpp
index 6c843d025a6396377ac5d5220c9409cd2681877a..182f6beb18a047b70130ba09bc7c1ca910fd3dd5 100644
--- a/python/curves_python.cpp
+++ b/python/curves_python.cpp
@@ -1,10 +1,11 @@
 #include "curves/bezier_curve.h"
-#include "curves/polynom.h"
+#include "curves/polynomial.h"
 #include "curves/exact_cubic.h"
-#include "curves/spline_deriv_constraint.h"
 #include "curves/curve_constraint.h"
-#include "curves/bezier_polynom_conversion.h"
+#include "curves/curve_conversion.h"
 #include "curves/bernstein.h"
+#include "curves/cubic_hermite_spline.h"
+#include "curves/piecewise_polynomial_curve.h"
 
 #include "python_definitions.h"
 #include "python_variables.h"
@@ -20,6 +21,8 @@
 using namespace curves;
 typedef double real;
 typedef Eigen::Vector3d point_t;
+typedef Eigen::Vector3d tangent_t;
+typedef std::pair<point_t, tangent_t> pair_point_tangent_t;
 typedef Eigen::Matrix<double, 6, 1, 0, 6, 1> point6_t;
 typedef Eigen::Matrix<double, 3, 1, 0, 3, 1> ret_point_t;
 typedef Eigen::Matrix<double, 6, 1, 0, 6, 1> ret_point6_t;
@@ -32,19 +35,20 @@ typedef std::pair<real, point_t> Waypoint;
 typedef std::vector<Waypoint> T_Waypoint;
 typedef std::pair<real, point6_t> Waypoint6;
 typedef std::vector<Waypoint6> T_Waypoint6;
+typedef std::vector<pair_point_tangent_t,Eigen::aligned_allocator<pair_point_tangent_t> > t_pair_point_tangent_t;
 
 typedef curves::bezier_curve  <real, real, 3, true, point_t> bezier3_t;
 typedef curves::bezier_curve  <real, real, 6, true, point6_t> bezier6_t;
-typedef curves::polynom  <real, real, 3, true, point_t, t_point_t> polynom_t;
+typedef curves::polynomial  <real, real, 3, true, point_t, t_point_t> polynomial_t;
+typedef curves::piecewise_polynomial_curve <real, real, 3, true, point_t, t_point_t> piecewise_polynomial_curve_t;
 typedef curves::exact_cubic  <real, real, 3, true, point_t, t_point_t> exact_cubic_t;
-typedef polynom_t::coeff_t coeff_t;
+typedef curves::cubic_hermite_spline <real, real, 3, true, point_t> cubic_hermite_spline_t;
+typedef polynomial_t::coeff_t coeff_t;
 typedef std::pair<real, point_t> waypoint_t;
 typedef std::vector<waypoint_t, Eigen::aligned_allocator<point_t> > t_waypoint_t;
 
 typedef curves::Bern<double> bernstein_t;
 
-
-typedef curves::spline_deriv_constraint  <real, real, 3, true, point_t, t_point_t> spline_deriv_constraint_t;
 typedef curves::curve_constraints<point_t> curve_constraints_t;
 typedef curves::curve_constraints<point6_t> curve_constraints6_t;
 /*** TEMPLATE SPECIALIZATION FOR PYTHON ****/
@@ -52,77 +56,119 @@ typedef curves::curve_constraints<point6_t> curve_constraints6_t;
 EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(bernstein_t)
 EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(bezier3_t)
 EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(bezier6_t)
-EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(polynom_t)
+EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(polynomial_t)
 EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(exact_cubic_t)
+EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(cubic_hermite_spline_t)
 EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(curve_constraints_t)
-EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(spline_deriv_constraint_t)
 
 namespace curves
 {
 using namespace boost::python;
 
+/* Template constructor bezier */
 template <typename Bezier, typename PointList, typename T_Point>
-Bezier* wrapBezierConstructorTemplate(const PointList& array, const real ub =1.)
+Bezier* wrapBezierConstructorTemplate(const PointList& array, const real T_min =0., const real T_max =1.)
 {
     T_Point asVector = vectorFromEigenArray<PointList, T_Point>(array);
-    return new Bezier(asVector.begin(), asVector.end(), ub);
+    return new Bezier(asVector.begin(), asVector.end(), T_min, T_max);
 }
 
 template <typename Bezier, typename PointList, typename T_Point, typename CurveConstraints>
-Bezier* wrapBezierConstructorConstraintsTemplate(const PointList& array, const CurveConstraints& constraints, const real ub =1.)
+Bezier* wrapBezierConstructorConstraintsTemplate(const PointList& array, const CurveConstraints& constraints, 
+                                                 const real T_min =0., const real T_max =1.)
 {
     T_Point asVector = vectorFromEigenArray<PointList, T_Point>(array);
-    return new Bezier(asVector.begin(), asVector.end(), constraints, ub);
+    return new Bezier(asVector.begin(), asVector.end(), constraints, T_min, T_max);
 }
+/* End Template constructor bezier */
 
-/*3D constructors */
+/*3D constructors bezier */
 bezier3_t* wrapBezierConstructor3(const point_list_t& array)
 {
     return wrapBezierConstructorTemplate<bezier3_t, point_list_t, t_point_t>(array) ;
 }
-bezier3_t* wrapBezierConstructorBounds3(const point_list_t& array, const real ub)
+bezier3_t* wrapBezierConstructorBounds3(const point_list_t& array, const real T_min, const real T_max)
 {
-    return wrapBezierConstructorTemplate<bezier3_t, point_list_t, t_point_t>(array, ub) ;
+    return wrapBezierConstructorTemplate<bezier3_t, point_list_t, t_point_t>(array, T_min, T_max) ;
 }
 bezier3_t* wrapBezierConstructor3Constraints(const point_list_t& array, const curve_constraints_t& constraints)
 {
     return wrapBezierConstructorConstraintsTemplate<bezier3_t, point_list_t, t_point_t, curve_constraints_t>(array, constraints) ;
 }
-bezier3_t* wrapBezierConstructorBounds3Constraints(const point_list_t& array, const curve_constraints_t& constraints, const real ub)
+bezier3_t* wrapBezierConstructorBounds3Constraints(const point_list_t& array, const curve_constraints_t& constraints,
+                                                   const real T_min, const real T_max)
 {
-    return wrapBezierConstructorConstraintsTemplate<bezier3_t, point_list_t, t_point_t, curve_constraints_t>(array, constraints, ub) ;
+    return wrapBezierConstructorConstraintsTemplate<bezier3_t, point_list_t, t_point_t, curve_constraints_t>(array, constraints, T_min, T_max) ;
 }
-/*END 3D constructors */
-/*6D constructors */
+/*END 3D constructors bezier */
+/*6D constructors bezier */
 bezier6_t* wrapBezierConstructor6(const point_list6_t& array)
 {
     return wrapBezierConstructorTemplate<bezier6_t, point_list6_t, t_point6_t>(array) ;
 }
-bezier6_t* wrapBezierConstructorBounds6(const point_list6_t& array, const real ub)
+bezier6_t* wrapBezierConstructorBounds6(const point_list6_t& array, const real T_min, const real T_max)
 {
-    return wrapBezierConstructorTemplate<bezier6_t, point_list6_t, t_point6_t>(array, ub) ;
+    return wrapBezierConstructorTemplate<bezier6_t, point_list6_t, t_point6_t>(array, T_min, T_max) ;
 }
 bezier6_t* wrapBezierConstructor6Constraints(const point_list6_t& array, const curve_constraints6_t& constraints)
 {
     return wrapBezierConstructorConstraintsTemplate<bezier6_t, point_list6_t, t_point6_t, curve_constraints6_t>(array, constraints) ;
 }
-bezier6_t* wrapBezierConstructorBounds6Constraints(const point_list6_t& array, const curve_constraints6_t& constraints, const real ub)
+bezier6_t* wrapBezierConstructorBounds6Constraints(const point_list6_t& array, const curve_constraints6_t& constraints, const real T_min, const real T_max)
+{
+    return wrapBezierConstructorConstraintsTemplate<bezier6_t, point_list6_t, t_point6_t, curve_constraints6_t>(array, constraints, T_min, T_max) ;
+}
+/*END 6D constructors bezier */
+
+/* Wrap Cubic hermite spline */
+t_pair_point_tangent_t getPairsPointTangent(const point_list_t& points, const point_list_t& tangents)
 {
-    return wrapBezierConstructorConstraintsTemplate<bezier6_t, point_list6_t, t_point6_t, curve_constraints6_t>(array, constraints, ub) ;
+    t_pair_point_tangent_t res;
+    if (points.size() != tangents.size())
+    {
+        throw std::length_error("size of points and tangents must be the same");
+    }
+    for(int i =0;i<points.cols();++i) 
+    {
+        res.push_back(pair_point_tangent_t(tangents.col(i), tangents.col(i)));
+    }
+    return res;
 }
-/*END 6D constructors */
 
-polynom_t* wrapSplineConstructor(const coeff_t& array)
+cubic_hermite_spline_t* wrapCubicHermiteSplineConstructor(const point_list_t& points, const point_list_t& tangents, const time_waypoints_t& time_pts) 
 {
-    return new polynom_t(array, 0., 1.);
+    t_pair_point_tangent_t ppt = getPairsPointTangent(points, tangents);
+    std::vector<real> time_control_pts;
+    for( int i =0; i<time_pts.size(); ++i)
+    {
+        time_control_pts.push_back(time_pts[i]);
+    }
+    return new cubic_hermite_spline_t(ppt.begin(), ppt.end(), time_control_pts);
 }
+/* End wrap Cubic hermite spline */
 
+/* Wrap polynomial */
+polynomial_t* wrapSplineConstructor(const coeff_t& array)
+{
+    return new polynomial_t(array, 0., 1.);
+}
+/* End wrap polynomial */
 
+/* Wrap piecewise polynomial curve */
+piecewise_polynomial_curve_t* wrapPiecewisePolynomialCurveConstructor(const polynomial_t& pol)
+{
+    return new piecewise_polynomial_curve_t(pol);
+}
+/* end wrap piecewise polynomial curve */
+
+/* Wrap exact cubic spline */
 t_waypoint_t getWayPoints(const coeff_t& array, const time_waypoints_t& time_wp)
 {
     t_waypoint_t res;
-    for(int i =0;i<array.cols();++i)
+    for(int i =0;i<array.cols();++i) 
+    {
         res.push_back(std::make_pair(time_wp(i), array.col(i)));
+    }
     return res;
 }
 
@@ -135,7 +181,9 @@ Eigen::Matrix<real, Eigen::Dynamic, Eigen::Dynamic> wayPointsToList(const Bezier
     Eigen::Matrix<real, Eigen::Dynamic, Eigen::Dynamic> res (dim, wps.size());
     int col = 0;
     for(cit_point cit = wps.begin(); cit != wps.end(); ++cit, ++col)
+    {
         res.block<dim,1>(0,col) = *cit;
+    }
     return res;
 }
 
@@ -145,17 +193,10 @@ exact_cubic_t* wrapExactCubicConstructor(const coeff_t& array, const time_waypoi
     return new exact_cubic_t(wps.begin(), wps.end());
 }
 
-
-spline_deriv_constraint_t* wrapSplineDerivConstraint(const coeff_t& array, const time_waypoints_t& time_wp, const curve_constraints_t& constraints)
-{
-    t_waypoint_t wps = getWayPoints(array, time_wp);
-    return new spline_deriv_constraint_t(wps.begin(), wps.end(),constraints);
-}
-
-spline_deriv_constraint_t* wrapSplineDerivConstraintNoConstraints(const coeff_t& array, const time_waypoints_t& time_wp)
+exact_cubic_t* wrapExactCubicConstructorConstraint(const coeff_t& array, const time_waypoints_t& time_wp, const curve_constraints_t& constraints)
 {
     t_waypoint_t wps = getWayPoints(array, time_wp);
-    return new spline_deriv_constraint_t(wps.begin(), wps.end());
+    return new exact_cubic_t(wps.begin(), wps.end(), constraints);
 }
 
 point_t get_init_vel(const curve_constraints_t& c)
@@ -197,7 +238,7 @@ void set_end_acc(curve_constraints_t& c, const point_t& val)
 {
     c.end_acc = val;
 }
-
+/* End wrap exact cubic spline */
 
 
 BOOST_PYTHON_MODULE(curves)
@@ -286,27 +327,55 @@ BOOST_PYTHON_MODULE(curves)
     /** END variable points bezier curve**/
 
 
-    /** BEGIN spline curve function**/
-    class_<polynom_t>("polynom",  init<const polynom_t::coeff_t, const real, const real >())
+    /** BEGIN polynomial curve function**/
+    class_<polynomial_t>("polynomial",  init<const polynomial_t::coeff_t, const real, const real >())
             .def("__init__", make_constructor(&wrapSplineConstructor))
-            .def("min", &polynom_t::min)
-            .def("max", &polynom_t::max)
-            .def("__call__", &polynom_t::operator())
-            .def("derivate", &polynom_t::derivate)
+            .def("min", &polynomial_t::min)
+            .def("max", &polynomial_t::max)
+            .def("__call__", &polynomial_t::operator())
+            .def("derivate", &polynomial_t::derivate)
+        ;
+    /** END polynomial function**/
+
+    /** BEGIN piecewise polynomial curve function **/
+    class_<piecewise_polynomial_curve_t>
+        ("piecewise_polynomial_curve", no_init)
+            .def("__init__", make_constructor(&wrapPiecewisePolynomialCurveConstructor))
+            .def("min", &piecewise_polynomial_curve_t::min)
+            .def("max", &piecewise_polynomial_curve_t::max)
+            .def("__call__", &piecewise_polynomial_curve_t::operator())
+            .def("derivate", &piecewise_polynomial_curve_t::derivate)
+            .def("add_polynomial_curve", &piecewise_polynomial_curve_t::add_polynomial_curve)
+            .def("is_continuous", &piecewise_polynomial_curve_t::is_continuous)
         ;
-    /** END cubic function**/
+    /** END piecewise polynomial curve function **/
 
 
     /** BEGIN exact_cubic curve**/
     class_<exact_cubic_t>
         ("exact_cubic", no_init)
             .def("__init__", make_constructor(&wrapExactCubicConstructor))
+            .def("__init__", make_constructor(&wrapExactCubicConstructorConstraint))
             .def("min", &exact_cubic_t::min)
             .def("max", &exact_cubic_t::max)
             .def("__call__", &exact_cubic_t::operator())
             .def("derivate", &exact_cubic_t::derivate)
+            .def("getNumberSplines", &exact_cubic_t::getNumberSplines)
+            .def("getSplineAt", &exact_cubic_t::getSplineAt)
         ;
-    /** END bezier curve**/
+    /** END exact_cubic curve**/
+
+
+    /** BEGIN cubic_hermite_spline **/
+    class_<cubic_hermite_spline_t>
+        ("cubic_hermite_spline", no_init)
+            .def("__init__", make_constructor(&wrapCubicHermiteSplineConstructor))
+            .def("min", &cubic_hermite_spline_t::min)
+            .def("max", &cubic_hermite_spline_t::max)
+            .def("__call__", &cubic_hermite_spline_t::operator())
+            .def("derivate", &cubic_hermite_spline_t::derivate)
+        ;
+    /** END cubic_hermite_spline **/
 
 
     /** BEGIN curve constraints**/
@@ -319,29 +388,21 @@ BOOST_PYTHON_MODULE(curves)
         ;
     /** END curve constraints**/
 
-
-    /** BEGIN spline_deriv_constraints**/
-    class_<spline_deriv_constraint_t>
-        ("spline_deriv_constraint", no_init)
-            .def("__init__", make_constructor(&wrapSplineDerivConstraint))
-            .def("__init__", make_constructor(&wrapSplineDerivConstraintNoConstraints))
-            .def("min", &exact_cubic_t::min)
-            .def("max", &exact_cubic_t::max)
-            .def("__call__", &exact_cubic_t::operator())
-            .def("derivate", &exact_cubic_t::derivate)
-        ;
-    /** END spline_deriv_constraints**/
-
-    /** BEGIN bernstein polynom**/
+    /** BEGIN bernstein polynomial**/
     class_<bernstein_t>
         ("bernstein", init<const unsigned int, const unsigned int>())
             .def("__call__", &bernstein_t::operator())
         ;
-    /** END bernstein polynom**/
-
-    /** BEGIN Bezier to polynom conversion**/
-    def("from_bezier", from_bezier<bezier3_t,polynom_t>);
-    /** END Bezier to polynom conversion**/
+    /** END bernstein polynomial**/
+
+    /** BEGIN curves conversion**/
+    def("polynomial_from_bezier", polynomial_from_curve<polynomial_t,bezier3_t>);
+    def("polynomial_from_hermite", polynomial_from_curve<polynomial_t,cubic_hermite_spline_t>);
+    def("bezier_from_hermite", bezier_from_curve<bezier3_t,cubic_hermite_spline_t>);
+    def("bezier_from_polynomial", bezier_from_curve<bezier3_t,polynomial_t>);
+    def("hermite_from_bezier", hermite_from_curve<cubic_hermite_spline_t, bezier3_t>);
+    def("hermite_from_polynomial", hermite_from_curve<cubic_hermite_spline_t, polynomial_t>);
+    /** END curves conversion**/
 
 
 }
diff --git a/python/python_definitions.h b/python/python_definitions.h
index d1b13a0d007dbf6335a2ca0baf62070fc90567a2..8c4b3d674e6e965191f70b74243c187a356a379c 100644
--- a/python/python_definitions.h
+++ b/python/python_definitions.h
@@ -12,7 +12,9 @@ namespace curves
 
 typedef double real;
 typedef Eigen::Vector3d point_t;
+typedef Eigen::Vector3d tangent_t;
 typedef Eigen::VectorXd vectorX_t;
+typedef std::pair<point_t, tangent_t> pair_point_tangent_t;
 typedef Eigen::Matrix<double, 6, 1, 0, 6, 1> point6_t;
 typedef Eigen::Matrix<double, 3, 1, 0, 3, 1> ret_point_t;
 typedef Eigen::Matrix<double, 6, 1, 0, 6, 1> ret_point6_t;
@@ -33,7 +35,9 @@ T_Point vectorFromEigenArray(const PointList& array)
 {
     T_Point res;
     for(int i =0;i<array.cols();++i)
+    {
         res.push_back(array.col(i));
+    }
     return res;
 }
 
diff --git a/python/python_variables.cpp b/python/python_variables.cpp
index 715c0d9550847c4645aacf863eb1a598e8ce0f2e..8306be298b6c831cb0cd2f3037350c8647e1d88e 100644
--- a/python/python_variables.cpp
+++ b/python/python_variables.cpp
@@ -12,7 +12,9 @@ std::vector<linear_variable_3_t> matrix3DFromEigenArray(const point_list_t& matr
     assert(vectors.cols() * 3  == matrices.cols() ) ;
     std::vector<linear_variable_3_t> res;
     for(int i =0;i<vectors.cols();++i)
+    {
         res.push_back(linear_variable_3_t(matrices.block<3,3>(0,i*3), vectors.col(i)));
+    }
     return res;
 }
 
@@ -21,10 +23,14 @@ variables_3_t fillWithZeros(const linear_variable_3_t& var, const std::size_t to
     variables_3_t res;
     std::vector<linear_variable_3_t>& vars = res.variables_;
     for (std::size_t idx = 0; idx < i; ++idx)
+    {
         vars.push_back(linear_variable_3_t::Zero());
+    }
     vars.push_back(var);
     for (std::size_t idx = i+1; idx < totalvar; ++idx)
+    {
         vars.push_back(linear_variable_3_t::Zero());
+    }
     return res;
 }
 
@@ -35,7 +41,9 @@ std::vector<variables_3_t> computeLinearControlPoints(const point_list_t& matric
     // now need to fill all this with zeros...
     std::size_t totalvar = variables.size();
     for (std::size_t i = 0; i < totalvar; ++i)
+    {
         res.push_back( fillWithZeros(variables[i],totalvar,i));
+    }
     return res;
 }
 
@@ -43,18 +51,17 @@ std::vector<variables_3_t> computeLinearControlPoints(const point_list_t& matric
 bezier_linear_variable_t* wrapBezierLinearConstructor(const point_list_t& matrices, const point_list_t& vectors)
 {
     std::vector<variables_3_t> asVector = computeLinearControlPoints(matrices, vectors);
-    return new bezier_linear_variable_t(asVector.begin(), asVector.end(), 1.) ;
+    return new bezier_linear_variable_t(asVector.begin(), asVector.end(), 0., 1.) ;
 }
 
-bezier_linear_variable_t* wrapBezierLinearConstructorBounds(const point_list_t& matrices, const point_list_t& vectors, const real ub)
+bezier_linear_variable_t* wrapBezierLinearConstructorBounds(const point_list_t& matrices, const point_list_t& vectors, const real T_min, const real T_max)
 {
     std::vector<variables_3_t> asVector = computeLinearControlPoints(matrices, vectors);
-    return new bezier_linear_variable_t(asVector.begin(), asVector.end(), ub) ;
+    return new bezier_linear_variable_t(asVector.begin(), asVector.end(), T_min, T_max) ;
 }
 
 
-LinearControlPointsHolder*
-        wayPointsToLists(const bezier_linear_variable_t& self)
+LinearControlPointsHolder* wayPointsToLists(const bezier_linear_variable_t& self)
 {
     typedef typename bezier_linear_variable_t::t_point_t t_point;
     typedef typename bezier_linear_variable_t::t_point_t::const_iterator cit_point;
diff --git a/python/python_variables.h b/python/python_variables.h
index 393284204cb61610870e2a041f69445cec7a54e4..d369c20fb9a4dab6ac885d575fb7c175cc84afcc 100644
--- a/python/python_variables.h
+++ b/python/python_variables.h
@@ -21,7 +21,7 @@ typedef curves::bezier_curve  <real, real, dim, true, variables_3_t> bezier_line
 bezier_linear_variable_t* wrapBezierLinearConstructor(const point_list_t& matrices, const point_list_t& vectors);
 
 bezier_linear_variable_t* wrapBezierLinearConstructorBounds
-    (const point_list_t& matrices, const point_list_t& vectors, const real ub);
+    (const point_list_t& matrices, const point_list_t& vectors, const real T_min, const real T_max);
 
 typedef std::pair<Eigen::Matrix<real, Eigen::Dynamic, Eigen::Dynamic>,
                   Eigen::Matrix<real, Eigen::Dynamic, Eigen::Dynamic> > linear_points_t;
diff --git a/python/test/test.py b/python/test/test.py
index 4c93b48b0aaea71e1ffa3b640dcc58e30e822f01..49eb020fc5061060095e2711e8efe36be5b65550 100644
--- a/python/test/test.py
+++ b/python/test/test.py
@@ -9,8 +9,11 @@ from numpy.linalg import norm
 
 import unittest
 
-from curves import bezier3, bezier6, curve_constraints, exact_cubic, from_bezier, polynom, spline_deriv_constraint
-
+from curves import bezier3, bezier6
+from curves import curve_constraints, polynomial, piecewise_polynomial_curve, exact_cubic, cubic_hermite_spline
+from curves import polynomial_from_bezier, polynomial_from_hermite
+from curves import bezier_from_hermite, bezier_from_polynomial
+from curves import hermite_from_bezier, hermite_from_polynomial
 
 class TestCurves(unittest.TestCase):
 	#def print_str(self, inStr):
@@ -23,7 +26,7 @@ class TestCurves(unittest.TestCase):
 		# - Variables : degree, nbWayPoints
 		__EPS = 1e-6
 		waypoints = matrix([[1., 2., 3.]]).T
-		a = bezier3(waypoints,2.)
+		a = bezier3(waypoints,0.,2.)
 		t = 0.
 		while t < 2.:
 			self.assertTrue (norm(a(t) - matrix([1., 2., 3.]).T) < __EPS)
@@ -33,7 +36,7 @@ class TestCurves(unittest.TestCase):
 		time_waypoints = matrix([0., 1.]).transpose()
 		# Create bezier6 and bezier3
 		a = bezier6(waypoints6)
-		a = bezier3(waypoints, 3.)
+		a = bezier3(waypoints, 0., 3.)
 		# Test : Degree, min, max, derivate
 		#self.print_str(("test 1")
 		self.assertEqual (a.degree, a.nbWaypoints - 1)
@@ -58,7 +61,7 @@ class TestCurves(unittest.TestCase):
 		# Create new bezier3 curve
 		waypoints = matrix([[1., 2., 3.], [4., 5., 6.], [4., 5., 6.], [4., 5., 6.], [4., 5., 6.]]).transpose()
 		a0 = bezier3(waypoints)
-		a1 = bezier3(waypoints, 3.)
+		a1 = bezier3(waypoints, 0., 3.)
 		prim0 = a0.compute_primitive(1)
 		prim1 = a1.compute_primitive(1)
 		# Check change in argument time_t of bezier3
@@ -82,12 +85,12 @@ class TestCurves(unittest.TestCase):
 		self.assertTrue (norm(a.derivate(1, 2) - c.end_acc) < 1e-10)
 		return
 
-	def test_polynom(self):
+	def test_polynomial(self):
 		# To test :
 		# - Functions : constructor, min, max, derivate
 		waypoints = matrix([[1., 2., 3.], [4., 5., 6.]]).transpose()
-		a = polynom(waypoints)
-		a = polynom(waypoints, -1., 3.)
+		a = polynomial(waypoints) # Defined on [0.,1.]
+		a = polynomial(waypoints, -1., 3.) # Defined on [-1.,3.]
 		a.min()
 		a.max()
 		a(0.4)
@@ -95,9 +98,27 @@ class TestCurves(unittest.TestCase):
 		a.derivate(0.4, 2)
 		return
 
+	def test_piecewise_polynomial_curve(self):
+		# To test :
+		# - Functions : constructor, min, max, derivate, add_polynomial_curve, is_continuous
+		waypoints1 = matrix([[1., 1., 1.]]).transpose()
+		waypoints2 = matrix([[1., 1., 1.], [1., 1., 1.]]).transpose()
+		a = polynomial(waypoints1, 0.,1.)
+		b = polynomial(waypoints2, 1., 3.)
+		ppc = piecewise_polynomial_curve(a)
+		ppc.add_polynomial_curve(b)
+		ppc.min()
+		ppc.max()
+		ppc(0.4)
+		self.assertTrue ((ppc.derivate(0.4, 0) == ppc(0.4)).all())
+		ppc.derivate(0.4, 2)
+		ppc.is_continuous(0)
+		ppc.is_continuous(1)
+		return
+
 	def test_exact_cubic(self):
 		# To test :
-		# - Functions : constructor, min, max, derivate
+		# - Functions : constructor, min, max, derivate, getNumberSplines, getSplineAt
 		waypoints = matrix([[1., 2., 3.], [4., 5., 6.]]).transpose()
 		time_waypoints = matrix([0., 1.]).transpose()
 		a = exact_cubic(waypoints, time_waypoints)
@@ -106,9 +127,11 @@ class TestCurves(unittest.TestCase):
 		a(0.4)
 		self.assertTrue ((a.derivate(0.4, 0) == a(0.4)).all())
 		a.derivate(0.4, 2)
+		a.getNumberSplines()
+		a.getSplineAt(0)
 		return
 
-	def test_spline_deriv_constraint(self):
+	def test_exact_cubic_constraint(self):
 		# To test :
 		# - Functions : constructor, min, max, derivate
 		waypoints = matrix([[1., 2., 3.], [4., 5., 6.]]).transpose()
@@ -122,17 +145,46 @@ class TestCurves(unittest.TestCase):
 		c.end_vel = matrix([0., 1., 1.]).transpose()
 		c.init_acc = matrix([0., 1., 1.]).transpose()
 		c.end_acc = matrix([0., 1., 1.]).transpose()
-		a = spline_deriv_constraint(waypoints, time_waypoints)
-		a = spline_deriv_constraint(waypoints, time_waypoints, c)
+		a = exact_cubic(waypoints, time_waypoints)
+		a = exact_cubic(waypoints, time_waypoints, c)
+		return
+
+	def test_cubic_hermite_spline(self):
+		points = matrix([[1., 2., 3.], [4., 5., 6.]]).transpose()
+		tangents = matrix([[1., 2., 3.], [4., 5., 6.]]).transpose()
+		time_points = matrix([0., 1.]).transpose()
+		a = cubic_hermite_spline(points, tangents, time_points)
+		a.min()
+		a.max()
+		a(0.4)
+		self.assertTrue ((a.derivate(0.4, 0) == a(0.4)).all())
+		a.derivate(0.4, 2)
 		return
 
-	def test_from_bezier(self):
-		# converting bezier to polynom
+	def test_conversion_curves(self):
 		__EPS = 1e-6
 		waypoints = matrix([[1., 2., 3.], [4., 5., 6.]]).transpose()
 		a = bezier3(waypoints)
-		a_pol = from_bezier(a)
+		# converting bezier to polynomial
+		a_pol = polynomial_from_bezier(a)
 		self.assertTrue (norm(a(0.3) - a_pol(0.3)) < __EPS)
+		# converting polynomial to hermite
+		a_chs = hermite_from_polynomial(a_pol);
+		self.assertTrue (norm(a_chs(0.3) - a_pol(0.3)) < __EPS)
+		# converting hermite to bezier
+		a_bc = bezier_from_hermite(a_chs);
+		self.assertTrue (norm(a_chs(0.3) - a_bc(0.3)) < __EPS)
+		self.assertTrue (norm(a(0.3) - a_bc(0.3)) < __EPS)
+		# converting bezier to hermite
+		a_chs = hermite_from_bezier(a);
+		self.assertTrue (norm(a(0.3) - a_chs(0.3)) < __EPS)
+		# converting hermite to polynomial
+		a_pol = polynomial_from_hermite(a_chs)
+		self.assertTrue (norm(a_pol(0.3) - a_chs(0.3)) < __EPS)
+		# converting polynomial to bezier
+		a_bc = bezier_from_polynomial(a_pol)
+		self.assertTrue (norm(a_bc(0.3) - a_pol(0.3)) < __EPS)
+		self.assertTrue (norm(a(0.3) - a_bc(0.3)) < __EPS)
 		return
 
 if __name__ == '__main__':
diff --git a/tests/Main.cpp b/tests/Main.cpp
index 162e20261e32065dc6b6ba9fa68835bd4e1767ed..20afa1fa6ecaa10d45d61484c76e871f0625a350 100644
--- a/tests/Main.cpp
+++ b/tests/Main.cpp
@@ -1,11 +1,12 @@
 
 #include "curves/exact_cubic.h"
 #include "curves/bezier_curve.h"
-#include "curves/polynom.h"
-#include "curves/spline_deriv_constraint.h"
+#include "curves/polynomial.h"
 #include "curves/helpers/effector_spline.h"
 #include "curves/helpers/effector_spline_rotation.h"
-#include "curves/bezier_polynom_conversion.h"
+#include "curves/curve_conversion.h"
+#include "curves/cubic_hermite_spline.h"
+#include "curves/piecewise_polynomial_curve.h"
 
 #include <string>
 #include <iostream>
@@ -16,22 +17,29 @@ using namespace std;
 namespace curves
 {
 typedef Eigen::Vector3d point_t;
+typedef Eigen::Vector3d tangent_t;
 typedef std::vector<point_t,Eigen::aligned_allocator<point_t> >  t_point_t;
-typedef polynom  <double, double, 3, true, point_t, t_point_t> polynom_t;
+typedef polynomial  <double, double, 3, true, point_t, t_point_t> polynomial_t;
 typedef exact_cubic <double, double, 3, true, point_t> exact_cubic_t;
-typedef spline_deriv_constraint <double, double, 3, true, point_t> spline_deriv_constraint_t;
 typedef bezier_curve  <double, double, 3, true, point_t> bezier_curve_t;
-typedef spline_deriv_constraint_t::spline_constraints spline_constraints_t;
+typedef exact_cubic_t::spline_constraints spline_constraints_t;
 typedef std::pair<double, point_t> Waypoint;
 typedef std::vector<Waypoint> T_Waypoint;
 
 
 typedef Eigen::Matrix<double,1,1> point_one;
-typedef polynom<double, double, 1, true, point_one> polynom_one;
+typedef polynomial<double, double, 1, true, point_one> polynom_one;
 typedef exact_cubic   <double, double, 1, true, point_one> exact_cubic_one;
 typedef std::pair<double, point_one> WaypointOne;
 typedef std::vector<WaypointOne> T_WaypointOne;
 
+typedef cubic_hermite_spline <double, double, 3, true, point_t> cubic_hermite_spline_t;
+typedef std::pair<point_t, tangent_t> pair_point_tangent_t;
+typedef std::vector<pair_point_tangent_t,Eigen::aligned_allocator<pair_point_tangent_t> > t_pair_point_tangent_t;
+
+typedef piecewise_polynomial_curve <double, double, 3, true, point_t> piecewise_polynomial_curve_t;
+
+
 bool QuasiEqual(const double a, const double b, const float margin)
 {
 	if ((a <= 0 && b <= 0) || (a >= 0 && b>= 0))
@@ -65,8 +73,32 @@ void ComparePoints(const Eigen::VectorXd& pt1, const Eigen::VectorXd& pt2, const
 	}
 }
 
-/*Cubic Function tests*/
+template<typename curve1, typename curve2>
+void compareCurves(curve1 c1, curve2 c2, const std::string& errMsg, bool& error)
+{
+    double T_min = c1.min();
+    double T_max = c1.max();
+    if (T_min!=c2.min() || T_max!=c2.max())
+    {
+        std::cout << "compareCurves, time min and max of curves does not match ["<<T_min<<","<<T_max<<"] " 
+                << " and ["<<c2.min()<<","<<c2.max()<<"] "<<std::endl;
+        error = true;
+    }
+    else
+    {
+        // derivative in T_min and T_max
+        ComparePoints(c1.derivate(T_min,1),c2.derivate(T_min,1),errMsg, error, false);
+        ComparePoints(c1.derivate(T_max,1),c2.derivate(T_max,1),errMsg, error, false);
+        // Test values on curves
+        for(double i =T_min; i<T_max; i+=0.02)
+        {
+            ComparePoints(c1(i),c2(i),errMsg, error, false);
+            ComparePoints(c1(i),c2(i),errMsg, error, false);
+        }
+    }
+}
 
+/*Cubic Function tests*/
 void CubicFunctionTest(bool& error)
 {
     std::string errMsg("In test CubicFunctionTest ; unexpected result for x ");
@@ -79,7 +111,7 @@ void CubicFunctionTest(bool& error)
     vec.push_back(b);
     vec.push_back(c);
     vec.push_back(d);
-    polynom_t cf(vec.begin(), vec.end(), 0, 1);
+    polynomial_t cf(vec.begin(), vec.end(), 0, 1);
     point_t res1;
     res1 =cf(0);
     point_t x0(1,2,3);
@@ -98,7 +130,7 @@ void CubicFunctionTest(bool& error)
     vec.push_back(b);
     vec.push_back(c);
     vec.push_back(d);
-    polynom_t cf2(vec, 0.5, 1);
+    polynomial_t cf2(vec, 0.5, 1);
     res1 = cf2(0.5);
     ComparePoints(x0, res1, errMsg + "x3 ", error);
     error = true;
@@ -130,68 +162,64 @@ void CubicFunctionTest(bool& error)
     if(cf.max() != 1)
     {
         error = true;
-        std::cout << "Evaluation of exactCubic error, MaxBound should be equal to 1\n";
+        std::cout << "Evaluation of cubic cf error, MaxBound should be equal to 1\n";
     }
     if(cf.min() != 0)
     {
         error = true;
-        std::cout << "Evaluation of exactCubic error, MinBound should be equal to 1\n";
+        std::cout << "Evaluation of cubic cf error, MinBound should be equal to 1\n";
     }
 }
 
 /*bezier_curve Function tests*/
-
 void BezierCurveTest(bool& error)
 {
-	std::string errMsg("In test BezierCurveTest ; unexpected result for x ");
-	point_t a(1,2,3);
-	point_t b(2,3,4);
-	point_t c(3,4,5);
-	point_t d(3,6,7);
+    std::string errMsg("In test BezierCurveTest ; unexpected result for x ");
+    point_t a(1,2,3);
+    point_t b(2,3,4);
+    point_t c(3,4,5);
+    point_t d(3,6,7);
 
-	std::vector<point_t> params;
-	params.push_back(a);
+    std::vector<point_t> params;
+    params.push_back(a);
 
-  // 1d curve
-  bezier_curve_t cf1(params.begin(), params.end());
-  point_t res1;
-  res1 = cf1(0);
-  point_t x10 = a ;
+    // 1d curve in [0,1]
+    bezier_curve_t cf1(params.begin(), params.end());
+    point_t res1;
+    res1 = cf1(0);
+    point_t x10 = a ;
     ComparePoints(x10, res1, errMsg + "1(0) ", error);
-  res1 =  cf1(1);
+    res1 =  cf1(1);
     ComparePoints(x10, res1, errMsg + "1(1) ", error);
 
-	// 2d curve
-  params.push_back(b);
-  bezier_curve_t cf(params.begin(), params.end());
-  res1 = cf(0);
-	point_t x20 = a ;
+    // 2d curve in [0,1]
+    params.push_back(b);
+    bezier_curve_t cf(params.begin(), params.end());
+    res1 = cf(0);
+    point_t x20 = a ;
     ComparePoints(x20, res1, errMsg + "2(0) ", error);
 
-	point_t x21 = b;
-  res1 = cf(1);
+    point_t x21 = b;
+    res1 = cf(1);
     ComparePoints(x21, res1, errMsg + "2(1) ", error);
 
-	//3d curve
-	params.push_back(c);
-	bezier_curve_t cf3(params.begin(), params.end());
-	res1 = cf3(0);
+    //3d curve in [0,1]
+    params.push_back(c);
+    bezier_curve_t cf3(params.begin(), params.end());
+    res1 = cf3(0);
     ComparePoints(a, res1, errMsg + "3(0) ", error);
 
-	res1 = cf3(1);
+    res1 = cf3(1);
     ComparePoints(c, res1, errMsg + "3(1) ", error);
 
-	//4d curve
-	params.push_back(d);
-    bezier_curve_t cf4(params.begin(), params.end(), 2);
-
-	res1 = cf4(2);
-    ComparePoints(d, res1, errMsg + "3(1) ", error);
+    //4d curve in [1,2]
+    params.push_back(d);
+    bezier_curve_t cf4(params.begin(), params.end(), 1., 2.);
 
-    //testing bernstein polynomes
-    bezier_curve_t cf5(params.begin(), params.end(),2.);
-    std::string errMsg2("In test BezierCurveTest ; Bernstein polynoms do not evaluate as analytical evaluation");
-    for(double d = 0.; d <2.; d+=0.1)
+    //testing bernstein polynomials
+    bezier_curve_t cf5(params.begin(), params.end(),1.,2.);
+    std::string errMsg2("In test BezierCurveTest ; Bernstein polynomials do not evaluate as analytical evaluation");
+    for(double d = 1.; d <2.; d+=0.1)
     {
         ComparePoints( cf5.evalBernstein(d) , cf5 (d), errMsg2, error);
         ComparePoints( cf5.evalHorner(d) , cf5 (d), errMsg2, error);
@@ -200,11 +228,11 @@ void BezierCurveTest(bool& error)
     }
 
     bool error_in(true);
+
 	try
 	{
 		cf(-0.4);
-	}
-	catch(...)
+	} catch(...)
 	{
         error_in = false;
 	}
@@ -214,11 +242,11 @@ void BezierCurveTest(bool& error)
         error = true;
 	}
     error_in = true;
+
 	try
 	{
 		cf(1.1);
-	}
-	catch(...)
+	} catch(...)
 	{
         error_in = false;
 	}
@@ -230,17 +258,17 @@ void BezierCurveTest(bool& error)
 	if(cf.max() != 1)
 	{
 		error = true;
-		std::cout << "Evaluation of exactCubic error, MaxBound should be equal to 1\n";
+		std::cout << "Evaluation of bezier cf error, MaxBound should be equal to 1\n";
 	}
 	if(cf.min() != 0)
 	{
 		error = true;
-		std::cout << "Evaluation of exactCubic error, MinBound should be equal to 1\n";
+		std::cout << "Evaluation of bezier cf error, MinBound should be equal to 1\n";
 	}
 }
 
 #include <ctime>
-void BezierCurveTestCompareHornerAndBernstein(bool& /*error*/)
+void BezierCurveTestCompareHornerAndBernstein(bool&) // error
 {
     using namespace std;
     std::vector<double> values;
@@ -264,8 +292,9 @@ void BezierCurveTestCompareHornerAndBernstein(bool& /*error*/)
     params.push_back(c);
 
     // 3d curve
-    bezier_curve_t cf(params.begin(), params.end());
+    bezier_curve_t cf(params.begin(), params.end()); // defined in [0,1]
 
+    // Check all evaluation of bezier curve
     clock_t s0,e0,s1,e1,s2,e2,s3,e3;
     s0 = clock();
     for(std::vector<double>::const_iterator cit = values.begin(); cit != values.end(); ++cit)
@@ -295,14 +324,12 @@ void BezierCurveTestCompareHornerAndBernstein(bool& /*error*/)
     }
     e3 = clock();
 
-
     std::cout << "time for analytical eval  " <<   double(e0 - s0) / CLOCKS_PER_SEC << std::endl;
     std::cout << "time for bernstein eval   "  <<   double(e1 - s1) / CLOCKS_PER_SEC << std::endl;
     std::cout << "time for horner eval      "     <<   double(e2 - s2) / CLOCKS_PER_SEC << std::endl;
     std::cout << "time for deCasteljau eval "     <<   double(e3 - s3) / CLOCKS_PER_SEC << std::endl;
 
-    std::cout << "now with high order polynom "    << std::endl;
-
+    std::cout << "now with high order polynomial "    << std::endl;
 
     params.push_back(d);
     params.push_back(e);
@@ -341,8 +368,6 @@ void BezierCurveTestCompareHornerAndBernstein(bool& /*error*/)
     }
     e3 = clock();
 
-
-
     std::cout << "time for analytical eval  " <<   double(e0 - s0) / CLOCKS_PER_SEC << std::endl;
     std::cout << "time for bernstein eval   "  <<   double(e1 - s1) / CLOCKS_PER_SEC << std::endl;
     std::cout << "time for horner eval      "     <<   double(e2 - s2) / CLOCKS_PER_SEC << std::endl;
@@ -352,7 +377,7 @@ void BezierCurveTestCompareHornerAndBernstein(bool& /*error*/)
 
 void BezierDerivativeCurveTest(bool& error)
 {
-    std::string errMsg("In test BezierDerivativeCurveTest ; unexpected result for x ");
+    std::string errMsg("In test BezierDerivativeCurveTest ;, Error While checking value of point on curve : ");
     point_t a(1,2,3);
     point_t b(2,3,4);
     point_t c(3,4,5);
@@ -371,7 +396,7 @@ void BezierDerivativeCurveTest(bool& error)
 
 void BezierDerivativeCurveTimeReparametrizationTest(bool& error)
 {
-    std::string errMsg("In test BezierDerivativeCurveTimeReparametrizationTest ; unexpected result for x ");
+    std::string errMsg("In test BezierDerivativeCurveTimeReparametrizationTest, Error While checking value of point on curve : ");
     point_t a(1,2,3);
     point_t b(2,3,4);
     point_t c(3,4,5);
@@ -386,18 +411,20 @@ void BezierDerivativeCurveTimeReparametrizationTest(bool& error)
     params.push_back(d);
     params.push_back(e);
     params.push_back(f);
-    double T = 2.;
+    double Tmin = 0.;
+    double Tmax = 2.;
+    double diffT = Tmax-Tmin;
     bezier_curve_t cf(params.begin(), params.end());
-    bezier_curve_t cfT(params.begin(), params.end(),T);
+    bezier_curve_t cfT(params.begin(), params.end(),Tmin,Tmax);
 
     ComparePoints(cf(0.5), cfT(1), errMsg, error);
-    ComparePoints(cf.derivate(0.5,1), cfT.derivate(1,1) * T, errMsg, error);
-    ComparePoints(cf.derivate(0.5,2), cfT.derivate(1,2) * T*T, errMsg, error);
+    ComparePoints(cf.derivate(0.5,1), cfT.derivate(1,1) * (diffT), errMsg, error);
+    ComparePoints(cf.derivate(0.5,2), cfT.derivate(1,2) * diffT*diffT, errMsg, error);
 }
 
 void BezierDerivativeCurveConstraintTest(bool& error)
 {
-    std::string errMsg("In test BezierDerivativeCurveConstraintTest ; unexpected result for x ");
+    std::string errMsg("In test BezierDerivativeCurveConstraintTest, Error While checking value of point on curve : ");
     point_t a(1,2,3);
     point_t b(2,3,4);
     point_t c(3,4,5);
@@ -411,26 +438,29 @@ void BezierDerivativeCurveConstraintTest(bool& error)
     std::vector<point_t> params;
     params.push_back(a);
     params.push_back(b);
-
     params.push_back(c);
-    bezier_curve_t cf3(params.begin(), params.end(), constraints);
 
-    assert(cf3.degree_ == params.size() + 3);
-    assert(cf3.size_   == params.size() + 4);
+    bezier_curve_t::num_t T_min = 1.0;
+    bezier_curve_t::num_t T_max = 3.0;
+    bezier_curve_t cf(params.begin(), params.end(), constraints, T_min, T_max);
+
+    assert(cf.degree_ == params.size() + 3);
+    assert(cf.size_   == params.size() + 4);
 
-    ComparePoints(a, cf3(0), errMsg, error);
-    ComparePoints(c, cf3(1), errMsg, error);
-    ComparePoints(constraints.init_vel, cf3.derivate(0.,1), errMsg, error);
-    ComparePoints(constraints.end_vel , cf3.derivate(1.,1), errMsg, error);
-    ComparePoints(constraints.init_acc, cf3.derivate(0.,2), errMsg, error);
-    ComparePoints(constraints.end_vel, cf3.derivate(1.,1), errMsg, error);
-    ComparePoints(constraints.end_acc, cf3.derivate(1.,2), errMsg, error);
+    ComparePoints(a, cf(T_min), errMsg, error);
+    ComparePoints(c, cf(T_max), errMsg, error);
+    ComparePoints(constraints.init_vel, cf.derivate(T_min,1), errMsg, error);
+    ComparePoints(constraints.end_vel , cf.derivate(T_max,1), errMsg, error);
+    ComparePoints(constraints.init_acc, cf.derivate(T_min,2), errMsg, error);
+    ComparePoints(constraints.end_vel, cf.derivate(T_max,1), errMsg, error);
+    ComparePoints(constraints.end_acc, cf.derivate(T_max,2), errMsg, error);
 }
 
 
-void BezierToPolynomConversionTest(bool& error)
+void toPolynomialConversionTest(bool& error)
 {
-    std::string errMsg("In test BezierToPolynomConversionTest ; unexpected result for x ");
+    // bezier to polynomial
+    std::string errMsg("In test BezierToPolynomialConversionTest, Error While checking value of point on curve : ");
     point_t a(1,2,3);
     point_t b(2,3,4);
     point_t c(3,4,5);
@@ -441,50 +471,120 @@ void BezierToPolynomConversionTest(bool& error)
     point_t h(43,6,7);
     point_t i(3,6,77);
 
-    std::vector<point_t> params;
-    params.push_back(a);
-    params.push_back(b);
-    params.push_back(c);
-    params.push_back(d);
-    params.push_back(e);
-    params.push_back(f);
-    params.push_back(g);
-    params.push_back(h);
-    params.push_back(i);
+    std::vector<point_t> control_points;
+    control_points.push_back(a);
+    control_points.push_back(b);
+    control_points.push_back(c);
+    control_points.push_back(d);
+    control_points.push_back(e);
+    control_points.push_back(f);
+    control_points.push_back(g);
+    control_points.push_back(h);
+    control_points.push_back(i);
+
+    bezier_curve_t::num_t T_min = 1.0;
+    bezier_curve_t::num_t T_max = 3.0;
+    bezier_curve_t bc(control_points.begin(), control_points.end(),T_min, T_max);
+    polynomial_t pol = polynomial_from_curve<polynomial_t, bezier_curve_t>(bc);
+    compareCurves<polynomial_t, bezier_curve_t>(pol, bc, errMsg, error);
+}
 
-    bezier_curve_t cf(params.begin(), params.end());
-    polynom_t pol =from_bezier<bezier_curve_t, polynom_t>(cf);
-    for(double i =0.; i<1.; i+=0.01)
-    {
-        ComparePoints(cf(i),pol(i),errMsg, error, true);
-        ComparePoints(cf(i),pol(i),errMsg, error, false);
-    }
+void cubicConversionTest(bool& error)
+{
+    std::string errMsg0("In test CubicConversionTest - convert hermite to, Error While checking value of point on curve : ");
+    std::string errMsg1("In test CubicConversionTest - convert bezier to, Error While checking value of point on curve : ");
+    std::string errMsg2("In test CubicConversionTest - convert polynomial to, Error While checking value of point on curve : ");
+    
+    // Create cubic hermite spline : Test hermite to bezier/polynomial
+    point_t p0(1,2,3);
+    point_t m0(2,3,4);
+    point_t p1(3,4,5);
+    point_t m1(3,6,7);
+    pair_point_tangent_t pair0(p0,m0);
+    pair_point_tangent_t pair1(p1,m1);
+    t_pair_point_tangent_t control_points;
+    control_points.push_back(pair0);
+    control_points.push_back(pair1);
+    std::vector< double > time_control_points;
+    polynomial_t::num_t T_min = 1.0;
+    polynomial_t::num_t T_max = 3.0;
+    time_control_points.push_back(T_min);
+    time_control_points.push_back(T_max);
+    cubic_hermite_spline_t chs0(control_points.begin(), control_points.end(), time_control_points);
+    
+    // hermite to bezier
+    //std::cout<<"======================= \n";
+    //std::cout<<"hermite to bezier \n";
+    bezier_curve_t bc0 = bezier_from_curve<bezier_curve_t, cubic_hermite_spline_t>(chs0);
+    compareCurves<cubic_hermite_spline_t, bezier_curve_t>(chs0, bc0, errMsg0, error);
+
+    // hermite to pol
+    //std::cout<<"======================= \n";
+    //std::cout<<"hermite to polynomial \n";
+    polynomial_t pol0 = polynomial_from_curve<polynomial_t, cubic_hermite_spline_t>(chs0);
+    compareCurves<cubic_hermite_spline_t, polynomial_t>(chs0, pol0, errMsg0, error);
+
+    // pol to hermite
+    //std::cout<<"======================= \n";
+    //std::cout<<"polynomial to hermite \n";
+    cubic_hermite_spline_t chs1 = hermite_from_curve<cubic_hermite_spline_t, polynomial_t>(pol0);
+    compareCurves<polynomial_t, cubic_hermite_spline_t>(pol0,chs1,errMsg2,error);
+
+    // pol to bezier
+    //std::cout<<"======================= \n";
+    //std::cout<<"polynomial to bezier \n";
+    bezier_curve_t bc1 = bezier_from_curve<bezier_curve_t, polynomial_t>(pol0);
+    compareCurves<bezier_curve_t, polynomial_t>(bc1, pol0, errMsg2, error);
+
+    // Bezier to pol
+    //std::cout<<"======================= \n";
+    //std::cout<<"bezier to polynomial \n";
+    polynomial_t pol1 = polynomial_from_curve<polynomial_t, bezier_curve_t>(bc0);
+    compareCurves<bezier_curve_t, polynomial_t>(bc0, pol1, errMsg1, error);
+
+    // bezier => hermite
+    //std::cout<<"======================= \n";
+    //std::cout<<"bezier to hermite \n";
+    cubic_hermite_spline_t chs2 = hermite_from_curve<cubic_hermite_spline_t, bezier_curve_t>(bc0);
+    compareCurves<bezier_curve_t, cubic_hermite_spline_t>(bc0, chs2, errMsg1, error);
 }
 
 /*Exact Cubic Function tests*/
 void ExactCubicNoErrorTest(bool& error)
 {
+    // Create an exact cubic spline with 7 waypoints => 6 polynomials defined in [0.0,3.0]
 	curves::T_Waypoint waypoints;
-	for(double i = 0; i <= 1; i = i + 0.2)
+	for(double i = 0.0; i <= 3.0; i = i + 0.5)
 	{
 		waypoints.push_back(std::make_pair(i,point_t(i,i,i)));
 	}
 	exact_cubic_t exactCubic(waypoints.begin(), waypoints.end());
-	point_t res1;
+
+    // Test number of polynomials in exact cubic
+    std::size_t numberSegments = exactCubic.getNumberSplines();
+    assert(numberSegments == 6);
+
+    // Test getSplineAt function
+    for (std::size_t i=0; i<numberSegments; i++)
+    {
+        exactCubic.getSplineAt(i);
+    }
+
+    // Other tests
 	try
 	{
-		exactCubic(0);
-		exactCubic(1);
+		exactCubic(0.0);
+		exactCubic(3.0);
 	}
 	catch(...)
 	{
 		error = true;
-		std::cout << "Evaluation of ExactCubicNoErrorTest error\n";
+		std::cout << "Evaluation of ExactCubicNoErrorTest error when testing value on bounds\n";
 	}
 	error = true;
 	try
 	{
-		exactCubic(1.2);
+		exactCubic(3.2);
 	}
 	catch(...)
 	{
@@ -492,26 +592,27 @@ void ExactCubicNoErrorTest(bool& error)
 	}
 	if(error)
 	{
-		std::cout << "Evaluation of exactCubic cf error, 1.2 should be an out of range value\n";
+		std::cout << "Evaluation of exactCubic cf error, 3.2 should be an out of range value\n";
 	}
-	if(exactCubic.max() != 1)
+
+	if(exactCubic.max() != 3.)
 	{
 		error = true;
-		std::cout << "Evaluation of exactCubic error, MaxBound should be equal to 1\n";
+		std::cout << "Evaluation of exactCubic error, MaxBound should be equal to 3\n";
 	}
-	if(exactCubic.min() != 0)
+	if(exactCubic.min() != 0.)
 	{
 		error = true;
-		std::cout << "Evaluation of exactCubic error, MinBound should be equal to 1\n";
+		std::cout << "Evaluation of exactCubic error, MinBound should be equal to 0\n";
 	}
 }
 
-
 /*Exact Cubic Function tests*/
 void ExactCubicTwoPointsTest(bool& error)
 {
+    // Create an exact cubic spline with 2 waypoints => 1 polynomial defined in [0.0,1.0]
 	curves::T_Waypoint waypoints;
-	for(double i = 0; i < 2; ++i)
+	for(double i = 0.0; i < 2.0; ++i)
 	{
 		waypoints.push_back(std::make_pair(i,point_t(i,i,i)));
 	}
@@ -523,6 +624,14 @@ void ExactCubicTwoPointsTest(bool& error)
 
 	res1 = exactCubic(1);
 	ComparePoints(point_t(1,1,1), res1, errmsg, error);
+
+    // Test number of polynomials in exact cubic
+    std::size_t numberSegments = exactCubic.getNumberSplines();
+    assert(numberSegments == 1);
+
+    // Test getSplineAt
+    assert(exactCubic(0.5) == (exactCubic.getSplineAt(0))(0.5));
+
 }
 
 void ExactCubicOneDimTest(bool& error)
@@ -544,7 +653,7 @@ void ExactCubicOneDimTest(bool& error)
 	ComparePoints(one, res1, errmsg, error);
 }
 
-void CheckWayPointConstraint(const std::string& errmsg, const double step, const curves::T_Waypoint& /*wayPoints*/, const exact_cubic_t* curve, bool& error )
+void CheckWayPointConstraint(const std::string& errmsg, const double step, const curves::T_Waypoint&, const exact_cubic_t* curve, bool& error )
 {
     point_t res1;
     for(double i = 0; i <= 1; i = i + step)
@@ -583,7 +692,11 @@ void ExactCubicVelocityConstraintsTest(bool& error)
     }
     std::string errmsg("Error in ExactCubicVelocityConstraintsTest (1); while checking that given wayPoints are crossed (expected / obtained)");
     spline_constraints_t constraints;
-    spline_deriv_constraint_t exactCubic(waypoints.begin(), waypoints.end());
+    constraints.end_vel = point_t(0,0,0);
+    constraints.init_vel = point_t(0,0,0);
+    constraints.end_acc = point_t(0,0,0);
+    constraints.init_acc = point_t(0,0,0);
+    exact_cubic_t exactCubic(waypoints.begin(), waypoints.end(), constraints);
     // now check that init and end velocity are 0
     CheckWayPointConstraint(errmsg, 0.2, waypoints, &exactCubic, error);
     std::string errmsg3("Error in ExactCubicVelocityConstraintsTest (2); while checking derivative (expected / obtained)");
@@ -598,7 +711,7 @@ void ExactCubicVelocityConstraintsTest(bool& error)
     constraints.end_acc = point_t(4,5,6);
     constraints.init_acc = point_t(-4,-4,-6);
     std::string errmsg2("Error in ExactCubicVelocityConstraintsTest (3); while checking that given wayPoints are crossed (expected / obtained)");
-    spline_deriv_constraint_t exactCubic2(waypoints.begin(), waypoints.end(),constraints);
+    exact_cubic_t exactCubic2(waypoints.begin(), waypoints.end(),constraints);
     CheckWayPointConstraint(errmsg2, 0.2, waypoints, &exactCubic2, error);
 
     std::string errmsg4("Error in ExactCubicVelocityConstraintsTest (4); while checking derivative (expected / obtained)");
@@ -763,7 +876,7 @@ void EffectorSplineRotationWayPointRotationTest(bool& error)
 void TestReparametrization(bool& error)
 {
     helpers::rotation_spline s;
-    const helpers::spline_deriv_constraint_one_dim& sp = s.time_reparam_;
+    const helpers::exact_cubic_constraint_one_dim& sp = s.time_reparam_;
     if(sp.min() != 0)
     {
         std::cout << "in TestReparametrization; min value is not 0, got " << sp.min() << std::endl;
@@ -794,18 +907,24 @@ void TestReparametrization(bool& error)
     }
 }
 
-point_t randomPoint(const double min, const double max ){
+point_t randomPoint(const double min, const double max )
+{
     point_t p;
     for(size_t i = 0 ; i < 3 ; ++i)
+    {
         p[i] =  (rand()/(double)RAND_MAX ) * (max-min) + min;
+    }
     return p;
 }
 
-void BezierEvalDeCasteljau(bool& error){
+void BezierEvalDeCasteljau(bool& error)
+{
     using namespace std;
     std::vector<double> values;
     for (int i =0; i < 100000; ++i)
+    {
         values.push_back(rand()/RAND_MAX);
+    }
 
     //first compare regular evaluation (low dim pol)
     point_t a(1,2,3);
@@ -828,7 +947,8 @@ void BezierEvalDeCasteljau(bool& error){
 
     for(std::vector<double>::const_iterator cit = values.begin(); cit != values.end(); ++cit)
     {
-        if(cf.evalDeCasteljau(*cit) != cf(*cit)){
+        if(cf.evalDeCasteljau(*cit) != cf(*cit))
+        {
             error = true;
             std::cout<<" De Casteljau evaluation did not return the same value as analytical"<<std::endl;
         }
@@ -845,7 +965,8 @@ void BezierEvalDeCasteljau(bool& error){
 
     for(std::vector<double>::const_iterator cit = values.begin(); cit != values.end(); ++cit)
     {
-        if(cf.evalDeCasteljau(*cit) != cf(*cit)){
+        if(cf.evalDeCasteljau(*cit) != cf(*cit))
+        {
             error = true;
             std::cout<<" De Casteljau evaluation did not return the same value as analytical"<<std::endl;
         }
@@ -853,88 +974,342 @@ void BezierEvalDeCasteljau(bool& error){
 
 }
 
-
 /**
  * @brief BezierSplitCurve test the 'split' method of bezier curve
  * @param error
  */
-void BezierSplitCurve(bool& error){
+void BezierSplitCurve(bool& error)
+{
     // test for degree 5
-    int n = 5;
+    size_t n = 5;
     double t_min = 0.2;
     double t_max = 10;
-    for(size_t i = 0 ; i < 1 ; ++i){
+    for(size_t i = 0 ; i < 1 ; ++i)
+    {
         // build a random curve and split it at random time :
         //std::cout<<"build a random curve"<<std::endl;
         point_t a;
         std::vector<point_t> wps;
-        for(size_t j = 0 ; j <= n ; ++j){
+        for(size_t j = 0 ; j <= n ; ++j)
+        {
             wps.push_back(randomPoint(-10.,10.));
         }
-        double t = (rand()/(double)RAND_MAX )*(t_max-t_min) + t_min;
-        double ts = (rand()/(double)RAND_MAX )*(t);
+        double t0 = (rand()/(double)RAND_MAX )*(t_max-t_min) + t_min;
+        double t1 = (rand()/(double)RAND_MAX )*(t_max-t0) + t0;
+        double ts = (rand()/(double)RAND_MAX )*(t1-t0)+t0;
 
-        bezier_curve_t c(wps.begin(), wps.end(),t);
+        bezier_curve_t c(wps.begin(), wps.end(),t0, t1);
         std::pair<bezier_curve_t,bezier_curve_t> cs = c.split(ts);
         //std::cout<<"split curve of duration "<<t<<" at "<<ts<<std::endl;
 
         // test on splitted curves :
-
-        if(! ((c.degree_ == cs.first.degree_) && (c.degree_ == cs.second.degree_) )){
+        if(! ((c.degree_ == cs.first.degree_) && (c.degree_ == cs.second.degree_) ))
+        {
             error = true;
             std::cout<<" Degree of the splitted curve are not the same as the original curve"<<std::endl;
         }
 
-        if(c.max() != (cs.first.max() + cs.second.max())){
+        if(c.max()-c.min() != (cs.first.max()-cs.first.min() + cs.second.max()-cs.second.min()))
+        {
             error = true;
             std::cout<<"Duration of the splitted curve doesn't correspond to the original"<<std::endl;
         }
 
-        if(c(0) != cs.first(0)){
+        if(c(t0) != cs.first(t0))
+        {
             error = true;
             std::cout<<"initial point of the splitted curve doesn't correspond to the original"<<std::endl;
         }
 
-        if(c(t) != cs.second(cs.second.max())){
+        if(c(t1) != cs.second(cs.second.max()))
+        {
             error = true;
             std::cout<<"final point of the splitted curve doesn't correspond to the original"<<std::endl;
         }
 
-        if(cs.first.max() != ts){
+        if(cs.first.max() != ts)
+        {
             error = true;
             std::cout<<"timing of the splitted curve doesn't correspond to the original"<<std::endl;
         }
 
-        if(cs.first(ts) != cs.second(0.)){
+        if(cs.first(ts) != cs.second(ts))
+        {
             error = true;
             std::cout<<"splitting point of the splitted curve doesn't correspond to the original"<<std::endl;
         }
 
         // check along curve :
-        double ti = 0.;
-        while(ti <= ts){
-            if((cs.first(ti) - c(ti)).norm() > 1e-14){
+        double ti = t0;
+        while(ti <= ts)
+        {
+            if((cs.first(ti) - c(ti)).norm() > 1e-14)
+            {
                 error = true;
                 std::cout<<"first splitted curve and original curve doesn't correspond, error = "<<cs.first(ti) - c(ti) <<std::endl;
             }
             ti += 0.01;
         }
-        while(ti <= t){
-            if((cs.second(ti-ts) - c(ti)).norm() > 1e-14){
+        while(ti <= t1)
+        {
+            if((cs.second(ti) - c(ti)).norm() > 1e-14)
+            {
                 error = true;
                 std::cout<<"second splitted curve and original curve doesn't correspond, error = "<<cs.second(ti-ts) - c(ti)<<std::endl;
             }
             ti += 0.01;
         }
+
     }
 }
 
 
+/* cubic hermite spline function test */
+void CubicHermitePairsPositionDerivativeTest(bool& error)
+{
+    std::string errmsg1("in Cubic Hermite 2 pairs (pos,vel), Error While checking that given wayPoints are crossed (expected / obtained) : ");
+    std::string errmsg2("in Cubic Hermite 2 points, Error While checking value of point on curve : ");
+    std::string errmsg3("in Cubic Hermite 2 points, Error While checking value of tangent on curve : ");
+    std::vector< pair_point_tangent_t > control_points;
+    point_t res1;
+
+    point_t p0(0.,0.,0.);
+    point_t p1(1.,2.,3.);
+    point_t p2(4.,4.,4.);
+
+    tangent_t t0(0.5,0.5,0.5);
+    tangent_t t1(0.1,0.2,-0.5);
+    tangent_t t2(0.1,0.2,0.3);
+
+    std::vector< double > time_control_points, time_control_points_test;
+
+    // Two pairs
+    control_points.clear();
+    control_points.push_back(pair_point_tangent_t(p0,t0));
+    control_points.push_back(pair_point_tangent_t(p1,t1));
+    time_control_points.push_back(0.);  // Time at P0
+    time_control_points.push_back(1.);  // Time at P1
+    // Create cubic hermite spline
+    cubic_hermite_spline_t cubic_hermite_spline_1Pair(control_points.begin(), control_points.end(), time_control_points);
+    //Check
+    res1 = cubic_hermite_spline_1Pair(0.);   // t=0
+    ComparePoints(p0, res1, errmsg1, error);
+    res1 = cubic_hermite_spline_1Pair(1.);   // t=1
+    ComparePoints(p1, res1, errmsg1, error);
+    // Test derivative : two pairs
+    res1 = cubic_hermite_spline_1Pair.derivate(0.,1);
+    ComparePoints(t0, res1, errmsg3, error);
+    res1 = cubic_hermite_spline_1Pair.derivate(1.,1);
+    ComparePoints(t1, res1, errmsg3, error);
+
+    // Three pairs
+    control_points.push_back(pair_point_tangent_t(p2,t2));
+    time_control_points.clear();
+    time_control_points.push_back(0.);  // Time at P0
+    time_control_points.push_back(2.);  // Time at P1
+    time_control_points.push_back(5.);  // Time at P2
+    cubic_hermite_spline_t cubic_hermite_spline_2Pairs(control_points.begin(), control_points.end(), time_control_points);
+    //Check
+    res1 = cubic_hermite_spline_2Pairs(0.);  // t=0
+    ComparePoints(p0, res1, errmsg1, error);
+    res1 = cubic_hermite_spline_2Pairs(2.);  // t=2
+    ComparePoints(p1, res1, errmsg2, error);
+    res1 = cubic_hermite_spline_2Pairs(5.);  // t=5
+    ComparePoints(p2, res1, errmsg1, error);
+    // Test derivative : three pairs
+    res1 = cubic_hermite_spline_2Pairs.derivate(0.,1);
+    ComparePoints(t0, res1, errmsg3, error);
+    res1 = cubic_hermite_spline_2Pairs.derivate(2.,1);
+    ComparePoints(t1, res1, errmsg3, error);
+    res1 = cubic_hermite_spline_2Pairs.derivate(5.,1);
+    ComparePoints(t2, res1, errmsg3, error);
+    // Test time control points by default [0,1] => with N control points : 
+    // Time at P0= 0. | Time at P1= 1.0/(N-1) | Time at P2= 2.0/(N-1) | ... | Time at P_(N-1)= (N-1)/(N-1)= 1.0
+    time_control_points_test.clear();
+    time_control_points_test.push_back(0.);  // Time at P0
+    time_control_points_test.push_back(0.5);  // Time at P1
+    time_control_points_test.push_back(1.0);  // Time at P2
+    cubic_hermite_spline_2Pairs.setTime(time_control_points_test);
+    res1 = cubic_hermite_spline_2Pairs(0.);  // t=0
+    ComparePoints(p0, res1, errmsg1, error);
+    res1 = cubic_hermite_spline_2Pairs(0.5); // t=0.5
+    ComparePoints(p1, res1, errmsg2, error);
+    res1 = cubic_hermite_spline_2Pairs(1.);  // t=1
+    ComparePoints(p2, res1, errmsg1, error);
+    // Test getTime
+    try
+    {
+        cubic_hermite_spline_2Pairs.getTime();
+    }
+    catch(...)
+    {
+        error = false;
+    }
+    if(error)
+    {
+        std::cout << "Cubic hermite spline test, Error when calling getTime\n";
+    }
+    // Test derivative : three pairs, time default
+    res1 = cubic_hermite_spline_2Pairs.derivate(0.,1);
+    ComparePoints(t0, res1, errmsg3, error);
+    res1 = cubic_hermite_spline_2Pairs.derivate(0.5,1);
+    ComparePoints(t1, res1, errmsg3, error);
+    res1 = cubic_hermite_spline_2Pairs.derivate(1.,1);
+    ComparePoints(t2, res1, errmsg3, error);
+}
+
+
+void piecewisePolynomialCurveTest(bool& error)
+{
+    std::string errmsg1("in piecewise polynomial curve test, Error While checking value of point on curve : ");
+    point_t a(1,1,1); // in [0,1[
+    point_t b(2,1,1); // in [1,2[
+    point_t c(3,1,1); // in [2,3]
+    point_t res;
+    t_point_t vec1, vec2, vec3;
+    vec1.push_back(a); // x=1, y=1, z=1
+    vec2.push_back(b); // x=2, y=1, z=1
+    vec3.push_back(c); // x=3, y=1, z=1
+    // Create three polynomials of constant value in the interval of definition
+    polynomial_t pol1(vec1.begin(), vec1.end(), 0, 1);
+    polynomial_t pol2(vec2.begin(), vec2.end(), 1, 2);
+    polynomial_t pol3(vec3.begin(), vec3.end(), 2, 3);
+
+    // 1 polynomial in curve
+    piecewise_polynomial_curve_t ppc(pol1);
+    res = ppc(0.5);
+    ComparePoints(a,res,errmsg1,error);
+
+    // 3 polynomials in curve
+    ppc.add_polynomial_curve(pol2);
+    ppc.add_polynomial_curve(pol3);
+
+    // Check values on piecewise curve
+    // t in [0,1[ -> res=a
+    res = ppc(0.);
+    ComparePoints(a,res,errmsg1,error);
+    res = ppc(0.5);
+    ComparePoints(a,res,errmsg1,error);
+    // t in [1,2[ -> res=b
+    res = ppc(1.0);
+    ComparePoints(b,res,errmsg1,error);
+    res = ppc(1.5);
+    ComparePoints(b,res,errmsg1,error);
+    // t in [2,3] -> res=c
+    res = ppc(2.0);
+    ComparePoints(c,res,errmsg1,error);
+    res = ppc(3.0);
+    ComparePoints(c,res,errmsg1,error);
+
+    // Create piecewise curve C0
+    point_t a1(1,1,1);
+    t_point_t vec_C0;
+    vec_C0.push_back(a);
+    vec_C0.push_back(a1);
+    polynomial_t pol_a(vec_C0, 1.0, 2.0);
+    piecewise_polynomial_curve_t ppc_C0(pol1); // for t in [0,1[ : x=1    , y=1    , z=1
+    ppc_C0.add_polynomial_curve(pol_a);        // for t in [1,2] : x=(t-1)+1  , y=(t-1)+1  , z=(t-1)+1
+    // Check value in t=0.5 and t=1.5
+    res = ppc_C0(0.5);
+    ComparePoints(a,res,errmsg1,error);
+    res = ppc_C0(1.5);
+    ComparePoints(point_t(1.5,1.5,1.5),res,errmsg1,error);
+
+    // Create piecewise curve C1 from Hermite
+    point_t p0(0.,0.,0.);
+    point_t p1(1.,2.,3.);
+    point_t p2(4.,4.,4.);
+    tangent_t t0(0.5,0.5,0.5);
+    tangent_t t1(0.1,0.2,-0.5);
+    tangent_t t2(0.1,0.2,0.3);
+    std::vector< pair_point_tangent_t > control_points_0;
+    control_points_0.push_back(pair_point_tangent_t(p0,t0));
+    control_points_0.push_back(pair_point_tangent_t(p1,t1)); // control_points_0 = 1st piece of curve
+    std::vector< pair_point_tangent_t > control_points_1;
+    control_points_1.push_back(pair_point_tangent_t(p1,t1));
+    control_points_1.push_back(pair_point_tangent_t(p2,t2)); // control_points_1 = 2nd piece of curve
+    std::vector< double > time_control_points0, time_control_points1;
+    time_control_points0.push_back(0.);
+    time_control_points0.push_back(1.); // hermite 0 between [0,1]
+    time_control_points1.push_back(1.);
+    time_control_points1.push_back(3.); // hermite 1 between [1,3]
+    cubic_hermite_spline_t chs0(control_points_0.begin(), control_points_0.end(), time_control_points0);
+    cubic_hermite_spline_t chs1(control_points_1.begin(), control_points_1.end(), time_control_points1);
+    // Convert to polynomial
+    polynomial_t pol_chs0 = polynomial_from_curve<polynomial_t, cubic_hermite_spline_t>(chs0);
+    polynomial_t pol_chs1 = polynomial_from_curve<polynomial_t, cubic_hermite_spline_t>(chs1);
+    piecewise_polynomial_curve_t ppc_C1(pol_chs0);
+    ppc_C1.add_polynomial_curve(pol_chs1);
+
+    // Create piecewise curve C2
+    point_t a0(0,0,0);
+    point_t b0(1,1,1);
+    t_point_t veca, vecb;
+    // in [0,1[
+    veca.push_back(a0);
+    veca.push_back(b0); // x=t, y=t, z=t 
+    // in [1,2]
+    vecb.push_back(b0);
+    vecb.push_back(b0); // x=(t-1)+1, y=(t-1)+1, z=(t-1)+1
+    polynomial_t pola(veca.begin(), veca.end(), 0, 1);
+    polynomial_t polb(vecb.begin(), vecb.end(), 1, 2);
+    piecewise_polynomial_curve_t ppc_C2(pola);
+    ppc_C2.add_polynomial_curve(polb);
+
+
+    // check C0 continuity
+    std::string errmsg2("in piecewise polynomial curve test, Error while checking continuity C0 on ");
+    std::string errmsg3("in piecewise polynomial curve test, Error while checking continuity C1 on ");
+    std::string errmsg4("in piecewise polynomial curve test, Error while checking continuity C2 on ");
+    // not C0
+    bool isC0 = ppc.is_continuous(0);
+    if (isC0)
+    {
+        std::cout << errmsg2 << " ppc " << std::endl;
+        error = true;
+    }
+    // C0
+    isC0 = ppc_C0.is_continuous(0);
+    if (not isC0)
+    {
+        std::cout << errmsg2 << " ppc_C0 " << std::endl;
+        error = true;
+    }
+    // not C1
+    bool isC1 = ppc_C0.is_continuous(1);
+    if (isC1)
+    {
+        std::cout << errmsg3 << " ppc_C0 " << std::endl;
+        error = true;
+    }
+    // C1
+    isC1 = ppc_C1.is_continuous(1);
+    if (not isC1)
+    {
+        std::cout << errmsg3 << " ppc_C1 " << std::endl;
+        error = true;
+    }
+    // not C2
+    bool isC2 = ppc_C1.is_continuous(2);
+    if (isC2)
+    {
+        std::cout << errmsg4 << " ppc_C1 " << std::endl;
+        error = true;
+    }
+    // C2
+    isC2 = ppc_C2.is_continuous(2);
+    if (not isC2)
+    {
+        std::cout << errmsg4 << " ppc_C2 " << std::endl;
+        error = true;
+    }
+}
 
 int main(int /*argc*/, char** /*argv[]*/)
 {
     std::cout << "performing tests... \n";
     bool error = false;
+    
     CubicFunctionTest(error);
     ExactCubicNoErrorTest(error);
     ExactCubicPointsCrossedTest(error); // checks that given wayPoints are crossed
@@ -951,15 +1326,18 @@ int main(int /*argc*/, char** /*argv[]*/)
     BezierDerivativeCurveConstraintTest(error);
     BezierCurveTestCompareHornerAndBernstein(error);
     BezierDerivativeCurveTimeReparametrizationTest(error);
-    BezierToPolynomConversionTest(error);
     BezierEvalDeCasteljau(error);
     BezierSplitCurve(error);
+    CubicHermitePairsPositionDerivativeTest(error);
+    piecewisePolynomialCurveTest(error);
+    toPolynomialConversionTest(error);
+    cubicConversionTest(error);
+
     if(error)
 	{
         std::cout << "There were some errors\n";
 		return -1;
-	}
-	else
+	} else
 	{
 		std::cout << "no errors found \n";
 		return 0;