Files
OpenNest/OpenNest.Engine/CirclePacking/FillEndEven.cs
T
ajandClaude Opus 5.5 6e2e27d6fc fix(engine): stop staggered circle fills overlapping
Staggered stripes were spaced only so adjacent stripes touched
diagonally. When the in-stripe pitch stretched past sqrt(3)*D, stripes
two apart, which sit directly over each other, came closer than a
diameter. Clamp the stripe spacing to at least a radius in both fills.

FillEndOdd also divided by zero when a single circle fit per stripe;
it now stacks those stripes a diameter apart. FillEndEven now clones
the template item, so placed circles keep its radius instead of zero.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 12:49:36 -04:00

84 lines
2.5 KiB
C#

using System;
using OpenNest.Geometry;
using OpenNest.Math;
namespace OpenNest.Engine.CirclePacking
{
internal class FillEndEven : FillEngine
{
public FillEndEven(Bin bin)
: base(bin) { }
public override void Fill(Item item)
{
var max = new Vector(
Bin.Right - item.BoundingBox.Right + Tolerance.Epsilon,
Bin.Top - item.BoundingBox.Top + Tolerance.Epsilon
);
var rows = System.Math.Floor((Bin.Length + Tolerance.Epsilon) / (item.Diameter));
if (rows == 0)
return;
var diameter = item.Diameter;
var remaining = Bin.Length - diameter * rows;
var radius = diameter * 0.5;
if (remaining < radius)
{
var yodd = Bin.Y + remaining;
var yoffset = diameter;
var xoffset = Trigonometry.Base(remaining, diameter);
int column = 0;
for (var x = Bin.X; x <= max.X; x += xoffset)
{
var y = column.IsOdd() ? yodd : Bin.Y;
for (; y <= max.Y; y += yoffset)
{
var addedItem = item.Clone();
addedItem.Center = new Vector(x, y);
Bin.Items.Add(addedItem);
}
column++;
}
}
else
{
var yoffset = (Bin.Length - diameter) / (2 * rows - 1);
// Adjacent columns touch diagonally, but columns two apart sit directly beside
// each other, so the column spacing can never drop below a radius.
var xoffset = System.Math.Max(Trigonometry.Base(yoffset, diameter), radius);
var yodd = Bin.Y + yoffset;
yoffset *= 2.0;
int column = 0;
for (var x = Bin.X; x <= max.X; x += xoffset)
{
var y = column.IsOdd() ? yodd : Bin.Y;
for (; y <= max.Y; y += yoffset)
{
var addedItem = item.Clone();
addedItem.Center = new Vector(x, y);
Bin.Items.Add(addedItem);
}
column++;
}
}
}
public override void Fill(Item item, int maxCount)
{
throw new NotImplementedException();
}
}
}