mirror of
https://github.com/ajisaacs/OpenNest.git
synced 2026-10-27 05:01:05 -04:00
Curved leads turned with the contour winding, which is backwards on outside perimeters: arc lead-ins arrived against the cut, and Line + Arc / arc lead-outs went the long way round on one winding. LeadTurn now gives the arc's turn direction for emission, the pierce-zone check and the preview, and the arc geometry mirrors with it. At convex outside corners, curved lead-ins use the first-cut edge's normal and arc lead-outs the last-cut edge's, whichever edge was picked. ArcLeadIn gains SweepAngle (degrees, (0, 180], default 180) in the cutting panel, settings, nest files and cut pins; older files read as 180. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
59 lines
2.6 KiB
C#
59 lines
2.6 KiB
C#
using System.Collections.Generic;
|
|
using OpenNest.Geometry;
|
|
using OpenNest.Math;
|
|
|
|
namespace OpenNest.CNC.CuttingStrategy
|
|
{
|
|
/// <summary>
|
|
/// A straight line into an arc that ends on the contour start, shared by
|
|
/// <see cref="LineArcLeadIn"/> and <see cref="CleanHoleLeadIn"/>. The arc's center lies
|
|
/// the arc radius along the contour normal; the line meets the arc at the approach angle
|
|
/// (degrees from the normal, on the side the arc turns from) and starts at the pierce point.
|
|
/// </summary>
|
|
internal readonly struct LineArcApproach
|
|
{
|
|
private LineArcApproach(Vector arcCenter, Vector arcStart, Vector piercePoint)
|
|
{
|
|
ArcCenter = arcCenter;
|
|
ArcStart = arcStart;
|
|
PiercePoint = piercePoint;
|
|
}
|
|
|
|
public Vector ArcCenter { get; }
|
|
|
|
public Vector ArcStart { get; }
|
|
|
|
public Vector PiercePoint { get; }
|
|
|
|
public static LineArcApproach Create(Vector contourStartPoint, double contourNormalAngle,
|
|
double arcRadius, double approachAngle, double lineLength, RotationType winding)
|
|
{
|
|
var arcCenterX = contourStartPoint.X + arcRadius * System.Math.Cos(contourNormalAngle);
|
|
var arcCenterY = contourStartPoint.Y + arcRadius * System.Math.Sin(contourNormalAngle);
|
|
|
|
// The approach angle is measured back from the normal against the turn, so the arc
|
|
// runs the short way round to the contour point whichever way it turns.
|
|
var approach = Angle.ToRadians(approachAngle);
|
|
var lineAngle = contourNormalAngle + (winding == RotationType.CCW ? approach : -approach);
|
|
var arcStartX = arcCenterX + arcRadius * System.Math.Cos(lineAngle);
|
|
var arcStartY = arcCenterY + arcRadius * System.Math.Sin(lineAngle);
|
|
|
|
return new LineArcApproach(
|
|
new Vector(arcCenterX, arcCenterY),
|
|
new Vector(arcStartX, arcStartY),
|
|
new Vector(
|
|
arcStartX + lineLength * System.Math.Cos(lineAngle),
|
|
arcStartY + lineLength * System.Math.Sin(lineAngle)));
|
|
}
|
|
|
|
/// <summary>Rapid to the pierce point, then the line and arc on the lead-in layer.</summary>
|
|
public List<ICode> ToCodes(Vector contourStartPoint, RotationType winding) =>
|
|
new List<ICode>
|
|
{
|
|
new RapidMove(PiercePoint),
|
|
new LinearMove(ArcStart) { Layer = LayerType.Leadin },
|
|
new ArcMove(contourStartPoint, ArcCenter, winding) { Layer = LayerType.Leadin },
|
|
};
|
|
}
|
|
}
|