Last active
December 8, 2020 19:07
-
-
Save Divran/78a7c0a3a0a497e17aa54e083a6a72c0 to your computer and use it in GitHub Desktop.
starfall mandelbrot generator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--@name mandelbrot | |
--@author Divran | |
--@client | |
local x, y = -0.7, 0 -- offset position of mandelbrot set | |
local w, h = 1.3, 1.3 -- size of mandelbrot set | |
local rt_w, rt_h = 1024, 1024 -- size of RT | |
local max_iterations = 100 | |
local function quotaCheck(n) | |
return math.max(quotaAverage(), quotaUsed()) < quotaMax()*n | |
end | |
render.createRenderTarget("RT") | |
local startTime = 0 | |
local current_x, current_y = -w, -h | |
local result_x, result_y = 0, 0 | |
local num_iterations = 0 | |
local current_rt_w = 64 | |
local current_rt_h = 64 | |
local current_max_iterations = 8 | |
local function doReset(also_size) | |
current_x, current_y = -w, -h | |
result_x, result_y = 0, 0 | |
num_iterations = 0 | |
if also_size then | |
startTime = 0 | |
current_rt_w = 64 | |
current_rt_h = 64 | |
current_max_iterations = 8 | |
end | |
end | |
local screen | |
local function getAimPos() | |
if not screen then | |
local c = chip():getLinkedComponents() | |
if c and #c > 0 then | |
screen = c[1] | |
else | |
return | |
end | |
end | |
local x, y = render.cursorPos(player(),screen) | |
return x, y | |
end | |
local doshit | |
hook.add("KeyPress","meme",function(ply,key) | |
if ply == player() and input.isMouseDown(MOUSE.MOUSE1) then | |
local _x, _y = getAimPos() | |
x = math.remap(_x,0,512,-w,w) + x | |
y = math.remap(_y,0,512,-h,h) + y | |
w = w * (input.isMouseDown(MOUSE.MOUSE2) and 0.1 or 0.5) | |
h = h * (input.isMouseDown(MOUSE.MOUSE2) and 0.1 or 0.5) | |
doReset(true) | |
hook.remove("renderoffscreen","thonk") | |
hook.add("renderoffscreen","thonk",doshit) | |
end | |
end) | |
function doshit() | |
render.selectRenderTarget("RT") | |
if startTime == 0 then | |
startTime = timer.realtime() | |
render.clear(Color(0,0,0,255)) | |
end | |
while quotaCheck(0.90) do | |
local passed = false | |
while quotaCheck(0.90) and num_iterations < current_max_iterations do | |
result_x, result_y = | |
result_x * result_x - result_y*result_y + (current_x + x), | |
2 * result_x * result_y + (current_y + y) | |
if result_x*result_x+result_y*result_y > 4 then | |
passed = true | |
-- it passed into infinity | |
break | |
end | |
num_iterations = num_iterations + 1 | |
end | |
if num_iterations >= current_max_iterations or passed then | |
--print("done with point:",current_x,current_y,"iterations:",num_iterations) | |
local c = Color(num_iterations / current_max_iterations * 360,1,1):hsvToRGB() | |
render.setColor(c) | |
local x = math.remap(current_x,-w,w,0,1024) | |
local y = math.remap(current_y,-h,h,0,1024) | |
render.drawRectFast(x,y,1024/current_rt_w,1024/current_rt_h) | |
result_x = 0 | |
result_y = 0 | |
num_iterations = 0 | |
current_x = current_x + w/current_rt_w | |
if current_x >= w then | |
current_x = -w | |
current_y = current_y + h/rt_h | |
if current_y >= h then | |
print(current_rt_w.."x"..current_rt_h.." ("..current_max_iterations..") done",math.round(timer.realtime()-startTime,2)) | |
if current_rt_w < rt_w or current_rt_h < rt_h or current_max_iterations < max_iterations then | |
current_rt_w = math.min(current_rt_w * 2,rt_w) | |
current_rt_h = math.min(current_rt_h * 2,rt_h) | |
current_max_iterations = math.min(current_max_iterations * 2,max_iterations) | |
doReset() | |
else | |
hook.remove("renderoffscreen","thonk") | |
end | |
break | |
end | |
end | |
end | |
end | |
render.selectRenderTarget() | |
end | |
hook.add("renderoffscreen", "thonk", doshit) | |
local lastX, lastY, hideAt = 0, 0, 0 | |
hook.add("render", "helloworld_render", function() | |
render.setRenderTargetTexture("RT") | |
render.drawTexturedRectFast(0,0,512,512) | |
local x, y = getAimPos() | |
if x and y then | |
if x == lastX and y == lastY and hideAt <= timer.realtime() then | |
return | |
elseif (x ~= lastX or y ~= lastY) then | |
hideAt = timer.realtime() + 1 | |
end | |
lastX = x | |
lastY = y | |
local size = input.isMouseDown(MOUSE.MOUSE2) and 512*0.1 or 512*0.5 | |
render.drawRectOutline(x-size/2,y-size/2,size,size) | |
end | |
end) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment