An approach to implement rectangular bin packing

孤街醉人 提交于 2019-11-27 06:22:58

问题


I'm trying to implement 2D bin packing using the Maximal rectangles algorithms as in the following paper.

http://clb.demon.fi/files/RectangleBinPack.pdf

In order to implement this, what type of a data structure will be most appropriate? After googling I found there are different implementation of Guillotine packing algorithm using trees. Can the same approach be applied to this as well. The algorithm itself is not much clear to me. Can I have more clarification on this as well.


回答1:


I stumbled on something when researching for automatic CSS sprite generation. I think in the source the rectangles where represented by tuples, the actual algorithm worked with a binary tree. Maybe it is useful to you.

http://codeincomplete.com/posts/2011/5/7/bin_packing/

edit here is the code sample from https://github.com/jakesgordon/bin-packing/blob/master/js/packer.js

/******************************************************************************

This is a very simple binary tree based bin packing algorithm that is initialized
with a fixed width and height and will fit each block into the first node where
it fits and then split that node into 2 parts (down and right) to track the
remaining whitespace.

Best results occur when the input blocks are sorted by height, or even better
when sorted by max(width,height).

Inputs:
------

  w:       width of target rectangle
  h:      height of target rectangle
  blocks: array of any objects that have .w and .h attributes

Outputs:
-------

  marks each block that fits with a .fit attribute pointing to a
  node with .x and .y coordinates

Example:
-------

  var blocks = [
    { w: 100, h: 100 },
    { w: 100, h: 100 },
    { w:  80, h:  80 },
    { w:  80, h:  80 },
    etc
    etc
  ];

  var packer = new Packer(500, 500);
  packer.fit(blocks);

  for(var n = 0 ; n < blocks.length ; n++) {
    var block = blocks[n];
    if (block.fit) {
      Draw(block.fit.x, block.fit.y, block.w, block.h);
    }
  }


******************************************************************************/

Packer = function(w, h) {
  this.init(w, h);
};

Packer.prototype = {

  init: function(w, h) {
    this.root = { x: 0, y: 0, w: w, h: h };
  },

  fit: function(blocks) {
    var n, node, block;
    for (n = 0; n < blocks.length; n++) {
      block = blocks[n];
      if (node = this.findNode(this.root, block.w, block.h))
        block.fit = this.splitNode(node, block.w, block.h);
    }
  },

  findNode: function(root, w, h) {
    if (root.used)
      return this.findNode(root.right, w, h) || this.findNode(root.down, w, h);
    else if ((w <= root.w) && (h <= root.h))
      return root;
    else
      return null;
  },

  splitNode: function(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          };
    return node;
  }

}


来源:https://stackoverflow.com/questions/21078959/an-approach-to-implement-rectangular-bin-packing

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!