18template<
typename T,
typename S = T>
19static std::array<T, 5> split_hermite_to_quadratic_beziers(
const hermite_node<T>& n0,
const hermite_node<T>& n1) {
22 bez[1] = n0.val + n0.tan * S(0.2667);
23 auto h = n1.val - n1.tan * S(0.2667);
24 bez[2] = (bez[1] + h) * S(0.5);
37template<
typename T,
typename S = T>
38static std::array<T, 4> hermite_to_cubic_bezier(
const hermite_node<T>& n0,
const hermite_node<T>& n1) {
41 n0.val + n0.tan / S(3),
42 n1.val - n1.tan / S(3),
56template<
typename T,
typename S = T>
57static std::pair<hermite_node<T>, hermite_node<T>> cubic_bezier_to_hermite(
const T& p0,
const T& p1,
const T& p2,
const T& p3) {
58 T t0 = S(3) * (p1 - p0);
59 T t1 = S(3) * (p3 - p2);
60 return { { p0, t0 }, { p3, t1 } };
72template<
typename T,
typename S = T>
73static std::array<T, 4> cubic_basis_to_bezier(
const T& b0,
const T& b1,
const T& b2,
const T& b3) {
74 constexpr S one_over_three = S(1) / S(3);
75 constexpr S one_over_six = S(1) / S(6);
76 T p0 = one_over_six * (b0 + S(4) * b1 + b2);
77 T p1 = one_over_three * (S(2) * b1 + b2);
78 T p2 = one_over_three * (b1 + S(2) * b2);
79 T p3 = one_over_six * (b1 + S(4) * b2 + b3);
80 return { p0, p1, p2, p3 };