Advertisement
billysback

Phx v0

Sep 27th, 2013
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 8.50 KB | None | 0 0
  1.  
  2. function createMatrix(...)
  3.         local mt = {
  4.         __tostring = function(t)
  5.             return "matrix"
  6.         end,
  7.         __pow = function(mat1, mat2)
  8.             if tostring(mat1) == "matrix" and type(mat2) == "number" then
  9.                 for i=1,mat2 do
  10.                     local NIL_VAL = mat1*mat1
  11.                 end
  12.             else
  13.                 error("I'm not powering matrices.")
  14.             end
  15.         end,
  16.         __sub = function(mat1, mat2)
  17.             if tostring(mat1) == "matrix" and tostring(mat2) == "matrix" then
  18.                 if #mat1.pos == #mat2.pos and mat1.h == mat2.h then
  19.                     for i=1,#mat1.pos do
  20.                         local p1 = mat1.pos[i]
  21.                         local p2 = mat2.pos[i]
  22.                         for j=1,#p1 do
  23.                             p1[j] = p1[j] - p2[j]
  24.                         end
  25.                     end
  26.                 else
  27.                     error("simplify your own matrices... :<")
  28.                 end
  29.             elseif tostring(mat1) == "matrix" or tostring(mat2) == "matrix" then
  30.                 local mat = mat1
  31.                 local n = mat2
  32.                 if tostring(mat2) == "matrix" then
  33.                     mat = mat2
  34.                     n = mat1
  35.                 end
  36.                 n = tonumber(n)
  37.                 if type(n) == "number" and tostring(mat) == "matrix" then
  38.                     mat:mathfunc(n, "-")
  39.                 end
  40.             else
  41.                 error("invalid matrix subtraction?")
  42.             end
  43.         end,
  44.         __add = function(mat1, mat2)
  45.             if tostring(mat1) == "matrix" and tostring(mat2) == "matrix" then
  46.                 if #mat1.pos == #mat2.pos and mat1.h == mat2.h then
  47.                     for i=1,#mat1.pos do
  48.                         local p1 = mat1.pos[i]
  49.                         local p2 = mat2.pos[i]
  50.                         for j=1,#p1 do
  51.                             p1[j] = p1[j] + p2[j]
  52.                         end
  53.                     end
  54.                 else
  55.                     error("simplify your own matrices... :<")
  56.                 end
  57.             elseif tostring(mat1) == "matrix" or tostring(mat2) == "matrix" then
  58.                 local mat = mat1
  59.                 local n = mat2
  60.                 if tostring(mat2) == "matrix" then
  61.                     mat = mat2
  62.                     n = mat1
  63.                 end
  64.                 n = tonumber(n)
  65.                 if type(n) == "number" and tostring(mat) == "matrix" then
  66.                     mat:mathfunc(n, "+")
  67.                 end
  68.             else
  69.                 error("invalid matrix addition?")
  70.             end
  71.         end,
  72.         __mul = function(mat1, mat2)
  73.             if tostring(mat1) == "matrix" and tostring(mat2) == "matrix" then
  74.                 mat1.mult(mat1, mat2)
  75.             elseif tostring(mat1) == "matrix" or tostring(mat2) == "matrix" then
  76.                 local mat = mat1
  77.                 local n = mat2
  78.                 if tostring(mat2) == "matrix" then
  79.                     mat = mat2
  80.                     n = mat1
  81.                 end
  82.                 n = tonumber(n)
  83.                 if type(n) == "number" and tostring(mat) == "matrix" then
  84.                     mat:mathfunc(n, "*")
  85.                 end
  86.             else
  87.                 error("invalid matrix multiplication?")
  88.             end
  89.         end
  90.     }
  91.     local args = {...}
  92.     local pos = {}
  93.     local centre = args[#args]
  94.     for i=1,#args-1,2 do
  95.         pos[#pos + 1] = {centre[1]-args[i], centre[2]-args[i+1]}
  96.     end
  97.     local matrix = {
  98.         pos = pos,
  99.         h = 2,
  100.         centre = centre,
  101.         moveCentre = function(self, x, y)
  102.             self.centre = {self.centre[1]+x, self.centre[2]+y}
  103.         end,
  104.         mathfunc = function(self, m, symbol)
  105.             for i=1,#self.pos do
  106.                 local p = self.pos[i]
  107.                 for j=1,#p do
  108.                     p[j] = loadstring("return "..p[j]..symbol..m.."")()
  109.                 end
  110.             end
  111.         end,
  112.         mult = function(mat1, mat2)
  113.             if mat1.h == mat2.h and mat1.h == 2 then
  114.                 for i=1,#mat1.pos do
  115.                     local spos = mat1.pos[i] -- is the sub table {x, y} in matrix.pos { {x1, y1}, {x2, y2} ... {xn, yn} }
  116.                     if #spos == 2 then
  117.                         local mpos = mat2.pos[1]
  118.                         if #mat2.pos == 2 then
  119.                             local npos = {}
  120.                             npos[1] = (spos[1] * mpos[3]) + (spos[2] * mpos[4])
  121.                             npos[2] = (spos[1] * mpos[1]) + (spos[2] * mpos[2])
  122.                             mat1.pos[i] = npos
  123.                         elseif #mat2.pos == 1 then
  124.                             spos[1] = spos[1] * mpos[1]
  125.                             spos[2] = spos[2] * mpos[2]
  126.                         else
  127.                             error("Matrix sizes have to be consistent of 1 or 2 positions, sorry :S")
  128.                         end
  129.                     end
  130.                 end
  131.             end
  132.         end,
  133.         getPos = function(self, i)
  134.             local pos = self.pos[i]
  135.             return pos[1]+self.centre[1], pos[2]+self.centre[2]
  136.         end,
  137.         getData = function(self)
  138.             local dat = ""
  139.             for i=1,#self.pos do
  140.                 local pos = self.pos[i]
  141.                 if i ~= 1 then dat = dat..", " end
  142.                 dat = dat.."["
  143.                 for j=1,#pos do
  144.                     if type(pos[j]) == "number" then
  145.                         if j == 1 then dat = dat..pos[j] else
  146.                             dat = dat..","..pos[j]
  147.                         end
  148.                     end
  149.                 end
  150.                 dat = dat.."]"
  151.             end
  152.             return dat..", {"..self.centre[1]..","..self.centre[2].."}"
  153.         end,
  154.         getTrueData = function(self)
  155.             local dat = ""
  156.             for i=1,#self.pos do
  157.                 local pos = {self:getPos(i)}
  158.                 if i ~= 1 then dat = dat..", " end
  159.                 dat = dat.."["
  160.                 for j=1,#pos do
  161.                     if type(pos[j]) == "number" then
  162.                         if j == 1 then dat = dat..pos[j] else
  163.                             dat = dat..","..pos[j]
  164.                         end
  165.                     end
  166.                 end
  167.                 dat = dat.."]"
  168.             end
  169.             return dat..", {"..self.centre[1]..","..self.centre[2].."}"
  170.         end
  171.     }
  172.     setmetatable(matrix, mt)
  173.     return matrix
  174. end
  175.  
  176. function createPosition(x1, y1, x2, y2, centre)
  177.     local pos = {
  178.         matrix = createMatrix(x1, y1, x2, y2, centre),
  179.         move = function(self, x, y)
  180.             self.matrix:moveCentre(-x, -y)
  181.         end,
  182.         rotate = function(self, ang)
  183.             --ang = math.deg(ang)
  184.             local rotMat = createMatrix(1, 1, {0,0})
  185.             rotMat.pos = { {math.cos(ang), math.sin(ang), -math.sin(ang), math.cos(ang)} }
  186.             rotMat.h = 2
  187.             local NIL_VAL = self.matrix * rotMat
  188.         end,
  189.         scale = function(self, scale)
  190.             scale = scale
  191.             local opos = { {self.matrix.pos[1][1], self.matrix.pos[1][2]}, {self.matrix.pos[2][1], self.matrix.pos[2][2]} }
  192.             local NIL_VAL = self.matrix * scale
  193.             --[[print("pre-scale-move:"..tostring(self))
  194.             local dif = {opos[1][1]-self.matrix.pos[1][1]+1, opos[1][2]-self.matrix.pos[1][2]+1}
  195.             print("dif:"..dif[1]..","..dif[2])
  196.             local p1 = self.matrix.pos[1]
  197.             local p2 = self.matrix.pos[2]
  198.             self.matrix.pos[1] = {p1[1]+dif[1], p1[2]+dif[2]}
  199.             self.matrix.pos[2] = {p2[1]+dif[1], p2[2]+dif[2]}]]
  200.         end,
  201.         getVector = function(self)
  202.             local p1 = {self.matrix:getPos(1)}
  203.             local p2 = {self.matrix:getPos(2)}
  204.             return { {p1[1], p1[2]}, {p2[1], p2[2]} }
  205.         end
  206.     }
  207.     local mt = {
  208.         __tostring = function(t)
  209.             local mat = t.matrix
  210.             return mat:getTrueData()
  211.         end,
  212.     }
  213.     setmetatable(pos, mt)
  214.     return pos
  215. end
  216.  
  217. function createLine(x1, y1, x2, y2)
  218.     local grad = math.abs(y1-y2)/math.abs(x1-x2)
  219.     local c = y1 - (grad*x1)
  220.     return {
  221.         from = {x1, y1},
  222.         to = {x2, y2},
  223.         grad = grad,
  224.         c = c,
  225.         intersectsLine = function(self, line)
  226.             local g = self.grad-line.grad
  227.             local c = line.c-self.c
  228.             local x = c/g
  229.             local y = (self.grad*x) + self.c
  230.             if x >= math.min(self.from[1], self.to[1]) and x <= math.max(self.from[1], self.to[1]) and y >= math.min(self.from[2], self.to[2]) and y <= math.max(self.from[2], self.to[2]) then
  231.                 return true
  232.             end
  233.             return false
  234.         end
  235.     }
  236. end
  237.  
  238. function createPLine(p1, p2) return createLine(p1[1], p1[2], p2[1], p2[2]) end
  239.  
  240. function createPhxProfile(x, y, width, height)
  241.     local pos = createPostition(x, y, width+x-1, height+y-1, {math.floor(x+(width/2)), math.floor(y+(height/2))})
  242.     return {
  243.         pos = pos,
  244.         getLines = function(self)
  245.             local vect = self.pos:getVector()
  246.             local p1 = vect[1]
  247.             local p2 = vect[2]
  248.             local corners = {
  249.                 {math.min(p1[1], p2[1]), math.min(p1[2], p2[2])},
  250.                 {math.min(p1[1], p2[1]), math.max(p1[2], p2[2])},
  251.                 {math.max(p1[1], p2[1]), math.max(p1[2], p2[2])},
  252.                 {math.max(p1[1], p2[1]), math.min(p1[2], p2[2])},
  253.             }
  254.             local lines = {}
  255.             for i=1,#corners do
  256.                 local p2 = corners[i+1]
  257.                 if i == #corners then p2 = corners[1] end
  258.                 lines[#lines + 1] = createPLine(corners[i], p2)
  259.             end
  260.         end
  261.         --[[
  262.             RELATED INFORMATION ABOUT THE PROFILE
  263.         ]]
  264.     }
  265. end
  266.  
  267. function plotVector(vect, color)
  268.     for i=1,#vect do
  269.         local p = vect[i]
  270.         term.setCursorPos(math.floor(p[1]+10), math.floor(p[2]+10))
  271.         term.setBackgroundColour(color)
  272.         term.write(" ")
  273.     end
  274. end
  275.  
  276. --[[
  277.     CODE WHICH USES PHX PROFILES TO DO STUFF...
  278. ]]
  279.  
  280.  
  281. local pos = createPosition(1, 1, 7, 7, {4, 4})
  282. --[[
  283. print("standard:"..tostring(pos))
  284. pos:move(5, 3)
  285. print("move:"..tostring(pos))
  286. pos:scale(7)
  287. print("scale:"..tostring(pos))
  288. ]]
  289.  
  290.  
  291.  
  292. term.setBackgroundColor(colors.black)
  293. term.clear()
  294. term.setCursorPos(1,1)
  295.  
  296. --[[
  297. plotVector(pos:getVector(), colors.green)
  298. pos:scale(2)
  299. plotVector(pos:getVector(), colors.lime)
  300. ]]
  301.  
  302.  
  303.  
  304. --[[
  305. pos:rotate(15)
  306. print("rotate:"..tostring(pos))]]
  307.  
  308.  
  309. --[[
  310.     Physics handling component, these are the functions use to detect collision etc.
  311.         General rules; 
  312.             "prof" stands for "profile" as in Phx Profile, usually followed by a number representative of which number profile it is for that function
  313. ]]
  314.  
  315. function detectCollision(prof1, prof2)
  316.     local lines1 = prof1:getLines()
  317.     local lines2 = prof2:getLines()
  318.     for i=1,#lines1 do
  319.         local l1 = lines1[i]
  320.         for j=1,#lines2 do
  321.             local l2 = lines2[j]
  322.             if l1:intersectsLine(l2) then return true end
  323.         end
  324.     end
  325.     return false
  326. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement