27 #ifndef RL_MATH_SPLINE_H
28 #define RL_MATH_SPLINE_H
55 typedef typename ::std::vector<Polynomial<T>>::const_iterator
ConstIterator;
59 typedef typename ::std::vector<Polynomial<T>>::iterator
Iterator;
87 template<
typename Container1,
typename Container2>
91 assert(x.size() == y.size());
93 ::std::size_t n = y.size();
99 T yd = (y[1] - y[0]) / (x[1] - x[0]);
100 T yBeforeLinear = y[0] + yd * (parabolicInterval / 2);
101 Real linearInterval = (x[1] - x[0]) - parabolicInterval;
102 assert(linearInterval > 0);
103 T yAfterLinear = y[0] + yd * (parabolicInterval / 2 + linearInterval);
111 for (::std::size_t i = 1; i < n - 1; ++i)
113 Real deltaXPrev = x[i] - x[i - 1];
114 Real deltaXNext = x[i + 1] - x[i];
115 Real linearInterval = deltaXNext - parabolicInterval;
116 assert(deltaXPrev > parabolicInterval && deltaXNext > parabolicInterval);
117 T ydPrev = (y[i] - y[i - 1]) / deltaXPrev;
118 T ydNext = (y[i + 1] - y[i]) / deltaXNext;
119 T yBeforeParabolic = y[i] + (-parabolicInterval / 2 * ydPrev);
120 T yBeforeLinear = y[i] + (parabolicInterval / 2 * ydNext);
121 T yAfterLinear = y[i] + ((parabolicInterval / 2 + linearInterval) * ydNext);
130 T yd = (y[n - 1] - y[n - 2]) / (x[n - 1] - x[n - 2]);
131 T yBeforeParabolic = y[n - 1] - yd * (parabolicInterval / 2);
152 template<
typename Container1,
typename Container2>
155 assert(x.size() > 1);
156 assert(x.size() == y.size());
158 ::std::size_t n = y.size();
164 T yd = (y[1] - y[0]) / (x[1] - x[0]);
165 T yBeforeLinear = y[0] + yd * (quarticInterval / 2);
166 Real linearInterval = (x[1] - x[0]) - quarticInterval;
167 assert(linearInterval > 0);
168 T yAfterLinear = y[0] + yd * (quarticInterval / 2 + linearInterval);
176 for (::std::size_t i = 1; i < n - 1; ++i)
178 Real deltaXPrev = x[i] - x[i - 1];
179 Real deltaXNext = x[i + 1] - x[i];
180 Real linearInterval = deltaXNext - quarticInterval;
181 assert(deltaXPrev > quarticInterval && deltaXNext > quarticInterval);
182 T ydPrev = (y[i] - y[i - 1]) / deltaXPrev;
183 T ydNext = (y[i + 1] - y[i]) / deltaXNext;
184 T yBeforeQuartic = y[i] + (-quarticInterval / 2 * ydPrev);
185 T yBeforeLinear = y[i] + (quarticInterval / 2 * ydNext);
186 T yAfterLinear = y[i] + ((quarticInterval / 2 + linearInterval) * ydNext);
195 T yd = (y[n - 1] - y[n - 2]) / (x[n - 1] - x[n - 2]);
196 T yBeforeQuartic = y[n - 1] - yd * (quarticInterval / 2);
217 template<
typename Container1,
typename Container2>
220 assert(x.size() > 1);
221 assert(x.size() == y.size());
223 ::std::size_t n = y.size();
229 T yd = (y[1] - y[0]) / (x[1] - x[0]);
230 T yBeforeLinear = y[0] + yd * (sexticInterval / 2);
231 Real linearInterval = (x[1] - x[0]) - sexticInterval;
232 assert(linearInterval > 0);
233 T yAfterLinear = y[0] + yd * (sexticInterval / 2 + linearInterval);
241 for (::std::size_t i = 1; i < n - 1; ++i)
243 Real deltaXPrev = x[i] - x[i - 1];
244 Real deltaXNext = x[i + 1] - x[i];
245 Real linearInterval = deltaXNext - sexticInterval;
246 assert(deltaXPrev > sexticInterval && deltaXNext > sexticInterval);
247 T ydPrev = (y[i] - y[i - 1]) / deltaXPrev;
248 T ydNext = (y[i + 1] - y[i]) / deltaXNext;
249 T yBeforeSextic = y[i] + (-sexticInterval / 2 * ydPrev);
250 T yBeforeLinear = y[i] + (sexticInterval / 2 * ydNext);
251 T yAfterLinear = y[i] + ((sexticInterval / 2 + linearInterval) * ydNext);
260 T yd = (y[n - 1] - y[n - 2]) / (x[n - 1] - x[n - 2]);
261 T yBeforeSextic = y[n - 1] - yd * (sexticInterval / 2);
270 #if !(defined(_MSC_VER) && _MSC_VER < 1800)
280 template<
typename U = T>
282 const typename ::std::enable_if< ::std::is_floating_point<U>::value, U>::type& q0,
283 const typename ::std::enable_if< ::std::is_floating_point<U>::value, U>::type& q1,
284 const typename ::std::enable_if< ::std::is_floating_point<U>::value, U>::type& vmax,
285 const typename ::std::enable_if< ::std::is_floating_point<U>::value, U>::type& amax
291 T
sign = (q1 > q0) ? 1 : -1;
299 T ta = 3 * vmax / (2 * amax);
310 T vreached = ::std::sqrt(2 *
distance * amax / 3);
311 T th = ::std::sqrt(3 *
distance / (2 * amax));
312 T xh = (q0 + q1) / 2;
333 #if !(defined(_MSC_VER) && _MSC_VER < 1800)
334 template<
typename U = T>
336 const typename ::std::enable_if< ::std::is_class<U>::value, U>::type& q0,
337 const typename ::std::enable_if< ::std::is_class<U>::value, U>::type& q1,
338 const typename ::std::enable_if< ::std::is_class<U>::value, U>::type& vmax,
339 const typename ::std::enable_if< ::std::is_class<U>::value, U>::type& amax
345 assert(q0.size() >= 1 && q0.size() == q1.size() && q0.size() == vmax.size() && q0.size() == amax.size() &&
"QuarticLinearQuarticAtRest: parameters must have same dimension.");
353 for (::std::size_t i = 0; i < dim; ++i)
362 tAcc[i] = 3 * vmax[i] / (2 * amax[i]);
363 tLin[i] = xl / vmax[i];
369 tAcc[i] = ::std::sqrt(3 *
distance / (2 * amax[i]));
382 for (::std::size_t i = 0; i < dim; ++i)
384 sign[i] = (q1[i] > q0[i]) ? 1 : -1;
386 xAfterAcc[i] = tAccMax *
distance / (2 * tLinMax + 2 * tAccMax);
387 vReached[i] =
distance / (tLinMax + tAccMax);
407 #if !(defined(_MSC_VER) && _MSC_VER < 1800)
420 template<
typename U = T>
422 const typename ::std::enable_if< ::std::is_floating_point<U>::value, U>::type& q0,
423 const typename ::std::enable_if< ::std::is_floating_point<U>::value, U>::type& q1,
424 const typename ::std::enable_if< ::std::is_floating_point<U>::value, U>::type& vmax,
425 const typename ::std::enable_if< ::std::is_floating_point<U>::value, U>::type& amax
428 T xta = 15 *
::std::pow(vmax, 2) / (16 * amax);
431 T
sign = (q1 > q0) ? 1 : -1;
439 T ta = 15 * vmax / (8 * amax);
450 T vreached = ::std::sqrt(8 *
distance * amax / 15);
451 T th = ::std::sqrt(15 *
distance / (8 * amax));
452 T xh = (q0 + q1) / 2;
473 #if !(defined(_MSC_VER) && _MSC_VER < 1800)
474 template<
typename U = T>
476 const typename ::std::enable_if< ::std::is_class<U>::value, U>::type& q0,
477 const typename ::std::enable_if< ::std::is_class<U>::value, U>::type& q1,
478 const typename ::std::enable_if< ::std::is_class<U>::value, U>::type& vmax,
479 const typename ::std::enable_if< ::std::is_class<U>::value, U>::type& amax
485 assert(q0.size() >= 1 && q0.size() == q1.size() && q0.size() == vmax.size() && q0.size() == amax.size() &&
"SexticLinearSexticAtRest: parameters must have same dimension.");
493 for (::std::size_t i = 0; i < dim; ++i)
502 tAcc[i] = 15 * vmax[i] / (8 * amax[i]);
503 tLin[i] = xl / vmax[i];
509 tAcc[i] = ::std::sqrt(15 *
distance / (8 * amax[i]));
522 for (::std::size_t i = 0; i < dim; ++i)
524 sign[i] = (q1[i] > q0[i]) ? 1 : -1;
526 xAfterAcc[i] = tAccMax *
distance / (2 * tLinMax + 2 * tAccMax);
527 vReached[i] =
distance / (tLinMax + tAccMax);
570 for (::std::size_t i = 0; i < dim; ++i)
572 sign(i) = (q1(i) > q0(i)) ? 1 : -1;
573 Real d = ::std::abs(q1(i) - q0(i));
578 if (vmax(i) * jmax(i) >= amax(i) * amax(i))
580 tj = amax(i) / jmax(i);
581 ta = tj + vmax(i) / amax(i);
585 tj = ::std::sqrt(vmax(i) / jmax(i));
589 Real tv = d / vmax(i) - ta;
590 vReached(i) =
sign(i) * vmax(i);
598 tj = amax(i) / jmax(i);
599 ta = tj / 2 + ::std::sqrt(::
std::pow(tj / 2, 2) + d / amax(i));
600 vReached(i) =
sign(i) * ((ta - tj) * amax(i));
606 vReached(i) =
sign(i) * (tj * tj * jmax(i));
626 for (::std::size_t i = 0; i < dim; ++i)
629 vLin(i) = (q1(i) - q0(i)) / (tAccMax + tLinMax);
630 qBeforeLin(i) = (q1(i) + q0(i)) / 2.0f - (tLinMax / 2.0f) * vLin(i);
631 aAcc(i) = vLin(i) / (tAccMax - tjFixed);
632 vAfterJerk(i) = aAcc(i) * tjFixed / 2;
633 xAfterJerk(i) = aAcc(i) * tjFixed * tjFixed / 6;
641 T vAfterConstAcc = vAfterJerk;
642 T xAfterConstAcc = xAfterJerk;
644 if (2 * tjFixed < tAccMax)
646 Real tConstAcc = tAccMax - 2 * tjFixed;
647 vAfterConstAcc += tConstAcc * aAcc;
648 xAfterConstAcc += tConstAcc * (vAfterJerk + vAfterConstAcc) / 2;
665 if (2 * tjFixed < tAccMax)
667 Real tConstAcc = tAccMax - 2 * tjFixed;
724 for (::std::size_t i = 0; i < this->
size(); ++i)
771 for (::std::size_t i = 0; i < this->
size(); ++i)
773 T maximumOfPolynomial = this->
polynomials[i].getAbsoluteMaximum();
775 for (::std::ptrdiff_t row = 0; row < maximum.size(); ++row)
777 Real y = maximumOfPolynomial[row];
779 if (y > maximum[row])
801 for (::std::size_t d = 0; d <= upToDerivative; ++d)
803 for (::std::size_t i = 1; i < this->
polynomials.size(); ++i)
868 for (::std::size_t i = 0; i < spline.
polynomials.size(); ++i)
885 for (::std::size_t i = 0; i < this->
size(); ++i)
914 ConstReverseIterator
rend()
const
928 #endif // RL_MATH_SPLINE_H