Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local arrayfunction = {}
- local function recurseMul(self, val)
- for k, v in pairs(self) do
- if type(v) == "table" then
- return recurseMul(v,val)
- else
- self[k]=(tonumber(v) or 0) * (tonumber(val) or 1)
- end
- end
- return self
- end
- function arrayfunction.mul(tble, v)
- if type(tble) ~= "array" then return nil end
- local self=getmetatable(tble)
- local r = recurseMul(self.__data,v)
- return tble
- end
- function arrayfunction.get(tble, ...)
- if type(tble) ~= "array" then return nil end
- local args = {...}
- local self = getmetatable(tble)
- local bfValue = self.__data
- for i=1, #args do
- if type(bfValue) == "table" then
- bfValue = rawget(bfValue,args[i])
- else
- return bfValue
- end
- end
- return bfValue
- end
- function arrayfunction.clear(tble)
- if type(tble) ~= "array" then return nil end
- local self = getmetatable(tble)
- self.__data = {}
- self.__count = 0
- return tble
- end
- function arrayfunction.count(tble)
- if type(tble) ~= "array" then return nil end
- return getmetatable(tble).__count
- end
- function arrayfunction.unpackValues(tble)
- if type(tble) ~= "array" then return nil end
- local self = getmetatable(tble)
- local n = {}
- for k, v in pairs(self.__data) do
- n[#n+1]=v
- end
- return unpack(n)
- end
- function arrayfunction.unpackKeys(tble)
- if type(tble) ~= "array" then return nil end
- local self = getmetatable(tble)
- local n = {}
- for k, v in pairs(self.__data) do
- n[#n+1]=k
- end
- return unpack(n)
- end
- function arrayfunction.unpackPairs(tble)
- if type(tble) ~= "array" then return nil end
- local self = getmetatable(tble)
- local n = {}
- for k, v in pairs(self.__data) do
- n[#n+1]={key=k, value=v}
- end
- return unpack(n)
- end
- local function newindex(tble,index,val)
- if getmetatable(tble).__data[index] and val == nil then
- getmetatable(tble).__count = getmetatable(tble).__count-1
- local bval = getmetatable(tble).__data[index]
- getmetatable(tble).__data2[bval] = getmetatable(tble).__data2[bval] or {}
- getmetatable(tble).__data2[bval][index]=nil
- end
- if not getmetatable(tble).__data[index] and val ~= nil then
- getmetatable(tble).__count = getmetatable(tble).__count+1
- getmetatable(tble).__data2[val] = getmetatable(tble).__data2[val] or {}
- getmetatable(tble).__data2[val][index]=true
- end
- getmetatable(tble).__data[index]=val
- end
- local function call(me, arg1)
- if not arg1 then
- return getmetatable(me).__count
- else
- if getmetatable(me).__data2[arg1] then
- return setmetatable(getmetatable(me).__data2[arg1], {__index=function(tble, index) return getmetatable(tble).__data2[arg1][index] end,__call=function(tble) local n={} for k, v in pairs(getmetatable(me).__data2[arg1]) do n[#n+1]=k end return n end })
- end
- end
- end
- local function new(me,tble)
- local count = 0
- local d2 = {}
- for k, v in pairs(tble) do
- count = count + 1
- d2[v] = d2[v] or {}
- d2[v][k]=true
- end
- if type(tble) == "table" or type(tble) == "array" then
- return setmetatable({},{__index=function(tble, index) return getmetatable(tble).__data[index] end,
- __newindex = newindex,
- __data=tble,
- __data2=d2,
- __count=count,
- __mul=arrayfunction.mul,
- __tostring=function() return tostring(tble):gsub("table:","array:") end,
- __type="array",
- __call=call,
- __len=function(tble) return #getmetatable(tble).__data end,
- })
- end
- end
- local array = setmetatable({},{__index=arrayfunction,__call=new,__tostring=function() return "ArrayClass" end,__type=="ArrayClass"})
- dim3D = {}
- dim2D = {}
- function dim3D.sphere(dx,dy,dz,r)
- local points = {}
- local check = {}
- for theta = -math.pi/2,math.pi/2, 1/r/2 do
- local subr = r*math.cos(theta)
- local z = math.sin(theta)*r
- for phi=0, 2*math.pi, 1/subr/2 do
- x=math.cos(phi)*subr
- y=math.sin(phi)*subr
- local dt = math.floor(dx+x+0.5)..":"..math.floor(dy+y+0.5)..":"..math.floor(dz+z+0.5)
- if not check[dt] then
- points[#points+1]={x=math.floor(dx+x+0.5),y=math.floor(dy+y+0.5),z=math.floor(dz+z+0.5)}
- check[dt]=true
- end
- end
- end
- return points
- end
- function dim2D.line(x0,y0,x1,y1)
- local dx, sx = math.abs(x1-x0), x0<x1 and 1 or -1
- local dy, sy = -math.abs(y1-y0), y0<y1 and 1 or -1
- local err = dx+dy
- local e2 = 0
- local points = {}
- while true do
- points[#points+1]={x=x0,y=y0}
- e2=2*err
- if e2>=dy then
- if x0 == x1 then break end
- err=err+dy x0=x0+sx
- end
- if e2<=dx then
- if y0 == y1 then break end
- err=err+dx y0=y0+sy
- end
- end
- return points
- end
- function dim3D.line(x0,y0,z0,x1,y1,z1)
- local points = {}
- points[#points+1]={x=x1,y=y1,z=z1}
- points[#points+1]={x=x0,y=y0,z=z0}
- local dx, sx = math.abs(x1-x0), x0<x1 and 1 or -1
- local dy, sy = math.abs(y1-y0), y0<y1 and 1 or -1
- local dz, sz = math.abs(z1-z0), z0<z1 and 1 or -1
- local dm = math.max(dx,dy,dz)
- local i = dm
- x1, y1, z1 = dm/2, dm/2, dm/2
- while true do
- points[#points+1]={x=x0,y=y0,z=z0}
- i=i-1
- if i==0 then break end
- x1=x1-dx
- if x1<0 then x1=x1+dm x0=x0+sx end
- y1=y1-dy
- if y1<0 then y1=y1+dm y0=y0+sy end
- z1=z1-dz
- if z1<0 then z1=z1+dm z0=z0+sz end
- end
- return points
- end
- function dim2D.circle(xm,ym,r)
- local points = {}
- local x, y, err=-r, 0, 2-2*r
- while (x<0) do
- points[#points+1]={x=xm-x,y=ym+y}
- points[#points+1]={x=xm-y,y=ym-x}
- points[#points+1]={x=xm+x,y=ym-y}
- points[#points+1]={x=xm+y,y=ym+x}
- r = err
- if r<=y then y=y+1 err=err+y*2+1 end
- if r>x or err>y then x=x+1 err=err+x*2+1 end
- sleep(0.2)
- end
- return points
- end
- function dim2D.ellipse(x0,y0,x1,y1)
- local a=math.abs(x1-x0)
- local b=math.abs(y1-y0)
- local b1 = bit.band(b,1)
- local dx, dy = 4*(1-a)*b^2, 4*(b1+1)*a^2
- local err, e2=dx+dy+b1*a^2, 0
- if x0>x1 then x0=x1 x1=x1+a end
- if y0>y1 then y0=y1 end
- y0=y0+(b+1)/2
- y1=y0-b1
- a=8*a^2
- b1=8*b^2
- local points = {}
- while x0 <= x1 do
- points[#points+1]={x=x1,y=y0}
- points[#points+1]={x=x0,y=y0}
- points[#points+1]={x=x0,y=y1}
- points[#points+1]={x=x1,y=y1}
- e2=2*err
- if e2<=dy then y0=y0+1 y1=y1-1 dy=dy+a err=err+dy end
- if e2 >= dx or 2*err > dy then x0=x0+1 x1=x1-1 dx=dx+b1 err=err+dx end
- end
- while y0-y1 < b do
- points[#points+1]={x=x0-1,y=y0}
- y0=y0+1
- points[#points+1]={x=x1+1,y=y0}
- points[#points+1]={x=x0-1,y=y1}
- y1=y1-1
- points[#points+1]={x=x1+1,y=y1}
- end
- return points
- end
- function dim2D.fastcircle(nx,ny,r)
- local x0, y0, x1, y1=nx-r, ny-r, nx+r, ny+r
- local a=math.abs(x1-x0)
- local b=math.abs(y1-y0)
- local b1 = bit.band(b,1)
- local dx, dy = 4*(1-a)*b^2, 4*(b1+1)*a^2
- local err, e2=dx+dy+b1*a^2, 0
- if x0>x1 then x0=x1 x1=x1+a end
- if y0>y1 then y0=y1 end
- y0=y0+(b+1)/2
- y1=y0-b1
- a=8*a^2
- b1=8*b^2
- local points = {}
- while x0 <= x1 do
- points[#points+1]={x=x1,y=y0}
- points[#points+1]={x=x0,y=y0}
- points[#points+1]={x=x0,y=y1}
- points[#points+1]={x=x1,y=y1}
- e2=2*err
- if e2<=dy then y0=y0+1 y1=y1-1 dy=dy+a err=err+dy end
- if e2 >= dx or 2*err > dy then x0=x0+1 x1=x1-1 dx=dx+b1 err=err+dx end
- end
- while y0-y1 < b do
- points[#points+1]={x=x0-1,y=y0}
- y0=y0+1
- points[#points+1]={x=x1+1,y=y0}
- points[#points+1]={x=x0-1,y=y1}
- y1=y1-1
- points[#points+1]={x=x1+1,y=y1}
- end
- return points
- end
- function dim2D.bezier(x0,y0,x1,y1,x2,y2)
- local sx, sy = x2-x1, y2-y1
- local xx, yy= x0-x1, y0-y1
- local xy = 0
- local dx, dy, err, cur = xx*sy-yy*sx, xx*sy-yy*sx, xx*sy-yy*sx, xx*sy-yy*sx
- --assert(xx*sx<=0 and yy*sy<=0)
- if sx^2+sy^2 > xx^2+yy^2 then x2=x0 x0=sx+x1 y2=y0 y0=sy+y1 cur=-cur end
- if cur ~= 0 then
- xx=xx+sx
- sx=x0<x2 and 1 or -1
- xx=xx*sx
- yy=yy+sy
- sy=y0<y2 and 1 or -1
- yy=yy*sy
- xy=2*xx*yy
- xx=xx^2
- yy=yy^2
- if cur*sx*sy < 0 then xx=-xx yy=-yy xy=-xy cur=-cur end
- dx=4*sy*cur*(x1-x0)+xx-xy
- dy=4*sx*cur*(y0-y1)+yy-xy
- xx=2*xx
- yy=2*yy
- err=dx+dy+xy
- local points = {}
- while dy < dx do
- print(dy,dx)
- points[#points+1]={x=x0,y=y0}
- if x0==x2 and y0==y2 then return points end
- y1=2*err<dx
- if 2*err > dy then x0=x0+sx dx=dx-xy dy=dy+yy err=err+dy end
- if y1 then y0=y0+sy dy=dy-xy dx=dx+xx err=err+dx end
- end
- return points
- end
- return dim2D.line(x0,y0,x2,y2)
- end
- function dim2D.triangle(x0,y0,x1,y1,x2,y2)
- local points={}
- local function line(x0,y0,x1,y1)
- local dx, sx = math.abs(x1-x0), x0<x1 and 1 or -1
- local dy, sy = -math.abs(y1-y0), y0<y1 and 1 or -1
- local err = dx+dy
- local e2 = 0
- while true do
- points[#points+1]={x=x0,y=y0}
- e2=2*err
- if e2>=dy then
- if x0 == x1 then break end
- err=err+dy x0=x0+sx
- end
- if e2<=dx then
- if y0 == y1 then break end
- err=err+dx y0=y0+sy
- end
- end
- end
- line(x0,y0,x1,y1)
- line(x0,y0,x2,y2)
- line(x1,y1,x2,y2)
- return points
- end
- local function fillBottomFlatTriangle(x0,y0,x1,y1,x2,y2,pts)
- local points=pts
- local function line(x0,y0,x1,y1)
- local dx, sx = math.abs(x1-x0), x0<x1 and 1 or -1
- local dy, sy = -math.abs(y1-y0), y0<y1 and 1 or -1
- local err = dx+dy
- local e2 = 0
- while true do
- points[#points+1]={x=x0,y=y0}
- e2=2*err
- if e2>=dy then
- if x0 == x1 then break end
- err=err+dy x0=x0+sx
- end
- if e2<=dx then
- if y0 == y1 then break end
- err=err+dx y0=y0+sy
- end
- end
- end
- local invslop1 = math.floor((x1-x0)/(y1-y0)+0.5)
- local invslop2 = math.floor((x2-x0)/(y2-y0)+0.5)
- local curx1 = x0
- local curx2 = x0
- for scanLineY=y0, y1 do
- line(curx1,scanLineY,curx2,scanLineY)
- curx1=curx1+invslop1
- curx2=curx2+invslop2
- end
- pts=points
- end
- local function fillTopFlatTriangle(x0,y0,x1,y1,x2,y2,pts)
- local points=pts
- local function line(x0,y0,x1,y1)
- local dx, sx = math.abs(x1-x0), x0<x1 and 1 or -1
- local dy, sy = -math.abs(y1-y0), y0<y1 and 1 or -1
- local err = dx+dy
- local e2 = 0
- while true do
- points[#points+1]={x=x0,y=y0}
- e2=2*err
- if e2>=dy then
- if x0 == x1 then break end
- err=err+dy x0=x0+sx
- end
- if e2<=dx then
- if y0 == y1 then break end
- err=err+dx y0=y0+sy
- end
- end
- end
- local invslop1 = math.floor((x2-x0)/(y2-y0)+0.5)
- local invslop2 = math.floor((x2-x1)/(y2-y1)+0.5)
- local curx1 = x2
- local curx2 = x2
- for scanLineY=y2, y0, -1 do
- line(curx1,scanLineY,curx2,scanLineY)
- curx1=curx1-invslop1
- curx2=curx2-invslop2
- end
- pts=points
- end
- function dim2D.filledtriangle(x0,y0,x1,y1,x2,y2)
- local points = dim2D.triangle(x0,y0,x1,y1,x2,y2)
- local function line(x0,y0,x1,y1)
- local points={}
- local dx, sx = math.abs(x1-x0), x0<x1 and 1 or -1
- local dy, sy = -math.abs(y1-y0), y0<y1 and 1 or -1
- local err = dx+dy
- local e2 = 0
- while true do
- points[#points+1]={x=x0,y=y0}
- e2=2*err
- if e2>=dy then
- if x0 == x1 then break end
- err=err+dy x0=x0+sx
- end
- if e2<=dx then
- if y0 == y1 then break end
- err=err+dx y0=y0+sy
- end
- end
- return points
- end
- local x3 = 0
- local y3 = math.min(y1,y2)
- local v1 = line(x0,y0,x1,y1)
- local v2 = line(x0,y0,x2,y2)
- if y3==y1 then
- for i=1, #v2 do
- if v2[i] and v2[i].y==y3 then
- x3=v2[i].x
- break
- end
- end
- fillBottomFlatTriangle(x0,y0,x1,y1,x3,y3,points)
- fillTopFlatTriangle(x1,y1,x3,y3,x2,y2,points)
- else
- for i=1, #v1 do
- if v1[i] and v1[i].y==y3 then
- x3=v1[i].x
- break
- end
- end
- fillBottomFlatTriangle(x0,y0,x3,y3,x2,y2,points)
- fillTopFlatTriangle(x3,y3,x2,y2,x1,y1,points)
- end
- return points
- end
- function dim2D.filledCircle(xm,ym,r)
- local points = {}
- local function line(x0,y0,x1,y1)
- local dx, sx = math.abs(x1-x0), x0<x1 and 1 or -1
- local dy, sy = -math.abs(y1-y0), y0<y1 and 1 or -1
- local err = dx+dy
- local e2 = 0
- while true do
- points[#points+1]={x=x0,y=y0}
- e2=2*err
- if e2>=dy then
- if x0 == x1 then break end
- err=err+dy x0=x0+sx
- end
- if e2<=dx then
- if y0 == y1 then break end
- err=err+dx y0=y0+sy
- end
- end
- end
- local x, y, err=-r, 0, 2-2*r
- while (x<0) do
- points[#points+1]={x=xm-x,y=ym+y}
- points[#points+1]={x=xm-y,y=ym-x}
- points[#points+1]={x=xm+x,y=ym-y}
- points[#points+1]={x=xm+y,y=ym+x}
- line(xm-x,ym+y,xm+x,ym+y)
- line(xm-x,ym-y,xm+x,ym-y)
- r = err
- if r<=y then y=y+1 err=err+y*2+1 end
- if r>x or err>y then x=x+1 err=err+x*2+1 end
- sleep(0.2)
- end
- return points
- end
- function dim2D.filledEllipse(x0,y0,x1,y1)
- local points = {}
- local function line(x0,y0,x1,y1)
- local dx, sx = math.abs(x1-x0), x0<x1 and 1 or -1
- local dy, sy = -math.abs(y1-y0), y0<y1 and 1 or -1
- local err = dx+dy
- local e2 = 0
- while true do
- points[#points+1]={x=x0,y=y0}
- e2=2*err
- if e2>=dy then
- if x0 == x1 then break end
- err=err+dy x0=x0+sx
- end
- if e2<=dx then
- if y0 == y1 then break end
- err=err+dx y0=y0+sy
- end
- end
- end
- local a=math.abs(x1-x0)
- local b=math.abs(y1-y0)
- local b1 = bit.band(b,1)
- local dx, dy = 4*(1-a)*b^2, 4*(b1+1)*a^2
- local err, e2=dx+dy+b1*a^2, 0
- if x0>x1 then x0=x1 x1=x1+a end
- if y0>y1 then y0=y1 end
- y0=y0+(b+1)/2
- y1=y0-b1
- a=8*a^2
- b1=8*b^2
- while x0 <= x1 do
- points[#points+1]={x=x1,y=y0}
- points[#points+1]={x=x0,y=y0}
- points[#points+1]={x=x0,y=y1}
- points[#points+1]={x=x1,y=y1}
- line(x0,y0,x1,y0)
- line(x0,y1,x1,y1)
- e2=2*err
- if e2<=dy then y0=y0+1 y1=y1-1 dy=dy+a err=err+dy end
- if e2 >= dx or 2*err > dy then x0=x0+1 x1=x1-1 dx=dx+b1 err=err+dx end
- end
- while y0-y1 < b do
- points[#points+1]={x=x0-1,y=y0}
- y0=y0+1
- points[#points+1]={x=x1+1,y=y0}
- points[#points+1]={x=x0-1,y=y1}
- y1=y1-1
- points[#points+1]={x=x1+1,y=y1}
- end
- return points
- end
- function dim2D.filledFastcircle(nx,ny,r)
- local points = {}
- local function line(x0,y0,x1,y1)
- local dx, sx = math.abs(x1-x0), x0<x1 and 1 or -1
- local dy, sy = -math.abs(y1-y0), y0<y1 and 1 or -1
- local err = dx+dy
- local e2 = 0
- while true do
- points[#points+1]={x=x0,y=y0}
- e2=2*err
- if e2>=dy then
- if x0 == x1 then break end
- err=err+dy x0=x0+sx
- end
- if e2<=dx then
- if y0 == y1 then break end
- err=err+dx y0=y0+sy
- end
- end
- end
- local x0, y0, x1, y1=nx-r, ny-r, nx+r, ny+r
- local a=math.abs(x1-x0)
- local b=math.abs(y1-y0)
- local b1 = bit.band(b,1)
- local dx, dy = 4*(1-a)*b^2, 4*(b1+1)*a^2
- local err, e2=dx+dy+b1*a^2, 0
- if x0>x1 then x0=x1 x1=x1+a end
- if y0>y1 then y0=y1 end
- y0=y0+(b+1)/2
- y1=y0-b1
- a=8*a^2
- b1=8*b^2
- while x0 <= x1 do
- points[#points+1]={x=x1,y=y0}
- points[#points+1]={x=x0,y=y0}
- points[#points+1]={x=x0,y=y1}
- points[#points+1]={x=x1,y=y1}
- line(x0,y0,x1,y0)
- line(x0,y1,x1,y1)
- e2=2*err
- if e2<=dy then y0=y0+1 y1=y1-1 dy=dy+a err=err+dy end
- if e2 >= dx or 2*err > dy then x0=x0+1 x1=x1-1 dx=dx+b1 err=err+dx end
- end
- while y0-y1 < b do
- points[#points+1]={x=x0-1,y=y0}
- y0=y0+1
- points[#points+1]={x=x1+1,y=y0}
- points[#points+1]={x=x0-1,y=y1}
- y1=y1-1
- points[#points+1]={x=x1+1,y=y1}
- end
- return points
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement