Advertisement
fatboychummy

Triangulator.lua

Jun 2nd, 2021
716
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 9.74 KB | None | 0 0
  1. local sX, sY, sZ = gps.locate() -- offsets to "0,0,0"
  2.  
  3. local canvas = peripheral.call("back", "canvas3d")
  4. canvas.clear()
  5. local c = canvas.create()
  6. --c.recenter()
  7.  
  8. local function clear()
  9.   term.clear()
  10.   term.setCursorPos(1, 1)
  11. end
  12.  
  13. local function cPrint(key, val)
  14.   print(string.format("Press '%s' to %s.", key, val))
  15. end
  16.  
  17. local function createLine()
  18.   local stage = 1
  19.  
  20.   -- get the points for the line
  21.   local points = {}
  22.   local boxes = {}
  23.   for stage = 1, 2 do
  24.     while true do
  25.       clear()
  26.       cPrint("enter", string.format("set position %d of line", stage))
  27.       cPrint("backspace", "cancel creating a new line")
  28.       local _, key = os.pullEvent("key")
  29.       if key == keys.enter then
  30.         -- create new point
  31.         points[stage] = {gps.locate()}
  32.         boxes[stage] = c.addBox(
  33.           points[stage][1] - sX - 0.25,
  34.           points[stage][2] - sY - 0.25,
  35.           points[stage][3] - sZ - 0.25,
  36.           0.5,
  37.           0.5,
  38.           0.5
  39.         )
  40.         os.sleep(1)
  41.         break
  42.       elseif key == keys.backspace then
  43.         for i = 1, #boxes do
  44.           boxes[i].remove()
  45.         end
  46.         return
  47.       end
  48.     end
  49.   end
  50.  
  51.   local p1 = {
  52.     points[1][1] - sX,
  53.     points[1][2] - sY,
  54.     points[1][3] - sZ
  55.   }
  56.   local p2 = {
  57.     points[2][1] - sX,
  58.     points[2][2] - sY,
  59.     points[2][3] - sZ
  60.   }
  61.  
  62.   -- create and return the line (with the proper offsets applied)
  63.   return {
  64.     c.addLine(p1, p2, 30),
  65.     boxes[1],
  66.     boxes[2]
  67.   }
  68. end
  69.  
  70. local function confirmDeletion(lines, pos)
  71.   local line = lines[pos]
  72.   for i = 1, #line do
  73.     line[i].setColor(255, 0, 0, 255)
  74.   end
  75.  
  76.   while true do
  77.     clear()
  78.     print("The line selected has been highlighted red.  Confirm deletion?")
  79.     cPrint('y', "delete")
  80.     cPrint('n', "cancel")
  81.     local _, key = os.pullEvent("key")
  82.     if key == keys.y then
  83.       for i = 1, #line do
  84.         line[i].remove()
  85.       end
  86.       table.remove(lines, pos)
  87.       print("Deleted.")
  88.       return
  89.     elseif key == keys.n then
  90.       break
  91.     end
  92.   end
  93.  
  94.   for i = 1, #line do
  95.     line[i].setColor(255, 255, 255, 255)
  96.   end
  97. end
  98.  
  99. local function selectLine(lines, cr, cy, cb)
  100.   -- determine player position
  101.   local pX, pY, pZ = gps.locate()
  102.   pX = pX - sX; pY = pY - sY; pZ = pZ - sZ
  103.  
  104.   -- determine what line is nearby
  105.   local near = false
  106.   for i = 1, #lines do
  107.     line = lines[i][1]
  108.     for o = 1, 2 do
  109.       lX, lY, lZ = line.getPoint(o)
  110.  
  111.       pt = lines[i][o + 1]
  112.       pt.setColor(cr, cy, cb, 255)
  113.  
  114.       if lX > pX - 1 and lX < pX + 1
  115.          and lY > pY - 1 and lY < pY + 1
  116.          and lZ > pZ - 1 and lZ < pZ + 1 then
  117.         near = i
  118.         pt.setColor(255, 255, 255, 255)
  119.         break
  120.       end
  121.  
  122.       pt.setColor(255, 255, 255, 255)
  123.       if near then
  124.         break
  125.       end
  126.     end
  127.   end
  128.  
  129.   return near
  130. end
  131.  
  132. local function deleteLine(lines)
  133.   while true do
  134.     clear()
  135.     print("Stand at the start or end position of a line to select it for removal.")
  136.     cPrint('enter', "select line for deletion")
  137.     cPrint('backspace', "cancel")
  138.     local _, key = os.pullEvent("key")
  139.     if key == keys.enter then
  140.       local near = selectLine(lines, 255, 0, 0)
  141.  
  142.       if near then
  143.         -- confirm deletion
  144.         confirmDeletion(lines, near)
  145.       else
  146.         print("Could not find any nearby lines.")
  147.       end
  148.  
  149.       os.sleep(2)
  150.     elseif key == keys.backspace then
  151.       return
  152.     end
  153.   end
  154. end
  155.  
  156. --------------------------------------------------------------------------------
  157. --------------------------------------------------------------------------------
  158. --
  159. -- Intersection functions
  160. --
  161. --------------------------------------------------------------------------------
  162. --------------------------------------------------------------------------------
  163.  
  164. local function calcIntersection(l1, l2, plane)
  165.   if plane == 'xz' then -- xz
  166.     local p11 = {l1[1].getPoint(1)}
  167.     local p12 = {l1[1].getPoint(2)}
  168.     local a1 = p12[3] - p11[3]
  169.     local b1 = p11[1] - p12[1]
  170.     local c1 = a1 * p11[1] + b1 * p11[3]
  171.  
  172.     local p21 = {l2[1].getPoint(1)}
  173.     local p22 = {l2[1].getPoint(2)}
  174.     local a2 = p22[3] - p21[3]
  175.     local b2 = p21[1] - p22[1]
  176.     local c2 = a2 * p21[1] + b2 * p21[3]
  177.  
  178.     local det = a1 * b2 - a2 * b1
  179.  
  180.     if det == 0 then
  181.       -- lines parallel
  182.       return false, "Lines are parallel, no intersection."
  183.     end
  184.  
  185.     return {(b2 * c1 - b1 * c2) / det, (a1 * c2 - a2 * c1) / det}
  186.   elseif plane == 'xy' then -- xy
  187.   elseif plane == 'zy' then -- zy
  188.   end
  189.   return false, "Not a plane."
  190. end
  191.  
  192. local function intersect(lines, points)
  193.   local intersectors = {}
  194.   local i = 1
  195.   while not intersectors[2] do
  196.     clear()
  197.     print("Stand at the start or end position of a line to select it for intersection.")
  198.     print(string.format("This will be line %d", i))
  199.     cPrint('enter', "select line for intersection")
  200.     cPrint('backspace', "cancel")
  201.     local _, key = os.pullEvent("key")
  202.     if key == keys.enter then
  203.       local near = selectLine(lines, 0, 255, 0)
  204.       local line = lines[near]
  205.       if line then
  206.         intersectors[i] = line
  207.         for o = 1, #intersectors do
  208.           for p = 1, #intersectors[o] do
  209.             intersectors[o][p].setColor(0, 255, 0)
  210.           end
  211.         end
  212.         i = i + 1
  213.       else
  214.         print("Could not find any lines nearby.")
  215.         os.sleep(2)
  216.       end
  217.     elseif key == keys.backspace then
  218.       return
  219.     end
  220.   end
  221.  
  222.   while true do
  223.     clear()
  224.     print("Select the plane to check for intersections on")
  225.     cPrint('x', "select xz plane (flat)")
  226.     cPrint('y', "select xy plane")
  227.     cPrint('z', "select zy plane")
  228.  
  229.     local _, key = os.pullEvent("key")
  230.  
  231.     local hit, err = calcIntersection(
  232.       intersectors[1],
  233.       intersectors[2],
  234.       key == keys.x and 'xz' or key == keys.y and 'xy' or key == keys.z and 'zy'
  235.     )
  236.  
  237.     if hit then
  238.       local function hString(a, b, c)
  239.         print(string.format("Calculated intersection point to be %.2f, %.2f, %.2f", a, b, c))
  240.       end
  241.       local extra = {intersectors[1][1].getPoint(1)}
  242.       local h1 = hit[1] - 0.25
  243.       local h2 = hit[2] - 0.25
  244.       local e1 = extra[1] - 0.25
  245.       local e2 = extra[2] - 0.25
  246.       local e3 = extra[3] - 0.25
  247.  
  248.       if key == keys.x then -- xz
  249.         points[#points + 1] = {
  250.           c.addBox(h1, e2, h2, 0.5, 0.5, 0.5),
  251.           c.addLine({0, 0, 0}, {hit[1], extra[2], hit[2]}, 10)
  252.         }
  253.         for i = 1, #points[#points] do
  254.           points[#points][i].setColor(0, 255, 0)
  255.         end
  256.         hString(hit[1], extra[2], hit[2])
  257.       elseif key == keys.y then -- xy
  258.         points[#points + 1] = {
  259.           c.addBox(h1, h2, e3, 0.5, 0.5, 0.5),
  260.           c.addLine({0, 0, 0}, {hit[1], hit[2], extra[3]}, 10)
  261.         }
  262.         for i = 1, #points[#points] do
  263.           points[#points][i].setColor(0, 255, 0)
  264.         end
  265.         hString(hit[1], hit[2], extra[3])
  266.       elseif key == keys.z then -- zy
  267.         points[#points + 1] = {
  268.           c.addBox(e1, h2, h1, 0.5, 0.5, 0.5),
  269.           c.addLine({0, 0, 0}, {extra[1], hit[2], hit[1]}, 10)
  270.         }
  271.         for i = 1, #points[#points] do
  272.           points[#points][i].setColor(0, 255, 0)
  273.         end
  274.         hString(extra[1], hit[2], hit[1])
  275.       end
  276.       os.sleep(2)
  277.       break
  278.     else
  279.       print(err)
  280.       os.sleep(2)
  281.       return
  282.     end
  283.   end
  284.  
  285.   for o = 1, #intersectors do
  286.     for p = 1, #intersectors[o] do
  287.       intersectors[o][p].setColor(255, 255, 255)
  288.     end
  289.   end
  290. end
  291.  
  292. local function recenter(lines, points)
  293.   local nX, nY, nZ = gps.locate()
  294.   local dX, dY, dZ = nX - sX, nY - sY, nZ - sZ
  295.   c.recenter()
  296.  
  297.   for i = 1, #lines do
  298.     local oX1, oY1, oZ1 = lines[i][1].getPoint(1)
  299.     local oX2, oY2, oZ2 = lines[i][1].getPoint(2)
  300.     local x1, y1, z1 = oX1 - dX, oY1 - dY, oZ1 - dZ
  301.     local x2, y2, z2 = oX2 - dX, oY2 - dY, oZ2 - dZ
  302.  
  303.     lines[i][1].setPoint(1, x1, y1, z1)
  304.     lines[i][1].setPoint(2, x2, y2, z2)
  305.     lines[i][2].setPosition(x1 - 0.25, y1 - 0.25, z1 - 0.25)
  306.     lines[i][3].setPosition(x2 - 0.25, y2 - 0.25, z2 - 0.25)
  307.   end
  308.  
  309.   for i = 1, #points do
  310.     local oX, oY, oZ = points[i][2].getPoint(2)
  311.     local x, y, z = oX - dX, oY - dY, oZ - dZ
  312.  
  313.     points[i][1].setPosition(x - 0.25, y - 0.25, z - 0.25)
  314.     points[i][2].setPoint(2, x, y, z)
  315.   end
  316.   sX, sY, sZ = nX, nY, nZ
  317. end
  318.  
  319. local lines = {}
  320. local points = {}
  321. local t = 0.5
  322. local tmr = os.startTimer(t)
  323. print("YABA DABA DOO")
  324. while true do
  325.   clear()
  326.   print(string.format("Currently %d lines", #lines))
  327.   print(string.format("Currently %d points", #points))
  328.   print(string.format("Origin set at %d, %d, %d", sX, sY, sZ))
  329.   cPrint('n', "create a new line")
  330.   cPrint('d', "delete a line")
  331.   cPrint('r', "delete a point (not implemented)")
  332.   cPrint('c', "calculate intersections")
  333.   cPrint('r', "recenter (use if lines disappear)")
  334.   cPrint('backspace', "clear everything")
  335.  
  336.   local ev = {os.pullEvent()}
  337.   print(ev[1], tmr, ev[2])
  338.   if ev[1] == "key" then
  339.     local key = ev[2]
  340.     if key == keys.n then
  341.       -- new line
  342.       lines[#lines+1] = createLine()
  343.     elseif key == keys.d then
  344.       -- delete line
  345.       deleteLine(lines)
  346.     elseif key == keys.c then
  347.       intersect(lines, points)
  348.     elseif key == keys.r then
  349.       recenter(lines, points)
  350.     elseif key == keys.backspace then
  351.       lines = {}
  352.       points = {}
  353.       canvas.clear()
  354.       c = canvas.create()
  355.       sX, sY, sZ = gps.locate()
  356.     end
  357.     tmr = os.startTimer(t)
  358.   elseif ev[1] == "timer" and ev[2] == tmr then
  359.     local pX, pY, pZ = gps.locate()
  360.     if pX then
  361.       pX = pX - sX; pY = pY - sY; pZ = pZ - sZ
  362.       for i = 1, #points do
  363.         points[i][2].setPoint(1, pX, pY + 0.1, pZ)
  364.       end
  365.     end
  366.     tmr = os.startTimer(t)
  367.   end
  368. end
  369.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement