param_func_spline0_dist.hpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Software License Agreement (BSD License) *
3  * Copyright (C) 2016 by Horatiu George Todoran <todorangrg@gmail.com> *
4  * *
5  * Redistribution and use in source and binary forms, with or without *
6  * modification, are permitted provided that the following conditions *
7  * are met: *
8  * *
9  * 1. Redistributions of source code must retain the above copyright *
10  * notice, this list of conditions and the following disclaimer. *
11  * 2. Redistributions in binary form must reproduce the above copyright *
12  * notice, this list of conditions and the following disclaimer in *
13  * the documentation and/or other materials provided with the *
14  * distribution. *
15  * 3. Neither the name of the copyright holder nor the names of its *
16  * contributors may be used to endorse or promote products derived *
17  * from this software without specific prior written permission. *
18  * *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT *
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS *
22  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE *
23  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, *
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, *
25  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; *
26  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER *
27  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT *
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY *
29  * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE *
30  * POSSIBILITY OF SUCH DAMAGE. *
31  ***************************************************************************/
32 
33 #ifndef PARAM_FUNC_SPLINE0_DIST_HPP
34 #define PARAM_FUNC_SPLINE0_DIST_HPP
35 
36 #include <memory>
37 #include <vector>
38 #include <algorithm>
39 #include <float.h>
40 
43 
44 namespace tuw
45 {
46 template <typename TNumType>
48 {
49  FuncCacheData(const FuncCtrlPt<TNumType>& _ctrlPt) : val(_ctrlPt.val), arc(_ctrlPt.arc)
50  {
51  }
52  const TNumType& val;
53  const TNumType& arc;
54  std::array<TNumType, nrModesMax_> cache;
55 };
56 
57 template <typename TNumType>
59 {
61 protected:
62  std::vector<std::vector<std::size_t> > arc2func_;
65 protected:
66  std::vector<std::size_t> funcEvalArcCacheIdxUnder_;
67 };
68 template <typename TNumType, size_t TArcLatticeSize>
70 {
72 protected:
73  std::array<std::vector<std::size_t>, TArcLatticeSize> arc2func_;
76 protected:
77  std::array<std::size_t, TArcLatticeSize> funcEvalArcCacheIdxUnder_;
78 };
79 
80 template <typename TNumType>
82 {
84 protected:
85  std::vector<std::vector<FuncCacheData<TNumType> > > funcEvalCache_;
86 };
87 template <typename TNumType, size_t TFuncSize>
89 {
91 protected:
92  std::array<std::vector<FuncCacheData<TNumType> >, TFuncSize> funcEvalCache_;
93 };
94 
101 template <typename TNumType, int TFuncSize, int TArcLatticeSize>
103  : public ParamFuncsBase<ParamFuncsSpline0Dist<TNumType, TFuncSize, TArcLatticeSize>, TNumType, TFuncSize,
104  TArcLatticeSize>,
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
110 {
111  using ParamFuncsBaseType =
113  using ParamFuncsDistBaseType =
117 
118 private:
119  static constexpr const bool IsFuncDyn = TFuncSize == -1;
120 
121 private:
122  static constexpr const bool IsArcDyn = TArcLatticeSize == -1;
123 
124 public:
125  using NumType = TNumType;
126  // special class member functions
127 public:
128  ParamFuncsSpline0Dist() = default;
129 
130 public:
131  virtual ~ParamFuncsSpline0Dist() = default;
132 
133 public:
135  : ParamFuncsBaseType(_other), ParamFuncsDistBaseType(_other)
136  {
137  initImplImpl();
138  this->setDistCfMode(_other.distCfMode_, _other.distRelFuncIdx_);
139  }
140 
141 public:
143  {
144  if (this != &_other)
145  {
146  ParamFuncsBaseType::operator=(_other);
147  ParamFuncsDistBaseType::operator=(_other);
148  this->setDistCfMode(_other.distCfMode_, _other.distRelFuncIdx_);
149  }
150  return *this;
151  }
152 
153 public:
155 
156 public:
157  ParamFuncsSpline0Dist& operator=(ParamFuncsSpline0Dist&&) = delete;
158 
159  //--------------------------------------- ParamFunc implementation ---------------------------------------//
160 
161 protected:
162  template <bool FuncDyn = (IsFuncDyn), bool ArcDyn = IsArcDyn,
163  typename std::enable_if<(FuncDyn) && (ArcDyn)>::type* = nullptr>
165  {
166  const size_t funcSize = this->funcsSize();
167  this->funcEvalCache_.resize(funcSize);
168  for (auto& funcEvalCacheI : this->funcEvalCache_)
169  {
170  funcEvalCacheI.clear();
171  }
172  this->arc2func_.resize(this->funcsArcSize());
173  for (auto& arc2funcI : this->arc2func_)
174  {
175  arc2funcI.clear();
176  }
177  this->funcEvalArcCacheIdxUnder_.resize(this->funcsArcSize());
178 
179  for (size_t funcIdx = 0; funcIdx < funcSize; ++funcIdx)
180  {
181  const size_t funcISize = this->funcCtrlPt_[funcIdx].size();
182  this->funcEvalReq_[funcIdx][asInt(FuncEvalMode::DIFF1)] = true; // force caching of DIFF1, used by computeFuncVal
183  this->funcEvalReq_[funcIdx][asInt(FuncEvalMode::DIFF2)] = false; // second function derivative is allways 0
184  for (size_t ctrlPtIdx = 0; ctrlPtIdx < funcISize; ++ctrlPtIdx)
185  {
186  this->funcEvalCache_[funcIdx].emplace_back(FuncCacheDataType(this->funcCtrlPt_[funcIdx][ctrlPtIdx]));
187  }
188  this->arc2func_[this->func2Arc_[funcIdx]].emplace_back(funcIdx);
189  }
190  }
191 
192 protected:
193  template <bool FuncDyn = (IsFuncDyn), bool ArcDyn = IsArcDyn,
194  typename std::enable_if<(!FuncDyn) && (ArcDyn)>::type* = nullptr>
196  {
197  for (auto& funcEvalCacheI : this->funcEvalCache_)
198  {
199  funcEvalCacheI.clear();
200  }
201  this->arc2func_.resize(this->funcsArcSize());
202  for (auto& arc2funcI : this->arc2func_)
203  {
204  arc2funcI.clear();
205  }
206  this->funcEvalArcCacheIdxUnder_.resize(this->funcsArcSize());
207 
208  for (size_t funcIdx = 0; funcIdx < TFuncSize; ++funcIdx)
209  {
210  const size_t funcISize = this->funcCtrlPt_[funcIdx].size();
211  this->funcEvalReq_[funcIdx][asInt(FuncEvalMode::DIFF1)] = true; // force caching of DIFF1, used by computeFuncVal
212  this->funcEvalReq_[funcIdx][asInt(FuncEvalMode::DIFF2)] = false; // second function derivative is allways 0
213  for (size_t ctrlPtIdx = 0; ctrlPtIdx < funcISize; ++ctrlPtIdx)
214  {
215  this->funcEvalCache_[funcIdx].emplace_back(FuncCacheDataType(this->funcCtrlPt_[funcIdx][ctrlPtIdx]));
216  }
217  this->arc2func_[this->func2Arc_[funcIdx]].emplace_back(funcIdx);
218  }
219  }
220 
221 protected:
222  template <bool FuncDyn = (IsFuncDyn), bool ArcDyn = IsArcDyn,
223  typename std::enable_if<(FuncDyn) && (!ArcDyn)>::type* = nullptr>
225  {
226  const size_t funcSize = this->funcsSize();
227  this->funcEvalCache_.resize(funcSize);
228  for (auto& funcEvalCacheI : this->funcEvalCache_)
229  {
230  funcEvalCacheI.clear();
231  }
232  for (auto& arc2funcI : this->arc2func_)
233  {
234  arc2funcI.clear();
235  }
236  for (size_t funcIdx = 0; funcIdx < funcSize; ++funcIdx)
237  {
238  const size_t funcISize = this->funcCtrlPt_[funcIdx].size();
239  this->funcEvalReq_[funcIdx][asInt(FuncEvalMode::DIFF1)] = true; // force caching of DIFF1, used by computeFuncVal
240  this->funcEvalReq_[funcIdx][asInt(FuncEvalMode::DIFF2)] = false; // second function derivative is allways 0
241  for (size_t ctrlPtIdx = 0; ctrlPtIdx < funcISize; ++ctrlPtIdx)
242  {
243  this->funcEvalCache_[funcIdx].emplace_back(FuncCacheDataType(this->funcCtrlPt_[funcIdx][ctrlPtIdx]));
244  }
245  this->arc2func_[this->func2Arc_[funcIdx]].emplace_back(funcIdx);
246  }
247  }
248 
249 protected:
250  template <bool FuncDyn = (IsFuncDyn), bool ArcDyn = IsArcDyn,
251  typename std::enable_if<(!FuncDyn) && (!ArcDyn)>::type* = nullptr>
253  {
254  for (auto& funcEvalCacheI : this->funcEvalCache_)
255  {
256  funcEvalCacheI.clear();
257  }
258  for (auto& arc2funcI : this->arc2func_)
259  {
260  arc2funcI.clear();
261  }
262  for (size_t funcIdx = 0; funcIdx < TFuncSize; ++funcIdx)
263  {
264  const size_t funcISize = this->funcCtrlPt_[funcIdx].size();
265  this->funcEvalReq_[funcIdx][asInt(FuncEvalMode::DIFF1)] = true; // force caching of DIFF1, used by computeFuncVal
266  this->funcEvalReq_[funcIdx][asInt(FuncEvalMode::DIFF2)] = false; // second function derivative is allways 0
267  for (size_t ctrlPtIdx = 0; ctrlPtIdx < funcISize; ++ctrlPtIdx)
268  {
269  this->funcEvalCache_[funcIdx].emplace_back(FuncCacheDataType(this->funcCtrlPt_[funcIdx][ctrlPtIdx]));
270  }
271  this->arc2func_[this->func2Arc_[funcIdx]].emplace_back(funcIdx);
272  }
273  }
275 public:
277  {
278  using fem = FuncEvalMode;
279 
280  for (size_t arcIdx = 0; arcIdx < this->funcsArcSize(); ++arcIdx)
281  {
282  for (size_t arcKnot = 1; arcKnot < this->funcsArcSize(arcIdx); ++arcKnot)
283  {
284  this->funcsArc(arcIdx, arcKnot) = fmax(this->funcsArc(arcIdx, arcKnot), this->funcsArc(arcIdx, arcKnot - 1));
285  }
286  }
287 
288  const TNumType funcSize = this->funcCtrlPt_.size();
289  for (size_t funcIdx = 0; funcIdx < funcSize; ++funcIdx)
290  {
291  auto& funcIEvalCache = this->funcEvalCache_[funcIdx];
292  auto funcIEvalCacheIter = funcIEvalCache.begin();
293  funcIEvalCacheIter->cache[asInt(fem::INT1)] = 0;
294  funcIEvalCacheIter->cache[asInt(fem::INT2)] = 0;
295  const auto& endIter = funcIEvalCache.end() - 1;
296 
297  this->funcEvalArcCacheIdxUnder_[this->func2Arc_[funcIdx]] = 0;
298  while (funcIEvalCacheIter != endIter)
299  {
300  auto& funcIEvalCacheLow = *(funcIEvalCacheIter);
301  auto& funcIEvalCacheHig = *(++funcIEvalCacheIter);
302  if (this->funcEvalReq_[funcIdx][asInt(fem::DIFF1)])
303  {
304  if (fabs(funcIEvalCacheLow.arc - funcIEvalCacheHig.arc) <= FLT_MIN)
305  {
306  funcIEvalCacheLow.cache[asInt(fem::DIFF1)] = 0;
307  }
308  else
309  {
310  funcIEvalCacheLow.cache[asInt(fem::DIFF1)] =
311  (funcIEvalCacheHig.val - funcIEvalCacheLow.val) / (funcIEvalCacheHig.arc - funcIEvalCacheLow.arc);
312  }
313  }
314  funcIEvalCacheLow.cache[asInt(fem::DIFF2)] = 0;
315  if (this->funcEvalReq_[funcIdx][asInt(fem::INT1)])
316  {
317  funcIEvalCacheHig.cache[asInt(fem::INT1)] =
318  funcIEvalCacheLow.cache[asInt(fem::INT1)] + computeFuncDeltaInt1(funcIdx, funcIEvalCacheHig.arc);
319  }
320  if (this->funcEvalReq_[funcIdx][asInt(fem::INT2)])
321  {
322  funcIEvalCacheHig.cache[asInt(fem::INT2)] =
323  funcIEvalCacheLow.cache[asInt(fem::INT2)] + computeFuncDeltaInt2(funcIdx, funcIEvalCacheHig.arc);
324  }
325 
326  ++this->funcEvalArcCacheIdxUnder_[this->func2Arc_[funcIdx]];
327  }
328  --this->funcEvalArcCacheIdxUnder_[this->func2Arc_[funcIdx]];
329  auto& funcIEvalCacheHig = *(funcIEvalCacheIter);
330  auto& funcIEvalCacheLow = *(--funcIEvalCacheIter);
331 
332  if (this->funcEvalReq_[funcIdx][asInt(fem::DIFF1)])
333  {
334  funcIEvalCacheHig.cache[asInt(fem::DIFF1)] = funcIEvalCacheLow.cache[asInt(fem::DIFF1)];
335  }
336 
337  funcIEvalCacheHig.cache[asInt(fem::DIFF2)] = 0;
338 
339  if (this->funcEvalReq_[funcIdx][asInt(fem::INT1)])
340  {
341  funcIEvalCacheHig.cache[asInt(fem::INT1)] =
342  funcIEvalCacheLow.cache[asInt(fem::INT1)] + computeFuncDeltaInt1(funcIdx, funcIEvalCacheHig.arc);
343  }
344  if (this->funcEvalReq_[funcIdx][asInt(fem::INT2)])
345  {
346  funcIEvalCacheHig.cache[asInt(fem::INT2)] =
347  funcIEvalCacheLow.cache[asInt(fem::INT2)] + computeFuncDeltaInt2(funcIdx, funcIEvalCacheHig.arc);
348  }
349  }
350  this->funcsArcEval_ = -1;
351  this->setEvalArc(this->funcsArcBegin_, EvalArcGuarantee::AT_BEGIN);
352  precomputeDist();
353  }
354 
355 public:
356  void setEvalArcImpl(const TNumType& _arcEval, const EvalArcGuarantee& _eAG)
357  {
358  using eag = EvalArcGuarantee;
359  const TNumType arcEvalNewBound = fmax(fmin(_arcEval, this->funcsArcEnd_), this->funcsArcBegin_);
360  if (arcEvalNewBound == this->funcsArcEval_)
361  {
362  return;
363  }
364  const size_t& funcsArcSz = this->funcsArcSize();
365  switch (_eAG)
366  {
367  case eag::NEAR_LAST:
368  if (arcEvalNewBound > this->funcsArcEval_)
369  {
370  for (size_t i = 0; i < funcsArcSz; ++i)
371  {
372  const size_t arcISize = this->funcCtrlPt_[i].size();
373  size_t& j = this->funcEvalArcCacheIdxUnder_[i];
374  while (this->funcsArc(i, j) < arcEvalNewBound)
375  {
376  if (++j >= arcISize)
377  {
378  break;
379  }
380  } //--j;
381  j = std::max(0, (int)j - 1);
382  }
383  }
384  else
385  {
386  for (size_t i = 0; i < funcsArcSz; ++i)
387  {
388  size_t& j = this->funcEvalArcCacheIdxUnder_[i];
389  while (this->funcsArc(i, j) >= arcEvalNewBound)
390  {
391  if (j == 0)
392  {
393  break;
394  }
395  --j;
396  }
397  }
398  }
399  break;
400  case eag::AT_BEGIN:
401  for (size_t i = 0; i < funcsArcSz; ++i)
402  {
403  this->funcEvalArcCacheIdxUnder_[i] = 0;
404  }
405  break;
406  case eag::AT_END:
407  for (size_t i = 0; i < funcsArcSz; ++i)
408  {
409  this->funcEvalArcCacheIdxUnder_[i] = this->funcCtrlPt_[this->arc2func_[i][0]].size() - 1;
410  }
411  break;
412  case eag::NONE:
413  for (size_t i = 0; i < funcsArcSz; ++i)
414  {
415  auto& aFuncAtArc = this->funcCtrlPt_[this->arc2func_[i][0]];
416  static TNumType referenceArc;
417  static FuncCtrlPtType dummy(0, 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,
422  [](const FuncCtrlPtType& a, const FuncCtrlPtType& b)
423  {
424  return a.arc <= b.arc;
425  })) -
426  1,
427  0);
428  }
429  break;
430  }
431  this->funcsArcEval_ = arcEvalNewBound;
432  }
433 
434 public:
435  TNumType computeFuncValImpl(const std::size_t& _funcIdx) const
436  {
437  const FuncCacheDataType& cacheData =
438  this->funcEvalCache_[_funcIdx][this->funcEvalArcCacheIdxUnder_[this->func2Arc_[_funcIdx]]];
439  return cacheData.val + cacheData.cache[asInt(FuncEvalMode::DIFF1)] * (this->funcsArcEval_ - cacheData.arc);
440  }
441 
442 public:
443  TNumType computeFuncDiff1Impl(const std::size_t& _funcIdx) const
444  {
445  const FuncCacheDataType& cacheData =
446  this->funcEvalCache_[_funcIdx][this->funcEvalArcCacheIdxUnder_[this->func2Arc_[_funcIdx]]];
447  return cacheData.cache[asInt(FuncEvalMode::DIFF1)];
448  }
449 
450 public:
451  TNumType computeFuncDiff2Impl(const std::size_t& _funcIdx) const
452  {
453  return 0;
454  }
455 
456 public:
457  TNumType computeFuncInt1Impl(const std::size_t& _funcIdx) const
458  {
459  const FuncCacheDataType& cacheData =
460  this->funcEvalCache_[_funcIdx][this->funcEvalArcCacheIdxUnder_[this->func2Arc_[_funcIdx]]];
461  return cacheData.cache[asInt(FuncEvalMode::INT1)] + computeFuncDeltaInt1(_funcIdx, this->funcsArcEval_);
462  }
463 
464 public:
465  TNumType computeFuncInt2Impl(const std::size_t& _funcIdx) const
466  {
467  const FuncCacheDataType& cacheData =
468  this->funcEvalCache_[_funcIdx][this->funcEvalArcCacheIdxUnder_[this->func2Arc_[_funcIdx]]];
469  return cacheData.cache[asInt(FuncEvalMode::INT2)] + computeFuncDeltaInt2(_funcIdx, this->funcsArcEval_);
470  }
471 
474 private:
475  TNumType computeFuncDeltaInt1(const std::size_t& _funcIdx, const TNumType& _arcEnd) const
476  {
477  const FuncCacheDataType& ctrlPtLow =
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.;
481  }
484 private:
485  TNumType computeFuncDeltaInt2(const std::size_t& _funcIdx, const TNumType& _arcEnd) const
486  {
487  const FuncCacheDataType& ctrlPtLow =
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.;
492  }
493 
494  // ///@brief Contains the index of the \htmlonly<u>next</u>\endhtmlonly control point relative to the last
495  // evaluation point.
496  // protected: std::vector< std::size_t > funcEvalArcCacheIdxUnder_;
497  // ///@brief Cached values of the used function evaluation modes.
498  // protected: std::vector< std::vector< FuncCacheDataType > > funcEvalCache_;
499  // ///@brief Maps the arc parametrizations to the functions that use them.
500  // private : std::vector< std::vector<std::size_t> > arc2func_;
501 
502  //--------------------------------------- ParamFuncDist implementation ---------------------------------------//
503 
505 
506  //(re-)implemented virtual functions
507 public:
508  void setDistCfModeImpl(TraveledDistCfMode _distCfMode, const std::vector<std::size_t>& _distRelFuncIdx)
509  {
510  distCfMode_ = _distCfMode;
511  distRelFuncIdx_ = _distRelFuncIdx;
512  switch (distCfMode_)
513  {
514  case TDM::NONE:
515  break;
516  case TDM::V:
517  distLinkedFuncIdx_.resize(1, _distRelFuncIdx[0]);
518  distEvalCache_.resize(this->funcCtrlPt_[_distRelFuncIdx[0]].size(), 0);
519  computeSFuncPtr_ = &ParamFuncsSpline0Dist::computeS_V;
520  computeDs2DtPtr_ = &ParamFuncsSpline0Dist::computeT_V;
521  distLinkedArcIdx_ = this->func2Arc_[_distRelFuncIdx[0]];
522  break;
523  case TDM::AV:
524  distLinkedFuncIdx_.resize(1, _distRelFuncIdx[0]);
525  distEvalCache_.resize(this->funcCtrlPt_[_distRelFuncIdx[0]].size(), 0);
526  computeSFuncPtr_ = &ParamFuncsSpline0Dist::computeS_AV;
527  computeDs2DtPtr_ = &ParamFuncsSpline0Dist::computeT_AV;
528  distLinkedArcIdx_ = this->func2Arc_[_distRelFuncIdx[0]];
529  break;
530  }
531  }
532 
533 public:
534  TNumType computeSImpl() const
535  {
536  return (this->*computeSFuncPtr_)();
537  }
538 
539 public:
540  TNumType computeTImpl(const TNumType& _s, const EvalArcGuarantee& _evalArcGuarantee)
541  {
542  size_t& arcIdx = this->funcEvalArcCacheIdxUnder_[distLinkedArcIdx_];
543 
544  const size_t cacheCtrlPtIdxRestore = arcIdx;
545  const size_t cacheArcEvalRestore = this->funcsArcEval_;
546 
547  TNumType resultT = computeTImplInternal(_s, _evalArcGuarantee);
548 
549  arcIdx = cacheCtrlPtIdxRestore;
550  this->funcsArcEval_ = cacheArcEvalRestore;
551 
552  return resultT;
553  }
554 
555 public:
556  void setEvalDistImpl(const TNumType& _funcsDistEval, const EvalArcGuarantee& _evalArcGuarantee)
557  {
558  this->setEvalArc(computeTImplInternal(_funcsDistEval, _evalArcGuarantee), _evalArcGuarantee);
559  }
560 
561 public:
562  void computeS2TLatticeImpl(const std::vector<TNumType>& _sLattice, std::vector<TNumType>& _tLattice)
563  {
564  const size_t slSize = _sLattice.size();
565  _tLattice.clear();
566  _tLattice.reserve(_sLattice.size());
567 
568  if (slSize > 0)
569  {
570  size_t i = 0;
571  this->setEvalDist(_sLattice[i], EvalArcGuarantee::NONE);
572  while ((this->funcsArcEval_ < this->funcsArcEnd_) && (i + 1 < slSize))
573  {
574  _tLattice.emplace_back(this->funcsArcEval_);
575  this->setEvalDist(_sLattice[++i], EvalArcGuarantee::NEAR_LAST);
576  }
577  }
578  _tLattice.emplace_back(this->funcsArcEnd_);
579  this->setEvalArc(this->funcsArcBegin_, EvalArcGuarantee::AT_BEGIN);
580  }
581 
582 public:
583  void computeS2TLatticeImpl(const TNumType& _arc0, const TNumType& _ds, std::vector<TNumType>& _tLattice)
584  {
585  this->setEvalArc(_arc0, EvalArcGuarantee::NONE);
586  _tLattice.clear();
587  _tLattice.reserve(distEvalCache_.back() / _ds);
588  const int idxBeforeStart = static_cast<int>(computeSImpl() / _ds) - 1;
589 
590  size_t i = 0;
591  this->setEvalDist(_ds * (++i + idxBeforeStart), EvalArcGuarantee::NEAR_LAST);
592  while (this->funcsArcEval_ < this->funcsArcEnd_)
593  {
594  _tLattice.emplace_back(this->funcsArcEval_);
595  this->setEvalDist(_ds * (++i + idxBeforeStart), EvalArcGuarantee::NEAR_LAST);
596  }
597  _tLattice.emplace_back(this->funcsArcEnd_);
598  this->setEvalArc(this->funcsArcBegin_, EvalArcGuarantee::AT_BEGIN);
599  }
600 
603 public:
604  static TNumType computeDeltaS_V_AV(const TNumType& _dt, const TNumType& _v0, const TNumType& _av)
605  {
606  const TNumType dtAbs = fabs(_dt);
607  if (dtAbs < FLT_MIN)
608  {
609  return 0;
610  }
611  const TNumType vAbs = fabs(_v0);
612  if (fabs(_av) < FLT_MIN)
613  {
614  return vAbs * _dt;
615  }
616  const TNumType v1 = _v0 + _av * dtAbs;
617  if (signum(v1) == signum(_v0))
618  {
619  return fabs(_v0 + v1) * _dt / 2.;
620  }
621  else
622  {
623  int retSign = 1;
624  if (_dt < 0)
625  {
626  retSign = -1;
627  }
628  TNumType dt1 = -_v0 / _av;
629  return retSign * (vAbs * dt1 + fabs(v1) * (dtAbs - dt1)) / 2.;
630  }
631  }
634 public:
635  static TNumType computeDeltaT_V_AV(const TNumType& _ds, const TNumType& _v0, const TNumType& _av)
636  {
637  TNumType v0 = _v0, av = _av;
638  if (v0 < 0)
639  {
640  av *= -1;
641  v0 *= -1;
642  }
643  if (fabs(av) < FLT_MIN)
644  {
645  return _ds / v0;
646  }
647 
648  int retSign = -1;
649  if (_ds < 0)
650  {
651  retSign = +1;
652  }
653  const TNumType v0v0 = v0 * v0;
654 
655  TNumType delta = v0v0 + 2. * av * fabs(_ds);
656  if (delta < 0)
657  {
658  return retSign * (+v0 + sqrt(-delta)) / av;
659  }
660  else
661  {
662  return retSign * (+v0 - sqrt(delta)) / av;
663  }
664  }
665 
667 private:
669  {
670  if (distCfMode_ == TDM::NONE)
671  {
672  return;
673  }
674 
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)
679  {
680  this->funcsArcEval_ = this->ctrlPtVal(func0Idx, funcCtrlPtIdx + 1, CtrlPtDim::ARC);
681  this->funcEvalArcCacheIdxUnder_[distLinkedArcIdx_] = funcCtrlPtIdx;
682  distEvalCache_[funcCtrlPtIdx + 1] = computeSImpl();
683  }
684  this->setEvalArc(this->funcsArcBegin_, EvalArcGuarantee::AT_BEGIN);
685  }
687 private:
688  TNumType computeTImplInternal(const TNumType& _s, const EvalArcGuarantee& _evalArcGuarantee)
689  {
690  using eag = EvalArcGuarantee;
691  size_t& arcCacheIdx = this->funcEvalArcCacheIdxUnder_[distLinkedArcIdx_];
692  const size_t ctrlPtSize = this->funcCtrlPt_[distLinkedFuncIdx_[0]].size();
693 
694  switch (_evalArcGuarantee)
695  {
696  case eag::NEAR_LAST:
697  {
698  const TNumType& distCache = distEvalCache_[arcCacheIdx];
699  if (distCache <= _s)
700  {
701  while (distEvalCache_[arcCacheIdx] <= _s)
702  {
703  if (++arcCacheIdx >= ctrlPtSize)
704  {
705  break;
706  }
707  }
708  --arcCacheIdx;
709  }
710  else
711  {
712  while (distEvalCache_[arcCacheIdx] >= _s)
713  {
714  if (arcCacheIdx == 0)
715  {
716  break;
717  }
718  --arcCacheIdx;
719  }
720  }
721  break;
722  }
723  case eag::AT_BEGIN:
724  arcCacheIdx = 0;
725  break;
726  case eag::AT_END:
727  arcCacheIdx = this->funcCtrlPt_[distLinkedFuncIdx_[0]].size() - 1;
728  break;
729  case eag::NONE:
730  arcCacheIdx =
731  std::distance(distEvalCache_.begin(), std::upper_bound(distEvalCache_.begin(), distEvalCache_.end(), _s)) -
732  1;
733  break;
734  }
735  this->funcsArcEval_ = this->ctrlPtVal(distLinkedFuncIdx_[0], arcCacheIdx, CtrlPtDim::ARC);
736 
737  return this->funcsArcEval_ + (this->*computeDs2DtPtr_)(_s - distEvalCache_[arcCacheIdx]);
738  }
740 private:
741  TNumType computeS_V() const
742  {
743  const size_t& funcIdx = distLinkedFuncIdx_[0];
744  const FuncCacheDataType& cacheData =
745  this->funcEvalCache_
746  [funcIdx][this->funcEvalArcCacheIdxUnder_[this->func2Arc_[funcIdx]]]; //*funcEvalCacheIter_[funcIdx];
747  return distEvalCache_[this->funcEvalArcCacheIdxUnder_[distLinkedArcIdx_]] +
748  computeDeltaS_V_AV(this->funcsArcEval_ - cacheData.arc, cacheData.val, this->computeFuncDiff1(funcIdx));
749  }
751 private:
752  TNumType computeS_AV() const
753  {
754  const size_t& funcIdx = distLinkedFuncIdx_[0];
755  const FuncCacheDataType& cacheData =
756  this->funcEvalCache_
757  [funcIdx][this->funcEvalArcCacheIdxUnder_[this->func2Arc_[funcIdx]]]; //*funcEvalCacheIter_[funcIdx];
758  return distEvalCache_[this->funcEvalArcCacheIdxUnder_[distLinkedArcIdx_]] +
759  computeDeltaS_V_AV(this->funcsArcEval_ - cacheData.arc, this->computeFuncInt1(funcIdx), cacheData.val);
760  }
763 private:
764  TNumType computeT_V(const TNumType& _ds) const
765  {
766  const size_t& funcIdx = distLinkedFuncIdx_[0];
767  return computeDeltaT_V_AV(_ds, this->computeFuncVal(funcIdx), this->computeFuncDiff1(funcIdx));
768  }
771 private:
772  TNumType computeT_AV(const TNumType& _ds) const
773  {
774  const size_t& funcIdx = distLinkedFuncIdx_[0];
775  return computeDeltaT_V_AV(_ds, this->computeFuncInt1(funcIdx), this->computeFuncVal(funcIdx));
776  }
777 
779 private:
780  std::vector<std::size_t> distLinkedFuncIdx_;
782 private:
783  std::vector<TNumType> distEvalCache_;
785 private:
786  TraveledDistCfMode distCfMode_;
788 private:
789  std::vector<std::size_t> distRelFuncIdx_;
791 private:
792  std::size_t distLinkedArcIdx_;
793 
794 private:
795  using ComputeSFuncPtr = TNumType (ParamFuncsSpline0Dist::*)() const;
796 
797 private:
798  using ComputeDs2DtPtr = TNumType (ParamFuncsSpline0Dist::*)(const TNumType&) const;
799 
800 private:
801  ComputeSFuncPtr computeSFuncPtr_;
802 
803 private:
804  ComputeDs2DtPtr computeDs2DtPtr_;
805 
806  template <typename TDerived2, typename TNumType2, int TFuncSize2, int TArcLatticeSize2>
807  friend class ParamFuncsBase;
808 };
809 }
810 
811 #endif // PARAM_FUNC_SPLINE0_DIST_HPP
TraveledDistCfMode distCfMode_
Closed form distance computation mode.
TNumType & arc
control point arc parameter
Definition: param_func.hpp:97
std::array< std::vector< FuncCacheData< TNumType > >, TFuncSize > funcEvalCache_
Cached values of the used function evaluation modes.
double(ParamFuncsSpline0Dist::*)() const ComputeSFuncPtr
TNumType computeT_V(const TNumType &_ds) const
Computes arc parametrization on a piecewise linear function describing the center linear velocity at ...
std::array< std::size_t, TArcLatticeSize > funcEvalArcCacheIdxUnder_
Contains the index of the <u>next</u> control point relative to the last evaluation point...
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
Definition: utils.h:87
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 ...
function single integral
Control point variable.
Definition: param_func.hpp:91
ParamFuncsSpline0Dist(const ParamFuncsSpline0Dist &_other)
EvalArcGuarantee
Flags if any guarantees about evaluation arc relative to last evaluation arc are present.
Definition: param_func.h:80
agent base center linear velocity is parametric function
Control point variable.
Definition: param_func.h:115
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
std::array< std::vector< std::size_t >, TArcLatticeSize > arc2func_
Maps the arc parametrizations to the functions that use them.
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.
Definition: param_func.hpp:61
constexpr int signum(T x, std::false_type is_signed)
Definition: utils.h:45
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.
Definition: param_func.hpp:45
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_
function double integral
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.


tuw_control
Author(s): George Todoran
autogenerated on Mon Jun 10 2019 15:27:21