pub fn catmull_rom_to_bezier<V: Animatable>(
    p0: &V,
    p1: &V,
    p2: &V,
    p3: &V,
    t0: f64,
    t1: f64,
    t2: f64,
    t3: f64,
) -> (V, V, V, V) {
    // Inner knot distance
    let s = t2 - t1;

    // Sample central difference around start and end
    let a1 = catmull_rom_value(p0, p1, p2, p3, t0, t1, t2, t3, t1 - s * TANGENT_EPSILON);
    let b1 = catmull_rom_value(p0, p1, p2, p3, t0, t1, t2, t3, t1 + s * TANGENT_EPSILON);

    let a2 = catmull_rom_value(p0, p1, p2, p3, t0, t1, t2, t3, t2 - s * TANGENT_EPSILON);
    let b2 = catmull_rom_value(p0, p1, p2, p3, t0, t1, t2, t3, t2 + s * TANGENT_EPSILON);

    // Scale to appropriate range
    // Bezier has factor of 3, central difference has factor of 2
    let d1 = b1
        .zip_map(a1, |b, a| b - a)
        .map(|d| d * V::cast_component(1.0 / (TANGENT_EPSILON * 6.0)));
    let d2 = a2
        .zip_map(b2, |b, a| b - a)
        .map(|d| d * V::cast_component(1.0 / (TANGENT_EPSILON * 6.0)));

    (
        *p1,
        p1.zip_map(d1, |val, d| val + d),
        p2.zip_map(d2, |val, d| val + d),
        *p2,
    )
}
// Convert non-uniform catmull rom to equivalent bezier spline
//
// Uses numerical approximation
Convert non-uniform catmull rom to equivalent bezier spline
Uses numerical approximation
Convert non - uniform catmull rom to equivalent bezier spline Uses numerical approximation
pub fn catmull_rom_to_bezier<V: Animatable>(
    p0: &V,
    p1: &V,
    p2: &V,
    p3: &V,
    t0: f64,
    t1: f64,
    t2: f64,
    t3: f64,
) -> (V, V, V, V) {
    // Inner knot distance
    let s = t2 - t1;
    // Sample central difference around start and end
    let a1 = catmull_rom_value(p0, p1, p2, p3, t0, t1, t2, t3, t1 - s * TANGENT_EPSILON);
    let b1 = catmull_rom_value(p0, p1, p2, p3, t0, t1, t2, t3, t1 + s * TANGENT_EPSILON);
    let a2 = catmull_rom_value(p0, p1, p2, p3, t0, t1, t2, t3, t2 - s * TANGENT_EPSILON);
    let b2 = catmull_rom_value(p0, p1, p2, p3, t0, t1, t2, t3, t2 + s * TANGENT_EPSILON);
    // Scale to appropriate range
    // Bezier has factor of 3, central difference has factor of 2
    let d1 = b1
        .zip_map(a1, |b, a| b - a)
        .map(|d| d * V::cast_component(1.0 / (TANGENT_EPSILON * 6.0)));
    let d2 = a2
        .zip_map(b2, |b, a| b - a)
        .map(|d| d * V::cast_component(1.0 / (TANGENT_EPSILON * 6.0)));
    (
        *p1,
        p1.zip_map(d1, |val, d| val + d),
        p2.zip_map(d2, |val, d| val + d),
        *p2,
    )
}
pub fn catmull_rom_to_bezier < V : Animatable > ( p0 : & V , p1 : & V , p2 : & V , p3 : & V , t0 : f64 , t1 : f64 , t2 : f64 , t3 : f64 , ) -> ( V , V , V , V ) { // Inner knot distance let s = t2 - t1 ; // Sample central difference around start and end let a1 = catmull_rom_value ( p0 , p1 , p2 , p3 , t0 , t1 , t2 , t3 , t1 - s * TANGENT_EPSILON ) ; let b1 = catmull_rom_value ( p0 , p1 , p2 , p3 , t0 , t1 , t2 , t3 , t1 + s * TANGENT_EPSILON ) ; let a2 = catmull_rom_value ( p0 , p1 , p2 , p3 , t0 , t1 , t2 , t3 , t2 - s * TANGENT_EPSILON ) ; let b2 = catmull_rom_value ( p0 , p1 , p2 , p3 , t0 , t1 , t2 , t3 , t2 + s * TANGENT_EPSILON ) ; // Scale to appropriate range // Bezier has factor of 3, central difference has factor of 2 let d1 = b1 . zip_map ( a1 , | b , a | b - a ) . map ( | d | d * V :: cast_component ( 1.0 / ( TANGENT_EPSILON * 6.0 ) ) ) ; let d2 = a2 . zip_map ( b2 , | b , a | b - a ) . map ( | d | d * V :: cast_component ( 1.0 / ( TANGENT_EPSILON * 6.0 ) ) ) ; ( * p1 , p1 . zip_map ( d1 , | val , d | val + d ) , p2 . zip_map ( d2 , | val , d | val + d ) , * p2 , ) }
Convert non-uniform catmull rom to equivalent bezier spline
Uses numerical approximation
Convert non - uniform catmull rom to equivalent bezier spline Uses numerical approximation
p0
&V
p1
&V
p2
&V
p3
&V
t0
f64
t1
f64
t2
f64
t3
f64
p0
&V
p1
&V
p2
&V
p3
&V
t0
f64
t1
f64
t2
f64
t3
f64