NicolasKlenert / enterpolation

This crate provides a myriad of different interpolation, extrapolation and animation methods.
Apache License 2.0
34 stars 3 forks source link

[bug] infinite step with equidistant #17

Closed luiswirth closed 2 years ago

luiswirth commented 2 years ago

When running the following code

use enterpolation::{bspline::BSpline, Curve};

fn main() {
    let spline = BSpline::builder()
        .clamped()
        .elements([0.0, 1.0, 2.0])
        .equidistant::<f32>() // equidistant knots
        .degree(3)
        .normalized() // domain 0.0..=1.0
        .constant::<4>() // degree + 1
        .build()
        .unwrap();

    dbg!(spline);
    for sample in spline.take(10) {
        println!("{sample}");
    }
}

I get the following (note the step: inf)

[src/main.rs:14] spline = BSpline {
    elements: [
        0.0,
        1.0,
        2.0,
    ],
    knots: BorderBuffer {
        inner: Equidistant {
            len: 1,
            step: inf,
            offset: 0.0,
        },
        n: 2,
    },
    space: ConstSpace {
        _phantom: PhantomData,
    },
    degree: 3,
}
thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', /home/luis/.local/share/cargo/registry/src/github.com-1ecc6299db9ec823/enterpolation-0.1.1/src/base/list.rs:438:51

panic at https://github.com/NicolasKlenert/enterpolation/blob/59231f4c0e2e813ff9272d76ed9d4d8f86c1a20b/src/base/list.rs#L438

NicolasKlenert commented 2 years ago

I'm trying to look into it tommorow and I will keep you updated!

NicolasKlenert commented 2 years ago

Okay so I looked into it and the reason for the bug is that the number of necessary knots (for a closed bspline of degree 3 with 3 elements) is only one, but at least two knots are necessary. This is not yet checked against. So basically a construction of such a bspline is not allowed as it is not well defined. The formula for a closed bspline (for this crate) is k = e - d + 1 with d = degree, k = #knots, e = #elements.

If you insert another element, the parameters would be fine again and you get a well behaved bspline. As the Director (basically the builder but errors are returned immediately) is public, changing the signature of the function is a breaking change.