Created
December 18, 2017 09:46
-
-
Save kongakong/7bbc21b3aa28388051d56b774ae3428e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
define (require) -> | |
# blocks = [ | |
# { w: 100, h: 100 }, | |
# { w: 100, h: 100 }, | |
# { w: 80, h: 80 }, | |
# { w: 80, h: 80 } | |
# ]; | |
# packer = new GrowingPacker() | |
# packer.fit(blocks) | |
# for n in [0..blocks.length] | |
# block = blocks[n] | |
# if block?.fit | |
# console.log(block.fit.x, block.fit.y, block.w, block.h); | |
class GrowingPacker | |
fit: (blocks) => | |
n = undefined | |
node = undefined | |
block = undefined | |
len = blocks.length | |
w = if len > 0 then blocks[0].w else 0 | |
h = if len > 0 then blocks[0].h else 0 | |
@root = | |
x: 0 | |
y: 0 | |
w: w | |
h: h | |
n = 0 | |
while n < len | |
block = blocks[n] | |
if node = @findNode(@root, block.w, bluock.h) | |
block.fit = @splitNode(node, block.w, block.h) | |
else | |
block.fit = @growNode(block.w, block.h) | |
n++ | |
return | |
findNode: (root, w, h) => | |
if root.used | |
@findNode(root.right, w, h) or @findNode(root.down, w, h) | |
else if w <= root.w and h <= root.h | |
root | |
else | |
null | |
splitNode: (node, w, h) => | |
node.used = true | |
node.down = | |
x: node.x | |
y: node.y + h | |
w: node.w | |
h: node.h - h | |
node.right = | |
x: node.x + w | |
y: node.y | |
w: node.w - w | |
h: h | |
node | |
growNode: (w, h) => | |
canGrowDown = w <= @root.w | |
canGrowRight = h <= @root.h | |
shouldGrowRight = canGrowRight and @root.h >= @root.w + w | |
# attempt to keep square-ish by growing right when height is much greater | |
# than width | |
shouldGrowDown = canGrowDown and @root.w >= @root.h + h | |
# attempt to keep square-ish by growing down when width is much greater | |
# than height | |
if shouldGrowRight | |
@growRight w, h | |
else if shouldGrowDown | |
@growDown w, h | |
else if canGrowRight | |
@growRight w, h | |
else if canGrowDown | |
@growDown w, h | |
else | |
null | |
# need to ensure sensible root starting size to avoid this happening | |
growRight: (w, h) => | |
@root = | |
used: true | |
x: 0 | |
y: 0 | |
w: @root.w + w | |
h: @root.h | |
down: @root | |
right: | |
x: @root.w | |
y: 0 | |
w: w | |
h: @root.h | |
if node = @findNode(@root, w, h) | |
@splitNode node, w, h | |
else | |
null | |
growDown: (w, h) => | |
@root = | |
used: true | |
x: 0 | |
y: 0 | |
w: @root.w | |
h: @root.h + h | |
down: | |
x: 0 | |
y: @root.h | |
w: @root.w | |
h: h | |
right: @root | |
if node = @findNode(@root, w, h) | |
@splitNode node, w, h | |
else | |
null |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment