В портированном коде есть проблемы, не могу понять, как это должно работать

Итак, я перенес этот бит кода из файла JavaScript в Lua. Это решение проблемы Bin Packing. По сути, это заданный целевой размер прямоугольника "init(x,y)", а затем ему дается таблица с блоками для заполнения указанного прямоугольника "fit(blocks)". Однако, когда я запускаю это, я получаю ошибку "попытка индексировать локальный" корень "(числовое значение)". Что здесь не так?

Я также не совсем понимаю, как работает этот код, кто-то помог мне с процессом портирования. Когда я передаю таблицу "блоки" в функцию подгонки, добавляет ли она атрибуты 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 ответ

Я не знаю, поможет ли это, но вот как я перенес бы код на 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"

Другие вопросы по тегам