| /* | |
| * Copyright 2022 Rive | |
| */ | |
| #include "rive/math/math_types.hpp" | |
| #include "rive/math/raw_path_utils.hpp" | |
| #include <cmath> | |
| // Extract subsets | |
| void rive::quad_subdivide(const rive::Vec2D src[3], float t, rive::Vec2D dst[5]) | |
| { | |
| assert(t >= 0 && t <= 1); | |
| auto ab = lerp(src[0], src[1], t); | |
| auto bc = lerp(src[1], src[2], t); | |
| dst[0] = src[0]; | |
| dst[1] = ab; | |
| dst[2] = lerp(ab, bc, t); | |
| dst[3] = bc; | |
| dst[4] = src[2]; | |
| } | |
| void rive::cubic_subdivide(const rive::Vec2D src[4], float t, rive::Vec2D dst[7]) | |
| { | |
| assert(t >= 0 && t <= 1); | |
| auto ab = lerp(src[0], src[1], t); | |
| auto bc = lerp(src[1], src[2], t); | |
| auto cd = lerp(src[2], src[3], t); | |
| auto abc = lerp(ab, bc, t); | |
| auto bcd = lerp(bc, cd, t); | |
| dst[0] = src[0]; | |
| dst[1] = ab; | |
| dst[2] = abc; | |
| dst[3] = lerp(abc, bcd, t); | |
| dst[4] = bcd; | |
| dst[5] = cd; | |
| dst[6] = src[3]; | |
| } | |
| void rive::line_extract(const rive::Vec2D src[2], float startT, float endT, rive::Vec2D dst[2]) | |
| { | |
| assert(startT <= endT); | |
| assert(startT >= 0 && endT <= 1); | |
| dst[0] = lerp(src[0], src[1], startT); | |
| dst[1] = lerp(src[0], src[1], endT); | |
| } | |
| void rive::quad_extract(const rive::Vec2D src[3], float startT, float endT, rive::Vec2D dst[3]) | |
| { | |
| assert(startT <= endT); | |
| assert(startT >= 0 && endT <= 1); | |
| rive::Vec2D tmp[5]; | |
| if (startT == 0 && endT == 1) | |
| { | |
| std::copy(src, src + 3, dst); | |
| } | |
| else if (startT == 0) | |
| { | |
| rive::quad_subdivide(src, endT, tmp); | |
| std::copy(tmp, tmp + 3, dst); | |
| } | |
| else if (endT == 1) | |
| { | |
| rive::quad_subdivide(src, startT, tmp); | |
| std::copy(tmp + 2, tmp + 5, dst); | |
| } | |
| else | |
| { | |
| assert(endT > 0); | |
| rive::quad_subdivide(src, endT, tmp); | |
| rive::Vec2D tmp2[5]; | |
| rive::quad_subdivide(tmp, startT / endT, tmp2); | |
| std::copy(tmp2 + 2, tmp2 + 5, dst); | |
| } | |
| } | |
| void rive::cubic_extract(const rive::Vec2D src[4], float startT, float endT, rive::Vec2D dst[4]) | |
| { | |
| assert(startT <= endT); | |
| assert(startT >= 0 && endT <= 1); | |
| rive::Vec2D tmp[7]; | |
| if (startT == 0 && endT == 1) | |
| { | |
| std::copy(src, src + 4, dst); | |
| } | |
| else if (startT == 0) | |
| { | |
| rive::cubic_subdivide(src, endT, tmp); | |
| std::copy(tmp, tmp + 4, dst); | |
| } | |
| else if (endT == 1) | |
| { | |
| rive::cubic_subdivide(src, startT, tmp); | |
| std::copy(tmp + 3, tmp + 7, dst); | |
| } | |
| else | |
| { | |
| assert(endT > 0); | |
| rive::cubic_subdivide(src, endT, tmp); | |
| rive::Vec2D tmp2[7]; | |
| rive::cubic_subdivide(tmp, startT / endT, tmp2); | |
| std::copy(tmp2 + 3, tmp2 + 7, dst); | |
| } | |
| } |