Files
OpenNest/OpenNest.Tests/SplineConverterTests.cs
2026-03-27 15:16:12 -04:00

133 lines
3.9 KiB
C#

using OpenNest.Geometry;
using OpenNest.Math;
using Xunit;
namespace OpenNest.Tests;
public class SplineConverterTests
{
[Fact]
public void Convert_SemicirclePoints_ProducesSingleArc()
{
var points = new System.Collections.Generic.List<Vector>();
for (var i = 0; i <= 50; i++)
{
var t = System.Math.PI * i / 50;
points.Add(new Vector(10 * System.Math.Cos(t), 10 * System.Math.Sin(t)));
}
var result = SplineConverter.Convert(points, isClosed: false, tolerance: 0.001);
Assert.Single(result);
Assert.IsType<Arc>(result[0]);
var arc = (Arc)result[0];
Assert.InRange(arc.Radius, 9.99, 10.01);
}
[Fact]
public void Convert_StraightLinePoints_ProducesSingleLine()
{
var points = new System.Collections.Generic.List<Vector>();
for (var i = 0; i <= 10; i++)
points.Add(new Vector(i, 2 * i + 1));
var result = SplineConverter.Convert(points, isClosed: false, tolerance: 0.001);
Assert.All(result, e => Assert.IsType<Line>(e));
}
[Fact]
public void Convert_SCurve_ProducesMultipleArcs()
{
var points = new System.Collections.Generic.List<Vector>();
for (var i = 0; i <= 30; i++)
{
var t = System.Math.PI * i / 30;
points.Add(new Vector(10 * System.Math.Cos(t), 10 * System.Math.Sin(t)));
}
for (var i = 1; i <= 30; i++)
{
var t = -System.Math.PI * i / 30;
points.Add(new Vector(-20 + 10 * System.Math.Cos(t), 10 * System.Math.Sin(t)));
}
var result = SplineConverter.Convert(points, isClosed: false, tolerance: 0.001);
var arcCount = result.Count(e => e is Arc);
Assert.True(arcCount >= 2, $"Expected at least 2 arcs, got {arcCount}");
}
[Fact]
public void Convert_TwoPoints_ProducesSingleLine()
{
var points = new System.Collections.Generic.List<Vector>
{
new Vector(0, 0),
new Vector(10, 5)
};
var result = SplineConverter.Convert(points, isClosed: false, tolerance: 0.001);
Assert.Single(result);
Assert.IsType<Line>(result[0]);
}
[Fact]
public void Convert_EndpointContinuity_EntitiesConnect()
{
var points = new System.Collections.Generic.List<Vector>();
for (var i = 0; i <= 80; i++)
{
var t = Angle.TwoPI * i / 80;
points.Add(new Vector(15 * System.Math.Cos(t), 8 * System.Math.Sin(t)));
}
var result = SplineConverter.Convert(points, isClosed: false, tolerance: 0.001);
for (var i = 0; i < result.Count - 1; i++)
{
var endPt = GetEndPoint(result[i]);
var startPt = GetStartPoint(result[i + 1]);
var gap = endPt.DistanceTo(startPt);
Assert.True(gap < 0.001,
$"Gap of {gap:F6} between entity {i} and {i + 1}");
}
}
[Fact]
public void Convert_EmptyPoints_ReturnsEmpty()
{
var result = SplineConverter.Convert(new System.Collections.Generic.List<Vector>(),
isClosed: false, tolerance: 0.001);
Assert.Empty(result);
}
[Fact]
public void Convert_SinglePoint_ReturnsEmpty()
{
var points = new System.Collections.Generic.List<Vector> { new Vector(5, 5) };
var result = SplineConverter.Convert(points, isClosed: false, tolerance: 0.001);
Assert.Empty(result);
}
private static Vector GetStartPoint(Entity e)
{
return e switch
{
Arc a => a.StartPoint(),
Line l => l.StartPoint,
_ => throw new System.Exception("Unexpected entity type")
};
}
private static Vector GetEndPoint(Entity e)
{
return e switch
{
Arc a => a.EndPoint(),
Line l => l.EndPoint,
_ => throw new System.Exception("Unexpected entity type")
};
}
}