Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,15 @@ module.exports = function(items, options) {
// Clone the items.
var newItems = items.map(function(item) { return inPlace ? item : { width: item.width, height: item.height, item: item }; });

// We need to know whether the widest item exceeds the maximum width.
// The optimal sorting strategy changes depending on this.
const widestWidth =
newItems.sort(function(a, b) { return b.width - a.width})[0].width
const widerThanMax = options.maxWidth && (widestWidth > options.maxWidth)

newItems = newItems.sort(function(a, b) {
if (options.maxWidth && !options.maxHeight) return b.width - a.width
if (options.maxWidth && !options.maxHeight && widerThanMax) return b.width - a.width
if (options.maxWidth && !options.maxHeight) return b.height - a.height
if (options.maxHeight) return b.height - a.height
// TODO: check that each actually HAS a width and a height.
// Sort based on the size (area) of each block.
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "bin-pack-with-constraints",
"version": "1.0.1",
"version": "1.0.2",
"description": "A packing algorithm for 2D bin packing that allows setting a max width or height. Largely based on code and a blog post by Jake Gordon and Bryan Burgers.",
"author": {
"name": "Enoch Riese",
Expand Down
10 changes: 7 additions & 3 deletions packer.growing.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ Construction:
{
maxWidth = Infinity: set a max width to constrain the growth in that direction
maxHeight = Infinity: set a max height to constrain the growth in that direction
TODO strictMax = false: reject blocks that are larger than the max
strictMax = false: require wider-than-max blocks to start at left boundary
PREVIOUS INTENDED TODO strictMax = false: reject blocks that are larger than the max
}

Inputs:
Expand Down Expand Up @@ -76,7 +77,7 @@ Example:
var GrowingPacker = function({maxWidth = Infinity, maxHeight = Infinity, strictMax = false}) {
this.maxWidth = maxWidth
this.maxHeight = maxHeight
// this.strictMax = strictMax
this.strictMax = strictMax
this.ensureSquare = maxWidth === Infinity && maxHeight === Infinity
};

Expand All @@ -87,7 +88,10 @@ GrowingPacker.prototype = {
if (len === 0) { return }

var n, node, block, fit;
var width = this.strictMax && (this.maxWidth < Infinity) ? this.maxWidth : blocks[0].width;
// Require wider-than-max blocks to start at the left boundary, so
// they encroach past the right boundary minimally.
var width = this.strictMax && (this.maxWidth < Infinity) ? Math.max(blocks[0].width, this.maxWidth) : blocks[0].width;

var height = this.strictMax && (this.maxHeight < Infinity) ? this.maxHeight : blocks[0].height;
this.root = { x: 0, y: 0, width, height };
for (n = 0; n < len ; n++) {
Expand Down
44 changes: 42 additions & 2 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -217,8 +217,48 @@ describe('bin-pack with maxWidth option', function() {
assert.equal(result.items.length, bins.length, "Result has same amount of items as the source");
verifyResult(result, result.items);
})
})

describe('with strictMax: true', function() {
it('packs items that exceed the maximum width at the left edge', function() {
var bins = [
{ width: 100, height: 10 },
{ width: 110, height: 10 },
];

var result = pack(bins, {maxWidth: 90, strictMax: true});
assert.ok('items' in result, "Result has items");
assert.equal(result.items.length, bins.length, "Result has same amount of items as the source");
assert.ok(result.width === 110, 'Width is that of the widest item')
verifyResult(result, result.items);
})

describe('with strictMax: true', function() {
it('rejects bins that exceed the maximum')
it('does not unnecessarily pack items to exceed the maximum width', function() {
var bins = [
{ width: 10, height: 110 },
{ width: 10, height: 110 },
{ width: 10, height: 110 },
{ width: 40, height: 48 },
{ width: 40, height: 48 },
{ width: 40, height: 48 },
{ width: 50, height: 48 },
{ width: 50, height: 48 },
{ width: 50, height: 48 },
{ width: 60, height: 48 },
{ width: 60, height: 48 },
{ width: 70, height: 48 },
{ width: 70, height: 48 },
{ width: 30, height: 48 },
{ width: 30, height: 48 },
{ width: 30, height: 48 },
];

var result = pack(bins, {maxWidth: 60, strictMax: true});
assert.ok('items' in result, "Result has items");
assert.equal(result.items.length, bins.length, "Result has same amount of items as the source");
assert.ok(result.width === 70, 'Width is that of the widest item')
verifyResult(result, result.items);
})

it('rejects bins that exceed the maximum')
})