Files
OpenNest/OpenNest.Tests/Geometry/NativeContoursTests.cs
T
ajandClaude Opus 5.5 6867ae2ee4 feat(arrange): let Fix Spacing clear overlaps on packed plates and tilt as a last resort
On a plate packed edge to edge, an overlap left by hand-placing extra
parts could not be fixed: straight push chains ran into the edge and
the relaxation gave up on pairs that share material, which have no
contact normal. The relaxation now pushes such a pair along its
shortest straight way out and lets the rest settle, which cleared a
0.92 sq in overlap on a 38-part plate with every part kept square.

When moves alone still cannot settle, the relaxation runs again as a
rigid one: an off-center push also turns a part, up to 3 degrees, if
its drawing is free to rotate. Moves stay first because a tilt turns
every part the push reaches.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 14:45:54 -05:00

58 lines
2.0 KiB
C#

using System.Collections.Generic;
using OpenNest.Geometry;
using Xunit;
namespace OpenNest.Tests.Geometry;
public class NativeContoursTests
{
private static ShapeProfile Rectangle(double width, double height) => new(new List<Entity>
{
new Line(new Vector(0, 0), new Vector(width, 0)),
new Line(new Vector(width, 0), new Vector(width, height)),
new Line(new Vector(width, height), new Vector(0, height)),
new Line(new Vector(0, height), new Vector(0, 0)),
});
[Fact]
public void Transformed_TurnsAboutTheOriginThenMoves()
{
var local = NativeContours.Of(Rectangle(4, 2), Vector.Zero);
var moved = local.Transformed(System.Math.PI / 2, new Vector(10, 5));
// A quarter turn puts the 4 x 2 rectangle at x -2..0, y 0..4 before the move.
Assert.Equal(8, moved.Bounds.Left, 9);
Assert.Equal(10, moved.Bounds.Right, 9);
Assert.Equal(5, moved.Bounds.Bottom, 9);
Assert.Equal(9, moved.Bounds.Top, 9);
}
[Fact]
public void Translated_MatchesContoursBuiltAtTheLocation()
{
var profile = Rectangle(4, 2);
var other = NativeContours.Of(Rectangle(1, 1), new Vector(8, 0));
var moved = NativeContours.Of(profile, Vector.Zero).Translated(new Vector(3, 0));
var built = NativeContours.Of(profile, new Vector(3, 0));
Assert.Equal(built.GapTo(other, 5, out _), moved.GapTo(other, 5, out var onMoved, out var onOther), 9);
Assert.Equal(1, moved.GapTo(other, 5, out _), 9);
Assert.Equal(7, onMoved.X, 9);
Assert.Equal(8, onOther.X, 9);
}
[Fact]
public void Nested_FindsAPartInsideAnotherWithoutTouching()
{
var outer = NativeContours.Of(Rectangle(10, 10), Vector.Zero);
var inner = NativeContours.Of(Rectangle(1, 1), new Vector(4, 4));
var apart = NativeContours.Of(Rectangle(1, 1), new Vector(20, 0));
Assert.True(outer.Nested(inner));
Assert.True(inner.Nested(outer));
Assert.False(outer.Nested(apart));
}
}