binpackingjs

repository·master·Indexed 41 days ago

https://github.com/olragon/binpackingjs

A fast, fully-typed 2D and 3D bin packing library for JavaScript and TypeScript featuring an immutable design and tree-shakeable modules. Version 4.1.0 provides stateless functions like pack2D and pack3D, as well as stateful Packer2D and Packer3D classes. It supports various 2D heuristics including BestShortSideFit, BestAreaFit, BestLongSideFit, and BottomLeft, and allows for custom heuristic implementations via the Heuristic interface.

Tokens
6.6K
Snippets
26
Records
33
Agent score
52%

What's inside binpackingjs

  1. Control Rotation in 2D and 3D

    master

    2D Rotation

    To prevent a box from being rotated to fit, set constrainRotation: true on the box object.

    3D Rotation

    To restrict an item to specific orientations, use the allowedRotations option with values from the RotationType enum.

    Available RotationType values: WHD, HWD, HDW, DHW, DWH, WDH.

    // 2D Example
    pack2D({
      bins: [{ width: 100, height: 50 }],
      boxes: [
        { width: 50, height: 100, constrainRotation: true },
      ],
    });
    
    // 3D Example
    import { pack3D, RotationType } from 'binpackingjs/3d';
    
    pack3D({
      bins: [{ name: 'Bin', width: 100, height: 100, depth: 300, maxWeight: 1500 }],
      items: [{
        name: 'Fragile Item',
        width: 150, height: 50, depth: 50, weight: 20,
        allowedRotations: [RotationType.WHD, RotationType.DHW],
      }],
    });
  2. Quick Start: 3D Bin Packing

    master

    To perform 3D bin packing, import pack3D from binpackingjs/3d. Pass an object containing bins (with name, width, height, depth, and maxWeight) and items (with name, width, height, depth, and weight). The result includes packedBins and unfitItems.

    import { pack3D } from 'binpackingjs/3d';
    
    const result = pack3D({
      bins: [
        { name: 'Small Box', width: 296, height: 296, depth: 8, maxWeight: 1000 },
      ],
      items: [
        { name: 'Item 1', width: 250, height: 250, depth: 2, weight: 200 },
        { name: 'Item 2', width: 250, height: 250, depth: 2, weight: 200 },
        { name: 'Item 3', width: 250, height: 250, depth: 2, weight: 200 },
      ],
    });
    
    console.log(result.packedBins[0].items.length); // 3
    console.log(result.unfitItems.length);          // 0
  3. Quick Start: 2D Bin Packing

    master

    To perform 2D bin packing, import pack2D from binpackingjs/2d. Pass an object containing bins (available containers) and boxes (items to pack). The result includes packedBins containing the placement data and unpackedBoxes for items that could not fit.

    import { pack2D } from 'binpackingjs/2d';
    
    const result = pack2D({
      bins: [
        { width: 100, height: 50 },
        { width: 50, height: 50 },
      ],
      boxes: [
        { width: 15, height: 10 },
        { width: 50, height: 45 },
        { width: 40, height: 40 },
        { width: 200, height: 200 }, // Too large to fit
      ],
    });
    
    console.log(result.packedBins[0].boxes);
    // [ 
    //   { width: 40, height: 40, x: 0, y: 0, rotated: false, sourceBox: ... },
    //   { width: 15, height: 10, x: 0, y: 40, rotated: false, sourceBox: ... },
    // ]
    
    console.log(result.unpackedBoxes.length); // 1
  4. Install binpackingjs

    master

    You can install binpackingjs using npm, bun, or yarn. The library is tree-shakeable, so you can import only the specific dimension modules you need (binpackingjs/2d or binpackingjs/3d) to minimize bundle size.

    npm install binpackingjs
    # or
    bun add binpackingjs
    # or
    yarn add binpackingjs
  5. Migrating from v3 to v4

    master

    Version 4 is a full rewrite. Key changes include:

    • Data Handling: Instead of using new Box() and checking properties on the box, pass plain objects and read placement data from the returned result object.
    • Immutability: Bins are no longer mutated in place; results are returned in a new object structure.
    • Imports: Use named imports from specific subpaths (e.g., import { pack2D } from 'binpackingjs/2d') instead of requiring the main package.
    • Return Values: Methods like packer.pack() now return the full result object (e.g., Pack3DResult) rather than being void or returning just the packed items.
  6. Use binpackingjs for 2D and 3D bin packing

    master

    The binpackingjs package provides APIs for solving 2D and 3D bin packing problems. The main entrypoint exports all functionality from the ./2d and ./3d modules, allowing you to call pack2D and pack3D directly. Use pack2D for arranging rectangular items in a 2D plane and pack3D for arranging rectangular cuboids in a 3D volume.

    import { pack2D, pack3D } from 'binpackingjs';
    
    // Example usage (requires specific options for each method)
    // const result2D = pack2D(options2D);
    // const result3D = pack3D(options3D);
  7. API Reference: pack3D(options)

    master

    The pack3D function performs 3D bin packing.

    Options:

    • bins (Bin3D[], required): Available bins { name, width, height, depth, maxWeight }.
    • items (Item3D[], required): Items to pack { name, width, height, depth, weight, allowedRotations? }.

    Returns: { packedBins: PackedBin3D[], unfitItems: Item3D[] }

    Each PackedItem3D includes position, rotationType, dimension, and sourceItem (reference to input).

  8. API Reference: pack2D(options)

    master

    The pack2D function performs 2D bin packing using a specified heuristic.

    Options:

    • bins (Bin2D[], required): Available bins { width, height }.
    • boxes (Box2D[], required): Boxes to pack { width, height, constrainRotation? }.
    • heuristic (Heuristic, default: BestShortSideFit): The placement strategy to use.
    • limit (number, default: all): Maximum number of boxes to pack.

    Returns: { packedBins: PackedBin2D[], unpackedBoxes: Box2D[] }

    Each PackedBin2D includes:

    • boxes: Packed boxes with x, y, width, height, rotated, and sourceBox (reference to input).
    • efficiency: Percentage of bin area used.
  9. Use the Class-based API

    master

    For an imperative programming style, use Packer2D or Packer3D classes.

    2D Usage:

    1. Instantiate Packer2D with an array of bins.
    2. Call .pack(boxes) with an array of boxes.

    3D Usage:

    1. Instantiate Packer3D.
    2. Use .addBin(bin) to add containers.
    3. Use .addItem(item) to add items.
    4. Call .pack() to execute.
    import { Packer2D } from 'binpackingjs/2d';
    import { Packer3D } from 'binpackingjs/3d';
    
    // 2D
    const packer2d = new Packer2D([{ width: 100, height: 50 }]);
    const result2d = packer2d.pack([{ width: 50, height: 50 }]);
    
    // 3D
    const packer3d = new Packer3D();
    packer3d.addBin({ name: 'Bin', width: 100, height: 100, depth: 100, maxWeight: 1000 });
    packer3d.addItem({ name: 'Item', width: 50, height: 50, depth: 50, weight: 10 });
    const result3d = packer3d.pack();
  10. Configure 2D Heuristics

    master

    You can customize the placement strategy in pack2D by providing a heuristic instance.

    Available Heuristics:

    • BestShortSideFit (default): Minimizes leftover on the shorter side.
    • BestAreaFit: Minimizes wasted area in the chosen free rectangle.
    • BestLongSideFit: Minimizes leftover on the longer side.
    • BottomLeft: Places items as low and left as possible.
    import { pack2D, BestAreaFit } from 'binpackingjs/2d';
    
    const result = pack2D({
      bins: [{ width: 100, height: 50 }],
      boxes: [{ width: 50, height: 100 }],
      heuristic: new BestAreaFit(),
    });
  11. Use pack3D for 3D bin packing

    master

    The pack3D function is the primary entrypoint for performing 3D bin packing. It accepts a Pack3DOptions object and returns a Pack3DResult containing the packed items and bin information.

    import { pack3D } from 'binpackingjs/3d';
    
    const result = pack3D({
      // ... Pack3DOptions
    });
  12. Perform 2D bin packing with pack2D()

    master

    Use the pack2D function to arrange a set of 2D boxes into a set of 2D bins. The function uses a heuristic to find optimal placements and supports scaling via a factor to improve performance through integer factorization.

    Parameters

    • bins: An array of Bin2D objects defining the available containers.
    • boxes: An array of Box2D objects to be packed.
    • heuristic: (Optional) A strategy used to find the best position for a box. Defaults to BestShortSideFit.
    • limit: (Optional) The maximum number of boxes to attempt to pack.
    • factor: (Optional) A scaling factor used to convert dimensions to integers for faster computation. If not provided, it is automatically computed based on all dimensions.

    Returns

    A Pack2DResult object containing:

    • packedBins: An array of PackedBin2D objects, each containing the bin dimensions, the list of PackedBox2D items inside, and the calculated efficiency (percentage of area used).
    • unpackedBoxes: An array of Box2D items that could not be placed in any bin.
    import { pack2D } from './2d/packer';
    
    const result = pack2D({
      bins: [{ width: 100, height: 100 }],
      boxes: [
        { width: 50, height: 50 },
        { width: 30, height: 30, constrainRotation: true }
      ],
      heuristic: new BestShortSideFit(),
      limit: 10
    });
    
    console.log(result.packedBins);
    console.log(result.unpackedBoxes);