But I did write a useful vector file:
Code: Select all
function vector(t)
if type(t)=="number" then
num=t
t={}
for i=1,num do
t[i]=0
end
else
num=math.min(4,math.max(#t,0))
end
local trans={
['x']=1,
['y']=2,
['z']=3,
['w']=4,
['r']=1,
['g']=2,
['b']=3,
['a']=4
}
local funcs={
["scale"]=function(vec,n)
local m=vec.magnitude/n
return vec*m
end,
["grayscale"]=function(vec)
v=vector(4)
if #vec=="3" then
v.a=255
else
v.a=vec.a
end
local n=(vec.r+vec.g+vec.b)/3
v.r=a
v.g=a
g.b=a
return v
end,
["average"]=function(vec)
local n=0
for i=1,#vec do
n=n+vec[i]
end
return n/#vec
end,
["set"]=function(vec)
if #vec==3 then
love.graphics.setColor(vec[1],vec[2],vec[3])
elseif #vec==4 then
love.graphics.setColor(vec[1],vec[2],vec[3])
end
end,
["tonumber"]=function(vec)
local t={}
for i=1,#vec do
table.insert(t,vec[i])
end
if _VERSION=="Lua 5.1" then
return unpack(t)
elseif _VERSION=="Lua 5.2" then
return table.unpack(t) --I don't like the change much.
end
end
}
local n=newproxy(true)
local mt=getmetatable(n)
local index={}
for i=1,num do
index[i]=t[i]
end
mt.__index=function(_,k)
k=string.lower(k)
if k=="magnitude" then
local n=0
for i=1,math.min(3,num) do
n=n+index[i]^2
end
n=math.sqrt(n)
return n
elseif k=="class" then
return "vector"..num
elseif k=="n" then
return num
elseif k=="v" then
return funcs.grayscale(n)
else
local tn=tonumber(k)
if tn then
return index[tn]
elseif trans[k] then
return index[trans[k]]
elseif funcs[k] then
return function(...)
funcs[k](n,...)
end
elseif math[k] then
return function(vec1,vec2)
if type(vec2)=="number" then
local v=vector(#vec1)
for i=1,#v do
v[i]=math[k](vec1[i],vec2)
end
return v
else
if #vec1~=#vec2 then
return
end
local v=vector(#vec1)
for i=1,#v do
v[i]=math[k](vec1[i],vec2[i])
end
return v
end
end
end
end
end
mt.__newindex=function(_,k,v)
k=string.lower(k)
local tn=tonumber(k) or index[trans]
if not tn then
return nil
end
index[tn]=v
end
mt.__len=function(vec)
return vec.n
end
mt.__tostring=function(vec)
local s=""
for i=1,#vec do
s=s..vec[i]..", "
end
return string.sub(s,1,-3)
end
mt.__concat=mt.__tostring
mt.__add=function(vec1,vec2)
if #vec1~=#vec2 then
return nil
end
local v=vector(#vec)
for i=1,#vec do
v[i]=vec1[i]+vec2[i]
end
end
mt.__unm=function(vec)
local v=vector(#vec)
for i=1,#vec do
v[i]=-vec[i]
end
return v
end
mt.__sub=function(vec1,vec2)
if #vec1~=#vec2 then
return nil
end
local v=vector(#vec)
for i=1,#vec do
v[i]=vec1[i]-vec2[i]
end
return v
end
mt.__mul=function(vec1,vec2)
if #vec1~=#vec2 then
return nil
end
local v=vector(#vec)
for i=1,#vec do
v[i]=vec1[i]*vec2[i]
end
return v
end
mt.__div=function(vec1,vec2)
if #vec1~=#vec2 then
return nil
end
local v=vector(#vec)
for i=1,#vec do
v[i]=vec1[i]/vec2[i]
end
return v
end
mt.__pow=function(vec1,vec2)
if #vec1~=#vec2 then
return nil
end
local v=vector(#vec)
for i=1,#vec do
v[i]=vec1[i]^vec2[i]
end
return v
end
mt.__mod=function(vec1,vec2)
if #vec1~=(type(vec2)=="number" and #vec1 or #vec2) then
return nil
end
local v=vector(#vec1)
for i=1,#vec1 do
v[i]=vec1[i]%(type(vec2)=="number" and vec2 or vec2[i])
end
return v
end
mt.__eq=function(vec1,vec2)
if #vec1~=#vec2 then return false end
for i=1,#vec1 do
if vec1[i]~=vec2[i] then
return false
end
end
return true
end
mt.__lt=function(vec1,vec2)
if #vec1~=#vec2 then return false end
for i=1,#vec1 do
if vec1[i]>=vec2[i] then
return false
end
end
return true
end
mt.__le=function(vec1,vec2)
if vec1==vec2 then return true end
if vec1<vec2 then return true end
return false
end
mt.__mode="v"
return n
end
function vector2(x,y)
return vector{x,y}
end
function vector3(x,y,z)
return vector{x,y,z}
end
function vector4(x,y,z,w)
return vector{x,y,z,w}
end
function colour3(r,g,b)
return vector{r,g,b}
end
function colour4(r,g,b,a)
return vector{r,g,b,a}
end
function set(t)
if type(t)=="table" then
return vector(t)
end
end