Skip to content

Instantly share code, notes, and snippets.

@soulik
Created April 30, 2014 19:22
Show Gist options
  • Save soulik/185bd1fc4e880ed7c8a8 to your computer and use it in GitHub Desktop.
Save soulik/185bd1fc4e880ed7c8a8 to your computer and use it in GitHub Desktop.
Mandelbrot set generator in Lua
return singleton(function()
local o = {}
local graphics, surfaces, matrix, bit, complex, color_spaces
local rad = math.rad
o.init = function()
matrix = math.matrix()
surfaces = (require 'EngineB/graphics/textures/surface')()
graphics = (require 'EngineB/graphics')()
complex = require 'utils/complex'
bit = require 'bit'
color_spaces = (require 'EngineB/graphics/color_spaces')()
end
o.quit = function()
end
local function genMandelbrot(width, height)
local mdata = {}
local clamp = function(v, min, max)
return math.min(math.max(v, min), max)
end
local function RGB(r,g,b)
--print(r,g,b)
local r,g,b = math.floor(clamp(r, 0, 1.0)*0xFF),math.floor(clamp(g, 0, 1.0)*0xFF),math.floor(clamp(b, 0, 1.0)*0xFF)
return bit.bor(r, 0x100*g, 0x10000*b)
end
local maxIterations = 500
local function getMBValue(x,y)
local iterations = 0
local z = complex {0, 0}
local c = complex {x, y}
local sum = complex {0, 0}
-- y = z^2 + c
while (z[1]^2 + z[2]^2 < 2*2) and (iterations < maxIterations) do
z = z^2 + c
iterations = iterations + 1
end
local i = 200
v = math.log((iterations+i)/(maxIterations+i) + 1.0)
return v
end
local vmin, vmax = math.huge, 0
for y=1,height do
for x=1,width do
local pos = (y-1)*height + x - 1
local rx,ry = (x-1)/width, (y-1)/height
-- <-2, 0.25>
local x0 = rx*3.0 - 2.0
local y0 = ry*2.0 - 1.0
local v = getMBValue(x0, y0)
if v < vmin then
vmin = v
end
if v > vmax then
vmax = v
end
local clampedV = clamp(v, 0, 1.0)
mdata[pos+1] = RGB(color_spaces.hsl2rgb(clamp(0.7 - clampedV*2.2, 0, 1.0), 1.0, clamp(0.6 - clampedV, 0, 1)))
end
end
print(vmin, vmax)
local data = {}
for i=1, (width*height) do
local rgb = mdata[i]
data[i] = bit.tobit(0xFF000000 + rgb)
end
return data
end
o.mandelbrot = function(texture, width, height)
local pixelformat = graphics.pixelFormat(SDL.PIXELFORMAT_ABGR8888, true)
local surface = surfaces.new(width, height, pixelformat)
surface.update(genMandelbrot(width, height))
texture.update(0,0, width, height, surface)
end
return o
end)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment