feat: add ArcCandidate and Kasa circle fitting

Foundation for the geometry simplifier that will replace consecutive line
segments with fitted arcs. Adds ArcCandidate data class, GeometrySimplifier
with stub Analyze/Apply methods, and FitCircle using the Kasa algebraic
least-squares method. Also adds InternalsVisibleTo for OpenNest.Tests on
OpenNest.Core.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-25 23:22:05 -04:00
parent 12173204d1
commit bbc02f6f3f
3 changed files with 139 additions and 0 deletions

View File

@@ -0,0 +1,43 @@
using OpenNest.Geometry;
using Xunit;
namespace OpenNest.Tests;
public class GeometrySimplifierTests
{
[Fact]
public void FitCircle_PointsOnKnownCircle_ReturnsCorrectCenterAndRadius()
{
// 21 points on a semicircle centered at (5, 3) with radius 10
var center = new Vector(5, 3);
var radius = 10.0;
var points = new List<Vector>();
for (var i = 0; i <= 20; i++)
{
var angle = i * System.Math.PI / 20;
points.Add(new Vector(
center.X + radius * System.Math.Cos(angle),
center.Y + radius * System.Math.Sin(angle)));
}
var (fitCenter, fitRadius) = GeometrySimplifier.FitCircle(points);
Assert.InRange(fitCenter.X, 4.999, 5.001);
Assert.InRange(fitCenter.Y, 2.999, 3.001);
Assert.InRange(fitRadius, 9.999, 10.001);
}
[Fact]
public void FitCircle_CollinearPoints_ReturnsInvalidCenter()
{
// Collinear points should produce degenerate result
var points = new List<Vector>
{
new(0, 0), new(1, 0), new(2, 0), new(3, 0), new(4, 0)
};
var (fitCenter, _) = GeometrySimplifier.FitCircle(points);
Assert.False(fitCenter.IsValid());
}
}