diff --git a/OpenNest.Tests/PolyLabelTests.cs b/OpenNest.Tests/PolyLabelTests.cs index 9090bce..97e4aa3 100644 --- a/OpenNest.Tests/PolyLabelTests.cs +++ b/OpenNest.Tests/PolyLabelTests.cs @@ -24,4 +24,106 @@ public class PolyLabelTests Assert.Equal(50, result.X, 1.0); Assert.Equal(50, result.Y, 1.0); } + + [Fact] + public void Triangle_ReturnsIncenter() + { + var p = new Polygon(); + p.Vertices.Add(new Vector(0, 0)); + p.Vertices.Add(new Vector(100, 0)); + p.Vertices.Add(new Vector(50, 86.6)); + + var result = PolyLabel.Find(p); + + // Incenter of equilateral triangle is at (50, ~28.9) + Assert.Equal(50, result.X, 1.0); + Assert.Equal(28.9, result.Y, 1.0); + Assert.True(p.ContainsPoint(result)); + } + + [Fact] + public void LShape_ReturnsPointInBottomLobe() + { + // L-shape: 100x100 with 50x50 cut from top-right + var p = new Polygon(); + p.Vertices.Add(new Vector(0, 0)); + p.Vertices.Add(new Vector(100, 0)); + p.Vertices.Add(new Vector(100, 50)); + p.Vertices.Add(new Vector(50, 50)); + p.Vertices.Add(new Vector(50, 100)); + p.Vertices.Add(new Vector(0, 100)); + + var result = PolyLabel.Find(p); + + Assert.True(p.ContainsPoint(result)); + // The bottom 100x50 lobe is the widest region + Assert.True(result.Y < 50, $"Expected label in bottom lobe, got Y={result.Y}"); + } + + [Fact] + public void ThinRectangle_CenteredOnBothAxes() + { + var p = new Polygon(); + p.Vertices.Add(new Vector(0, 0)); + p.Vertices.Add(new Vector(200, 0)); + p.Vertices.Add(new Vector(200, 10)); + p.Vertices.Add(new Vector(0, 10)); + + var result = PolyLabel.Find(p); + + Assert.Equal(100, result.X, 1.0); + Assert.Equal(5, result.Y, 1.0); + Assert.True(p.ContainsPoint(result)); + } + + [Fact] + public void SquareWithLargeHole_AvoidsHole() + { + var outer = Square(100); + + var hole = new Polygon(); + hole.Vertices.Add(new Vector(20, 20)); + hole.Vertices.Add(new Vector(80, 20)); + hole.Vertices.Add(new Vector(80, 80)); + hole.Vertices.Add(new Vector(20, 80)); + + var result = PolyLabel.Find(outer, new[] { hole }); + + // Point should be inside outer but outside hole + Assert.True(outer.ContainsPoint(result)); + Assert.False(hole.ContainsPoint(result)); + } + + [Fact] + public void CShape_ReturnsPointInLeftBar() + { + // C-shape opening to the right: left bar is 20 wide, top/bottom arms are 20 tall + var p = new Polygon(); + p.Vertices.Add(new Vector(0, 0)); + p.Vertices.Add(new Vector(100, 0)); + p.Vertices.Add(new Vector(100, 20)); + p.Vertices.Add(new Vector(20, 20)); + p.Vertices.Add(new Vector(20, 80)); + p.Vertices.Add(new Vector(100, 80)); + p.Vertices.Add(new Vector(100, 100)); + p.Vertices.Add(new Vector(0, 100)); + + var result = PolyLabel.Find(p); + + Assert.True(p.ContainsPoint(result)); + // Label should be in the left vertical bar (x < 20), not at bbox center (50, 50) + Assert.True(result.X < 20, $"Expected label in left bar, got X={result.X}"); + } + + [Fact] + public void DegeneratePolygon_ReturnsFallback() + { + var p = new Polygon(); + p.Vertices.Add(new Vector(5, 5)); + + var result = PolyLabel.Find(p); + + Assert.Equal(5, result.X, 0.01); + Assert.Equal(5, result.Y, 0.01); + } }