blob: 34503004a8537ce8b4e151ea2c55d363d25934da [file] [log] [blame]
 #ifndef _RIVE_CUBIC_UTILITIES_HPP_ #define _RIVE_CUBIC_UTILITIES_HPP_ #include "rive/math/vec2d.hpp" #include namespace rive { /// /// Utility functions for recursively subdividing a cubic. /// class CubicUtilities { public: static void computeHull(const Vec2D& from, const Vec2D& fromOut, const Vec2D& toIn, const Vec2D& to, float t, Vec2D* hull) { hull[0] = Vec2D::lerp(from, fromOut, t); hull[1] = Vec2D::lerp(fromOut, toIn, t); hull[2] = Vec2D::lerp(toIn, to, t); hull[3] = Vec2D::lerp(hull[0], hull[1], t); hull[4] = Vec2D::lerp(hull[1], hull[2], t); hull[5] = Vec2D::lerp(hull[3], hull[4], t); } static bool tooFar(const Vec2D& a, const Vec2D& b, float threshold) { return std::max(std::abs(a.x - b.x), std::abs(a.y - b.y)) > threshold; } static bool shouldSplitCubic(const Vec2D& from, const Vec2D& fromOut, const Vec2D& toIn, const Vec2D& to, float threshold) { Vec2D oneThird = Vec2D::lerp(from, to, 1.0f / 3.0f); Vec2D twoThird = Vec2D::lerp(from, to, 2.0f / 3.0f); return tooFar(fromOut, oneThird, threshold) || tooFar(toIn, twoThird, threshold); } static float cubicAt(float t, float a, float b, float c, float d) { float ti = 1.0f - t; float value = ti * ti * ti * a + 3.0f * ti * ti * t * b + 3.0f * ti * t * t * c + t * t * t * d; return value; } }; } // namespace rive #endif