В портированном коде есть проблемы, не могу понять, как это должно работать
Итак, я перенес этот бит кода из файла 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"