Loading...
Searching...
No Matches
piecewise_curve.h
Go to the documentation of this file.
1
8#ifndef _CLASS_PIECEWISE_CURVE
9#define _CLASS_PIECEWISE_CURVE
10
11#include <boost/serialization/vector.hpp>
12#include <fstream>
13#include <memory>
14#include <sstream>
15
16#include "curve_abc.h"
17#include "curve_conversion.h"
18
19namespace ndcurves {
31template <typename Time = double, typename Numeric = Time, bool Safe = false,
32 typename Point = Eigen::Matrix<Numeric, Eigen::Dynamic, 1>,
33 typename Point_derivate = Point,
34 typename CurveType =
37 : public curve_abc<Time, Numeric, Safe, Point, Point_derivate> {
38 typedef Point point_t;
40 typedef std::vector<point_t, Eigen::aligned_allocator<point_t> > t_point_t;
41 typedef std::vector<point_derivate_t,
42 Eigen::aligned_allocator<point_derivate_t> >
44 typedef Time time_t;
45 typedef Numeric num_t;
47 base_curve_t; // parent class
48 typedef CurveType curve_t; // contained curves base class
49 typedef std::shared_ptr<curve_t> curve_ptr_t;
50 typedef typename std::vector<curve_ptr_t> t_curve_ptr_t;
51 typedef typename std::vector<Time> t_time_t;
54 typedef piecewise_curve<Time, Numeric, Safe, Point_derivate, Point_derivate,
55 typename CurveType::curve_derivate_t>
57 typedef std::shared_ptr<typename piecewise_curve_derivate_t::curve_t>
59
60 public:
64 piecewise_curve() : dim_(0), size_(0), T_min_(0), T_max_(0) {}
65
71 : dim_(0), size_(0), T_min_(0), T_max_(0) {
73 }
74
76 : dim_(0), size_(0), T_min_(0), T_max_(0) {
77 for (typename t_curve_ptr_t::const_iterator it = curves_list.begin();
78 it != curves_list.end(); ++it) {
80 }
81 }
82
90
91 virtual ~piecewise_curve() {}
92
93 virtual point_t operator()(const Time t) const {
94 check_if_not_empty();
95 if (Safe & !(T_min_ <= t && t <= T_max_)) {
96 // std::cout<<"[Min,Max]=["<<T_min_<<","<<T_max_<<"]"<<"
97 // t="<<t<<std::endl;
98 throw std::out_of_range("can't evaluate piecewise curve, out of range");
99 }
100 return (*curves_.at(find_interval(t)))(t);
101 }
102
114 const Numeric prec = Eigen::NumTraits<Numeric>::dummy_precision()) const {
115 if (num_curves() != other.num_curves()) return false;
116 for (size_t i = 0; i < num_curves(); ++i) {
117 if (!curve_at_index(i)->isApprox(other.curve_at_index(i).get(), prec))
118 return false;
119 }
120 return true;
121 }
122
123 virtual bool isApprox(
124 const base_curve_t* other,
125 const Numeric prec = Eigen::NumTraits<Numeric>::dummy_precision()) const {
127 dynamic_cast<const piecewise_curve_t*>(other);
128 if (other_cast)
129 return isApprox(*other_cast, prec);
130 else
131 return false;
132 }
133
134 virtual bool operator==(const piecewise_curve_t& other) const {
135 return isApprox(other);
136 }
137
138 virtual bool operator!=(const piecewise_curve_t& other) const {
139 return !(*this == other);
140 }
141
148 virtual point_derivate_t derivate(const Time t,
149 const std::size_t order) const {
150 check_if_not_empty();
151 if (Safe & !(T_min_ <= t && t <= T_max_)) {
152 throw std::invalid_argument(
153 "can't evaluate piecewise curve, out of range");
154 }
155 return (*curves_.at(find_interval(t))).derivate(t, order);
156 }
157
165 const std::size_t order) const {
167 for (typename t_curve_ptr_t::const_iterator itc = curves_.begin();
168 itc < curves_.end(); ++itc) {
169 curve_derivate_ptr_t ptr((*itc)->compute_derivate_ptr(order));
170 res->add_curve_ptr(ptr);
171 }
172 return res;
173 }
174
175 template <typename Curve>
176 void add_curve(const Curve& curve) {
177 curve_ptr_t curve_ptr = std::make_shared<Curve>(curve);
179 }
180
188 if (size_ == 0) { // first curve added
189 dim_ = cf->dim();
190 }
191 // Check time continuity : Beginning time of cf must be equal to T_max_ of
192 // actual piecewise curve.
193 if (size_ != 0 && !(fabs(cf->min() - T_max_) < MARGIN)) {
194 std::stringstream ss;
195 ss << "Can not add new Polynom to PiecewiseCurve : time discontinuity "
196 "between T_max_ and pol.min(). Current "
197 "T_max is "
198 << T_max_ << " new curve min is " << cf->min();
199 throw std::invalid_argument(ss.str().c_str());
200 }
201 if (cf->dim() != dim_) {
202 std::stringstream ss;
203 ss << "All the curves in a piecewiseCurve should have the same "
204 "dimension. Current dim is "
205 << dim_ << " dim of the new curve is " << cf->dim();
206 throw std::invalid_argument(ss.str().c_str());
207 }
208 curves_.push_back(cf);
209 size_ = curves_.size();
210 T_max_ = cf->max();
211 if (size_ == 1) {
212 // First curve added
213 time_curves_.push_back(cf->min());
214 T_min_ = cf->min();
215 }
216 time_curves_.push_back(T_max_);
217 }
218
223 bool is_continuous(const std::size_t order) {
224 check_if_not_empty();
225 bool isContinuous = true;
226 std::size_t i = 0;
227 if (order == 0) {
229 while (isContinuous && i < (size_ - 1)) {
231 curve_ptr_t next = curves_.at(i + 1);
232 value_end = (*current)(current->max());
233 value_start = (*next)(next->min());
234 if (!value_end.isApprox(value_start, MARGIN)) {
235 isContinuous = false;
236 }
237 i++;
238 }
239 } else {
241 while (isContinuous && i < (size_ - 1)) {
243 curve_ptr_t next = curves_.at(i + 1);
244 value_end = current->derivate(current->max(), order);
245 value_start = next->derivate(next->min(), order);
246 if (!value_end.isApprox(value_start, MARGIN)) {
247 isContinuous = false;
248 }
249 i++;
250 }
251 }
252 return isContinuous;
253 }
254
257 std::size_t num_curves() const { return curves_.size(); }
258
266 return curves_[find_interval(t)];
267 }
268
272 curve_ptr_t curve_at_index(const std::size_t idx) const {
273 if (Safe && idx >= num_curves()) {
274 throw std::length_error(
275 "curve_at_index: requested index greater than number of curves in "
276 "piecewise_curve instance");
277 }
278 return curves_[idx];
279 }
280
284 template <typename Bezier>
286 check_if_not_empty();
287 // check if given Bezier curve have the correct dimension :
289 boost::is_same<typename Bezier::point_t, point_t>::value);
290 BOOST_STATIC_ASSERT(boost::is_same<typename Bezier::point_derivate_t,
292 // Create piecewise curve
294 // Convert and add all other curves (segments)
295 for (std::size_t i = 0; i < size_; i++) {
297 }
298 return pc_res;
299 }
300
305 template <typename Hermite>
307 check_if_not_empty();
308 // check if given Hermite curve have the correct dimension :
310 boost::is_same<typename Hermite::point_t, point_t>::value);
311 BOOST_STATIC_ASSERT(boost::is_same<typename Hermite::point_derivate_t,
313 // Create piecewise curve
315 // Convert and add all other curves (segments)
316 for (std::size_t i = 0; i < size_; i++) {
318 }
319 return pc_res;
320 }
321
325 template <typename Polynomial>
327 check_if_not_empty();
328 // check if given Polynomial curve have the correct dimension :
330 boost::is_same<typename Polynomial::point_t, point_t>::value);
331 BOOST_STATIC_ASSERT(boost::is_same<typename Polynomial::point_derivate_t,
333 // Create piecewise curve
335 // Convert and add all other curves (segments)
336 for (std::size_t i = 0; i < size_; i++) {
338 }
339 return pc_res;
340 }
341
347 template <typename Polynomial>
350 if (Safe & !(points.size() > 1)) {
351 // std::cout<<"[Min,Max]=["<<T_min_<<","<<T_max_<<"]"<<"
352 // t="<<t<<std::endl;
353 throw std::invalid_argument(
354 "piecewise_curve::convert_discrete_points_to_polynomial: Error, less "
355 "than 2 discrete points");
356 }
357 if (points.size() != time_points.size()) {
358 throw std::invalid_argument(
359 "piecewise_curve::convert_discrete_points_to_polynomial: Error, "
360 "points and time_points must have the same "
361 "size.");
362 }
363 // check if given Polynomial curve have the correct dimension :
365 boost::is_same<typename Polynomial::point_t, point_t>::value);
366 BOOST_STATIC_ASSERT(boost::is_same<typename Polynomial::point_derivate_t,
369
370 for (size_t i = 1; i < points.size(); ++i) {
372 time_points[i - 1], time_points[i]));
373 }
374 return piecewise_res;
375 }
376
383 template <typename Polynomial>
387 if (Safe & !(points.size() > 1)) {
388 // std::cout<<"[Min,Max]=["<<T_min_<<","<<T_max_<<"]"<<"
389 // t="<<t<<std::endl;
390 throw std::invalid_argument(
391 "piecewise_curve::convert_discrete_points_to_polynomial: Error, less "
392 "than 2 discrete points");
393 }
394 if (points.size() != time_points.size()) {
395 throw std::invalid_argument(
396 "piecewise_curve::convert_discrete_points_to_polynomial: Error, "
397 "points and time_points must have the same "
398 "size.");
399 }
400 if (points.size() != points_derivative.size()) {
401 throw std::invalid_argument(
402 "piecewise_curve::convert_discrete_points_to_polynomial: Error, "
403 "points and points_derivative must have the "
404 "same size.");
405 }
406 // check if given Polynomial curve have the correct dimension :
408 boost::is_same<typename Polynomial::point_t, point_t>::value);
409 BOOST_STATIC_ASSERT(boost::is_same<typename Polynomial::point_derivate_t,
412
413 for (size_t i = 1; i < points.size(); ++i) {
417 }
418 return piecewise_res;
419 }
420
429 template <typename Polynomial>
433 if (Safe & !(points.size() > 1)) {
434 // std::cout<<"[Min,Max]=["<<T_min_<<","<<T_max_<<"]"<<"
435 // t="<<t<<std::endl;
436 throw std::invalid_argument(
437 "piecewise_curve::convert_discrete_points_to_polynomial: Error, less "
438 "than 2 discrete points");
439 }
440 if (points.size() != time_points.size()) {
441 throw std::invalid_argument(
442 "piecewise_curve::convert_discrete_points_to_polynomial: Error, "
443 "points and time_points must have the same "
444 "size.");
445 }
446 if (points.size() != points_derivative.size()) {
447 throw std::invalid_argument(
448 "piecewise_curve::convert_discrete_points_to_polynomial: Error, "
449 "points and points_derivative must have the "
450 "same size.");
451 }
452 if (points.size() != points_second_derivative.size()) {
453 throw std::invalid_argument(
454 "piecewise_curve::convert_discrete_points_to_polynomial: Error, "
455 "points and points_second_derivative must "
456 "have the same size.");
457 }
458 // check if given Polynomial curve have the correct dimension :
460 boost::is_same<typename Polynomial::point_t, point_t>::value);
461 BOOST_STATIC_ASSERT(boost::is_same<typename Polynomial::point_derivate_t,
464
465 for (size_t i = 1; i < points.size(); ++i) {
467 points[i - 1], points_derivative[i - 1],
470 }
471 return piecewise_res;
472 }
473
485 template <typename Polynomial>
487 const std::string& filename, const time_t dt, const size_t dim) {
488 if (dim <= 0)
489 throw std::invalid_argument("The dimension should be strictly positive.");
490 if (dt <= 0.)
491 throw std::invalid_argument("The time step should be strictly positive.");
492
494 std::ifstream file;
495 file.open(filename.c_str());
496 point_t last_pos = point_t::Zero(dim), last_vel = point_t::Zero(dim),
497 last_acc = point_t::Zero(dim), new_pos = point_t::Zero(dim),
498 new_vel = point_t::Zero(dim), new_acc = point_t::Zero(dim);
499 bool use_vel, use_acc;
500 std::string line;
501 // read first line to found out if we use velocity / acceleration :
502 std::getline(file, line);
503 std::istringstream iss_length(line);
504 const size_t length =
505 std::distance(std::istream_iterator<std::string>(iss_length),
506 std::istream_iterator<std::string>());
507 if (length == dim) {
508 use_vel = false;
509 use_acc = false;
510 } else if (length == dim * 2) {
511 use_vel = true;
512 use_acc = false;
513 } else if (length == dim * 3) {
514 use_vel = true;
515 use_acc = true;
516 } else {
517 std::stringstream error;
518 error << "The first line of the file shold contains either " << dim
519 << ", " << dim * 2 << " or " << dim * 3
520 << "values, got : " << length;
521 throw std::invalid_argument(error.str());
522 }
523 // initialize the first points of the trajectory:
524 num_t val;
525 std::istringstream iss(line);
526 for (size_t i = 0; i < dim; ++i) {
527 iss >> val;
528 last_pos[i] = val;
529 }
530 if (use_vel) {
531 for (size_t i = 0; i < dim; ++i) {
532 iss >> val;
533 last_vel[i] = val;
534 }
535 }
536 if (use_acc) {
537 for (size_t i = 0; i < dim; ++i) {
538 iss >> val;
539 last_acc[i] = val;
540 }
541 }
542
543 size_t current_length;
544 size_t line_id = 0;
545 // parse all lines of the file:
546 while (std::getline(file, line)) {
547 ++line_id;
548 std::istringstream iss_length(line);
550 std::distance(std::istream_iterator<std::string>(iss_length),
551 std::istream_iterator<std::string>());
552 if (current_length != length) {
553 std::stringstream error;
554 error << "Cannot parse line " << line_id << " got " << current_length
555 << " values instead of " << length;
556 throw std::invalid_argument(error.str());
557 }
558 std::istringstream iss(line);
559 // parse the points values from the file:
560 for (size_t i = 0; i < dim; ++i) {
561 iss >> val;
562 new_pos[i] = val;
563 }
564 if (use_vel) {
565 for (size_t i = 0; i < dim; ++i) {
566 iss >> val;
567 new_vel[i] = val;
568 }
569 }
570 if (use_acc) {
571 for (size_t i = 0; i < dim; ++i) {
572 iss >> val;
573 new_acc[i] = val;
574 }
575 }
576 // append a new curves connectiong this points
577 if (use_acc) {
578 piecewise_res.add_curve(
580 dt * static_cast<time_t>(line_id - 1),
581 dt * static_cast<time_t>(line_id)));
582 } else if (use_vel) {
583 piecewise_res.add_curve(
585 dt * static_cast<time_t>(line_id - 1),
586 dt * static_cast<time_t>(line_id)));
587 } else {
588 piecewise_res.add_curve(
589 Polynomial(last_pos, new_pos, dt * static_cast<time_t>(line_id - 1),
590 dt * static_cast<time_t>(line_id)));
591 }
595 }
596
597 file.close();
598 return piecewise_res;
599 }
600
601 private:
606 std::size_t find_interval(const Numeric t) const {
607 // time before first control point time.
608 if (t < time_curves_[0]) {
609 return 0;
610 }
611 // time is after last control point time
612 if (t > time_curves_[size_ - 1]) {
613 return size_ - 1;
614 }
615
616 std::size_t left_id = 0;
617 std::size_t right_id = size_ - 1;
618 while (left_id <= right_id) {
619 const std::size_t middle_id = left_id + (right_id - left_id) / 2;
620 if (time_curves_.at(middle_id) < t) {
621 left_id = middle_id + 1;
622 } else if (time_curves_.at(middle_id) > t) {
623 right_id = middle_id - 1;
624 } else {
625 return middle_id;
626 }
627 }
628 return left_id - 1;
629 }
630
631 void check_if_not_empty() const {
632 if (curves_.size() == 0) {
633 throw std::runtime_error("Error in piecewise curve : No curve added");
634 }
635 }
636
637 /*Helpers*/
638 public:
641 std::size_t virtual dim() const { return dim_; };
644 Time virtual min() const { return T_min_; }
647 Time virtual max() const { return T_max_; }
650 virtual std::size_t degree() const {
651 throw std::runtime_error(
652 "degree() method is not implemented for this type of curve.");
653 }
654 std::size_t getNumberCurves() { return curves_.size(); }
655 /*Helpers*/
656
657 /* Attributes */
658 std::size_t dim_; // Dim of curve
659 t_curve_ptr_t curves_; // for curves 0/1/2 : [ curve0, curve1, curve2 ]
660 t_time_t time_curves_; // for curves 0/1/2 : [ Tmin0, Tmax0,Tmax1,Tmax2 ]
661 std::size_t size_; // Number of segments in piecewise curve = size of curves_
663 /* Attributes */
664
665 // Serialization of the class
667
668 template <class Archive>
669 void serialize(Archive& ar, const unsigned int version) {
670 if (version) {
671 // Do something depending on version ?
672 }
674 ar& boost::serialization::make_nvp("dim", dim_);
675 ar& boost::serialization::make_nvp("curves", curves_);
676 ar& boost::serialization::make_nvp("time_curves", time_curves_);
677 ar& boost::serialization::make_nvp("size", size_);
678 ar& boost::serialization::make_nvp("T_min", T_min_);
679 ar& boost::serialization::make_nvp("T_max", T_max_);
680 }
681}; // End struct piecewise curve
682} // namespace ndcurves
683
685 SINGLE_ARG(typename Time, typename Numeric, bool Safe, typename Point,
686 typename Point_derivate, typename CurveType),
687 SINGLE_ARG(ndcurves::piecewise_curve<Time, Numeric, Safe, Point,
688 Point_derivate, CurveType>))
689
690#endif // _CLASS_PIECEWISE_CURVE
#define DEFINE_CLASS_TEMPLATE_VERSION(Template, Type)
Definition archive.hpp:27
#define SINGLE_ARG(...)
Definition archive.hpp:23
interface for a Curve of arbitrary dimension.
Eigen::Matrix< Numeric, Eigen::Dynamic, 1 > Point
Definition effector_spline.h:28
double Numeric
Definition effector_spline.h:26
double Time
Definition effector_spline.h:27
Definition bernstein.h:20
bool isApprox(const T a, const T b, const T eps=1e-6)
Definition curve_abc.h:25
Represents a curve of dimension Dim. If value of parameter Safe is false, no verification is made on ...
Definition curve_abc.h:36
Definition piecewise_curve.h:37
static piecewise_curve_t convert_discrete_points_to_polynomial(t_point_t points, t_time_t time_points)
Convert discrete points into piecewise polynomial curve with C0 continuity.
Definition piecewise_curve.h:348
piecewise_curve(const t_curve_ptr_t &curves_list)
Definition piecewise_curve.h:75
virtual point_derivate_t derivate(const Time t, const std::size_t order) const
Evaluate the derivative of order N of curve at time t.
Definition piecewise_curve.h:148
void add_curve_ptr(const curve_ptr_t &cf)
Add a new curve to piecewise curve, which should be defined in where is equal to of the actual pie...
Definition piecewise_curve.h:187
std::shared_ptr< curve_t > curve_ptr_t
Definition piecewise_curve.h:49
Numeric num_t
Definition piecewise_curve.h:45
CurveType curve_t
Definition piecewise_curve.h:48
virtual bool operator!=(const piecewise_curve_t &other) const
Definition piecewise_curve.h:138
t_time_t time_curves_
Definition piecewise_curve.h:660
piecewise_curve< Time, Numeric, Safe, Point_derivate, Point_derivate, typename CurveType::curve_derivate_t > piecewise_curve_derivate_t
Definition piecewise_curve.h:56
virtual std::size_t dim() const
Get dimension of curve.
Definition piecewise_curve.h:641
virtual Time min() const
Get the minimum time for which the curve is defined.
Definition piecewise_curve.h:644
std::vector< Time > t_time_t
Definition piecewise_curve.h:51
Point point_t
Definition piecewise_curve.h:38
virtual bool operator==(const piecewise_curve_t &other) const
Definition piecewise_curve.h:134
std::vector< point_derivate_t, Eigen::aligned_allocator< point_derivate_t > > t_point_derivate_t
Definition piecewise_curve.h:43
piecewise_curve(const curve_ptr_t &cf)
Constructor. Initialize a piecewise curve by giving the first curve.
Definition piecewise_curve.h:70
static piecewise_curve_t convert_discrete_points_to_polynomial(t_point_t points, t_point_derivate_t points_derivative, t_point_derivate_t points_second_derivative, t_time_t time_points)
Convert discrete points into piecewise polynomial curve with C2 continuity.
Definition piecewise_curve.h:430
piecewise_curve_t convert_piecewise_curve_to_polynomial()
Convert all curves in piecewise curve into polynomial curves.
Definition piecewise_curve.h:326
std::size_t num_curves() const
Get number of curves in piecewise curve.
Definition piecewise_curve.h:257
virtual std::size_t degree() const
Get the degree of the curve.
Definition piecewise_curve.h:650
std::size_t getNumberCurves()
Definition piecewise_curve.h:654
std::size_t dim_
Definition piecewise_curve.h:658
Time T_min_
Definition piecewise_curve.h:662
piecewise_curve_t convert_piecewise_curve_to_bezier()
Convert all curves in piecewise curve into bezier curves.
Definition piecewise_curve.h:285
Point_derivate point_derivate_t
Definition piecewise_curve.h:39
std::vector< curve_ptr_t > t_curve_ptr_t
Definition piecewise_curve.h:50
virtual ~piecewise_curve()
Definition piecewise_curve.h:91
Time time_t
Definition piecewise_curve.h:44
virtual Time max() const
Get the maximum time for which the curve is defined.
Definition piecewise_curve.h:647
virtual bool isApprox(const base_curve_t *other, const Numeric prec=Eigen::NumTraits< Numeric >::dummy_precision()) const
isApprox check if other and *this are approximately equal given a precision threshold Only two curves...
Definition piecewise_curve.h:123
t_curve_ptr_t curves_
Definition piecewise_curve.h:659
static piecewise_curve_t convert_discrete_points_to_polynomial(t_point_t points, t_point_derivate_t points_derivative, t_time_t time_points)
Convert discrete points into piecewise polynomial curve with C1 continuity.
Definition piecewise_curve.h:384
curve_ptr_t curve_at_index(const std::size_t idx) const
Get curve at specified index in piecewise curve.
Definition piecewise_curve.h:272
std::size_t size_
Definition piecewise_curve.h:661
bool is_continuous(const std::size_t order)
Check if the curve is continuous of order given.
Definition piecewise_curve.h:223
curve_abc< Time, Numeric, Safe, point_t, point_derivate_t > base_curve_t
Definition piecewise_curve.h:47
void serialize(Archive &ar, const unsigned int version)
Definition piecewise_curve.h:669
piecewise_curve(const piecewise_curve &other)
Definition piecewise_curve.h:83
piecewise_curve_derivate_t * compute_derivate_ptr(const std::size_t order) const
compute_derivate return a piecewise_curve which is the derivative of this at given order
Definition piecewise_curve.h:164
friend class boost::serialization::access
Definition piecewise_curve.h:666
void add_curve(const Curve &curve)
Definition piecewise_curve.h:176
piecewise_curve()
Empty constructor. Add at least one curve to call other class functions.
Definition piecewise_curve.h:64
std::vector< point_t, Eigen::aligned_allocator< point_t > > t_point_t
Definition piecewise_curve.h:40
static piecewise_curve_t load_piecewise_from_text_file(const std::string &filename, const time_t dt, const size_t dim)
load_piecewise_from_text_file build a piecewise polynomial from a list of discrete points read from a...
Definition piecewise_curve.h:486
virtual point_t operator()(const Time t) const
Evaluation of the cubic spline at time t.
Definition piecewise_curve.h:93
piecewise_curve< Time, Numeric, Safe, Point, Point_derivate, CurveType > piecewise_curve_t
Definition piecewise_curve.h:53
std::shared_ptr< typename piecewise_curve_derivate_t::curve_t > curve_derivate_ptr_t
Definition piecewise_curve.h:58
Time T_max_
Definition piecewise_curve.h:662
piecewise_curve_t convert_piecewise_curve_to_cubic_hermite()
Convert all curves in piecewise curve into cubic hermite curves. Curves need to be of degree inferior...
Definition piecewise_curve.h:306
bool isApprox(const piecewise_curve_t &other, const Numeric prec=Eigen::NumTraits< Numeric >::dummy_precision()) const
isApprox check if other and *this are approximately equals. Only two curves of the same class can be ...
Definition piecewise_curve.h:112
curve_ptr_t curve_at_time(const time_t t) const
Get curve corresponding to time t in piecewise curve. Example : A piecewise curve PC made of two curv...
Definition piecewise_curve.h:265