33 #ifndef PARAM_FUNC_SPLINE0_DIST_HPP 34 #define PARAM_FUNC_SPLINE0_DIST_HPP 46 template <
typename TNumType>
54 std::array<TNumType, nrModesMax_>
cache;
57 template <
typename TNumType>
68 template <
typename TNumType,
size_t TArcLatticeSize>
73 std::array<std::vector<std::size_t>, TArcLatticeSize>
arc2func_;
80 template <
typename TNumType>
87 template <
typename TNumType,
size_t TFuncSize>
101 template <
typename TNumType,
int TFuncSize,
int TArcLatticeSize>
103 :
public ParamFuncsBase<ParamFuncsSpline0Dist<TNumType, TFuncSize, TArcLatticeSize>, TNumType, TFuncSize,
105 public ParamFuncsDistBase<ParamFuncsSpline0Dist<TNumType, TFuncSize, TArcLatticeSize>, TNumType>,
106 public std::conditional<TFuncSize == -1, ParamFuncsSpline0DistFuncVarsDyn<TNumType>,
107 ParamFuncsSpline0DistFuncVarsStatic<TNumType, TFuncSize> >::type,
108 public std::conditional<TArcLatticeSize == -1, ParamFuncsSpline0DistArcVarsDyn<TNumType>,
109 ParamFuncsSpline0DistArcVarsStatic<TNumType, TArcLatticeSize> >::type
111 using ParamFuncsBaseType =
119 static constexpr
const bool IsFuncDyn = TFuncSize == -1;
122 static constexpr
const bool IsArcDyn = TArcLatticeSize == -1;
146 ParamFuncsBaseType::operator=(_other);
147 ParamFuncsDistBaseType::operator=(_other);
162 template <
bool FuncDyn = (IsFuncDyn),
bool ArcDyn = IsArcDyn,
163 typename std::enable_if<(FuncDyn) && (ArcDyn)>::type* =
nullptr>
166 const size_t funcSize = this->funcsSize();
167 this->funcEvalCache_.resize(funcSize);
168 for (
auto& funcEvalCacheI : this->funcEvalCache_)
170 funcEvalCacheI.clear();
172 this->arc2func_.resize(this->funcsArcSize());
173 for (
auto& arc2funcI : this->arc2func_)
177 this->funcEvalArcCacheIdxUnder_.resize(this->funcsArcSize());
179 for (
size_t funcIdx = 0; funcIdx < funcSize; ++funcIdx)
181 const size_t funcISize = this->funcCtrlPt_[funcIdx].size();
184 for (
size_t ctrlPtIdx = 0; ctrlPtIdx < funcISize; ++ctrlPtIdx)
186 this->funcEvalCache_[funcIdx].emplace_back(
FuncCacheDataType(this->funcCtrlPt_[funcIdx][ctrlPtIdx]));
188 this->arc2func_[this->func2Arc_[funcIdx]].emplace_back(funcIdx);
193 template <
bool FuncDyn = (IsFuncDyn),
bool ArcDyn = IsArcDyn,
194 typename std::enable_if<(!FuncDyn) && (ArcDyn)>::type* =
nullptr>
197 for (
auto& funcEvalCacheI : this->funcEvalCache_)
199 funcEvalCacheI.clear();
201 this->arc2func_.resize(this->funcsArcSize());
202 for (
auto& arc2funcI : this->arc2func_)
206 this->funcEvalArcCacheIdxUnder_.resize(this->funcsArcSize());
208 for (
size_t funcIdx = 0; funcIdx < TFuncSize; ++funcIdx)
210 const size_t funcISize = this->funcCtrlPt_[funcIdx].size();
213 for (
size_t ctrlPtIdx = 0; ctrlPtIdx < funcISize; ++ctrlPtIdx)
215 this->funcEvalCache_[funcIdx].emplace_back(
FuncCacheDataType(this->funcCtrlPt_[funcIdx][ctrlPtIdx]));
217 this->arc2func_[this->func2Arc_[funcIdx]].emplace_back(funcIdx);
222 template <
bool FuncDyn = (IsFuncDyn),
bool ArcDyn = IsArcDyn,
223 typename std::enable_if<(FuncDyn) && (!ArcDyn)>::type* =
nullptr>
226 const size_t funcSize = this->funcsSize();
227 this->funcEvalCache_.resize(funcSize);
228 for (
auto& funcEvalCacheI : this->funcEvalCache_)
230 funcEvalCacheI.clear();
232 for (
auto& arc2funcI : this->arc2func_)
236 for (
size_t funcIdx = 0; funcIdx < funcSize; ++funcIdx)
238 const size_t funcISize = this->funcCtrlPt_[funcIdx].size();
241 for (
size_t ctrlPtIdx = 0; ctrlPtIdx < funcISize; ++ctrlPtIdx)
243 this->funcEvalCache_[funcIdx].emplace_back(
FuncCacheDataType(this->funcCtrlPt_[funcIdx][ctrlPtIdx]));
245 this->arc2func_[this->func2Arc_[funcIdx]].emplace_back(funcIdx);
250 template <
bool FuncDyn = (IsFuncDyn),
bool ArcDyn = IsArcDyn,
251 typename std::enable_if<(!FuncDyn) && (!ArcDyn)>::type* =
nullptr>
254 for (
auto& funcEvalCacheI : this->funcEvalCache_)
256 funcEvalCacheI.clear();
258 for (
auto& arc2funcI : this->arc2func_)
262 for (
size_t funcIdx = 0; funcIdx < TFuncSize; ++funcIdx)
264 const size_t funcISize = this->funcCtrlPt_[funcIdx].size();
267 for (
size_t ctrlPtIdx = 0; ctrlPtIdx < funcISize; ++ctrlPtIdx)
269 this->funcEvalCache_[funcIdx].emplace_back(
FuncCacheDataType(this->funcCtrlPt_[funcIdx][ctrlPtIdx]));
271 this->arc2func_[this->func2Arc_[funcIdx]].emplace_back(funcIdx);
280 for (
size_t arcIdx = 0; arcIdx < this->funcsArcSize(); ++arcIdx)
282 for (
size_t arcKnot = 1; arcKnot < this->funcsArcSize(arcIdx); ++arcKnot)
284 this->funcsArc(arcIdx, arcKnot) = fmax(this->funcsArc(arcIdx, arcKnot), this->funcsArc(arcIdx, arcKnot - 1));
288 const TNumType funcSize = this->funcCtrlPt_.size();
289 for (
size_t funcIdx = 0; funcIdx < funcSize; ++funcIdx)
291 auto& funcIEvalCache = this->funcEvalCache_[funcIdx];
292 auto funcIEvalCacheIter = funcIEvalCache.begin();
295 const auto& endIter = funcIEvalCache.end() - 1;
297 this->funcEvalArcCacheIdxUnder_[this->func2Arc_[funcIdx]] = 0;
298 while (funcIEvalCacheIter != endIter)
300 auto& funcIEvalCacheLow = *(funcIEvalCacheIter);
301 auto& funcIEvalCacheHig = *(++funcIEvalCacheIter);
304 if (fabs(funcIEvalCacheLow.arc - funcIEvalCacheHig.arc) <= FLT_MIN)
311 (funcIEvalCacheHig.val - funcIEvalCacheLow.val) / (funcIEvalCacheHig.arc - funcIEvalCacheLow.arc);
318 funcIEvalCacheLow.cache[
asInt(
fem::INT1)] + computeFuncDeltaInt1(funcIdx, funcIEvalCacheHig.arc);
323 funcIEvalCacheLow.cache[
asInt(
fem::INT2)] + computeFuncDeltaInt2(funcIdx, funcIEvalCacheHig.arc);
326 ++this->funcEvalArcCacheIdxUnder_[this->func2Arc_[funcIdx]];
328 --this->funcEvalArcCacheIdxUnder_[this->func2Arc_[funcIdx]];
329 auto& funcIEvalCacheHig = *(funcIEvalCacheIter);
330 auto& funcIEvalCacheLow = *(--funcIEvalCacheIter);
342 funcIEvalCacheLow.cache[
asInt(
fem::INT1)] + computeFuncDeltaInt1(funcIdx, funcIEvalCacheHig.arc);
347 funcIEvalCacheLow.cache[
asInt(
fem::INT2)] + computeFuncDeltaInt2(funcIdx, funcIEvalCacheHig.arc);
350 this->funcsArcEval_ = -1;
359 const TNumType arcEvalNewBound = fmax(fmin(_arcEval, this->funcsArcEnd_), this->funcsArcBegin_);
360 if (arcEvalNewBound == this->funcsArcEval_)
364 const size_t& funcsArcSz = this->funcsArcSize();
368 if (arcEvalNewBound > this->funcsArcEval_)
370 for (
size_t i = 0; i < funcsArcSz; ++i)
372 const size_t arcISize = this->funcCtrlPt_[i].size();
373 size_t& j = this->funcEvalArcCacheIdxUnder_[i];
374 while (this->funcsArc(i, j) < arcEvalNewBound)
381 j = std::max(0, (
int)j - 1);
386 for (
size_t i = 0; i < funcsArcSz; ++i)
388 size_t& j = this->funcEvalArcCacheIdxUnder_[i];
389 while (this->funcsArc(i, j) >= arcEvalNewBound)
401 for (
size_t i = 0; i < funcsArcSz; ++i)
403 this->funcEvalArcCacheIdxUnder_[i] = 0;
407 for (
size_t i = 0; i < funcsArcSz; ++i)
409 this->funcEvalArcCacheIdxUnder_[i] = this->funcCtrlPt_[this->arc2func_[i][0]].size() - 1;
413 for (
size_t i = 0; i < funcsArcSz; ++i)
415 auto& aFuncAtArc = this->funcCtrlPt_[this->arc2func_[i][0]];
416 static TNumType referenceArc;
418 referenceArc = arcEvalNewBound;
419 this->funcEvalArcCacheIdxUnder_[i] =
420 std::max((
int)std::distance(aFuncAtArc.begin(),
421 std::upper_bound(aFuncAtArc.begin(), aFuncAtArc.end(), dummy,
424 return a.
arc <= b.arc;
431 this->funcsArcEval_ = arcEvalNewBound;
438 this->funcEvalCache_[_funcIdx][this->funcEvalArcCacheIdxUnder_[this->func2Arc_[_funcIdx]]];
446 this->funcEvalCache_[_funcIdx][this->funcEvalArcCacheIdxUnder_[this->func2Arc_[_funcIdx]]];
460 this->funcEvalCache_[_funcIdx][this->funcEvalArcCacheIdxUnder_[this->func2Arc_[_funcIdx]]];
468 this->funcEvalCache_[_funcIdx][this->funcEvalArcCacheIdxUnder_[this->func2Arc_[_funcIdx]]];
478 this->funcEvalCache_[_funcIdx][this->funcEvalArcCacheIdxUnder_[this->func2Arc_[_funcIdx]]];
479 const TNumType dt = _arcEnd - ctrlPtLow.
arc;
480 return ctrlPtLow.
val * dt + computeFuncDiff1Impl(_funcIdx) * dt * dt / 2.;
488 this->funcEvalCache_[_funcIdx][this->funcEvalArcCacheIdxUnder_[this->func2Arc_[_funcIdx]]];
489 const TNumType dt = _arcEnd - ctrlPtLow.
arc;
490 const TNumType dtdt = dt * dt;
491 return ctrlPtLow.
val * dtdt / 2. + computeFuncDiff1Impl(_funcIdx) * dtdt * dt / 6.;
510 distCfMode_ = _distCfMode;
511 distRelFuncIdx_ = _distRelFuncIdx;
517 distLinkedFuncIdx_.resize(1, _distRelFuncIdx[0]);
518 distEvalCache_.resize(this->funcCtrlPt_[_distRelFuncIdx[0]].size(), 0);
521 distLinkedArcIdx_ = this->func2Arc_[_distRelFuncIdx[0]];
524 distLinkedFuncIdx_.resize(1, _distRelFuncIdx[0]);
525 distEvalCache_.resize(this->funcCtrlPt_[_distRelFuncIdx[0]].size(), 0);
528 distLinkedArcIdx_ = this->func2Arc_[_distRelFuncIdx[0]];
536 return (this->*computeSFuncPtr_)();
542 size_t& arcIdx = this->funcEvalArcCacheIdxUnder_[distLinkedArcIdx_];
544 const size_t cacheCtrlPtIdxRestore = arcIdx;
545 const size_t cacheArcEvalRestore = this->funcsArcEval_;
547 TNumType resultT = computeTImplInternal(_s, _evalArcGuarantee);
549 arcIdx = cacheCtrlPtIdxRestore;
550 this->funcsArcEval_ = cacheArcEvalRestore;
558 this->setEvalArc(computeTImplInternal(_funcsDistEval, _evalArcGuarantee), _evalArcGuarantee);
564 const size_t slSize = _sLattice.size();
566 _tLattice.reserve(_sLattice.size());
572 while ((this->funcsArcEval_ < this->funcsArcEnd_) && (i + 1 < slSize))
574 _tLattice.emplace_back(this->funcsArcEval_);
578 _tLattice.emplace_back(this->funcsArcEnd_);
587 _tLattice.reserve(distEvalCache_.back() / _ds);
588 const int idxBeforeStart =
static_cast<int>(computeSImpl() / _ds) - 1;
592 while (this->funcsArcEval_ < this->funcsArcEnd_)
594 _tLattice.emplace_back(this->funcsArcEval_);
597 _tLattice.emplace_back(this->funcsArcEnd_);
606 const TNumType dtAbs = fabs(_dt);
611 const TNumType vAbs = fabs(_v0);
612 if (fabs(_av) < FLT_MIN)
616 const TNumType v1 = _v0 + _av * dtAbs;
619 return fabs(_v0 + v1) * _dt / 2.;
628 TNumType dt1 = -_v0 / _av;
629 return retSign * (vAbs * dt1 + fabs(v1) * (dtAbs - dt1)) / 2.;
637 TNumType v0 = _v0, av = _av;
643 if (fabs(av) < FLT_MIN)
653 const TNumType v0v0 = v0 * v0;
655 TNumType delta = v0v0 + 2. * av * fabs(_ds);
658 return retSign * (+v0 + sqrt(-delta)) / av;
662 return retSign * (+v0 - sqrt(delta)) / av;
675 const size_t& func0Idx = distLinkedFuncIdx_[0];
676 const size_t ctrlPtSize = this->funcCtrlPt_[func0Idx].size() - 1;
677 distEvalCache_[0] = 0;
678 for (
size_t funcCtrlPtIdx = 0; funcCtrlPtIdx < ctrlPtSize; ++funcCtrlPtIdx)
680 this->funcsArcEval_ = this->ctrlPtVal(func0Idx, funcCtrlPtIdx + 1,
CtrlPtDim::ARC);
681 this->funcEvalArcCacheIdxUnder_[distLinkedArcIdx_] = funcCtrlPtIdx;
682 distEvalCache_[funcCtrlPtIdx + 1] = computeSImpl();
691 size_t& arcCacheIdx = this->funcEvalArcCacheIdxUnder_[distLinkedArcIdx_];
692 const size_t ctrlPtSize = this->funcCtrlPt_[distLinkedFuncIdx_[0]].size();
694 switch (_evalArcGuarantee)
698 const TNumType& distCache = distEvalCache_[arcCacheIdx];
701 while (distEvalCache_[arcCacheIdx] <= _s)
703 if (++arcCacheIdx >= ctrlPtSize)
712 while (distEvalCache_[arcCacheIdx] >= _s)
714 if (arcCacheIdx == 0)
727 arcCacheIdx = this->funcCtrlPt_[distLinkedFuncIdx_[0]].size() - 1;
731 std::distance(distEvalCache_.begin(), std::upper_bound(distEvalCache_.begin(), distEvalCache_.end(), _s)) -
735 this->funcsArcEval_ = this->ctrlPtVal(distLinkedFuncIdx_[0], arcCacheIdx,
CtrlPtDim::ARC);
737 return this->funcsArcEval_ + (this->*computeDs2DtPtr_)(_s - distEvalCache_[arcCacheIdx]);
743 const size_t& funcIdx = distLinkedFuncIdx_[0];
746 [funcIdx][this->funcEvalArcCacheIdxUnder_[this->func2Arc_[funcIdx]]];
747 return distEvalCache_[this->funcEvalArcCacheIdxUnder_[distLinkedArcIdx_]] +
748 computeDeltaS_V_AV(this->funcsArcEval_ - cacheData.
arc, cacheData.
val, this->computeFuncDiff1(funcIdx));
754 const size_t& funcIdx = distLinkedFuncIdx_[0];
757 [funcIdx][this->funcEvalArcCacheIdxUnder_[this->func2Arc_[funcIdx]]];
758 return distEvalCache_[this->funcEvalArcCacheIdxUnder_[distLinkedArcIdx_]] +
759 computeDeltaS_V_AV(this->funcsArcEval_ - cacheData.
arc, this->computeFuncInt1(funcIdx), cacheData.
val);
766 const size_t& funcIdx = distLinkedFuncIdx_[0];
767 return computeDeltaT_V_AV(_ds, this->computeFuncVal(funcIdx), this->computeFuncDiff1(funcIdx));
774 const size_t& funcIdx = distLinkedFuncIdx_[0];
775 return computeDeltaT_V_AV(_ds, this->computeFuncInt1(funcIdx), this->computeFuncVal(funcIdx));
780 std::vector<std::size_t> distLinkedFuncIdx_;
789 std::vector<std::size_t> distRelFuncIdx_;
792 std::size_t distLinkedArcIdx_;
806 template <
typename TDerived2,
typename TNumType2,
int TFuncSize2,
int TArcLatticeSize2>
811 #endif // PARAM_FUNC_SPLINE0_DIST_HPP TraveledDistCfMode distCfMode_
Closed form distance computation mode.
TNumType & arc
control point arc parameter
TNumType computeSImpl() const
double(ParamFuncsSpline0Dist::*)() const ComputeSFuncPtr
friend class ParamFuncsBase
TNumType computeT_V(const TNumType &_ds) const
Computes arc parametrization on a piecewise linear function describing the center linear velocity at ...
TNumType computeT_AV(const TNumType &_ds) const
Computes arc parametrization on a piecewise linear function describing the center linear acceleration...
control point arc parameter
TNumType computeTImplInternal(const TNumType &_s, const EvalArcGuarantee &_evalArcGuarantee)
Internal implementation of computing the arc parametrization given a distance _s. ...
void setEvalArcImpl(const TNumType &_arcEval, const EvalArcGuarantee &_eAG)
std::vector< TNumType > distEvalCache_
Cached values of traveled distance computation.
static TNumType computeDeltaS_V_AV(const TNumType &_dt, const TNumType &_v0, const TNumType &_av)
Helper function that computes deltaS (from the evalArc_ position) operating on one function control p...
function second derivative
constexpr auto asInt(Enumeration const value) -> typename std::underlying_type< Enumeration >::type
std::vector< std::size_t > funcEvalArcCacheIdxUnder_
Contains the index of the <u>next</u> control point relative to the last evaluation point...
TNumType computeFuncInt1Impl(const std::size_t &_funcIdx) const
double computeS_AV() const
Computes distance on a piecewise linear function describing the center linear acceleration.
std::vector< std::vector< FuncCacheData< TNumType > > > funcEvalCache_
Cached values of the used function evaluation modes.
TNumType computeS_AV() const
Computes distance on a piecewise linear function describing the center linear acceleration.
double computeT_V(const double &_ds) const
Computes arc parametrization on a piecewise linear function describing the center linear velocity at ...
ParamFuncsSpline0Dist(const ParamFuncsSpline0Dist &_other)
EvalArcGuarantee
Flags if any guarantees about evaluation arc relative to last evaluation arc are present.
agent base center linear velocity is parametric function
static TNumType computeDeltaT_V_AV(const TNumType &_ds, const TNumType &_v0, const TNumType &_av)
Helper function that computes deltaT (from the evalArc_ position) operating on one function control p...
TNumType computeTImpl(const TNumType &_s, const EvalArcGuarantee &_evalArcGuarantee)
double(ParamFuncsSpline0Dist::*)(const double &) const ComputeDs2DtPtr
agent base center linear acceleration is parametric function
void setDistCfModeImpl(TraveledDistCfMode _distCfMode, const std::vector< std::size_t > &_distRelFuncIdx)
TNumType computeFuncDiff2Impl(const std::size_t &_funcIdx) const
TNumType computeFuncValImpl(const std::size_t &_funcIdx) const
void setEvalDistImpl(const TNumType &_funcsDistEval, const EvalArcGuarantee &_evalArcGuarantee)
void precomputeImpl()
Precomputes cached data. To be called after ANY control point modifications.
EvalArcGuarantee
Flags if any guarantees about evaluation arc relative to last evaluation arc are present.
constexpr int signum(T x, std::false_type is_signed)
TNumType computeFuncDeltaInt2(const std::size_t &_funcIdx, const TNumType &_arcEnd) const
Computes the double integral integral of the parametric function _ on interval [funcEvalArcCacheIdxOl...
TNumType computeFuncDiff1Impl(const std::size_t &_funcIdx) const
std::vector< std::vector< std::size_t > > arc2func_
Maps the arc parametrizations to the functions that use them.
ParamFuncsSpline0Dist & operator=(const ParamFuncsSpline0Dist &_other)
close to previous evaluation arc
TNumType computeFuncDeltaInt1(const std::size_t &_funcIdx, const TNumType &_arcEnd) const
Computes the integral of the parametric function _ on interval [funcEvalArcCacheIdxOld_[func2Arc_[_fu...
void computeS2TLatticeImpl(const TNumType &_arc0, const TNumType &_ds, std::vector< TNumType > &_tLattice)
FuncEvalMode
Required type of computation relative to the parametric function.
double computeS_V() const
Computes distance on a piecewise linear function describing the center linear velocity.
double computeT_AV(const double &_ds) const
Computes arc parametrization on a piecewise linear function describing the center linear acceleration...
std::array< TNumType, nrModesMax_ > cache
std::vector< std::size_t > distRelFuncIdx_
TraveledDistCfMode
Required type of traveled distance computation relative to the parametric function.
this evaluation arc is at the arc parametrization begin
void computeS2TLatticeImpl(const std::vector< TNumType > &_sLattice, std::vector< TNumType > &_tLattice)
TNumType computeS_V() const
Computes distance on a piecewise linear function describing the center linear velocity.
this evaluation arc is at the arc parametrization end
FuncCacheData(const FuncCtrlPt< TNumType > &_ctrlPt)
function first derivative
TNumType computeFuncInt2Impl(const std::size_t &_funcIdx) const
void precomputeDist()
Precomputes distance invervals.