diff --git a/OpenNest.Tests/Geometry/ArcBoundingBoxTests.cs b/OpenNest.Tests/Geometry/ArcBoundingBoxTests.cs new file mode 100644 index 0000000..ef363fe --- /dev/null +++ b/OpenNest.Tests/Geometry/ArcBoundingBoxTests.cs @@ -0,0 +1,54 @@ +using OpenNest.Geometry; + +namespace OpenNest.Tests.Geometry; + +/// +/// An arc whose sweep is below Tolerance.Epsilon must not be bounded as a full +/// circle: its box covers only the endpoints. Ordinary arcs still reach the cardinal +/// extents they cross. +/// +public class ArcBoundingBoxTests +{ + private const double Tol = 1e-9; + + [Theory] + [InlineData(false)] + [InlineData(true)] + public void NearZeroSweep_BoundsCoverOnlyTheEndpoints(bool reversed) + { + var center = new Vector(10, 20); + const double radius = 50; + const double a = 0.3; + const double b = 0.3 + 1e-6; // sweep well below Tolerance.Epsilon (1e-5) + + var arc = reversed + ? new Arc(center, radius, b, a, reversed: true) + : new Arc(center, radius, a, b); + + var x1 = center.X + radius * System.Math.Cos(a); + var y1 = center.Y + radius * System.Math.Sin(a); + var x2 = center.X + radius * System.Math.Cos(b); + var y2 = center.Y + radius * System.Math.Sin(b); + var box = arc.BoundingBox; + + Assert.Equal(System.Math.Min(x1, x2), box.X, Tol); + Assert.Equal(System.Math.Min(y1, y2), box.Y, Tol); + Assert.Equal(System.Math.Max(x1, x2), box.X + box.Length, Tol); + Assert.Equal(System.Math.Max(y1, y2), box.Y + box.Width, Tol); + } + + [Fact] + public void ArcCrossingQuarterTurn_StillReachesTopOfCircle() + { + const double radius = 10; + const double a = 0.1; + var arc = new Arc(new Vector(0, 0), radius, a, System.Math.PI - a); + + var box = arc.BoundingBox; + + Assert.Equal(-radius * System.Math.Cos(a), box.X, Tol); + Assert.Equal(radius * System.Math.Sin(a), box.Y, Tol); + Assert.Equal(radius * System.Math.Cos(a), box.X + box.Length, Tol); + Assert.Equal(radius, box.Y + box.Width, Tol); + } +} diff --git a/OpenNest.Tests/Geometry/EllipseConverterTests.cs b/OpenNest.Tests/Geometry/EllipseConverterTests.cs index 92a4bd8..f0f4913 100644 --- a/OpenNest.Tests/Geometry/EllipseConverterTests.cs +++ b/OpenNest.Tests/Geometry/EllipseConverterTests.cs @@ -3,17 +3,13 @@ using OpenNest.Geometry; using OpenNest.IO; using OpenNest.Math; using Xunit; -using Xunit.Abstractions; namespace OpenNest.Tests.Geometry; public class EllipseConverterTests { - private readonly ITestOutputHelper _output; private const double Tol = 1e-10; - public EllipseConverterTests(ITestOutputHelper output) => _output = output; - [Fact] public void EvaluatePoint_AtZero_ReturnsMajorAxisEnd() { @@ -293,31 +289,6 @@ public class EllipseConverterTests } } - [Fact] - public void DxfImport_ArcBoundingBoxes_Diagnostic() - { - var path = @"C:\Users\aisaacs\Desktop\11ga tab.dxf"; - if (!System.IO.File.Exists(path)) - return; - - var result = Dxf.Import(path); - var all = (System.Collections.Generic.IEnumerable)result.Entities; - var bbox = all.GetBoundingBox(); - _output.WriteLine( - $"Overall: X={bbox.X:F4} Y={bbox.Y:F4} W={bbox.Length:F4} H={bbox.Width:F4}" - ); - - for (var i = 0; i < result.Entities.Count; i++) - { - var e = result.Entities[i]; - var b = e.BoundingBox; - var flag = (b.Length > 1 || b.Width > 1) ? " ***" : ""; - _output.WriteLine( - $"{i + 1,3}. {e.GetType().Name,-8} X={b.X:F4} Y={b.Y:F4} W={b.Length:F4} H={b.Width:F4}{flag}" - ); - } - } - [Fact] public void ToOpenNest_FlippedNormalZ_ProducesCorrectArcs() {