--- a/src/geometry.cpp Thu Apr 14 11:08:20 2022 +0300 +++ b/src/geometry.cpp Mon May 16 01:40:49 2022 +0300 @@ -235,3 +235,43 @@ } return (sum < 0) ? Winding::Anticlockwise : Winding::Clockwise; } + +/** + * @brief computes the point on a Bezier curve + * @param curve + * @param t scalar between 0 and 1, with t=0 being P0 and t=1 being P3 + * @return point on curve + */ +glm::vec3 geom::pointOnCurve(const BezierCurve &curve, float t) +{ + // clamp t as rounding errors might make it slightly out of bounds + t = std::clamp(t, 0.0f, 1.0f); + const float t_2 = t * t; + const float t_3 = t * t * t; + const float coeffs[3] = { + -1*t_3 +3*t_2 -3*t +1, + +3*t_3 -6*t_2 +3*t, + -3*t_3 +3*t_2, + }; + return coeffs[0] * curve[0] + coeffs[1] * curve[1] + coeffs[2] * curve[2] + t_3 * curve[3]; +} + +/** + * @brief computes the derivative of a point on a Bezier curve + * @param curve + * @param t scalar between 0 and 1, with t=0 being P0 and t=1 being P3 + * @return point on curve + */ +glm::vec3 geom::derivativeOnCurve(const BezierCurve &curve, float t) +{ + // clamp t as rounding errors might make it slightly out of bounds + t = std::clamp(t, 0.0f, 1.0f); + const float t_2 = t * t; + const float coeffs[4] = { + -3*t_2 + 6*t -3, + +9*t_2 -12*t +3, + -9*t_2 + 6*t, + +3*t_2 + }; + return coeffs[0] * curve[0] + coeffs[1] * curve[1] + coeffs[2] * curve[2] + coeffs[3] * curve[3]; +}