mirror of
https://github.com/ajisaacs/OpenNest.git
synced 2026-10-14 18:21:55 -04:00
78 lines
2.9 KiB
C#
78 lines
2.9 KiB
C#
using System.Collections.Generic;
|
|
using OpenNest.CNC;
|
|
using OpenNest.Engine.Fill;
|
|
using OpenNest.Geometry;
|
|
using Xunit;
|
|
|
|
namespace OpenNest.Engine.Tests.Fill;
|
|
|
|
public class ExpanderSpecRegressionTests
|
|
{
|
|
private static Program Disk(double radius)
|
|
{
|
|
var p = new Program();
|
|
p.MoveTo(radius, 0);
|
|
p.ArcTo(-radius, 0, 0, 0, RotationType.CCW);
|
|
p.ArcTo(radius, 0, 0, 0, RotationType.CCW);
|
|
return p;
|
|
}
|
|
|
|
private static (Plate Plate, Part A, Part B) Fixture()
|
|
{
|
|
var plate = new Plate(new Size(12, 30)) { EdgeSpacing = new Spacing(0, 0) };
|
|
var a = new Part(new Drawing("disk-a", Disk(2)), new Vector(7, 6));
|
|
var b = new Part(new Drawing("disk-b", Disk(2)), new Vector(9, 6));
|
|
plate.Parts.Add(a);
|
|
plate.Parts.Add(b);
|
|
return (plate, a, b);
|
|
}
|
|
|
|
[Fact]
|
|
public void Separate_OverlappingNativeDisks_RetainsCertifiedConvexExit()
|
|
{
|
|
var (plate, a, b) = Fixture();
|
|
var result = Expander.Separate(new List<Part> { a, b }, plate, spacing: 3);
|
|
Assert.True(result.Converged,
|
|
$"remaining violations={result.Violations.Count}; mover=({result.Positions[1].X:R},{result.Positions[1].Y:R})");
|
|
// Independent analytic disk material clearance, not production polygons.
|
|
Assert.True(result.Positions[1].DistanceTo(result.Positions[0]) - 4 >= 2.99);
|
|
Assert.Equal(7, a.Location.X);
|
|
Assert.Equal(9, b.Location.X); // scratch-only
|
|
}
|
|
|
|
[Fact]
|
|
public void Separate_OverlappingNativeDisks_CannotPassThroughThirdWall()
|
|
{
|
|
var (plate, a, b) = Fixture();
|
|
var wallProgram = new Program();
|
|
wallProgram.MoveTo(0, 0);
|
|
wallProgram.LineTo(0.2, 0);
|
|
wallProgram.LineTo(0.2, 12);
|
|
wallProgram.LineTo(0, 12);
|
|
wallProgram.LineTo(0, 0);
|
|
var wall = new Part(new Drawing("fixed-wall", wallProgram), new Vector(12, 0));
|
|
plate.Parts.Add(wall);
|
|
|
|
var result = Expander.Separate(new List<Part> { a, b }, plate, spacing: 3);
|
|
Assert.False(result.Converged);
|
|
Assert.True(result.Positions[1].X + 2 <= 12 + 1e-6,
|
|
$"native disk crossed third wall: centre={result.Positions[1].X:R}");
|
|
Assert.Equal(9, b.Location.X);
|
|
Assert.Equal(12, wall.Location.X);
|
|
}
|
|
|
|
[Fact]
|
|
public void Expand_OverlappingNativeDisks_RetainsExistingSeparation()
|
|
{
|
|
var (plate, a, b) = Fixture();
|
|
var result = Expander.Expand(new List<Part> { a, b }, plate,
|
|
new Expander.Options { InitialStep = 0.5, MaxSpacing = 3 });
|
|
var nativeGap = a.Location.DistanceTo(b.Location) - 4;
|
|
Assert.True(nativeGap >= 2.99,
|
|
$"native gap={nativeGap:R}; achieved={result.AchievedSpacing:R}; violations={result.Violations.Count}");
|
|
Assert.True(result.AchievedSpacing >= 2.9);
|
|
Assert.Empty(result.Violations);
|
|
Assert.Equal(7, a.Location.X);
|
|
}
|
|
}
|