User:Meevere
Hello there. I have a useful piece of code for vectors using 30log lib:
Usage:
Vector2 = require("vector")[1] -- Or whatever name it would have
local v1 = Vector2({1,2})
local v2 = v1 + {2,3} -- Auto-converts other objects for easier usage
local scaled = {2,1} * v1 --- Element-wise multiplication
Module itself
local Class = require("libs/30log")
local Vector2 = Class("Vector2", {0, 0})
function Vector2:init(a, b)
if type(a) == "table" then
-- Create from table --
if (a["x"] ~= nil) and (a["y"] ~= nil) then
-- This is something like Vector2 - duck typing
if type(a["x"]) == "function" then
self[1] = a:x();
else
self[1] = a.x;
end
if type(a["y"]) == "function" then
self[2] = a:y();
else
self[2] = a.y;
end
else
-- Then just by numbers
self[1] = a[1]; self[2] = a[2]
end
else
-- Then think of an a as number
self[1] = a or 0; self[2] = b or 0
end
end
function Vector2.__tostring(v)
return 'Vector<'..tostring(v[1])..','..tostring(v[2])..'>'
end
function Vector2.fromPolar(r, phi)
local x = r * math.cos(phi)
local y = r * math.sin(phi)
return Vector2(x,y)
end
function Vector2:x()
return self[1]
end
function Vector2:y()
return self[2]
end
function Vector2.__eq(v1, v2)
return v1[1] == v2[1] and v1[2] == v2[2]
end
function Vector2.__add(v1, v2)
local out = Vector2()
out[1] = v1[1] + v2[1]
out[2] = v1[2] + v2[2]
return out
end
function Vector2.__unm(v)
return Vector2(-v[1], -v[2])
end
function Vector2.__sub(v1, v2)
return v1 + (-v2)
end
function Vector2.__mul(a, b)
local out = Vector2()
if (type(a) == "table") and (type(b) == "table") then
-- Multiply component-vice
out[1] = a[1] * b[1]
out[2] = a[2] * b[2]
return out
end
if( type(a) == "table" ) then
return b * a -- swap order
end
-- Multiply by scalar (first argument)
out[1] = a * b[1]
out[2] = a * b[2]
return out
end
local function inverse(v)
return Vector2(1/v[1], 1/v[2])
end
function Vector2.__div(a, b)
local inv;
if type(b) == "table" then
inv = inverse(b)
else
inv = 1/b
end
return a * inv
end
function Vector2:magsqr()
return self[1]*self[1] + self[2]*self[2]
end
function Vector2:mag()
return math.sqrt(self:magsqr())
end
-- Returns the angle from x axis from in range [-pi,pi)
function Vector2:angle()
local phi = math.acos(self[1]/math.sqrt(self:magsqr()))
if(self[2] < 0) then
phi = -phi
end
return phi
end
local Vector3 = Class("Vector3", {0, 0, 0})
function Vector3:init(a, b, c)
if type(a) == "table" then
-- Create from table --
if (a["x"] ~= nil) and (a["y"] ~= nil) and (a["z"] ~= nil) then
-- This is something like Vector2 - duck typing
self[1] = a.x; self[2] = a.y; self[3] = a.y
else
-- Then just by numbers
self[1] = a[1]; self[2] = a[2]; self[3] = a[3]
end
else
-- Then think of an a as number
self[1] = a or 0; self[2] = b or 0; self[3] = c or 0
end
end
function Vector3:x()
return self[1]
end
function Vector3:y()
return self[2]
end
function Vector3:z()
return self[3]
end
function Vector3.__add(v1, v2)
local out = Vector3()
out[1] = v1[1] + v2[1]
out[2] = v1[2] + v2[2]
out[3] = v1[3] + v2[3]
return out
end
function Vector3.__unm(v)
return Vector3(-v[1], -v[2], -v[3])
end
function Vector3.__sub(v1, v2)
return v1 + (-v2)
end
function Vector3.__mul(a, b)
local out = Vector3()
if (type(a) == "table") and (type(b) == "table") then
-- Multiply component-vice
out[1] = a[1] * b[1]
out[2] = a[2] * b[2]
out[3] = a[3] * b[3]
return out
end
if( type(a) == "table" ) then
return b * a -- swap order
end
-- Multiply by scalar (first argument)
out[1] = a * b[1]
out[2] = a * b[2]
out[3] = a * b[3]
return out
end
-- adjacent methods
function Vector3:getXY()
return Vector2(self[1], self[2])
end
function Vector3:setXY(v)
self[1] = v[1]
self[2] = v[2]
end
return {Vector2, Vector3}