mirror of
https://github.com/ajisaacs/OpenNest.git
synced 2026-11-14 12:35:07 -05:00
Geometry, nesting and import code now call PortableMath instead of System.Math for Sin, Cos, Tan, Atan, Atan2, Asin and Acos (Core, Engine, IO, Data; 269 calls in 64 files). A test fails if those projects call the runtime's trig again. With the runtime's trig, Windows and Linux disagreed in the last bit at non-quarter angles and the same job could nest differently: the learned-angle nests (a cross fixture) placed 23 parts in Strip on Windows and 28 on Linux. Now every Engine.Tests pin gives the same layout on both (3600 passing on Linux and on DesktopPC), Linux layouts are unchanged, and the learned-angle rows are re-pinned to the shared layouts, which pass the overlap and work-area checks, and run on every platform again. Fixes Project Memory 518f3b58.
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 * PortableMath.Cos(contourNormalAngle);
|
|
var arcCenterY = contourStartPoint.Y + arcRadius * PortableMath.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 * PortableMath.Cos(lineAngle);
|
|
var arcStartY = arcCenterY + arcRadius * PortableMath.Sin(lineAngle);
|
|
|
|
return new LineArcApproach(
|
|
new Vector(arcCenterX, arcCenterY),
|
|
new Vector(arcStartX, arcStartY),
|
|
new Vector(
|
|
arcStartX + lineLength * PortableMath.Cos(lineAngle),
|
|
arcStartY + lineLength * PortableMath.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 },
|
|
};
|
|
}
|
|
}
|