Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Panic in polygon difference #913

Open
andreaswendler opened this issue Oct 1, 2022 · 10 comments
Open

Panic in polygon difference #913

andreaswendler opened this issue Oct 1, 2022 · 10 comments

Comments

@andreaswendler
Copy link

I get a panic when executing the following code:

let p1: MultiPolygon<f32> = MultiPolygon::new(vec![Polygon::new ( LineString::from(vec![Coordinate { x: 140.50, y: 62.24 }, Coordinate { x: 140.07, y: 62.34 }, Coordinate { x: 136.94, y: 63.05 }, Coordinate { x: 140.50, y: 62.24 }]), vec![] )]);
let p2: MultiPolygon<f32> = MultiPolygon::new(vec![Polygon::new ( LineString::from(vec![Coordinate { x: 142.50, y: 61.44 }, Coordinate { x: 142.06, y: 61.55 }, Coordinate { x: 140.07, y: 62.34 }, Coordinate { x: 142.50, y: 61.44 }]), vec![] )]);

let intersection = p2.intersection(&p1);
let result = p1.difference(&intersection);

The panic looks like this:

thread 'main' panicked at 'assembly segments must be eulierian', /home/andi/.cargo/registry/src/github.com-1ecc6299db9ec823/geo-0.23.0/src/algorithm/bool_ops/assembly.rs:46:13
stack backtrace:
   0: rust_begin_unwind
             at /rustc/a55dd71d5fb0ec5a6a3a9e8c27b2127ba491ce52/library/std/src/panicking.rs:584:5
   1: core::panicking::panic_fmt
             at /rustc/a55dd71d5fb0ec5a6a3a9e8c27b2127ba491ce52/library/core/src/panicking.rs:142:14
   2: geo::algorithm::bool_ops::assembly::RegionAssembly<T>::finish
             at /home/andi/.cargo/registry/src/github.com-1ecc6299db9ec823/geo-0.23.0/src/algorithm/bool_ops/assembly.rs:46:13
   3: <geo::algorithm::bool_ops::spec::BoolOp<T> as geo::algorithm::bool_ops::spec::Spec<T>>::finish
             at /home/andi/.cargo/registry/src/github.com-1ecc6299db9ec823/geo-0.23.0/src/algorithm/bool_ops/spec.rs:52:9
   4: geo::algorithm::bool_ops::op::Proc<T,S>::sweep
             at /home/andi/.cargo/registry/src/github.com-1ecc6299db9ec823/geo-0.23.0/src/algorithm/bool_ops/op.rs:160:9
   5: <geo_types::geometry::multi_polygon::MultiPolygon<T> as geo::algorithm::bool_ops::BooleanOps>::boolean_op
             at /home/andi/.cargo/registry/src/github.com-1ecc6299db9ec823/geo-0.23.0/src/algorithm/bool_ops/mod.rs:94:9
   6: geo::algorithm::bool_ops::BooleanOps::difference
             at /home/andi/.cargo/registry/src/github.com-1ecc6299db9ec823/geo-0.23.0/src/algorithm/bool_ops/mod.rs:39:9
   7: SVGRenderer::main
             at ./src/main.rs:23:15
   8: core::ops::function::FnOnce::call_once
             at /rustc/a55dd71d5fb0ec5a6a3a9e8c27b2127ba491ce52/library/core/src/ops/function.rs:248:5

I use version 0.23.0 of the geo library with rustc 1.64.0.

I use the intersection and following difference because I need the boolean operation A & ~B which is not directly present in the included boolean operations as far as I could see.

@bobroberts177
Copy link

I ran into the same issue doing a union:

  #[test]
  fn test_geo() {
    let pg1 = Polygon::new(
      LineString(vec![
        Coordinate {x: 367.679, y: 302.785},
        Coordinate {x: 146.985, y: 90.13},
        Coordinate {x: 235.63, y: 197.771},
        Coordinate {x: 222.764, y: 233.747},
        Coordinate {x: 200.38180602615253, y: 288.3378373783007},
        Coordinate {x: 207.575, y: 288.205},
        Coordinate {x: 367.679, y: 302.785},
      ]),
      vec![],
    );

    let pg2 = Polygon::new(
      LineString(vec![
        Coordinate {x: 367.679, y: 302.785},
        Coordinate {x: 203.351, y: 279.952},
        Coordinate {x: 200.373, y: 288.338},
        Coordinate {x: 206.73187706275607, y: 288.2205700292493},
        Coordinate {x: 208.489, y: 286.233},
        Coordinate {x: 212.24, y: 285.478},
        Coordinate {x: 367.679, y: 302.785},
      ]),
      vec![],
    );

    let upg = pg1.union(&pg2);
    println!("{:?}", upg);
  }

The panic is the same:

thread 'xxx::tests::test_geo' panicked at 'assembly segments must be eulierian', xxx\geo-0.23.0\src\algorithm\bool_ops\assembly.rs:46:13

@urschrei
Copy link
Member

urschrei commented Oct 4, 2022

I’m out of action (🤒) rn, but we might try testing these errors against HEAD to see whether the recent fixes are relevant here?

@bobroberts177
Copy link

The HEAD version does indeed fix this issue. Thanks and hope you feel better!

@bobroberts177
Copy link

After returning to my original code using the HEAD version, I found a different example of the same issue.

This one fails non-deterministically so you might have to do cargo test two or three times to see it but it is the same panic.

Example code is really long, click here to see it
#[test]
fn test_polygon_union2() {
    let pg1 = Polygon::new(
        LineString(vec![
            Coordinate {
                x: 0.0,
                y: 243.4003107156999,
            },
            Coordinate {
                x: 66.27444465680952,
                y: 250.87823764635957,
            },
            Coordinate {
                x: 96.33638429757961,
                y: 248.20750628598208,
            },
            Coordinate {
                x: 96.52875443322587,
                y: 236.0960826183176,
            },
            Coordinate {
                x: 109.01797296466019,
                y: 237.22982767630356,
            },
            Coordinate {
                x: 110.67808356405288,
                y: 222.36101161840142,
            },
            Coordinate {
                x: 177.32511967843928,
                y: 245.4303896678587,
            },
            Coordinate {
                x: 220.03681983758034,
                y: 231.22020737406902,
            },
            Coordinate {
                x: 220.26051686053162,
                y: 230.70916392688252,
            },
            Coordinate {
                x: 222.76475236003864,
                y: 233.7471699986308,
            },
            Coordinate {
                x: 235.63037504441513,
                y: 197.77142864845837,
            },
            Coordinate {
                x: 46.120740248112526,
                y: 194.2466054578009,
            },
            Coordinate {
                x: 0.0,
                y: 197.3285470235943,
            },
            Coordinate {
                x: 1.6250409484162764e-15,
                y: 195.62006213211825,
            },
            Coordinate {
                x: 0.0,
                y: 195.62006213211825,
            },
            Coordinate {
                x: 0.0,
                y: 166.11923271453853,
            },
            Coordinate {
                x: 84.46350148899029,
                y: 172.13043318345098,
            },
            Coordinate {
                x: 85.18497315136065,
                y: 135.51645414474072,
            },
            Coordinate {
                x: 113.74634762902987,
                y: 143.6756896905261,
            },
            Coordinate {
                x: 120.613520578221,
                y: 116.4384347293961,
            },
            Coordinate {
                x: 120.61352057822103,
                y: 116.43843472939612,
            },
            Coordinate {
                x: 120.95625623486023,
                y: 115.07904294864129,
            },
            Coordinate {
                x: 133.11594113032265,
                y: 121.5727268145846,
            },
            Coordinate {
                x: 136.76528203129863,
                y: 99.7945926414018,
            },
            Coordinate {
                x: 136.76528203129865,
                y: 99.79459264140182,
            },
            Coordinate {
                x: 136.95169923472406,
                y: 98.68211261321306,
            },
            Coordinate {
                x: 142.86571296028092,
                y: 103.2131667249273,
            },
            Coordinate {
                x: 146.98556814305613,
                y: 90.1306295921712,
            },
            Coordinate {
                x: 149.81840786246337,
                y: 87.34720718892197,
            },
            Coordinate {
                x: 149.8184078624634,
                y: 87.34720718892198,
            },
            Coordinate {
                x: 157.36666554726634,
                y: 79.93062466875924,
            },
            Coordinate {
                x: 184.82983774975878,
                y: 111.82526107380869,
            },
            Coordinate {
                x: 211.8877775129764,
                y: 95.80693442569219,
            },
            Coordinate {
                x: 227.5571963507852,
                y: 98.78793110381741,
            },
            Coordinate {
                x: 218.607932670586,
                y: 55.083930748810644,
            },
            Coordinate {
                x: 221.83929458508348,
                y: 52.149586224826386,
            },
            Coordinate {
                x: 221.83929458508348,
                y: 52.14958622482635,
            },
            Coordinate {
                x: 232.98401357993802,
                y: 42.029257391594996,
            },
            Coordinate {
                x: 241.8190745801098,
                y: 13.993506274058689,
            },
            Coordinate {
                x: 241.1380006507843,
                y: 0.0,
            },
            Coordinate {
                x: 241.60061958968532,
                y: 2.044378041651483e-14,
            },
            Coordinate {
                x: 241.60061958968532,
                y: -2.842170943040401e-14,
            },
            Coordinate {
                x: 249.98742446013085,
                y: -2.842170943040401e-14,
            },
            Coordinate {
                x: 249.98742446013085,
                y: 1.85917124373295e-14,
            },
            Coordinate {
                x: 254.4202314064203,
                y: 2.842170943040401e-14,
            },
            Coordinate {
                x: 247.73005601682144,
                y: 120.74050514867251,
            },
            Coordinate {
                x: 259.2004570591687,
                y: 144.14650678216447,
            },
            Coordinate {
                x: 266.8397653781389,
                y: 154.40474480753,
            },
            Coordinate {
                x: 296.8607072090515,
                y: 129.49256607782735,
            },
            Coordinate {
                x: 352.116978342238,
                y: 128.0069901264593,
            },
            Coordinate {
                x: 375.0780451860593,
                y: 94.15446213853835,
            },
            Coordinate {
                x: 374.98659859747573,
                y: 100.58888400844128,
            },
            Coordinate {
                x: 375.530089594595,
                y: 124.2204839556052,
            },
            Coordinate {
                x: 400.0,
                y: 94.35082668552377,
            },
            Coordinate {
                x: 400.0,
                y: 101.6071057208606,
            },
            Coordinate {
                x: 400.0,
                y: 105.80164716197932,
            },
            Coordinate {
                x: 400.0,
                y: 113.6261499931943,
            },
            Coordinate {
                x: 400.0,
                y: 311.5380102022039,
            },
            Coordinate {
                x: 400.0,
                y: 318.2032485086692,
            },
            Coordinate {
                x: 400.0,
                y: 334.71250969254965,
            },
            Coordinate {
                x: 400.0,
                y: 352.42377480851513,
            },
            Coordinate {
                x: 367.67936762793977,
                y: 302.785219017324,
            },
            Coordinate {
                x: 243.8528456455854,
                y: 299.9323675588228,
            },
            Coordinate {
                x: 221.67982343202226,
                y: 315.355350903515,
            },
            Coordinate {
                x: 221.61838827018173,
                y: 313.1570930513446,
            },
            Coordinate {
                x: 217.6731029946546,
                y: 302.77563506887896,
            },
            Coordinate {
                x: 213.10441329274047,
                y: 314.6831957928891,
            },
            Coordinate {
                x: 212.0282774321647,
                y: 314.64026940589486,
            },
            Coordinate {
                x: 212.02827743216469,
                y: 314.64026940589486,
            },
            Coordinate {
                x: 195.75881007955047,
                y: 313.99129052009226,
            },
            Coordinate {
                x: 195.7588100795505,
                y: 313.99129052009226,
            },
            Coordinate {
                x: 178.69748010894065,
                y: 313.3107247292978,
            },
            Coordinate {
                x: 91.47746829048103,
                y: 360.79965086361875,
            },
            Coordinate {
                x: 91.50558129979011,
                y: 359.2500343818318,
            },
            Coordinate {
                x: 94.33238284142949,
                y: 356.13256626509633,
            },
            Coordinate {
                x: 91.61943785201197,
                y: 355.85870231057015,
            },
            Coordinate {
                x: 162.45878409633931,
                y: 319.40542293651487,
            },
            Coordinate {
                x: 175.5596215520651,
                y: 305.00719248486604,
            },
            Coordinate {
                x: 213.481559734292,
                y: 289.176602821379,
            },
            Coordinate {
                x: 212.24082541367974,
                y: 285.47846008552216,
            },
            Coordinate {
                x: 208.48923723966695,
                y: 286.23369014455,
            },
            Coordinate {
                x: 207.57515300304166,
                y: 288.20504863551156,
            },
            Coordinate {
                x: 206.815011642407,
                y: 288.2191843160252,
            },
            Coordinate {
                x: 206.79761990399714,
                y: 288.2195077348923,
            },
            Coordinate {
                x: 206.73263552048343,
                y: 288.22071619233367,
            },
            Coordinate {
                x: 206.69670020700084,
                y: 288.2213844497616,
            },
            Coordinate {
                x: 200.38308697914755,
                y: 288.338793163584,
            },
            Coordinate {
                x: 200.37329511724553,
                y: 288.3389752542301,
            },
            Coordinate {
                x: 195.94507795197933,
                y: 287.70516880563525,
            },
            Coordinate {
                x: 195.94507795197936,
                y: 287.70516880563525,
            },
            Coordinate {
                x: 177.75137408933563,
                y: 285.1011215329728,
            },
            Coordinate {
                x: 172.47639728970307,
                y: 284.71995173556473,
            },
            Coordinate {
                x: 172.37763068066027,
                y: 284.7175565773759,
            },
            Coordinate {
                x: 203.35149933375834,
                y: 279.95282911519445,
            },
            Coordinate {
                x: 87.0909970255105,
                y: 274.6019377637631,
            },
            Coordinate {
                x: 0.0,
                y: 291.1811710503077,
            },
            Coordinate {
                x: 1.1448520206537763e-14,
                y: 275.9029490745503,
            },
            Coordinate {
                x: -2.842170943040401e-14,
                y: 275.9029490745503,
            },
            Coordinate {
                x: 0.0,
                y: 243.4003107156999,
            },
        ]),
        vec![],
    );
    let pg2 = Polygon::new(
        LineString(vec![
            Coordinate {
                x: 367.67936762793977,
                y: 302.785219017324,
            },
            Coordinate {
                x: 400.0,
                y: 330.3364189888756,
            },
            Coordinate {
                x: 400.0,
                y: 85.7094729663055,
            },
            Coordinate {
                x: 375.530089594595,
                y: 124.2204839556052,
            },
            Coordinate {
                x: 374.98659859747573,
                y: 100.58888400844128,
            },
            Coordinate {
                x: 375.3219047536835,
                y: 76.99586322948593,
            },
            Coordinate {
                x: 352.116978342238,
                y: 128.0069901264593,
            },
            Coordinate {
                x: 296.8607072090515,
                y: 129.49256607782735,
            },
            Coordinate {
                x: 266.8397653781389,
                y: 154.40474480753,
            },
            Coordinate {
                x: 259.2004570591687,
                y: 144.14650678216447,
            },
            Coordinate {
                x: 247.73005601682144,
                y: 120.74050514867251,
            },
            Coordinate {
                x: 219.9183226476331,
                y: 53.89398800789357,
            },
            Coordinate {
                x: 214.79766598486256,
                y: 58.54396880088095,
            },
            Coordinate {
                x: 205.3180727584858,
                y: 37.66458141235276,
            },
            Coordinate {
                x: 204.9384743502853,
                y: 42.52909575499811,
            },
            Coordinate {
                x: 198.598592783954,
                y: 39.913773753454365,
            },
            Coordinate {
                x: 227.5571963507852,
                y: 98.78793110381741,
            },
            Coordinate {
                x: 211.8877775129764,
                y: 95.80693442569219,
            },
            Coordinate {
                x: 184.82983774975878,
                y: 111.82526107380869,
            },
            Coordinate {
                x: 157.3407287714804,
                y: 79.95610899189123,
            },
            Coordinate {
                x: 146.98556814305613,
                y: 90.1306295921712,
            },
            Coordinate {
                x: 142.86571296028092,
                y: 103.2131667249273,
            },
            Coordinate {
                x: 137.06964785547663,
                y: 97.97823184186473,
            },
            Coordinate {
                x: 133.11594113032265,
                y: 121.5727268145846,
            },
            Coordinate {
                x: 121.48741956113471,
                y: 112.97229086146046,
            },
            Coordinate {
                x: 121.26181604684658,
                y: 113.86710164957617,
            },
            Coordinate {
                x: 235.63037504441513,
                y: 197.77142864845837,
            },
            Coordinate {
                x: 222.76475236003864,
                y: 233.7471699986308,
            },
            Coordinate {
                x: 215.48785333121916,
                y: 232.73364849354883,
            },
            Coordinate {
                x: 177.32511967843928,
                y: 245.4303896678587,
            },
            Coordinate {
                x: 96.36950989237457,
                y: 246.12195328963338,
            },
            Coordinate {
                x: 96.33638429757961,
                y: 248.20750628598208,
            },
            Coordinate {
                x: 66.27444465680952,
                y: 250.87823764635957,
            },
            Coordinate {
                x: 5.684341886080802e-14,
                y: 252.7246858385403,
            },
            Coordinate {
                x: 0.0,
                y: 287.00851453579764,
            },
            Coordinate {
                x: 87.0909970255105,
                y: 274.6019377637631,
            },
            Coordinate {
                x: 203.35149933375834,
                y: 279.95282911519445,
            },
            Coordinate {
                x: 186.21553206604779,
                y: 286.312588294279,
            },
            Coordinate {
                x: 200.37329511724553,
                y: 288.3389752542301,
            },
            Coordinate {
                x: 204.07584923592933,
                y: 288.2701221108328,
            },
            Coordinate {
                x: 208.48923723966695,
                y: 286.23369014455,
            },
            Coordinate {
                x: 212.24082541367974,
                y: 285.47846008552216,
            },
            Coordinate {
                x: 213.481559734292,
                y: 289.176602821379,
            },
            Coordinate {
                x: 168.6386654992429,
                y: 312.61353982953256,
            },
            Coordinate {
                x: 162.45878409633931,
                y: 319.40542293651487,
            },
            Coordinate {
                x: 93.1525434103433,
                y: 357.43372298059234,
            },
            Coordinate {
                x: 91.50558129979011,
                y: 359.2500343818318,
            },
            Coordinate {
                x: 91.43334419528333,
                y: 363.2318140095328,
            },
            Coordinate {
                x: 178.69748010894065,
                y: 313.3107247292978,
            },
            Coordinate {
                x: 201.68701198375604,
                y: 314.2277627894801,
            },
            Coordinate {
                x: 217.6731029946546,
                y: 302.77563506887896,
            },
            Coordinate {
                x: 221.61838827018173,
                y: 313.1570930513446,
            },
            Coordinate {
                x: 221.67982343202226,
                y: 315.355350903515,
            },
            Coordinate {
                x: 243.8528456455854,
                y: 299.9323675588228,
            },
            Coordinate {
                x: 367.67936762793977,
                y: 302.785219017324,
            },
        ]),
        vec![],
    );
    let upg = pg1.union(&pg2);
    println!("{:?}", upg);
}

@andreaswendler
Copy link
Author

Unfortunately, my application also still produces panics when using the latest commit of this library.
However, I get a different error:

let p1: MultiPolygon<f32> = MultiPolygon::new(vec![Polygon::new ( LineString::from(vec![Coordinate { x: 142.50143433, y: 61.44324493 }, Coordinate { x: 142.05662537, y: 61.54975128 }, Coordinate { x: 140.07255554, y: 62.33781433 }, Coordinate { x: 142.50143433, y: 61.44324493 }]), vec![] )]);
let p2: MultiPolygon<f32> = MultiPolygon::new(vec![Polygon::new ( LineString::from(vec![Coordinate { x: 140.50358582, y: 62.23768616 }, Coordinate { x: 140.07255554, y: 62.33781433 }, Coordinate { x: 136.93997192, y: 63.05339432 }, Coordinate { x: 140.50358582, y: 62.23768616 }]), vec![] )]);

let intersection = p1.intersection(&p2);
let result = p1.difference(&intersection);

results in the output:

thread 'main' panicked at 'segment not found in active-vec-set: 2', /home/andi/.cargo/git/checkouts/geo-e2eaf128a090474c/18a9208/geo/src/algorithm/sweep/vec_set.rs:22:14
stack backtrace:
   0: rust_begin_unwind
             at /rustc/a55dd71d5fb0ec5a6a3a9e8c27b2127ba491ce52/library/std/src/panicking.rs:584:5
   1: core::panicking::panic_fmt
             at /rustc/a55dd71d5fb0ec5a6a3a9e8c27b2127ba491ce52/library/core/src/panicking.rs:142:14
   2: core::result::unwrap_failed
             at /rustc/a55dd71d5fb0ec5a6a3a9e8c27b2127ba491ce52/library/core/src/result.rs:1814:5
   3: core::result::Result<T,E>::expect
             at /rustc/a55dd71d5fb0ec5a6a3a9e8c27b2127ba491ce52/library/core/src/result.rs:1064:23
   4: geo::algorithm::sweep::vec_set::VecSet<geo::algorithm::sweep::active::Active<T>>::index_of
             at /home/andi/.cargo/git/checkouts/geo-e2eaf128a090474c/18a9208/geo/src/algorithm/sweep/vec_set.rs:20:9
   5: geo::algorithm::sweep::proc::Sweep<C>::handle_event
             at /home/andi/.cargo/git/checkouts/geo-e2eaf128a090474c/18a9208/geo/src/algorithm/sweep/proc.rs:232:30
   6: geo::algorithm::sweep::proc::Sweep<C>::next_event::{{closure}}
             at /home/andi/.cargo/git/checkouts/geo-e2eaf128a090474c/18a9208/geo/src/algorithm/sweep/proc.rs:46:13
   7: core::option::Option<T>::map
             at /rustc/a55dd71d5fb0ec5a6a3a9e8c27b2127ba491ce52/library/core/src/option.rs:929:29
   8: geo::algorithm::sweep::proc::Sweep<C>::next_event
             at /home/andi/.cargo/git/checkouts/geo-e2eaf128a090474c/18a9208/geo/src/algorithm/sweep/proc.rs:44:9
   9: <geo::algorithm::sweep::iter::CrossingsIter<C> as core::iter::traits::iterator::Iterator>::next
             at /home/andi/.cargo/git/checkouts/geo-e2eaf128a090474c/18a9208/geo/src/algorithm/sweep/iter.rs:170:26
  10: geo::algorithm::bool_ops::op::Proc<T,S>::sweep
             at /home/andi/.cargo/git/checkouts/geo-e2eaf128a090474c/18a9208/geo/src/algorithm/bool_ops/op.rs:68:30
  11: <geo_types::geometry::multi_polygon::MultiPolygon<T> as geo::algorithm::bool_ops::BooleanOps>::boolean_op
             at /home/andi/.cargo/git/checkouts/geo-e2eaf128a090474c/18a9208/geo/src/algorithm/bool_ops/mod.rs:94:9
  12: geo::algorithm::bool_ops::BooleanOps::difference
             at /home/andi/.cargo/git/checkouts/geo-e2eaf128a090474c/18a9208/geo/src/algorithm/bool_ops/mod.rs:39:9
  13: SVGRenderer::main
             at ./src/main.rs:23:15
  14: core::ops::function::FnOnce::call_once
             at /rustc/a55dd71d5fb0ec5a6a3a9e8c27b2127ba491ce52/library/core/src/ops/function.rs:248:5

@michaelkirk
Copy link
Member

michaelkirk commented Oct 5, 2022

I'm not very familiar with the bool ops implementation yet, but I did want to try to help solve this issue.

To start with, I reproduced a similar error with simpler (triangular) inputs:

#[test]
fn test_polygon_union2() {
    init_log();
    use wkt::TryFromWkt;

    let poly1: Polygon = Polygon::try_from_wkt_str("POLYGON((204.0 287.0,206.69670020700084 288.2213844497616,200.38308697914755 288.338793163584,204.0 287.0))").unwrap();
    let poly2: Polygon = Polygon::try_from_wkt_str("POLYGON((210.0 290.0,204.07584923592933 288.2701221108328,212.24082541367974 285.47846008552216,210.0 290.0))").unwrap();

    // panics!
    let upg = poly1.union(&poly2);
}

here's what those look like rendered (poly1 on the left):
Screen Shot 2022-10-05 at 3 26 10 PM

This crossing looks interesting:
image

To be clear, I have no idea if that's the point causing our slip-up, but it just looks topologically interesting to have a vertex of poly2 which appears to be on the crossing point into poly1.

dabreegster added a commit to a-b-street/abstreet that referenced this issue Nov 10, 2022
@dabreegster
Copy link
Contributor

I have a reproducible crash with difference, 0.23.0. It's almost definitely more complex than the examples listed here, but I can turn into WKT if useful. Recording how to repro for my own memory:
Screenshot from 2022-11-10 15-20-44

@michaelkirk
Copy link
Member

I thought I left a response on this long ago, sorry for letting the thread drop. Unfortunately I didn't take very good notes either, but as I recall the root of the issue was a lack of available precision.

A little more specifically:

With B.O. we maintain an invariant of visiting intersections and vertices in a certain order - (the "sweep" is monotonic).

We can robustly compute when there is an intersection, but we also need to store the actual (X,Y) value of that intersection so we can order it WRT to our other crossings, to maintain the invariant that we're sweeping monotonically.

However, because our floating point representation is finite, the number that we store may entail some error.

IIRC, this panic is happening when we have two very close intersections, such that the amount of error in the f64 representation of the intersection is enough to break the monotonicity of the sweep.

Like if we are trying to visit numbers in increasing order and we have: [1.001, 1.002], it seems easy, but if our representation only allowed storing to the tenth decimal, [1.0(01), 1.0(02)], looks like [1.0, 1.0], so we might "incorrectly" sort them as [1.0(02), 1.0(01)].

If we were trying to visit them monotonically, we might get it wrong.

Anyway, not sure if this is helpful to anyone or if I'm even remembering the issue correctly, but I wanted to record my discoveries in case it's helpful for someone down the line.

@michaelkirk
Copy link
Member

IIRC, this panic is happening when we have two very close intersections, such that the amount of error in the f64 representation of the intersection is enough to break the monotonicity of the sweep.

Looking at my debug branch a bit, I think this might be related to our usage of Float::next_after, which I recall we use as a sort of "tie breaker" in a scenario like this - maybe it's bringing in it's own problems though?

@RobWalt
Copy link
Contributor

RobWalt commented Oct 31, 2023

Implemented all the listed failed cases in this issue as test cases for a new implementation of the algo here a6184b1 and all the tests succeed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants