RectpackSharp 1.2.0
dotnet add package RectpackSharp --version 1.2.0
NuGet\Install-Package RectpackSharp -Version 1.2.0
<PackageReference Include="RectpackSharp" Version="1.2.0" />
paket add RectpackSharp --version 1.2.0
#r "nuget: RectpackSharp, 1.2.0"
// Install RectpackSharp as a Cake Addin #addin nuget:?package=RectpackSharp&version=1.2.0 // Install RectpackSharp as a Cake Tool #tool nuget:?package=RectpackSharp&version=1.2.0
RectpackSharp
A rectangle packing library made in C# for .NET Standard.
Loosely based on the well-known C++ rectpack-2D library
This started as a side-project for the TrippyGL graphics library but as it grew, I decided to give it it's own repository and open the project for everyone to use.
The libary is quite small, so you can even just chuck the files directly onto your project if you don't want additional DLLs!
Usage
Once you have the library, just add using RectpackSharp
to access the library types.
You will see the PackingRectangle
type and the RectanglePacker
static class.
Create a PackingRectangle
for each rectangle you want and put them all in a single array. You can identify your rectangles using the PackingRectangle.Id
field, as the order of the rectangles is not preserved. Afterwards, just call RectanglePacker.Pack
. That's it!
PackingRectangle[] rectangles = new PackingRectangle[amount];
// Set the width and height of your rectangles
// ...
RectanglePacker.Pack(rectangles, out PackingRectangle bounds);
// All the rectangles in the array were assigned X and Y values. Bounds contains the width and height of the bin.
Specifying no extra parameters means the library will try all it's tools in order to find the best bin it can. If performance is important, you can trade space efficiency for performance with the optional parameters:
packingHint
allows you to specify which methods to try when packing. Default isPackingHints.FindBest
.acceptableDensity
makes the library stop searching once it found a solution with said density or better. Density is calculated as usedArea/binArea, so a density of 0 will yield the fastest solution it can, but possibly not an efficient one. Default is 1.stepSize
is by how much to vary the bin size after each try. Higher values might be faster but skip possibly better solutions. Default is 1.
So for example, if you know all your rectangles are squares, you might wanna try
RectanglePacker.Pack(rectangles, out PackingRectangle bounds, PackingHints.Width, 1, 1);
Pack
also provides two additional arguments of type uint?
, called maxBoundsWidth
and maxBoundsHeight
. These may be used to constrain the resulting bin to a given width and/or height. If, for example, you want a max bin height of 500, you may do something like this:
RectanglePacker.Pack(rectangles, out PackingRectangle bounds, PackingHints.FindBest, 1, 1, null, 500);
Need Help?
Feel free to come ask questions over at the TrippyGL Discord server!
Gallery
Here's a test case where the rectangles have relatively similar dimentions.
In this test case, all the squares are the same size. Currently, the library doesn't handle the edges very well on these cases.
It also works like a charm for texture atlases or sprite sheets!
The most complicated cases are when the rectangles have very irregular dimentions, because there's no good answer to "what to put where". For these next test cases, we simply generated 512 or 2048 random rectangles (each side being from 20 to 200) and packed them.
Fuck it, here's 65536 random rectangles in a ~24k x 24k bin.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 is compatible. 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. |
.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. |
-
.NETStandard 2.0
- Microsoft.Bcl.HashCode (>= 1.1.1)
- System.Memory (>= 4.5.4)
-
net5.0
- Microsoft.Bcl.HashCode (>= 1.1.1)
- System.Memory (>= 4.5.4)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
- Added Span support on .NET 5.0 and greater