2013-03-16 101 views
2

我想为Lua制作一些Vector3库,它可以让您用简单的语法进行简单的3D位置操作。我会提到我正在使用Luaj来运行用于Java操作的Lua代码。(Lua)使用非数字值进行数学运算

这里是我开始的代码:

Vector3 = { 
new = function (x1, y1, z1) 
    return {x = x1, y = y1, z = z1} 
end 
} 



Position1 = Vector3.new(1, 5, 8) 
Position2 = Vector3.new(4, 7, 2) 

这里就是我希望能够发生:

Subtraction = Position1 - Position2 
print(Subtraction.x, Subtraction.y, Subtraction.z) -- prints "-3, -2, 6" 

上作出确切的代码工作的任何想法?

+3

你应该定义__sub元方法。 – 2013-03-16 18:36:04

+0

感谢!这是我的问题的解决方案! – 2013-03-16 18:48:50

回答

3

这就是元表和元方法是。您应该阅读in the documentation

基本上,它们让你重新定义运营商(以及其他一些事物)对你的价值观所做的事情。你现在想要的是定义__sub metamethod,它定义了如何处理-运算符。我想在将来你会想重新定义其他的metamethods。

首先,在你Vector3“类”,它有两个向量定义一个减法功能:

function Vector3.subtract(u,v) 
    return Vector3.new(u.x - v.x, u.y - v.y, u.z - v.z) 
end 

然后创建让Vector3知道元表也应该给所有的向量:

Vector3.mt = {__sub = Vector3.subtract} 

当你创建一个新的载体:

new = function (x1, y1, z1) 
    local vec = {x = x1, y = y1, z = z1} 
    setmetatable(vec, Vector3.mt) 
    return vec 
end 

你可以也可以在您的new函数中将metatable(mt)作为局部变量 - 这将防止外部代码与metatable混淆(因为它只能通过您的new函数访问)。然而,里面有它Vector3让你核对用法像v - "string"

function Vector3.subtract(u,v) 
    if getmetatable(u) ~= Vector3.mt or 
     getmetatable(v) ~= Vector3.mt then 
     error("Only vectors can be subtracted from vectors", 2) 
    end 
    return Vector3.new(u.x - v.x, u.y - v.y, u.z - v.z) 
end 
3

你可以做这样的事情:

Vector3 = {} 

mt = {} 

function Vector3:new(_x, _y, _z) 
    return setmetatable({ 
    x = _x or 0, 
    y = _y or 0, 
    z = _z or 0 
    }, mt) 
end 

mt.__sub = function(v1, v2) return Vector3:new(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z) end 
mt.__tostring = function(v) return "Vector3=(" .. v.x .. "," .. v.y .. "," .. v.z .. ")" end 
mt.__index = Vector3 -- redirect queries to the Vector3 table 

-- test Vector3 
Position1 = Vector3:new(1, 5, 8) 
Position2 = Vector3:new(4, 7, 2) 
Sub = Position1 - Position2 
print(Sub) 

这将打印:

Vector3=(-3,-2,6)

更多的Lua & OO,请参阅:http://lua-users.org/wiki/ObjectOrientationTutorial