diff --git a/OpenNest.Core/Geometry/PolyLabel.cs b/OpenNest.Core/Geometry/PolyLabel.cs index a0312ff2..92b92e2f 100644 --- a/OpenNest.Core/Geometry/PolyLabel.cs +++ b/OpenNest.Core/Geometry/PolyLabel.cs @@ -73,8 +73,18 @@ namespace OpenNest.Geometry var initial = new List(); for (var x = minX; x < maxX; x += cellSize) + { for (var y = minY; y < maxY; y += cellSize) + { initial.Add(new Cell(x + halfCell, y + halfCell, halfCell, outer, holes)); + // Far from the origin a step smaller than the coordinate's precision + // no longer advances; the grid would never end. + if (y + cellSize == y) + break; + } + if (x + cellSize == x) + break; + } initial.Sort((a, b) => b.MaxDist.CompareTo(a.MaxDist)); diff --git a/OpenNest.Tests/Geometry/PolyLabelDifferentialTests.cs b/OpenNest.Tests/Geometry/PolyLabelDifferentialTests.cs index 95144815..e010d96a 100644 --- a/OpenNest.Tests/Geometry/PolyLabelDifferentialTests.cs +++ b/OpenNest.Tests/Geometry/PolyLabelDifferentialTests.cs @@ -68,6 +68,21 @@ public class PolyLabelDifferentialTests Assert.True(Same(PolyLabel.Find(shape), PolyLabel.Find(shape, null, 0.5, int.MaxValue))); } + // Quality review: at 1e16 a 1-unit grid step no longer changes x (1e16 + 1 == 1e16), and + // the starting grid loop never ended, allocating cells without limit even with a budget. + [Fact] + public async Task Find_FinishesWhenGridStepsStopAdvancingFarFromTheOrigin() + { + var far = Rectangle(1e16, 0, 8, 1); + + var search = Task.Run(() => (PolyLabel.Find(far, null, 0.01, 4096), PolyLabel.Find(far, null, 0.01))); + + Assert.Same(search, await Task.WhenAny(search, Task.Delay(TimeSpan.FromSeconds(20)))); + var (bounded, unbounded) = await search; + Assert.InRange(bounded.Y, 0, 1); + Assert.InRange(unbounded.Y, 0, 1); + } + private static (Polygon outer, List holes) RandomShape(Random random) { var scale = System.Math.Pow(10, random.NextDouble() * 4 - 1);