Skip to content

Instantly share code, notes, and snippets.

@kongakong
Created December 18, 2017 09:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kongakong/7bbc21b3aa28388051d56b774ae3428e to your computer and use it in GitHub Desktop.
Save kongakong/7bbc21b3aa28388051d56b774ae3428e to your computer and use it in GitHub Desktop.
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