1 #ifndef GRAIL_BEZIER_SPLINE_H
2 #define GRAIL_BEZIER_SPLINE_H
5 #include "../../libs/vector2/vector2.h"
13 template <
typename ContextType>
29 const std::vector<Vector2>& points,
30 const std::vector<Vector2>& tangents,
31 float epsilon = 0.001f)
32 :
Curve<ContextType>{childEvaluator}, points(points), tangents{ tangents }, epsilon{ epsilon }
45 std::vector<Vector2>&& points,
46 std::vector<Vector2>&& tangents,
47 float epsilon = 0.001f)
48 :
Curve<ContextType>{childEvaluator}, points(std::move(points)), tangents(std::move(tangents)), epsilon{ epsilon }
53 virtual float Sample(
float argument)
const override final
55 if (argument <= points.front().x)
56 return points.front().y;
57 else if (argument > points.back().x)
58 return points.back().y;
60 for (std::size_t i = 1; i < points.size(); ++i)
62 if (argument == points[i].x)
65 if (argument > points[i - 1].x && argument < points[i].x)
73 float middle = (begin + end) / 2.0f;
74 result = BezierInterpolation(i - 1, i, middle);
76 if (result.x < argument)
81 while (end - begin > epsilon);
93 std::vector<Vector2>&
GetPoints() {
return points; }
98 const std::vector<Vector2>&
GetPoints()
const {
return points; }
109 const std::vector<Vector2>&
GetTangents()
const {
return tangents; }
111 EvaluatorType GetEvaluatorType() const override final {
return EvaluatorType::CURVE_BEZIER; }
116 assert(points.size() > 1);
117 assert(points.size() == tangents.size());
118 Vector2 leftVelocity = tangents.front();
119 leftGradient = leftVelocity.x != 0 ? leftVelocity.y / leftVelocity.x : std::numeric_limits<float>::quiet_NaN();
120 leftIntercept = leftVelocity.y - leftGradient * leftVelocity.x;
122 Vector2 rightVelocity = tangents.back();
123 rightGradient = rightVelocity.x != 0 ? rightVelocity.y / rightVelocity.x : std::numeric_limits<float>::quiet_NaN();
124 rightIntercept = rightVelocity.y - rightGradient * rightVelocity.x;
127 Vector2 BezierInterpolation(
const std::size_t beginIndex,
const std::size_t endIndex,
float t)
const
129 static const float BINOMIAL_COEFFICIENTS[4] = { 1, 3, 3, 1 };
130 Vector2 p0 = points[beginIndex];
131 Vector2 p3 = points[endIndex];
132 Vector2 p1 = p0 + tangents[beginIndex];
133 Vector2 p2 = p3 - tangents[endIndex];
134 Vector2 interpPoints[4]{ p0, p1, p2, p3 };
136 float tComponent = 1;
137 float oneMinusT = 1 - t;
138 float oneMinusTComponent = oneMinusT * oneMinusT * oneMinusT;
139 Vector2 result{ 0, 0 };
140 for (
int pointIndex = 0; pointIndex < 4; ++pointIndex)
142 result += BINOMIAL_COEFFICIENTS[pointIndex] *
145 interpPoints[pointIndex];
147 oneMinusTComponent /= (1 - t);
153 std::vector<Vector2> points{};
154 std::vector<Vector2> tangents{};
155 float epsilon = 0.0f;
157 float leftGradient = 0.0f;
158 float leftIntercept = 0.0f;
159 float rightGradient = 0.0f;
160 float rightIntercept = 0.0f;
The BezierSpline class -Composite Cubic Bezier Curve.
Definition: BezierSpline.hh:19
std::vector< Vector2 > & GetPoints()
GetPoints.
Definition: BezierSpline.hh:93
virtual float Sample(float argument) const override final
Sample - Transforms argument into output value depending on the type of Curve.
Definition: BezierSpline.hh:53
const std::vector< Vector2 > & GetTangents() const
GetTangents.
Definition: BezierSpline.hh:109
BezierSpline(std::shared_ptr< utility::Evaluator< ContextType >> childEvaluator, const std::vector< Vector2 > &points, const std::vector< Vector2 > &tangents, float epsilon=0.001f)
BezierSpline - Constructor.
Definition: BezierSpline.hh:28
std::vector< Vector2 > & GetTangents()
GetTangents.
Definition: BezierSpline.hh:104
BezierSpline(std::shared_ptr< utility::Evaluator< ContextType >> childEvaluator, std::vector< Vector2 > &&points, std::vector< Vector2 > &&tangents, float epsilon=0.001f)
BezierSpline - Constructor.
Definition: BezierSpline.hh:44
const std::vector< Vector2 > & GetPoints() const
GetPoints.
Definition: BezierSpline.hh:98
The Curve class - Defines objects transforming one value into the other.
Definition: Curve.hh:21
The Evaluator class - base class being able to evaluate given context and output the result.
Definition: Evaluator.hh:21