Grail (C++)  1.3.0
A multi-platform, modular, universal engine for embedding advanced AI in games.
LinearlyInterpolatedCurve.hh
1 // Copyright QED Software 2023.
2 
3 #ifndef GRAIL_LINEARLY_INTERPOLATED_CURVE_H
4 #define GRAIL_LINEARLY_INTERPOLATED_CURVE_H
5 
6 #include "Curve.hh"
7 #include "../../libs/vector2/vector2.h"
8 
9 #include <algorithm>
10 #include <cassert>
11 
12 namespace grail
13 {
14 namespace evaluator
15 {
16  template <typename ContextType>
21  class LinearlyInterpolatedCurve final : public Curve<ContextType>
22  {
23  public:
29  LinearlyInterpolatedCurve(std::shared_ptr<Evaluator<ContextType>> childEvaluator,
30  const std::vector<Vector2>& points)
31  : Curve<ContextType>{childEvaluator}, points(points)
32  {
33  }
34 
40  LinearlyInterpolatedCurve(std::shared_ptr<Evaluator<ContextType>> childEvaluator,
41  std::vector<Vector2>&& points)
42  : Curve<ContextType>{childEvaluator}, points(std::move(points))
43  {
44  }
45 
46  virtual float Sample(float argument) const override final
47  {
48  assert(points.size() > 1);
49 
50  if(argument < points.front().x)
51  {
52  return points.front().y;
53  }
54  else if(argument > points.back().x)
55  {
56  return points.back().y;
57  }
58 
59  auto iter = std::find_if(points.begin(),
60  points.end(),
61  [argument](const Vector2& point) { return point.x > argument; });
62  size_t secondPointIndex = std::distance(points.begin(), iter);
63  Vector2 firstPoint = points[secondPointIndex - 1];
64  Vector2 secondPoint = points[secondPointIndex];
65 
66  float deltaY = secondPoint.y - firstPoint.y;
67  float deltaX = secondPoint.x - firstPoint.x;
68  return firstPoint.y + deltaY * (argument - firstPoint.x) / deltaX;
69  }
70 
71  void SetPointY(std::size_t pointIndex, float y) { points[pointIndex].y = y; }
72 
77  std::vector<Vector2>& GetPoints() { return points; }
82  const std::vector<Vector2>& GetPoints() const { return points; }
83 
84  virtual data::EvaluatorType GetEvaluatorType() const override final
85  {
86  return data::EvaluatorType::CURVE_LINEAR_INTERPOLATED;
87  }
88 
89  private:
90  std::vector<Vector2> points{};
91  };
92 }
93 }
94 
95 #endif // GRAIL_LINEARLY_INTERPOLATED_CURVE_H
grail::evaluator::LinearlyInterpolatedCurve::GetPoints
const std::vector< Vector2 > & GetPoints() const
GetPoints.
Definition: LinearlyInterpolatedCurve.hh:82
grail::evaluator::Evaluator
The Evaluator class - base class being able to evaluate given context and output the result.
Definition: Evaluator.hh:22
grail::evaluator::LinearlyInterpolatedCurve::LinearlyInterpolatedCurve
LinearlyInterpolatedCurve(std::shared_ptr< Evaluator< ContextType >> childEvaluator, const std::vector< Vector2 > &points)
LinearlyInterpolatedCurve - Constructor.
Definition: LinearlyInterpolatedCurve.hh:29
grail::evaluator::LinearlyInterpolatedCurve
The LinearlyInterpolatedCurve class -Curve consisting of multiple linear segments.
Definition: LinearlyInterpolatedCurve.hh:21
grail::evaluator::LinearlyInterpolatedCurve::GetPoints
std::vector< Vector2 > & GetPoints()
GetPoints.
Definition: LinearlyInterpolatedCurve.hh:77
grail::evaluator::LinearlyInterpolatedCurve::Sample
virtual float Sample(float argument) const override final
Sample - Transforms argument into output value depending on the type of Curve.
Definition: LinearlyInterpolatedCurve.hh:46
grail::evaluator::LinearlyInterpolatedCurve::LinearlyInterpolatedCurve
LinearlyInterpolatedCurve(std::shared_ptr< Evaluator< ContextType >> childEvaluator, std::vector< Vector2 > &&points)
LinearlyInterpolatedCurve - Constructor.
Definition: LinearlyInterpolatedCurve.hh:40
grail::evaluator::Curve
The Curve class - Defines objects transforming one value into the other.
Definition: Curve.hh:21