Tomlacko

ComputerCraft MandelBrot renderer

Mar 23rd, 2019
304
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 5.34 KB | None | 0 0
  1. --ComputerCraft MandelBrot renderer
  2. --by Tomlacko
  3. --pastebin UnZrcfER
  4. -----------------------
  5. --1 optional parameter: external monitor side
  6. --Zoom by clicking on any spot
  7. --move by arrow keys, zoom by num+/num-
  8. --press space to save image as screenshot openable in paint program
  9. -----------------------
  10.  
  11. function drawBar()
  12.   m.setBackgroundColor(colors.black)
  13.   m.setCursorPos(1, h)
  14.   m.clearLine()
  15.   m.write(" < " .. "ZoomFactor: " .. tostring(zoomspeed) .. " > ")
  16.   m.setCursorPos(w-3,h)
  17.   m.write("Exit")
  18. end
  19.  
  20. function Screenshot()
  21.   if isMonitor then
  22.     print("Enter screenshot filename: ")
  23.   else
  24.     m.setCursorPos(1,h)
  25.     m.setBackgroundColor(colors.black)
  26.     m.clearLine()
  27.     m.write("Enter screenshot filename: ")
  28.   end
  29.   name = read()
  30.   if name=="" then
  31.     if not isMonitor then
  32.       drawBar()
  33.       return true
  34.     end
  35.     print("Canceled...")
  36.     return false
  37.   end
  38.   file = fs.open(name, "w")
  39.   for y=1, h-1 do
  40.     for x=1, w do
  41.       if pixels[y][x]<10 then
  42.         file.write(tostring(pixels[y][x]))
  43.       elseif pixels[y][x]==10 then
  44.         file.write("a")
  45.       elseif pixels[y][x]==11 then
  46.         file.write("b")
  47.       elseif pixels[y][x]==12 then
  48.         file.write("c")
  49.       elseif pixels[y][x]==13 then
  50.         file.write("d")
  51.       elseif pixels[y][x]==14 then
  52.         file.write("e")
  53.       elseif pixels[y][x]==15 then
  54.         file.write("f")
  55.       end
  56.     end
  57.     file.write("\n")
  58.   end
  59.   file.close()
  60.   if not isMonitor then
  61.     drawBar()
  62.     return true
  63.   end
  64.   print("Saved successfully...")
  65.   return false
  66. end
  67.  
  68. args = {...}
  69. isMonitor = false
  70. if args[1]=="top" or args[1]=="bottom" or args[1]=="left" or args[1]=="right" or args[1]=="front" or args[1]=="back" then
  71.   m = peripheral.wrap(args[1])
  72.   m.setTextScale(0.5)
  73.   isMonitor = true
  74. elseif args[1]~=nil then
  75.   print("Invalid monitor side argument!")
  76.   return
  77. else
  78.   m = term
  79. end
  80. w, h = m.getSize()
  81.  
  82. if m.isColor() then
  83.   gamut = 16
  84. else
  85.   gamut = 2
  86. end
  87. colordiff = 8
  88. maxiter = 512
  89. midx = w/2
  90. midy = h/2
  91. zoom = math.min(w,h)/3
  92. offX = -0.5
  93. offY = 0
  94. zoomspeed = 4
  95. interupt = 5
  96.  
  97. pixels = {}
  98. for y=1, h-1 do
  99.   pixels[y] = {}
  100.   for x=1, w do
  101.     pixels[y][x] = "0"
  102.   end
  103. end
  104.  
  105. while true do
  106.   m.setBackgroundColor(colors.black)
  107.   m.clear()
  108.   m.setBackgroundColor(colors.white)
  109.   drawBar()
  110.   skip = false
  111.   for y=1, h-1 do
  112.     for x=1, w do
  113.       xm = x-midx
  114.       ym = y-midy
  115.       x0 = xm/zoom + offX
  116.       y0 = (ym*1.5)/zoom + offY
  117.       a = 0
  118.       b = 0
  119.       rx = 0
  120.       ry = 0
  121.       c = 0
  122.       while (c<maxiter) and (rx*rx+ry*ry <= 4) do
  123.         rx = a*a - b*b + x0
  124.         ry = 2*a*b + y0
  125.         a = rx
  126.         b = ry
  127.         c = c + 1
  128.       end
  129.       if gamut <= 2 then
  130.         cl = (c%2)*32767 + 1
  131.         m.setBackgroundColor(cl)
  132.         pixels[y][x] = (c%2)*15
  133.       else
  134.         if c==1 or c == maxiter then
  135.           cl = 15
  136.         else
  137.           cl = math.floor(c/colordiff+math.log(c)^2)%(gamut-1)
  138.         end
  139.         --cl = math.abs((c-1+gamut-1)%((gamut-1)*2)-(gamut-1))
  140.         --print(math.pow(2,cl))
  141.         m.setBackgroundColor(math.pow(2,cl))
  142.         pixels[y][x] = cl
  143.       end
  144.       m.setCursorPos(x, y)
  145.       m.write(" ")
  146.     end
  147.     if y%interupt==0 then
  148.       os.startTimer(0.05)
  149.       ev, s, xpos, ypos = os.pullEvent()
  150.       if ev == "monitor_touch" or ev == "key" or ev == "mouse_click" or ev == "mouse_scroll" then
  151.         skip = true
  152.         break
  153.       end
  154.     end
  155.     if skip then break end
  156.   end
  157.  
  158.  
  159.  
  160.  
  161.   while true do
  162.     if skip then
  163.       skip = false
  164.     else
  165.       ev, s, xpos, ypos = os.pullEvent()
  166.     end
  167.     if (not isMonitor and (ev=="mouse_click" or ev=="mouse_scroll")) or (isMonitor and ev=="monitor_touch" and args[1]==s) then
  168.       if ypos==h then
  169.         if xpos>=w-3 then
  170.           m.setBackgroundColor(colors.black)
  171.           if isMonitor then
  172.             m.setTextScale(1)
  173.           end
  174.           m.clear()
  175.           m.setCursorPos(1,1)
  176.           return
  177.         elseif xpos <= 3 then
  178.           zoomspeed = zoomspeed - 0.5
  179.         elseif xpos > 3+12+#tostring(zoomspeed) and xpos <= 3+12+3+#tostring(zoomspeed) then
  180.           zoomspeed = zoomspeed + 0.5
  181.         end
  182.         drawBar()
  183.       else
  184.         xpos = xpos - midx
  185.         ypos = ypos - midy
  186.         offX = offX + xpos/zoom
  187.         offY = offY + (ypos*1.5)/zoom
  188.         if (zoomspeed<0) or (zoomspeed>0 and ((ev=="mouse_click" and s==2) or (ev=="mouse_scroll" and s==1))) then
  189.           zoom = zoom/math.abs(zoomspeed)
  190.         elseif zoomspeed ~= 0 then
  191.           zoom = zoom*math.abs(zoomspeed)
  192.         end
  193.         break
  194.       end
  195.     elseif ev=="key" then
  196.       if s==200 then
  197.         offY = offY - (midy/2)/zoom
  198.         break
  199.       elseif s==208 then
  200.         offY = offY + (midy/2)/zoom
  201.         break
  202.       elseif s==203 then
  203.         offX = offX - (midx/2)/zoom
  204.         break
  205.       elseif s==205 then
  206.         offX = offX + (midx/2)/zoom
  207.         break
  208.       elseif (s==78 and zoomspeed>0) or (s==74 and zoomspeed<0) then
  209.         zoom = zoom*math.abs(zoomspeed)
  210.         break
  211.       elseif (s==78 and zoomspeed<0) or (s==74 and zoomspeed>0) then
  212.         zoom = zoom/math.abs(zoomspeed)
  213.         break
  214.       elseif s==57 then
  215.         sleep(0.1)
  216.         if Screenshot() then
  217.           break --read moves page down
  218.         end
  219.       end
  220.     end
  221.   end
  222. end
Add Comment
Please, Sign In to add comment