Created
October 20, 2021 15:43
-
-
Save corpsmoderne/7ff1cd15d84b61f2efc2edee783c5e20 to your computer and use it in GitHub Desktop.
Mandelbrot in Elixir
This file contains hidden or 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
defmodule Mandel do | |
defp mandel(x0, y0, zoom, iter_max) do | |
loop = fn | |
(_, _, _, ^iter_max) -> 0 | |
(self, x, y, iter) -> | |
x_x = x * x |> div(zoom) | |
y_y = y * y |> div(zoom) | |
if x_x + y_y > 4 * zoom do | |
iter | |
else | |
self.(self, x_x - y_y + x0, | |
(2 * x * y |> div(zoom)) + y0, | |
iter+1) | |
end | |
end | |
loop.(loop, x0, y0, 0) | |
end | |
defp to_color(v) do | |
<< rem(v*v, 256), 0, rem(v*v*v, 256)>> | |
end | |
defp render_line(y, fromx, tox, zoom) do | |
for x <- fromx..tox-1 do | |
mandel(x, y, zoom, 128) | |
|> to_color | |
end | |
|> Enum.join() | |
end | |
defp render_par_({w, h}, {offx, offy}, z) do | |
n = System.schedulers_online | |
to = self() | |
for i <- 0..n-1 do | |
spawn(fn -> | |
msg = for y <- 0..(h-1) // n do | |
{y+i, render_line(y+offy+i, offx, w+offx, z)} | |
end | |
send to, msg | |
end) | |
end | |
for _ <- 0..n-1 do | |
receive do | |
msg -> msg | |
end | |
end | |
|> List.flatten() | |
|> Enum.sort(fn {i,_}, {j,_} -> i<j end) | |
|> Enum.map(fn {_,l} -> l end) | |
|> Enum.join() | |
end | |
defp write_image(buff, filename, w, h) do | |
File.write(filename, "P6\n#{w} #{h}\n255\n" <> buff, [:binary]) | |
end | |
def render_par(filename \\ "out.ppm", | |
{w, h} \\ {1600, 1200}, | |
{ox, oy} \\ { -2400, -800 }, | |
zoom \\ 3000) do | |
offx = ox-div(w,2) | |
offy = oy-div(h,2) | |
render_par_({w, h}, {offx, offy}, zoom) | |
|> write_image(filename, w, h) | |
end | |
def render(filename \\ "out.ppm", | |
{w, h} \\ {1600, 1200}, | |
{ox, oy} \\ { -2400, -800 }, | |
zoom \\ 3000) do | |
offx = ox-div(w,2) | |
offy = oy-div(h,2) | |
for y <- 0..(h-1) , x <- 0..(w-1) do | |
mandel(x+offx, y+offy, zoom, 128) | |
|> to_color | |
end | |
|> Enum.join() | |
|> write_image(filename, w, h) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment