From cd6e9ba5e719850cf948ff54371167f7fd09f466 Mon Sep 17 00:00:00 2001 From: Taco de Wolff Date: Sun, 12 Jan 2025 11:20:11 +0100 Subject: [PATCH] Path intersections: fix bug when snapping creates intersections in the same column --- path_intersection.go | 10 ++++++++-- path_intersection_test.go | 1 + 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/path_intersection.go b/path_intersection.go index 8770b2a..7735f68 100644 --- a/path_intersection.go +++ b/path_intersection.go @@ -1936,6 +1936,7 @@ func bentleyOttmann(ps, qs Paths, op pathOp, fillRule FillRule) *Path { // process all events of the current column n := len(squares) x := snap(queue.Top().X, BentleyOttmannEpsilon) + BentleyOttmannLoop: for 0 < len(*queue) && snap(queue.Top().X, BentleyOttmannEpsilon) == x { event := queue.Top() // TODO: breaking intersections into two right and two left endpoints is not the most @@ -2088,8 +2089,10 @@ func bentleyOttmann(ps, qs Paths, op pathOp, fillRule FillRule) *Path { } if 0 < len(*queue) && snap(queue.Top().X, BentleyOttmannEpsilon) == x { - // TODO: this happens very rarely, but apparently not a bug, why not? - fmt.Println("WARNING: new intersections in this column!") + //fmt.Println("WARNING: new intersections in this column!") + goto BentleyOttmannLoop // TODO: is this correct? seems to work + // TODO: almost parallel combined with overlapping segments may create many intersections considering order of + // of overlapping segments and snapping after each column } else if has { // sort overlapping segments again // this is needed when segments get cut and now become equal to the adjacent @@ -2187,6 +2190,9 @@ func bentleyOttmann(ps, qs Paths, op pathOp, fillRule FillRule) *Path { } } if next == nil { + fmt.Println(ps) + fmt.Println(op) + fmt.Println(qs) panic("next node for result polygon is nil, probably buggy intersection code") break } else if next == first { diff --git a/path_intersection_test.go b/path_intersection_test.go index deb301f..94cd90d 100644 --- a/path_intersection_test.go +++ b/path_intersection_test.go @@ -1349,6 +1349,7 @@ func TestPathSettle(t *testing.T) { {NonZero, "M3.013236014856396 2.0031317319105995L2.999840299505024 1.999840299505024zM2.999840299505024 2.000159700494976L3.0059914294253502 2.000159700494976L2.999840299505024 1.993265873649733zM3.000159700494976 1.999840299505024L2.360148227002341 1.999840299505024zM3.000159700494976 2.000159700494976L2.995741685965072 1.9901318032831057z", "M2.9998403000000002 1.99326587L3.00599143 2.0001597L2.9998403000000002 2.0001597z"}, {NonZero, "M0.070313747660117 7.153464460137324L0.062498752339883 7.148436252339883zM0.062498752339883 7.148438747660117L0.070313747660117 7.148438747660117z", ""}, {NonZero, "M1.828127495320234 7.578127495320234L1.828127495320234 7.562497504679766z M1.828122504679766 7.562502495320234L1.843752495320234 7.562502495320234z M1.841755539006334 7.57144770006846L1.841799370320234 7.562497504679766L1.826169379679766 7.562497504679766z M1.826169379679766 7.562502495320234L1.841799370320234 7.562502495320234z M1.841794379679766 7.562497504679766L1.841794379679766 7.567987843663488z M1.841794379679766 7.546872504679766L1.841794379679766 7.562502495320234L1.857424370320234 7.562502495320234z", "M1.82616938 7.5624975L1.84179438 7.5624975L1.84179438 7.5468725L1.85742437 7.5625025L1.84179935 7.5625025L1.84179438 7.5635166L1.84175554 7.5714477L1.8281275000000001 7.56362194L1.82617807 7.5625025z"}, + {NonZero, "M0.5791607706898958 -0.0017990842812309893L0.5791256283147277 0.0006388019799032918z M0.24732247524502785 -0.0006388019799032918L0.5791440451040444 -0.0006388019799032918L0.5790883795787067 0.0032228100758402434z", "M0.24732248 -0.0006388L0.57914404 -0.0006388L0.57914404 -0.0006387200000000001L0.5791256300000001 0.0006388L0.57908838 0.00322281z"}, } for _, tt := range tts { t.Run(fmt.Sprint(tt.p), func(t *testing.T) {