feat: add EllipseConverter evaluation helpers with tests
Add EllipseConverter static class with foundational methods for converting ellipse parameters to circular arcs: EvaluatePoint, EvaluateTangent, EvaluateNormal, and IntersectNormals. All 8 unit tests pass. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
81
OpenNest.Tests/EllipseConverterTests.cs
Normal file
81
OpenNest.Tests/EllipseConverterTests.cs
Normal file
@@ -0,0 +1,81 @@
|
||||
using OpenNest.Geometry;
|
||||
using OpenNest.Math;
|
||||
using Xunit;
|
||||
|
||||
namespace OpenNest.Tests;
|
||||
|
||||
public class EllipseConverterTests
|
||||
{
|
||||
private const double Tol = 1e-10;
|
||||
|
||||
[Fact]
|
||||
public void EvaluatePoint_AtZero_ReturnsMajorAxisEnd()
|
||||
{
|
||||
var p = EllipseConverter.EvaluatePoint(10, 5, 0, new Vector(0, 0), 0);
|
||||
Assert.InRange(p.X, 10 - Tol, 10 + Tol);
|
||||
Assert.InRange(p.Y, -Tol, Tol);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EvaluatePoint_AtHalfPi_ReturnsMinorAxisEnd()
|
||||
{
|
||||
var p = EllipseConverter.EvaluatePoint(10, 5, 0, new Vector(0, 0), System.Math.PI / 2);
|
||||
Assert.InRange(p.X, -Tol, Tol);
|
||||
Assert.InRange(p.Y, 5 - Tol, 5 + Tol);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EvaluatePoint_WithRotation_RotatesCorrectly()
|
||||
{
|
||||
var p = EllipseConverter.EvaluatePoint(10, 5, System.Math.PI / 2, new Vector(0, 0), 0);
|
||||
Assert.InRange(p.X, -Tol, Tol);
|
||||
Assert.InRange(p.Y, 10 - Tol, 10 + Tol);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EvaluatePoint_WithCenter_TranslatesCorrectly()
|
||||
{
|
||||
var p = EllipseConverter.EvaluatePoint(10, 5, 0, new Vector(100, 200), 0);
|
||||
Assert.InRange(p.X, 110 - Tol, 110 + Tol);
|
||||
Assert.InRange(p.Y, 200 - Tol, 200 + Tol);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EvaluateTangent_AtZero_PointsUp()
|
||||
{
|
||||
var t = EllipseConverter.EvaluateTangent(10, 5, 0, 0);
|
||||
Assert.InRange(t.X, -Tol, Tol);
|
||||
Assert.True(t.Y > 0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EvaluateNormal_AtZero_PointsInward()
|
||||
{
|
||||
var n = EllipseConverter.EvaluateNormal(10, 5, 0, 0);
|
||||
Assert.True(n.X < 0);
|
||||
Assert.InRange(n.Y, -Tol, Tol);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IntersectNormals_PerpendicularNormals_FindsCenter()
|
||||
{
|
||||
var p1 = new Vector(5, 0);
|
||||
var n1 = new Vector(-1, 0);
|
||||
var p2 = new Vector(0, 5);
|
||||
var n2 = new Vector(0, -1);
|
||||
var center = EllipseConverter.IntersectNormals(p1, n1, p2, n2);
|
||||
Assert.InRange(center.X, -Tol, Tol);
|
||||
Assert.InRange(center.Y, -Tol, Tol);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IntersectNormals_ParallelNormals_ReturnsInvalid()
|
||||
{
|
||||
var p1 = new Vector(0, 0);
|
||||
var n1 = new Vector(1, 0);
|
||||
var p2 = new Vector(0, 5);
|
||||
var n2 = new Vector(1, 0);
|
||||
var center = EllipseConverter.IntersectNormals(p1, n1, p2, n2);
|
||||
Assert.False(center.IsValid());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user