mirror of
https://github.com/ajisaacs/OpenNest.git
synced 2026-11-14 10:15:07 -05:00
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>
58 lines
2.0 KiB
C#
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));
|
|
}
|
|
}
|