feat: add ISplitFeature interface and StraightSplit implementation

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-24 11:58:00 -04:00
parent 765a862440
commit 5afb311ac7
3 changed files with 96 additions and 0 deletions

View File

@@ -0,0 +1,22 @@
using System.Collections.Generic;
using OpenNest.Geometry;
namespace OpenNest;
public class SplitFeatureResult
{
public List<Entity> NegativeSideEdge { get; }
public List<Entity> PositiveSideEdge { get; }
public SplitFeatureResult(List<Entity> negativeSideEdge, List<Entity> positiveSideEdge)
{
NegativeSideEdge = negativeSideEdge;
PositiveSideEdge = positiveSideEdge;
}
}
public interface ISplitFeature
{
string Name { get; }
SplitFeatureResult GenerateFeatures(SplitLine line, double extentStart, double extentEnd, SplitParameters parameters);
}

View File

@@ -0,0 +1,22 @@
using System.Collections.Generic;
using OpenNest.Geometry;
namespace OpenNest;
public class StraightSplit : ISplitFeature
{
public string Name => "Straight";
public SplitFeatureResult GenerateFeatures(SplitLine line, double extentStart, double extentEnd, SplitParameters parameters)
{
var (negEdge, posEdge) = line.Axis == CutOffAxis.Vertical
? (new Line(new Vector(line.Position, extentStart), new Vector(line.Position, extentEnd)),
new Line(new Vector(line.Position, extentEnd), new Vector(line.Position, extentStart)))
: (new Line(new Vector(extentStart, line.Position), new Vector(extentEnd, line.Position)),
new Line(new Vector(extentEnd, line.Position), new Vector(extentStart, line.Position)));
return new SplitFeatureResult(
new List<Entity> { negEdge },
new List<Entity> { posEdge });
}
}

View File

@@ -0,0 +1,52 @@
using OpenNest.Geometry;
namespace OpenNest.Tests.Splitting;
public class SplitFeatureTests
{
[Fact]
public void StraightSplit_Vertical_ProducesSingleLineEachSide()
{
var feature = new StraightSplit();
var line = new SplitLine(50.0, CutOffAxis.Vertical);
var parameters = new SplitParameters { Type = SplitType.Straight };
var result = feature.GenerateFeatures(line, 10.0, 90.0, parameters);
Assert.Single(result.NegativeSideEdge);
var negLine = Assert.IsType<Line>(result.NegativeSideEdge[0]);
Assert.Equal(50.0, negLine.StartPoint.X, 6);
Assert.Equal(10.0, negLine.StartPoint.Y, 6);
Assert.Equal(50.0, negLine.EndPoint.X, 6);
Assert.Equal(90.0, negLine.EndPoint.Y, 6);
Assert.Single(result.PositiveSideEdge);
var posLine = Assert.IsType<Line>(result.PositiveSideEdge[0]);
Assert.Equal(50.0, posLine.StartPoint.X, 6);
Assert.Equal(90.0, posLine.StartPoint.Y, 6);
Assert.Equal(50.0, posLine.EndPoint.X, 6);
Assert.Equal(10.0, posLine.EndPoint.Y, 6);
}
[Fact]
public void StraightSplit_Horizontal_ProducesSingleLineEachSide()
{
var feature = new StraightSplit();
var line = new SplitLine(40.0, CutOffAxis.Horizontal);
var parameters = new SplitParameters { Type = SplitType.Straight };
var result = feature.GenerateFeatures(line, 5.0, 95.0, parameters);
var negLine = Assert.IsType<Line>(result.NegativeSideEdge[0]);
Assert.Equal(5.0, negLine.StartPoint.X, 6);
Assert.Equal(40.0, negLine.StartPoint.Y, 6);
Assert.Equal(95.0, negLine.EndPoint.X, 6);
Assert.Equal(40.0, negLine.EndPoint.Y, 6);
}
[Fact]
public void StraightSplit_Name()
{
Assert.Equal("Straight", new StraightSplit().Name);
}
}