using System.Collections.Generic; using OpenNest.Math; namespace OpenNest.Engine.Fill { internal record CombinationResult(bool Found, int Count1, int Count2); internal static class BestCombination { /// /// Every count of that fits, each with as many of /// as fit beside it. Spiral blocks need these: the combination /// with the least waste is not always one whose blocks can share the sheet. /// public static IEnumerable AllFrom2( double length1, double length2, double overallLength ) { overallLength += Tolerance.Epsilon; var maxCount1 = (int)System.Math.Floor(overallLength / length1); for (var c1 = 0; c1 <= maxCount1; c1++) { var c2 = (int)System.Math.Floor((overallLength - c1 * length1) / length2); if (c1 > 0 || c2 > 0) yield return new CombinationResult(true, c1, c2); } } public static CombinationResult FindFrom2( double length1, double length2, double overallLength ) { overallLength += Tolerance.Epsilon; var count1 = 0; var count2 = 0; var maxCount1 = (int)System.Math.Floor(overallLength / length1); var bestRemnant = overallLength + 1; for (var c1 = 0; c1 <= maxCount1; c1++) { var remaining = overallLength - c1 * length1; var c2 = (int)System.Math.Floor(remaining / length2); var remnant = remaining - c2 * length2; if (!(remnant < bestRemnant)) continue; count1 = c1; count2 = c2; bestRemnant = remnant; if (remnant.IsEqualTo(0)) break; } return new CombinationResult(count1 > 0 || count2 > 0, count1, count2); } } }