在Lua三维表 [英] Three dimensional table in Lua

查看:257
本文介绍了在Lua三维表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要存储的三维表像素的最佳方式。我需要做的是有多个X,Y表(基本上三维)这是光栅多个二维像素的地图与透明度。你看,我可以轻松地创建两个维度,像这样:

I need the best way to store a three dimensional table for pixels. What I need to do is have multiple x,y tables (basically three dimensional) it is to raster multiple two dimensional pixel maps with transparency. You see I can create two dimensions easily like so:

pixels = {{},{}}
pixels[1][5] = "green" --just an example
print(pixels[1][5])

不过,我不能做到这一点像我一样在Java中...

However, I cannot do this like I can in Java...

pixels = {{}, {}, {}}
pixels[1][4][3] = "red" -- [x][y][z]
print(pixels[1][4][3])

这是我想要的功能,但我已经令人作呕做这个...

This is the functionality I want, but I have disgustingly got around this by doing this...

pixels = {}
pixels["x23,y02,z05"] = "green"
print(pixels["x23,y02,z05"]")

我只是用string.sub,并string.concat读取和设置表...我真的想例如2到工作的功能,但是我知道这可能需要不同的方式实现。

I just use string.sub, and string.concat to read and set the tables... I really would like the functionality of example 2 to work, however I know it might need to be implemented differently.

推荐答案

有基本上都是去这两种方法

There are basically two ways to go about this

自动生成的表子表采用透明和元表本质上创建后,你应该能够对他们给忘了。

Auto-tables generate sub-tables transparently using metatables and essentially after creating it you should be able to forget about them.

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

什么是不是很好关于他们的是,它们所产生的表地段的 - 显然。这是一些内存开销和深度的每个级别增加了执行时间。

What is not so nice about them is that they generate lots of tables -- obviously. That's some memory overhead and each level of depth increases the execution time.

什么是对他们很好的是,他们可以在尺寸完全动态的。你甚至可以让他们无限深。尽管在你的用例,这是极有可能没有必要的,甚至可能是一个坏主意。

What's nice about them is that they can be completely dynamic in size. You could even make them infinitely deep. Though in your use-case this is very likely not necessary and probably even a bad idea.

此结构非常适合非整数索引虽然,例如,你可以做深度甚至依赖于一个模板结构等实施动态透明的配置表,但我越来越扯到...

This structure is very suitable for non-integer indexes though, you could for example make the depth even depend on a "template structure" and so implement a transparent dynamic configuration table, but I'm getting side-tracked...

的其他变体是扁平阵列。 user3125367已经写他们,但我想在这个扩大,因为这是可以做到方便多了,并解释了一些东西。

The other variant are flattened arrays. user3125367 already wrote about them, but I want to expand on this as this can be done a lot more convenient and explain a few things.

通常压扁你的多维数组在CG是一个好主意,无论如何,既然那么你可以很容易做很多矩阵运算。计算修正指数也是所需的处理时间方面相对便宜。但应当指出,尽管一种显而易见的,这种方法只用数字键和你的矩阵的一个predefined大小的工作原理。

Often flattening your multi-dimensional arrays is a good idea in CG anyway, since then you can do many matrix operations very easily. Calculating a modified index is also relatively cheap in terms of processing time required. But it should be noted, although kind of obvious, that this approach only works with numeric keys and a predefined size of your matrix.

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);

这code是从我的另一个答案采取:<一href=\"http://stackoverflow.com/questions/16919625/dynamic-tables-or-arrays/16942322#16942322\">dynamic表或阵列

This code is taken from another answer from me: dynamic tables or arrays

大概可以优化的一点(例如计算 X * Y 在封闭),但我想在这里粘贴在原code。无论如何,这样,你既可以方便的对扁平化结构,只需使用普通的数组索引工作:

It can probably be optimised a little (for example calculate X*Y in the closure) but I wanted to paste the original code here. Anyway, with this you can both easily work on the flattened structure by just using normal array indexing:

for i=1, #mdt
    mdt[i] = (mdt[i] or 0)*.5
end

还有机会获得3D指标直接:

As well as access 3d indexes directly:

mdt(12, 13, 14, 0)

您也可以轻松地修改函数来通过添加 __指数字段的元表或使表保存矩阵尺寸等丢失的钥匙返回默认值

You can also easily modify the function to return a default value for missing keys by adding an __index field to the metatable or so that the table saves the matrix dimensions etc.

这篇关于在Lua三维表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆