RectangleBinPack.CSharp 1.0.4

dotnet add package RectangleBinPack.CSharp --version 1.0.4
                    
NuGet\Install-Package RectangleBinPack.CSharp -Version 1.0.4
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="RectangleBinPack.CSharp" Version="1.0.4" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="RectangleBinPack.CSharp" Version="1.0.4" />
                    
Directory.Packages.props
<PackageReference Include="RectangleBinPack.CSharp" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add RectangleBinPack.CSharp --version 1.0.4
                    
#r "nuget: RectangleBinPack.CSharp, 1.0.4"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package RectangleBinPack.CSharp@1.0.4
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=RectangleBinPack.CSharp&version=1.0.4
                    
Install as a Cake Addin
#tool nuget:?package=RectangleBinPack.CSharp&version=1.0.4
                    
Install as a Cake Tool

RectangleBinPack C#

NuGet License

中文文档 (Chinese)

A complete, high-performance C# port of the famous RectangleBinPack library by Jukka Jylänki.

🆕 New Feature: Added SingleBinPack algorithm specifically optimized for packing large quantities of a single type of rectangle.

📦 Algorithms Included

This library faithfully implements the core algorithms from the original C++ library, plus a new specialized algorithm:

  1. MaxRects (MaxRectsBinPack) - Recommended. Highest packing density for mixed shapes.
  2. Skyline (SkylineBinPack) - Fastest. Good for runtime packing.
  3. Guillotine (GuillotineBinPack) - Simulates edge-to-edge cuts.
  4. Shelf (ShelfBinPack) - Simple row-based layout.
  5. SingleBin (SingleBinPack) - [New] Optimized for mass production of a single part type. Supports mixed horizontal/vertical layouts.

🌟 Single Part Packing Examples

The new SingleBinPack algorithm is designed to maximize utilization when packing thousands of identical items. It automatically determines the best combination of horizontal and vertical placements. | Example 1 | Example 2 | Example 3 | Example 4 |

⚙️ Algorithm Parameters & Heuristics

Different algorithms offer various heuristic strategies. Choosing the right heuristic significantly impacts the packing quality.

1. MaxRectsBinPack

Init: new MaxRectsBinPack(width, height, allowRotations: true) Method: Insert(w, h, FreeRectChoiceHeuristic)

Heuristic Description Recommendation
RectBestShortSideFit Best Short Side Fit. Positions the rectangle to minimize the remaining short side of the free space. ⭐ Recommended. Usually yields the best results.
RectBestAreaFit Best Area Fit. Chooses the smallest free rectangle into which the new one fits. Good alternative.
RectBottomLeftRule Bottom Left. Places the rectangle as far down and left as possible (Tetris-style). Good for intuitive layouts.
RectContactPointRule Contact Point. Chooses the placement where the rectangle touches other rects as much as possible. Reduces fragmentation.
RectBestLongSideFit Best Long Side Fit. Minimizes the remaining long side. Less commonly used.

2. SkylineBinPack

Init: new SkylineBinPack(width, height, useWasteMap: true) Method: Insert(w, h, LevelChoiceHeuristic)

Heuristic Description
LevelBottomLeft Places the rectangle at the lowest, leftmost position on the skyline.
LevelMinWasteFit Places the rectangle where it causes the least "wasted" area (gaps) below it.

3. GuillotineBinPack

Init: new GuillotineBinPack(width, height) Method: Insert(w, h, merge, FreeRectChoiceHeuristic, GuillotineSplitHeuristic) Requires two strategies: one for choosing the rect, one for splitting the space.

A. Choice Strategy (FreeRectChoiceHeuristic):

  • RectBestAreaFit: Preferred.
  • RectBestShortSideFit / RectBestLongSideFit
  • (And corresponding "Worst" fits)

B. Split Strategy (GuillotineSplitHeuristic):

  • SplitMinimizeArea: Recommended. Splits so the smaller leftover rectangle is minimized (keeping the larger area intact).
  • SplitMaximizeArea: Splits so the larger leftover rectangle is maximized.
  • SplitShorterLeftoverAxis / SplitLongerLeftoverAxis.

4. ShelfBinPack

Init: new ShelfBinPack(width, height, useWasteMap: false) Method: Insert(w, h, ShelfChoiceHeuristic)

Heuristic Description
ShelfNextFit Puts the new rectangle to the last open shelf. Starts a new shelf if it doesn't fit. Fastest.
ShelfBestAreaFit Chooses the shelf with smallest remaining shelf area.
ShelfFirstFit Tests each shelf and packs into the first one where it fits.
ShelfBestHeightFit Chooses the shelf with best-matching height.

🚀 Installation

This library is available on NuGet.

.NET CLI

dotnet add package RectangleBinPack.CSharp

Package Manager

Install-Package RectangleBinPack.CSharp

💻 Usage

  1. Basic Example (MaxRects - Mixed Parts)
using System;
using System.Collections.Generic;
using RectangleBinPacking;

public class Program
{
    public static void Main()
    {
        // 1. Initialize a 1024x1024 bin, allowing 90-degree rotations
        var packer = new MaxRectsBinPack(1024, 1024, allowRotations: true);

        // 2. Prepare items to pack
        var items = new List<(int w, int h)> 
        { 
            (200, 100), (50, 50), (300, 300), (1000, 500) 
        };

        // 3. Pack items
        foreach (var item in items)
        {
            Rect result = packer.Insert(item.w, item.h, FreeRectChoiceHeuristic.RectBestShortSideFit);

            if (result.Height > 0)
            {
                Console.WriteLine($"Packed {item.w}x{item.h} at X={result.X}, Y={result.Y}, Rotated={result.Width != item.w}");
            }
            else
            {
                Console.WriteLine($"Failed to pack {item.w}x{item.h}: Bin is full!");
            }
        }
    }
}
  1. Single Part Example (SingleBinPack)
using RectangleBinPacking;

// 1. Initialize bin size (Width, Height)
var singlePacker = new SingleBinPack(3000, 1500);

// 2. Pack 500 copies of a 200x100 part
// The algorithm will automatically decide the optimal mix of horizontal and vertical placements.
List<Rect> results = singlePacker.Insert(partWidth: 200, partHeight: 100, quantity: 500);

Console.WriteLine($"Successfully packed {results.Count} items.");
foreach(var rect in results)
{
    Console.WriteLine($"Part at: {rect.X}, {rect.Y} Size: {rect.Width}x{rect.Height}");
}
  1. Advanced Example (Skyline with Waste Map)
// Initialize Skyline packer, enable WasteMap (second arg true) to recover gaps
var skylinePacker = new SkylineBinPack(2048, 2048, useWasteMap: true);

Rect node = skylinePacker.Insert(200, 150, SkylineBinPack.LevelChoiceHeuristic.LevelBottomLeft);

if (node.Height > 0)
{
    Console.WriteLine($"Skyline Placed at: {node.X}, {node.Y}");
}

📄 License

Released under Public Domain (Unlicense) or MIT. You are free to use, modify, and distribute this software for any purpose, commercial or otherwise.
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • .NETStandard 2.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.4 111 1/28/2026
1.0.3 95 1/27/2026
1.0.2 95 1/17/2026
1.0.1 96 1/17/2026
1.0.0 98 1/17/2026