diff --git a/examples/overlay_editor/src/draw/path.rs b/examples/overlay_editor/src/draw/path.rs index 9dbda54..b9384b0 100644 --- a/examples/overlay_editor/src/draw/path.rs +++ b/examples/overlay_editor/src/draw/path.rs @@ -94,7 +94,7 @@ impl PathWidget { FloatPoint::new(v.x, v.y) }).collect(); - let sub_triangulation = stroke_builder.build_open_path_mesh::, usize>(&screen_path); + let sub_triangulation = stroke_builder.build_open_path_mesh::(&screen_path); builder.append(sub_triangulation); let r2 = 2.0 * width; @@ -111,7 +111,7 @@ impl PathWidget { let v0 = m0 + t0; let v1 = m0 + t1; - let arrow_triangulation = stroke_builder.build_open_path_mesh::, usize>(&[v0, m, v1]); + let arrow_triangulation = stroke_builder.build_open_path_mesh::(&[v0, m, v1]); builder.append(arrow_triangulation); a = b; diff --git a/examples/overlay_editor/src/draw/shape.rs b/examples/overlay_editor/src/draw/shape.rs index 970a136..7e3ff3a 100644 --- a/examples/overlay_editor/src/draw/shape.rs +++ b/examples/overlay_editor/src/draw/shape.rs @@ -155,7 +155,7 @@ impl ShapeWidget { .collect(); let sub_triangulation = - stroke_builder.build_closed_path_mesh::, usize>(&world_path); + stroke_builder.build_closed_path_mesh::(&world_path); builder.append(sub_triangulation); } } @@ -192,7 +192,7 @@ impl ShapeWidget { .collect(); let sub_triangulation = - stroke_builder.build_closed_path_mesh::, usize>(&world_path); + stroke_builder.build_closed_path_mesh::(&world_path); builder.append(sub_triangulation); } diff --git a/examples/tests/outline/test_8.json b/examples/tests/outline/test_8.json new file mode 100644 index 0000000..1ff8b01 --- /dev/null +++ b/examples/tests/outline/test_8.json @@ -0,0 +1,12 @@ +{ + "scale": 100.0, + "outline": [ + [ + [53.0, 42.0], + [35.0, 66.0], + [26.0, 75.0], + [27.0, 74.0], + [53.0, 42.0] + ] + ] +} \ No newline at end of file diff --git a/examples/tests/outline/test_9.json b/examples/tests/outline/test_9.json new file mode 100644 index 0000000..534d4a5 --- /dev/null +++ b/examples/tests/outline/test_9.json @@ -0,0 +1,18 @@ +{ + "scale": 100.0, + "outline": [ + [ + [0.0, 0.0], + [100.0, 0.0], + [100.0, 100.0], + [0.0, 100.0] + ], + [ + [53.0, 42.0], + [27.0, 74.0], + [26.0, 75.0], + [35.0, 66.0], + [53.0, 42.0] + ] + ] +} \ No newline at end of file diff --git a/iOverlay/Cargo.toml b/iOverlay/Cargo.toml index 7018fe9..62ef955 100644 --- a/iOverlay/Cargo.toml +++ b/iOverlay/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "i_overlay" -version = "6.0.0" +version = "6.0.1" authors = ["Nail Sharipov "] edition = "2024" rust-version = "1.88" diff --git a/iOverlay/src/mesh/outline/builder.rs b/iOverlay/src/mesh/outline/builder.rs index 5dbe2a1..d5c16c8 100644 --- a/iOverlay/src/mesh/outline/builder.rs +++ b/iOverlay/src/mesh/outline/builder.rs @@ -159,8 +159,12 @@ impl, P: FloatPointCompatible> Builder { let vp = s0.b - s0.a; let cross = vi.cross_product(vp); - debug_assert!(cross != 0, "not possible! UniqueSegmentsIter guarantee it"); - let outer_corner = (cross > 0) == self.extend; + let outer_corner = if cross != 0 { + (cross > 0) == self.extend + } else { + vi.dot_product(vp) < 0 + }; + if outer_corner { if s0.b_top != s1.a_top { self.join_builder.add_join(s0, s1, adapter, segments); diff --git a/iOverlay/src/mesh/outline/offset.rs b/iOverlay/src/mesh/outline/offset.rs index e8215e3..4937373 100644 --- a/iOverlay/src/mesh/outline/offset.rs +++ b/iOverlay/src/mesh/outline/offset.rs @@ -1220,6 +1220,24 @@ mod tests { }; } + #[test] + fn test_real_case_1_offset() { + let contour = vec![ + [53.0, 42.0], + [35.0, 66.0], + [26.0, 75.0], + [27.0, 74.0], + [53.0f64, 42.0], + ]; + + let style = OutlineStyle::new(1.0f64).line_join(LineJoin::Round(1.0f64)); + contour.outline(&style); + + if let Some(shape) = contour.outline(&style).first() { + assert!(shape[0].len() < 1_000); + }; + } + fn create_star(r0: f64, r1: f64, count: usize, angle: f64) -> Shape<[f64; 2]> { let da = core::f64::consts::PI / count as f64; let mut a = angle;