diff --git a/OpenNest.Core/Splitting/ISplitFeature.cs b/OpenNest.Core/Splitting/ISplitFeature.cs new file mode 100644 index 0000000..055d73d --- /dev/null +++ b/OpenNest.Core/Splitting/ISplitFeature.cs @@ -0,0 +1,22 @@ +using System.Collections.Generic; +using OpenNest.Geometry; + +namespace OpenNest; + +public class SplitFeatureResult +{ + public List NegativeSideEdge { get; } + public List PositiveSideEdge { get; } + + public SplitFeatureResult(List negativeSideEdge, List positiveSideEdge) + { + NegativeSideEdge = negativeSideEdge; + PositiveSideEdge = positiveSideEdge; + } +} + +public interface ISplitFeature +{ + string Name { get; } + SplitFeatureResult GenerateFeatures(SplitLine line, double extentStart, double extentEnd, SplitParameters parameters); +} diff --git a/OpenNest.Core/Splitting/StraightSplit.cs b/OpenNest.Core/Splitting/StraightSplit.cs new file mode 100644 index 0000000..5ef039d --- /dev/null +++ b/OpenNest.Core/Splitting/StraightSplit.cs @@ -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 { negEdge }, + new List { posEdge }); + } +} diff --git a/OpenNest.Tests/Splitting/SplitFeatureTests.cs b/OpenNest.Tests/Splitting/SplitFeatureTests.cs new file mode 100644 index 0000000..5818744 --- /dev/null +++ b/OpenNest.Tests/Splitting/SplitFeatureTests.cs @@ -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(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(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(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); + } +}