Files
OpenNest/OpenNest.Engine/CirclePacking/FillEndOdd.cs
T
aj 451841401a refactor(engine): align namespaces with directory layout under OpenNest.Engine
All 132 OpenNest.Engine source files now declare namespaces matching
their nested directories: Jobs/, Jobs/Placement/, Jobs/Adapters/,
Fill/, RectanglePacking/, CirclePacking/, and engine-root types moved
from 'OpenNest' to 'OpenNest.Engine'. RootNamespace updated accordingly.
Consumers (Api, Console, Mcp, Benchmark, Training, desktop app, tests)
gained the explicit usings the move requires; CLAUDE.md updated.
2026-09-21 13:18:34 -04:00

79 lines
2.5 KiB
C#

using System;
using OpenNest.Geometry;
using OpenNest.Math;
namespace OpenNest.Engine.CirclePacking
{
internal class FillEndOdd : FillEngine
{
public FillEndOdd(Bin bin)
: base(bin) { }
public override void Fill(Item item)
{
var bin1 = FillHorizontal(item);
var bin2 = FillVertical(item);
if (bin1.Items.Count > bin2.Items.Count)
Bin.Items.AddRange(bin1.Items);
else
Bin.Items.AddRange(bin2.Items);
}
public override void Fill(Item item, int maxCount)
{
throw new NotImplementedException();
}
private Bin FillHorizontal(Item item) => FillAxis(item, horizontal: true);
private Bin FillVertical(Item item) => FillAxis(item, horizontal: false);
private Bin FillAxis(Item item, bool horizontal)
{
var bin = Bin.Clone() as Bin;
var max = new Vector(
bin.Right - item.BoundingBox.Right + Tolerance.Epsilon,
bin.Top - item.BoundingBox.Top + Tolerance.Epsilon
);
var primarySize = horizontal ? bin.Width : bin.Length;
var count = System.Math.Floor((primarySize + Tolerance.Epsilon) / item.Diameter);
if (count == 0)
return bin;
var primaryOffset = (primarySize - item.Diameter) / (count - 1);
var secondaryOffset = horizontal
? Trigonometry.Height(primaryOffset * 0.5, item.Diameter)
: Trigonometry.Base(primaryOffset * 0.5, item.Diameter);
var outerStart = horizontal ? bin.Y : bin.X;
var outerMax = horizontal ? max.Y : max.X;
var innerStart = horizontal ? bin.X : bin.Y;
var innerMax = horizontal ? max.X : max.Y;
var stripe = 0;
for (var outer = outerStart; outer <= outerMax; outer += secondaryOffset)
{
var inner = stripe.IsOdd() ? innerStart + primaryOffset * 0.5 : innerStart;
for (; inner <= innerMax; inner += primaryOffset)
{
var addedItem = item.Clone() as Item;
addedItem.Center = horizontal
? new Vector(inner, outer)
: new Vector(outer, inner);
bin.Items.Add(addedItem);
}
stripe++;
}
return bin;
}
}
}