diff --git a/OpenNest.Engine.Tests/CirclePacking/FillEndOverlapTests.cs b/OpenNest.Engine.Tests/CirclePacking/StaggeredFillTests.cs
similarity index 77%
rename from OpenNest.Engine.Tests/CirclePacking/FillEndOverlapTests.cs
rename to OpenNest.Engine.Tests/CirclePacking/StaggeredFillTests.cs
index d9edde63..f68cb0f6 100644
--- a/OpenNest.Engine.Tests/CirclePacking/FillEndOverlapTests.cs
+++ b/OpenNest.Engine.Tests/CirclePacking/StaggeredFillTests.cs
@@ -3,7 +3,7 @@ using OpenNest.Geometry;
namespace OpenNest.Engine.Tests.CirclePacking;
-public class FillEndOverlapTests
+public class StaggeredFillTests
{
private const double Diameter = 10;
@@ -18,11 +18,11 @@ public class FillEndOverlapTests
[Theory]
[MemberData(nameof(BinSizes))]
- public void FillEndOdd_PlacesNoOverlappingCircles(double width, double length)
+ public void HalfPitch_PlacesNoOverlappingCircles(double width, double length)
{
var bin = new Bin { Location = new Vector(0, 0), Size = new Size(width, length) };
- new FillEndOdd(bin).Fill(CreateItem());
+ StaggeredFill.Fill(bin, CreateItem(), StaggerMode.HalfPitch);
Assert.NotEmpty(bin.Items);
AssertNoOverlaps(bin.Items);
@@ -30,11 +30,11 @@ public class FillEndOverlapTests
[Theory]
[MemberData(nameof(BinSizes))]
- public void FillEndEven_PlacesNoOverlappingCircles(double width, double length)
+ public void SlackShift_PlacesNoOverlappingCircles(double width, double length)
{
var bin = new Bin { Location = new Vector(0, 0), Size = new Size(width, length) };
- new FillEndEven(bin).Fill(CreateItem());
+ StaggeredFill.Fill(bin, CreateItem(), StaggerMode.SlackShift);
Assert.NotEmpty(bin.Items);
Assert.All(bin.Items, i => Assert.Equal(Diameter, i.Diameter, 9));
@@ -42,35 +42,35 @@ public class FillEndOverlapTests
}
[Fact]
- public void FillEndOdd_SingleCircleWidth_StacksAlongTheOtherAxis()
+ public void HalfPitch_SingleCircleWidth_StacksAlongTheOtherAxis()
{
var bin = new Bin { Location = new Vector(0, 0), Size = new Size(1.5 * Diameter, 1.5 * Diameter) };
- new FillEndOdd(bin).Fill(CreateItem());
+ StaggeredFill.Fill(bin, CreateItem(), StaggerMode.HalfPitch);
AssertNoOverlaps(bin.Items);
}
[Theory]
[MemberData(nameof(BinSizes))]
- public void FillEnd_KeepsEveryCircleInsideTheBin(double width, double length)
+ public void StaggeredFill_KeepsEveryCircleInsideTheBin(double width, double length)
{
var odd = new Bin { Location = new Vector(3, 7), Size = new Size(width, length) };
var even = new Bin { Location = new Vector(3, 7), Size = new Size(width, length) };
- new FillEndOdd(odd).Fill(CreateItem());
- new FillEndEven(even).Fill(CreateItem());
+ StaggeredFill.Fill(odd, CreateItem(), StaggerMode.HalfPitch);
+ StaggeredFill.Fill(even, CreateItem(), StaggerMode.SlackShift);
AssertInside(odd);
AssertInside(even);
}
[Fact]
- public void FillEndOdd_StretchesStripesToTheBinOnALongSheet()
+ public void HalfPitch_StretchesStripesToTheBinOnALongSheet()
{
var bin = new Bin { Location = new Vector(0, 0), Size = new Size(59.375, 119.75) };
- new FillEndOdd(bin).Fill(new Item { Radius = 4.125 });
+ StaggeredFill.Fill(bin, new Item { Radius = 4.125 }, StaggerMode.HalfPitch);
// Staggered all the way places 108; the last stripes stacked straight fit one more.
AssertNoOverlaps(bin.Items, 8.25);
@@ -79,24 +79,24 @@ public class FillEndOverlapTests
}
[Fact]
- public void FillEndEven_TriesTheStripesAlongTheLongSide()
+ public void SlackShift_TriesTheStripesAlongTheLongSide()
{
var bin = new Bin { Location = new Vector(0, 0), Size = new Size(59.375, 119.75) };
- new FillEndEven(bin).Fill(new Item { Radius = 4.125 });
+ StaggeredFill.Fill(bin, new Item { Radius = 4.125 }, StaggerMode.SlackShift);
AssertNoOverlaps(bin.Items, 8.25);
Assert.Equal(112, bin.Items.Count);
}
[Fact]
- public void FillEndOdd_EndsWithStraightStripesWhenTheyFitMore()
+ public void HalfPitch_EndsWithStraightStripesWhenTheyFitMore()
{
// 13 discs to a stripe: seven staggered stripes place 88 and six straight ones 78, but
// five staggered and two straight over the fifth place 89.
var bin = new Bin { Location = new Vector(0, 0), Size = new Size(59.8, 119.8) };
- new FillEndOdd(bin).Fill(new Item { Radius = 4.6 });
+ StaggeredFill.Fill(bin, new Item { Radius = 4.6 }, StaggerMode.HalfPitch);
AssertNoOverlaps(bin.Items, 9.2);
AssertInside(bin);
@@ -112,13 +112,13 @@ public class FillEndOverlapTests
}
[Fact]
- public void FillEndOdd_KeepsStaggeredStripesWhenStraightOnesFitNoMore()
+ public void HalfPitch_KeepsStaggeredStripesWhenStraightOnesFitNoMore()
{
// Seven staggered stripes place 88; too short for the mixed 89, straight stripes from
// any switch point place at most 78.
var bin = new Bin { Location = new Vector(0, 0), Size = new Size(57.2, 119.8) };
- new FillEndOdd(bin).Fill(new Item { Radius = 4.6 });
+ StaggeredFill.Fill(bin, new Item { Radius = 4.6 }, StaggerMode.HalfPitch);
Assert.Equal(88, bin.Items.Count);
var stripes = bin.Items.GroupBy(i => System.Math.Round(i.Center.Y, 6)).Select(g => g.Count());
diff --git a/OpenNest.Engine/CirclePacking/FillEndEven.cs b/OpenNest.Engine/CirclePacking/FillEndEven.cs
deleted file mode 100644
index 3a7d87f1..00000000
--- a/OpenNest.Engine/CirclePacking/FillEndEven.cs
+++ /dev/null
@@ -1,84 +0,0 @@
-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 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);
-
- /// Stripes run along Y and step along X when horizontal, and the reverse otherwise.
- private Bin FillAxis(Item item, bool horizontal)
- {
- var bin = Bin.Clone() as Bin;
-
- var max = new Vector(
- bin.Right - item.Radius + Tolerance.Epsilon,
- bin.Top - item.Radius + Tolerance.Epsilon
- );
-
- // A box's Length runs along X and its Width along Y.
- var stripeSize = horizontal ? bin.Width : bin.Length;
- var diameter = item.Diameter;
- var radius = item.Radius;
- var rows = System.Math.Floor((stripeSize + Tolerance.Epsilon) / diameter);
-
- if (rows == 0)
- return bin;
-
- var remaining = stripeSize - diameter * rows;
- double oddShift;
- double innerOffset;
- double outerOffset;
-
- if (remaining < radius)
- {
- oddShift = remaining;
- innerOffset = diameter;
- outerOffset = Trigonometry.Base(remaining, diameter);
- }
- else
- {
- oddShift = (stripeSize - diameter) / (2 * rows - 1);
- innerOffset = oddShift * 2.0;
- // Adjacent stripes touch diagonally, but stripes two apart sit directly beside
- // each other, so the stripe spacing can never drop below a radius.
- outerOffset = System.Math.Max(Trigonometry.Base(oddShift, diameter), radius);
- }
-
- AddStripes(bin, item, new Stripes(
- InnerAlongX: !horizontal,
- OuterStart: (horizontal ? bin.X : bin.Y) + radius,
- OuterMax: horizontal ? max.X : max.Y,
- OuterStep: outerOffset,
- InnerStart: (horizontal ? bin.Y : bin.X) + radius,
- InnerMax: horizontal ? max.Y : max.X,
- InnerStep: innerOffset,
- Shift: oddShift));
-
- return bin;
- }
- }
-}
diff --git a/OpenNest.Engine/CirclePacking/FillEndOdd.cs b/OpenNest.Engine/CirclePacking/FillEndOdd.cs
deleted file mode 100644
index 8183f06c..00000000
--- a/OpenNest.Engine/CirclePacking/FillEndOdd.cs
+++ /dev/null
@@ -1,72 +0,0 @@
-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.Radius + Tolerance.Epsilon,
- bin.Top - item.Radius + Tolerance.Epsilon
- );
-
- // A box's Length runs along X and its Width along Y.
- var primarySize = horizontal ? bin.Length : bin.Width;
- var count = System.Math.Floor((primarySize + Tolerance.Epsilon) / item.Diameter);
-
- if (count == 0)
- return bin;
-
- // A single circle per stripe cannot stagger; stack the stripes a diameter apart.
- var primaryOffset = count > 1
- ? (primarySize - item.Diameter) / (count - 1)
- : double.PositiveInfinity;
-
- // Adjacent stripes touch diagonally, but stripes two apart sit directly over each
- // other, so the stripe spacing can never drop below a radius.
- var secondaryOffset = count > 1
- ? System.Math.Max(Trigonometry.Height(primaryOffset * 0.5, item.Diameter), item.Diameter * 0.5)
- : item.Diameter;
-
- AddStripes(bin, item, new Stripes(
- InnerAlongX: horizontal,
- OuterStart: (horizontal ? bin.Y : bin.X) + item.Radius,
- OuterMax: horizontal ? max.Y : max.X,
- OuterStep: secondaryOffset,
- InnerStart: (horizontal ? bin.X : bin.Y) + item.Radius,
- InnerMax: horizontal ? max.X : max.Y,
- InnerStep: primaryOffset,
- Shift: count > 1 ? primaryOffset * 0.5 : 0));
-
- return bin;
- }
- }
-}
diff --git a/OpenNest.Engine/CirclePacking/FillEngine.cs b/OpenNest.Engine/CirclePacking/FillEngine.cs
deleted file mode 100644
index 2ffb9259..00000000
--- a/OpenNest.Engine/CirclePacking/FillEngine.cs
+++ /dev/null
@@ -1,106 +0,0 @@
-using System.Collections.Generic;
-using OpenNest.Geometry;
-using OpenNest.Math;
-
-namespace OpenNest.Engine.CirclePacking
-{
- internal abstract class FillEngine
- {
- public FillEngine(Bin bin)
- {
- Bin = bin;
- }
-
- public Bin Bin { get; set; }
-
- public abstract void Fill(Item item);
-
- public abstract void Fill(Item item, int maxCount);
-
- ///
- /// Lays staggered stripes apart into ,
- /// odd stripes shifted along their length by . The last stripes
- /// may instead stack straight: a diameter apart, each repeating the last staggered stripe's
- /// positions. Straight stacking climbs faster per stripe than staggering, so where the
- /// sheet leaves too little for one more staggered stripe, a few straight ones can fit more.
- /// Every switch point is tried, all staggered and all straight included, and the one placing
- /// the most is kept; a tie keeps the stripes staggered.
- ///
- protected static void AddStripes(Bin bin, Item item, Stripes stripes)
- {
- var staggered = new List();
- for (var outer = stripes.OuterStart; outer <= stripes.OuterMax; outer += stripes.OuterStep)
- staggered.Add(outer);
-
- var counts = new int[staggered.Count];
- var total = 0;
- for (var stripe = 0; stripe < counts.Length; stripe++)
- {
- for (var inner = InnerStart(stripes, stripe); inner <= stripes.InnerMax; inner += stripes.InnerStep)
- counts[stripe]++;
- total += counts[stripe];
- }
-
- var switchAt = staggered.Count;
- var straightCount = 0;
- var best = total;
- var placed = 0;
-
- for (var stripe = 0; stripe < counts.Length; stripe++)
- {
- placed += counts[stripe];
- var straight = 0;
- for (var outer = staggered[stripe] + item.Diameter; outer <= stripes.OuterMax; outer += item.Diameter)
- straight++;
-
- if (placed + straight * counts[stripe] > best)
- {
- best = placed + straight * counts[stripe];
- switchAt = stripe + 1;
- straightCount = straight;
- }
- }
-
- for (var stripe = 0; stripe < switchAt; stripe++)
- AddStripe(bin, item, stripes, staggered[stripe], InnerStart(stripes, stripe));
-
- var last = switchAt - 1;
- var straightOuter = last >= 0 ? staggered[last] : 0;
- for (var stripe = 0; stripe < straightCount; stripe++)
- {
- straightOuter += item.Diameter;
- AddStripe(bin, item, stripes, straightOuter, InnerStart(stripes, last));
- }
- }
-
- private static double InnerStart(Stripes stripes, int stripe) =>
- stripe.IsOdd() ? stripes.InnerStart + stripes.Shift : stripes.InnerStart;
-
- private static void AddStripe(Bin bin, Item item, Stripes stripes, double outer, double innerStart)
- {
- for (var inner = innerStart; inner <= stripes.InnerMax; inner += stripes.InnerStep)
- {
- var addedItem = item.Clone();
- addedItem.Center = stripes.InnerAlongX
- ? new Vector(inner, outer)
- : new Vector(outer, inner);
- bin.Items.Add(addedItem);
- }
- }
-
- ///
- /// Stripes run along the inner axis, X when , and step along the
- /// other; starts and maxima are circle centers.
- ///
- protected readonly record struct Stripes(
- bool InnerAlongX,
- double OuterStart,
- double OuterMax,
- double OuterStep,
- double InnerStart,
- double InnerMax,
- double InnerStep,
- double Shift
- );
- }
-}
diff --git a/OpenNest.Engine/CirclePacking/StaggeredFill.cs b/OpenNest.Engine/CirclePacking/StaggeredFill.cs
new file mode 100644
index 00000000..781494b0
--- /dev/null
+++ b/OpenNest.Engine/CirclePacking/StaggeredFill.cs
@@ -0,0 +1,191 @@
+using System.Collections.Generic;
+using OpenNest.Geometry;
+using OpenNest.Math;
+
+namespace OpenNest.Engine.CirclePacking
+{
+ /// How far shifts every other stripe along its length.
+ internal enum StaggerMode
+ {
+ ///
+ /// Half the pitch, so odd stripes nest in the gaps and hold one disc fewer; the pitch is
+ /// stretched until a stripe's discs span the bin.
+ ///
+ HalfPitch,
+
+ ///
+ /// By the room a full stripe leaves, so every stripe holds as many discs as fit and odd
+ /// stripes drop only as deep into the gaps as that shift allows.
+ ///
+ SlackShift,
+ }
+
+ ///
+ /// Fills a bin with stripes of equal discs, every other stripe shifted along its length by the
+ /// , stripes along X and along Y tried and the one placing more kept.
+ ///
+ internal static class StaggeredFill
+ {
+ public static void Fill(Bin bin, Item item, StaggerMode mode)
+ {
+ var alongX = Layout(bin, item, mode, alongX: true);
+ var alongY = Layout(bin, item, mode, alongX: false);
+
+ // On a tie, half-pitch stripes run along Y and slack-shifted ones along X.
+ var keepAlongX = mode == StaggerMode.HalfPitch
+ ? alongX.Count > alongY.Count
+ : alongX.Count >= alongY.Count;
+
+ bin.Items.AddRange(keepAlongX ? alongX : alongY);
+ }
+
+ /// Stripes run along X and step along Y when , and the reverse otherwise.
+ private static List- Layout(Bin bin, Item item, StaggerMode mode, bool alongX)
+ {
+ var items = new List
- ();
+ var diameter = item.Diameter;
+ var radius = item.Radius;
+
+ // A box's Length runs along X and its Width along Y.
+ var stripeLength = alongX ? bin.Length : bin.Width;
+ var count = System.Math.Floor((stripeLength + Tolerance.Epsilon) / diameter);
+
+ if (count == 0)
+ return items;
+
+ var (pitch, step, shift) = mode == StaggerMode.HalfPitch
+ ? HalfPitch(stripeLength, count, diameter)
+ : SlackShift(stripeLength, count, diameter);
+
+ var max = new Vector(
+ bin.Right - radius + Tolerance.Epsilon,
+ bin.Top - radius + Tolerance.Epsilon
+ );
+
+ AddStripes(items, item, new Stripes(
+ AlongX: alongX,
+ OuterStart: (alongX ? bin.Y : bin.X) + radius,
+ OuterMax: alongX ? max.Y : max.X,
+ OuterStep: step,
+ InnerStart: (alongX ? bin.X : bin.Y) + radius,
+ InnerMax: alongX ? max.X : max.Y,
+ InnerStep: pitch,
+ Shift: shift));
+
+ return items;
+ }
+
+ private static (double Pitch, double Step, double Shift) HalfPitch(double stripeLength, double count, double diameter)
+ {
+ // A single disc per stripe cannot stagger; stack the stripes a diameter apart.
+ if (count == 1)
+ return (double.PositiveInfinity, diameter, 0);
+
+ var pitch = (stripeLength - diameter) / (count - 1);
+
+ // Adjacent stripes touch diagonally, but stripes two apart sit directly over each
+ // other, so the stripe spacing can never drop below a radius.
+ return (pitch, System.Math.Max(Trigonometry.Height(pitch * 0.5, diameter), diameter * 0.5), pitch * 0.5);
+ }
+
+ private static (double Pitch, double Step, double Shift) SlackShift(double stripeLength, double count, double diameter)
+ {
+ var remaining = stripeLength - diameter * count;
+
+ if (remaining < diameter * 0.5)
+ return (diameter, Trigonometry.Base(remaining, diameter), remaining);
+
+ var shift = (stripeLength - diameter) / (2 * count - 1);
+
+ // Adjacent stripes touch diagonally, but stripes two apart sit directly beside
+ // each other, so the stripe spacing can never drop below a radius.
+ return (shift * 2.0, System.Math.Max(Trigonometry.Base(shift, diameter), diameter * 0.5), shift);
+ }
+
+ ///
+ /// Lays staggered stripes apart, odd stripes shifted along
+ /// their length by . The last stripes may instead stack
+ /// straight: a diameter apart, each repeating the last staggered stripe's positions.
+ /// Straight stacking climbs faster per stripe than staggering, so where the bin leaves
+ /// too little for one more staggered stripe, a few straight ones can fit more. Every
+ /// switch point is tried, all staggered and all straight included, and the one placing
+ /// the most is kept; a tie keeps the stripes staggered.
+ ///
+ private static void AddStripes(List
- items, Item item, Stripes stripes)
+ {
+ var staggered = new List();
+ for (var outer = stripes.OuterStart; outer <= stripes.OuterMax; outer += stripes.OuterStep)
+ staggered.Add(outer);
+
+ var counts = new int[staggered.Count];
+ var total = 0;
+ for (var stripe = 0; stripe < counts.Length; stripe++)
+ {
+ for (var inner = InnerStart(stripes, stripe); inner <= stripes.InnerMax; inner += stripes.InnerStep)
+ counts[stripe]++;
+ total += counts[stripe];
+ }
+
+ var switchAt = staggered.Count;
+ var straightCount = 0;
+ var best = total;
+ var placed = 0;
+
+ for (var stripe = 0; stripe < counts.Length; stripe++)
+ {
+ placed += counts[stripe];
+ var straight = 0;
+ for (var outer = staggered[stripe] + item.Diameter; outer <= stripes.OuterMax; outer += item.Diameter)
+ straight++;
+
+ if (placed + straight * counts[stripe] > best)
+ {
+ best = placed + straight * counts[stripe];
+ switchAt = stripe + 1;
+ straightCount = straight;
+ }
+ }
+
+ for (var stripe = 0; stripe < switchAt; stripe++)
+ AddStripe(items, item, stripes, staggered[stripe], InnerStart(stripes, stripe));
+
+ var last = switchAt - 1;
+ var straightOuter = last >= 0 ? staggered[last] : 0;
+ for (var stripe = 0; stripe < straightCount; stripe++)
+ {
+ straightOuter += item.Diameter;
+ AddStripe(items, item, stripes, straightOuter, InnerStart(stripes, last));
+ }
+ }
+
+ private static double InnerStart(Stripes stripes, int stripe) =>
+ stripe.IsOdd() ? stripes.InnerStart + stripes.Shift : stripes.InnerStart;
+
+ private static void AddStripe(List
- items, Item item, Stripes stripes, double outer, double innerStart)
+ {
+ for (var inner = innerStart; inner <= stripes.InnerMax; inner += stripes.InnerStep)
+ {
+ var addedItem = item.Clone();
+ addedItem.Center = stripes.AlongX
+ ? new Vector(inner, outer)
+ : new Vector(outer, inner);
+ items.Add(addedItem);
+ }
+ }
+
+ ///
+ /// Stripes run along the inner axis, X when , and step along the
+ /// other; starts and maxima are disc centers.
+ ///
+ private readonly record struct Stripes(
+ bool AlongX,
+ double OuterStart,
+ double OuterMax,
+ double OuterStep,
+ double InnerStart,
+ double InnerMax,
+ double InnerStep,
+ double Shift
+ );
+ }
+}
diff --git a/OpenNest.Engine/Strategies/CircleFillStrategy.cs b/OpenNest.Engine/Strategies/CircleFillStrategy.cs
index 94b98c2e..891d3e64 100644
--- a/OpenNest.Engine/Strategies/CircleFillStrategy.cs
+++ b/OpenNest.Engine/Strategies/CircleFillStrategy.cs
@@ -9,8 +9,9 @@ using OpenNest.Geometry;
namespace OpenNest.Engine.Strategies;
///
-/// Staggers round parts edge to edge with and ,
-/// which stretch a row's pitch to the sheet so the next row drops deeper than a fixed lattice does.
+/// Staggers round parts edge to edge with , whose half-pitch rows stretch
+/// their pitch to the sheet so the next row drops deeper than a fixed lattice does, and whose
+/// slack-shifted rows keep every row full; the better of the two is kept.
///
public class CircleFillStrategy : IFillStrategy
{
@@ -35,22 +36,22 @@ public class CircleFillStrategy : IFillStrategy
var area = context.WorkArea.Offset(gap * 0.5);
var comparer = context.Policy?.Comparer ?? new DefaultFillComparer();
- var odd = Pack(area, spaced, bin => new FillEndOdd(bin), item, context.Item.Drawing);
- var even = Pack(area, spaced, bin => new FillEndEven(bin), item, context.Item.Drawing);
+ var halfPitch = Pack(area, spaced, StaggerMode.HalfPitch, item, context.Item.Drawing);
+ var slackShift = Pack(area, spaced, StaggerMode.SlackShift, item, context.Item.Drawing);
- return comparer.IsBetter(even, odd, context.WorkArea) ? even : odd;
+ return comparer.IsBetter(slackShift, halfPitch, context.WorkArea) ? slackShift : halfPitch;
}
private static List Pack(
Box area,
Item spaced,
- System.Func engine,
+ StaggerMode mode,
Item item,
Drawing drawing
)
{
var bin = new Bin { Location = area.Location, Size = area.Size };
- engine(bin).Fill(spaced);
+ StaggeredFill.Fill(bin, spaced, mode);
return bin.Items.Select(i => new Part(drawing, i.Center + item.PartOffset)).ToList();
}
}