From b112f70f6aeef16b7e8f596dc3a26e75ae42b010 Mon Sep 17 00:00:00 2001 From: AJ Isaacs Date: Thu, 12 Mar 2026 23:12:09 -0400 Subject: [PATCH] feat: add LeadOut hierarchy (5 classes) Co-Authored-By: Claude Opus 4.6 --- .../CuttingStrategy/LeadOuts/ArcLeadOut.cs | 27 +++++++++++++++++++ .../CNC/CuttingStrategy/LeadOuts/LeadOut.cs | 11 ++++++++ .../CuttingStrategy/LeadOuts/LineLeadOut.cs | 26 ++++++++++++++++++ .../LeadOuts/MicrotabLeadOut.cs | 16 +++++++++++ .../CNC/CuttingStrategy/LeadOuts/NoLeadOut.cs | 14 ++++++++++ 5 files changed, 94 insertions(+) create mode 100644 OpenNest.Core/CNC/CuttingStrategy/LeadOuts/ArcLeadOut.cs create mode 100644 OpenNest.Core/CNC/CuttingStrategy/LeadOuts/LeadOut.cs create mode 100644 OpenNest.Core/CNC/CuttingStrategy/LeadOuts/LineLeadOut.cs create mode 100644 OpenNest.Core/CNC/CuttingStrategy/LeadOuts/MicrotabLeadOut.cs create mode 100644 OpenNest.Core/CNC/CuttingStrategy/LeadOuts/NoLeadOut.cs diff --git a/OpenNest.Core/CNC/CuttingStrategy/LeadOuts/ArcLeadOut.cs b/OpenNest.Core/CNC/CuttingStrategy/LeadOuts/ArcLeadOut.cs new file mode 100644 index 0000000..95d8724 --- /dev/null +++ b/OpenNest.Core/CNC/CuttingStrategy/LeadOuts/ArcLeadOut.cs @@ -0,0 +1,27 @@ +using System.Collections.Generic; +using OpenNest.Geometry; + +namespace OpenNest.CNC.CuttingStrategy +{ + public class ArcLeadOut : LeadOut + { + public double Radius { get; set; } + + public override List Generate(Vector contourEndPoint, double contourNormalAngle, + RotationType winding = RotationType.CW) + { + var arcCenterX = contourEndPoint.X + Radius * System.Math.Cos(contourNormalAngle); + var arcCenterY = contourEndPoint.Y + Radius * System.Math.Sin(contourNormalAngle); + var arcCenter = new Vector(arcCenterX, arcCenterY); + + var endPoint = new Vector( + arcCenterX + Radius * System.Math.Cos(contourNormalAngle + System.Math.PI / 2), + arcCenterY + Radius * System.Math.Sin(contourNormalAngle + System.Math.PI / 2)); + + return new List + { + new ArcMove(endPoint, arcCenter, winding) + }; + } + } +} diff --git a/OpenNest.Core/CNC/CuttingStrategy/LeadOuts/LeadOut.cs b/OpenNest.Core/CNC/CuttingStrategy/LeadOuts/LeadOut.cs new file mode 100644 index 0000000..6915c5f --- /dev/null +++ b/OpenNest.Core/CNC/CuttingStrategy/LeadOuts/LeadOut.cs @@ -0,0 +1,11 @@ +using System.Collections.Generic; +using OpenNest.Geometry; + +namespace OpenNest.CNC.CuttingStrategy +{ + public abstract class LeadOut + { + public abstract List Generate(Vector contourEndPoint, double contourNormalAngle, + RotationType winding = RotationType.CW); + } +} diff --git a/OpenNest.Core/CNC/CuttingStrategy/LeadOuts/LineLeadOut.cs b/OpenNest.Core/CNC/CuttingStrategy/LeadOuts/LineLeadOut.cs new file mode 100644 index 0000000..c72847b --- /dev/null +++ b/OpenNest.Core/CNC/CuttingStrategy/LeadOuts/LineLeadOut.cs @@ -0,0 +1,26 @@ +using System.Collections.Generic; +using OpenNest.Geometry; +using OpenNest.Math; + +namespace OpenNest.CNC.CuttingStrategy +{ + public class LineLeadOut : LeadOut + { + public double Length { get; set; } + public double ApproachAngle { get; set; } = 90.0; + + public override List Generate(Vector contourEndPoint, double contourNormalAngle, + RotationType winding = RotationType.CW) + { + var overcutAngle = contourNormalAngle + Angle.ToRadians(ApproachAngle); + var endPoint = new Vector( + contourEndPoint.X + Length * System.Math.Cos(overcutAngle), + contourEndPoint.Y + Length * System.Math.Sin(overcutAngle)); + + return new List + { + new LinearMove(endPoint) + }; + } + } +} diff --git a/OpenNest.Core/CNC/CuttingStrategy/LeadOuts/MicrotabLeadOut.cs b/OpenNest.Core/CNC/CuttingStrategy/LeadOuts/MicrotabLeadOut.cs new file mode 100644 index 0000000..13dc799 --- /dev/null +++ b/OpenNest.Core/CNC/CuttingStrategy/LeadOuts/MicrotabLeadOut.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; +using OpenNest.Geometry; + +namespace OpenNest.CNC.CuttingStrategy +{ + public class MicrotabLeadOut : LeadOut + { + public double GapSize { get; set; } = 0.03; + + public override List Generate(Vector contourEndPoint, double contourNormalAngle, + RotationType winding = RotationType.CW) + { + return new List(); + } + } +} diff --git a/OpenNest.Core/CNC/CuttingStrategy/LeadOuts/NoLeadOut.cs b/OpenNest.Core/CNC/CuttingStrategy/LeadOuts/NoLeadOut.cs new file mode 100644 index 0000000..8a45cc8 --- /dev/null +++ b/OpenNest.Core/CNC/CuttingStrategy/LeadOuts/NoLeadOut.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using OpenNest.Geometry; + +namespace OpenNest.CNC.CuttingStrategy +{ + public class NoLeadOut : LeadOut + { + public override List Generate(Vector contourEndPoint, double contourNormalAngle, + RotationType winding = RotationType.CW) + { + return new List(); + } + } +}