我需要为像素存储三维表的最佳方法。我需要做的是拥有多个x,y表(基本上是三维表),以具有透明度的栅格化多个二维像素图。您会看到我可以轻松地创建两个尺寸,如下所示:
pixels = {{},{}}
pixels[1][5] = "green" --just an example
print(pixels[1][5])
但是,我不能像在Java中那样做...
pixels = {{}, {}, {}}
pixels[1][4][3] = "red" -- [x][y][z]
print(pixels[1][4][3])
这是我想要的功能,但是通过执行此操作,我感到非常厌恶...
pixels = {}
pixels["x23,y02,z05"] = "green"
print(pixels["x23,y02,z05"]")
我只使用string.sub和string.concat来读取和设置表...我确实希望示例2的功能能够正常工作,但是我知道它可能需要以不同的方式实现。
最佳答案
基本上有两种方法可以解决此问题
自动表
自动表使用元表透明地生成子表,基本上,在创建后,您应该能够忘记它们。
function newAutotable(dim)
local MT = {};
for i=1, dim do
MT[i] = {__index = function(t, k)
if i < dim then
t[k] = setmetatable({}, MT[i+1])
return t[k];
end
end}
end
return setmetatable({}, MT[1]);
end
-- Usage
local at = newAutotable(3);
print(at[0]) -- returns table
print(at[0][1]) -- returns table
print(at[0][1][2]) -- returns nil
at[0][1][2] = 2;
print(at[0][1][2]) -- returns value
print(at[0][1][3][3]) -- error, because only 3 dimensions set
关于它们的不好之处在于它们会生成很多表-显然。那是一些内存开销,每个深度级别都会增加执行时间。
它们的优点在于它们的大小可以完全动态。您甚至可以使它们无限深。尽管在您的用例中,这很有可能不是必需的,甚至是一个坏主意。
但是,此结构非常适合非整数索引,例如,您可以使深度甚至取决于“模板结构”,从而实现透明的动态配置表,但是我偏偏了...
展平数组
另一个变体是扁平数组。 user3125367已经写过关于它们的内容,但是我想对此进行扩展,因为这样做可以更加方便并解释一些事情。
无论如何,通常平整多维数组在CG中都是一个好主意,因为这样您就可以非常轻松地执行许多矩阵运算。就所需的处理时间而言,计算修改后的索引也相对便宜。但应注意,尽管很明显,但此方法仅适用于数字键和矩阵的预定义大小。
function newMdArray(X, Y, Z)
local MT = { __call = function(t, x, y, z, v)
if x>X or y>Y or z>Z or x<1 or y<1 or z<1 then return; end
local k = x + X*(y-1) + X*Y*(z-1);
if v ~= nil then t[k] = v; end
return t[k];
end };
return setmetatable({}, MT);
end
-- Usage
local mdt = newMdArray(100, 100, 100);
local v = mdt(1, 2, 3);
mdt(1, 2, 3, v*.1);
此代码来自我的另一个答案:dynamic tables or arrays
可能可以对其进行一些优化(例如,在闭包中计算
X*Y
),但是我想在此处粘贴原始代码。无论如何,通过使用常规数组索引,您都可以轻松地在扁平化结构上工作:for i=1, #mdt
mdt[i] = (mdt[i] or 0)*.5
end
以及直接访问3d索引:
mdt(12, 13, 14, 0)
您还可以通过将
__index
字段添加到元表中来轻松地修改该函数以返回缺少键的默认值,或者使表保存矩阵尺寸等。关于arrays - Lua中的三维表,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21229211/