Skip to content

Spline from fit_from_points has discontinuity #28

@nicolaschan

Description

@nicolaschan

There are sometimes discontinuities in the bezier spline given from Curve::fit_from_points. I expect the spline to consist of connecting curves. Since the spline does connect most of the time, I think it must be a bug when it isn't connected.

I've attached an example with points that trigger this bug with flo_curves = "0.7.2".

mod test {
    use flo_curves::{bezier, BezierCurve, BezierCurveFactory, Coord2};

    #[test]
    fn test_demonstrate_discontinuity() {
        let points = vec![
            Coord2(72.0, 216.0),
            Coord2(73.0, 217.0),
            Coord2(74.0, 218.0),
            Coord2(75.0, 219.0),
            Coord2(74.0, 220.0),
            Coord2(75.0, 221.0),
            Coord2(75.0, 222.0),
            Coord2(75.0, 223.0),
            Coord2(76.0, 224.0),
            Coord2(77.0, 225.0),
            Coord2(77.0, 226.0),
            Coord2(77.0, 227.0),
            Coord2(78.0, 227.0),
            Coord2(79.0, 227.0),
            Coord2(80.0, 228.0),
            Coord2(79.0, 229.0),
            Coord2(80.0, 230.0),
            Coord2(81.0, 231.0),
            Coord2(82.0, 232.0),
            Coord2(82.0, 233.0),
            Coord2(82.0, 234.0),
            Coord2(83.0, 235.0),
            Coord2(83.0, 236.0),
            Coord2(83.0, 237.0),
            Coord2(84.0, 238.0),
            Coord2(85.0, 239.0),
            Coord2(84.0, 240.0),
            Coord2(83.0, 241.0),
            Coord2(82.0, 241.0),
            Coord2(81.0, 241.0),
            Coord2(80.0, 242.0),
            Coord2(80.0, 243.0),
            Coord2(80.0, 244.0),
            Coord2(81.0, 245.0),
            Coord2(80.0, 246.0),
            Coord2(81.0, 247.0),
            Coord2(82.0, 248.0),
            Coord2(83.0, 249.0),
            Coord2(84.0, 250.0),
            Coord2(84.0, 251.0),
            Coord2(84.0, 252.0),
            Coord2(83.0, 251.0),
            Coord2(82.0, 251.0),
            Coord2(81.0, 251.0),
            Coord2(80.0, 250.0),
            Coord2(81.0, 249.0),
            Coord2(80.0, 248.0),
            Coord2(79.0, 247.0),
            Coord2(78.0, 246.0),
            Coord2(78.0, 245.0),
            Coord2(78.0, 244.0),
            Coord2(77.0, 243.0),
            Coord2(76.0, 242.0),
            Coord2(76.0, 241.0),
            Coord2(76.0, 240.0),
            Coord2(75.0, 239.0),
            Coord2(75.0, 238.0),
            Coord2(75.0, 237.0),
            Coord2(74.0, 237.0),
            Coord2(73.0, 237.0),
            Coord2(72.0, 236.0),
            Coord2(73.0, 235.0),
            Coord2(72.0, 234.0),
            Coord2(71.0, 233.0),
            Coord2(71.0, 232.0),
            Coord2(71.0, 231.0),
            Coord2(70.0, 230.0),
            Coord2(69.0, 229.0),
            Coord2(68.0, 228.0),
            Coord2(67.0, 227.0),
            Coord2(66.0, 226.0),
            Coord2(65.0, 225.0),
            Coord2(65.0, 224.0),
            Coord2(65.0, 223.0),
            Coord2(64.0, 223.0),
            Coord2(63.0, 223.0),
            Coord2(64.0, 222.0),
            Coord2(65.0, 222.0),
            Coord2(66.0, 222.0),
            Coord2(65.0, 221.0),
            Coord2(66.0, 220.0),
            Coord2(66.0, 219.0),
            Coord2(66.0, 218.0),
            Coord2(65.0, 217.0),
            Coord2(65.0, 216.0),
            Coord2(65.0, 215.0),
            Coord2(64.0, 214.0),
            Coord2(64.0, 213.0),
            Coord2(64.0, 212.0),
            Coord2(64.0, 211.0),
            Coord2(64.0, 210.0),
            Coord2(63.0, 209.0),
            Coord2(62.0, 208.0),
            Coord2(62.0, 207.0),
            Coord2(62.0, 206.0),
            Coord2(61.0, 205.0),
            Coord2(62.0, 204.0),
            Coord2(61.0, 204.0),
            Coord2(60.0, 204.0),
            Coord2(60.0, 203.0),
            Coord2(60.0, 202.0),
            Coord2(59.0, 201.0),
        ];
        let spline = bezier::Curve::fit_from_points(&points, 1.0).unwrap();
        let mut last = None;
        for curve in spline {
            if let Some(last) = last {
                if curve.start_point() != last {
                    panic!(
                        "Discontinuity detected between ({:?}, {:?}) and ({:?}, {:?})",
                        last.0,
                        last.1,
                        curve.start_point().0,
                        curve.start_point().1
                    );
                }
            }
            last = Some(curve.end_point());
        }
    }
}

The output is:

---- example::test::test_demonstrate_discontinuity stdout ----
thread 'example::test::test_demonstrate_discontinuity' panicked at src/example.rs:115:21:
Discontinuity detected between (60.0, 203.0) and (60.0, 202.0)
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions