移植代码有问题,无法弄清楚这应该如何工作

时间:2015-05-28 00:43:21

标签: sorting lua love2d

好的,所以我将这段代码从javascript文件移植到Lua。这是Bin Packing问题的解决方案。基本上,这是一个给定的目标矩形大小“init(x,y)”,然后给出一个带有块的表来填充所述矩形,“fit(blocks)”。 然而,当我运行这个时,我得到错误“尝试索引本地'root'(数字值)”。这里出了什么问题?

没有完全理解这段代码是如何工作的,有人帮我一起移植过程。当我将表“块”传递给fit函数时,它是否添加了block.fit.x和block.fit.y的属性?
任何帮助表示赞赏。

编辑:通过更改“。”修复错误。调用方法时“:”。

--ported from https://github.com/jakesgordon/bin-packing

local _M = {}

mt = {
  init = function(t, x, y)       --takes in dimensions of target rect.
    t.root = { x = 0, y = 0, x = x, y = y }
  end,

  fit = function(t, blocks)     --passes table "blocks"
    local n, node, block
    for k, block in pairs(blocks) do
      if node == t.findNode(t.root, block.x, block.y) then
        block.fit = t.splitNode(node, block.x, block.y)
      end
    end
  end,

  findNode = function(t, root, x, y)
    if root.used then                 --if root.used then
      return t.findNode(root.right, x, y) or t.findNode(root.down, x, y)
      elseif (x <= root.x) and (y <= root.y) then
        return root
      else
        return nil
    end
  end,

  splitNode = function(t, node, x, y)
    node.used = true
    node.down = { x = node.x,   y = node.y + y, x = node.x,   y = node.y - y }
    node.right = { x = node.x + x, y = node.y,   x = node.x - x, y = y      }
    return node;
  end,
}

setmetatable(_M, mt)

-- Let's do the object-like magic
mt.__index = function(t, k)
  if nil ~= mt[k] then
    return mt[k]
  else
    return t[k]
  end
end

mt.__call = function(t, ...)
  local new_instance = {}
  setmetatable(new_instance, mt)
  new_instance:init(...)
  return new_instance
end

return _M

1 个答案:

答案 0 :(得分:0)

我不知道这是否会有所帮助,但这就是我将代码移植到Lua的方式。

local Packer = {}

Packer.__index = Packer

function Packer:findNode (root, w, h)
  if root.used then
    return self:findNode(root.right, w, h) or self:findNode(root.down, w, h)
  elseif w <= root.w and h <= root.h then
    return root
  else
    return nil
  end
end

function Packer:fit (blocks)
  local node
  for _, block in pairs(blocks) do
    node = self:findNode(self.root, block.w, block.h)
    if node then
      block.fit = self:splitNode(node, block.w, block.h)
    end
  end
end

function Packer.init (w, h)
  local packer = {}
  packer.root = {x = 0, y = 0, w = w, h = h}
  return setmetatable(packer, Packer)
end

function Packer: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         }
  return node
end

return Packer

只需将其放在packer.lua这样的文件中,然后将其导入main.lua local Packer = require "packer"