| /* | |
| * Copyright 2024 Rive | |
| */ | |
| #include "rive/math/vec2d.hpp" | |
| #include "rive/math/bezier_utils.hpp" | |
| #include <catch.hpp> | |
| namespace rive | |
| { | |
| float pow2(float x) { return x * x; } | |
| float pow3(float x) { return x * x * x; } | |
| Vec2D eval_cubic(const Vec2D* p, float t) | |
| { | |
| return pow3(1 - t) * p[0] + 3 * pow2(1 - t) * t * p[1] + | |
| 3 * (1 - t) * pow2(t) * p[2] + pow3(t) * p[3]; | |
| } | |
| void check_eval_cubic(const math::EvalCubic& evalCubic, | |
| const Vec2D* cubic, | |
| float t0, | |
| float t1) | |
| { | |
| float4 pp = evalCubic.at({t0, t0, t1, t1}); | |
| Vec2D p0 = eval_cubic(cubic, t0); | |
| Vec2D p1 = eval_cubic(cubic, t1); | |
| CHECK(pp.x == Approx(p0.x).margin(1e-3f)); | |
| CHECK(pp.y == Approx(p0.y).margin(1e-3f)); | |
| CHECK(pp.z == Approx(p1.x).margin(1e-3f)); | |
| CHECK(pp.w == Approx(p1.y).margin(1e-3f)); | |
| } | |
| TEST_CASE("EvalCubic_at", "EvalCubic") | |
| { | |
| Vec2D cubics[][4] = { | |
| {{199, 1225}, {197, 943}, {349, 607}, {549, 427}}, | |
| {{549, 427}, {349, 607}, {197, 943}, {199, 1225}}, | |
| {{460, 1060}, {403, -320}, {60, 660}, {1181, 634}}, | |
| {{1181, 634}, {60, 660}, {403, -320}, {460, 1060}}, | |
| {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, | |
| {{0, 0}, {0, 0}, {0, 0}, {100, 100}}, | |
| {{0, 0}, {0, 0}, {100, 100}, {100, 100}}, | |
| {{0, 0}, {100, 100}, {100, 100}, {0, 0}}, | |
| {{-100, -100}, {100, 100}, {100, -100}, {-100, 100}}, // Cusp | |
| }; | |
| for (auto cubic : cubics) | |
| { | |
| math::EvalCubic evalCubic(cubic); | |
| check_eval_cubic(evalCubic, cubic, 0, 1); | |
| for (float t = 0; t <= 1; t += 1e-2f) | |
| { | |
| check_eval_cubic(evalCubic, cubic, t, t + 3e-3f); | |
| } | |
| } | |
| } | |
| } // namespace rive |