| #ifndef _RIVE_CUBIC_UTILITIES_HPP_ |
| #define _RIVE_CUBIC_UTILITIES_HPP_ |
| |
| #include "rive/math/vec2d.hpp" |
| #include <algorithm> |
| |
| 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 |