Skip to content

Instantly share code, notes, and snippets.

@Mononofu
Last active July 22, 2022 21:20
Show Gist options
  • Save Mononofu/409e1bed5fc84981d0e41bd019e58a45 to your computer and use it in GitHub Desktop.
Save Mononofu/409e1bed5fc84981d0e41bd019e58a45 to your computer and use it in GitHub Desktop.
Rendering a mandelbrot zoom sequence with Julia
using ColorSchemes
using Dates
using Images
using Printf
colors = RGB{Float32}.(colorschemes[:inferno].colors)
n_colors = length(colors)
black = RGB{Float32}(0, 0, 0)
function interpolate_color(n)
if n == 0
return black
end
c1 = colors[1 + Int32(floor(n * 10)) % n_colors]
c2 = colors[1 + Int32(floor(n * 10 + 1)) % n_colors]
frac = n % 1
RGB{Float32}(c1 * frac + c2 * (1 - frac))
end
mid = complex(-0.743643887035763, 0.13182590421259918)
png_lock = ReentrantLock()
Threads.@threads for zoom = 0:1000
range = 1.025^(1-zoom)
step = range / 350.0
x0 = [-range:step:range;] .* complex(1, 0)
y0 = [-range:step:range;] .* complex(0, 1)
na = [CartesianIndex()]
c = mid .+ (x0[na,:] .+ y0[:,na])
z = c .* 0
escaped_at = zeros(Int16, size(z))
for i = 1:2000
z = ifelse.(escaped_at .> 0, z, z.^2 .+ c)
escaped = abs.(z) .> 256
freshly_escaped = (escaped_at .== 0) .& escaped
escaped_at = ifelse.(freshly_escaped, Int16(i), escaped_at)
end
# Interpolate colors according to https://en.wikipedia.org/wiki/Plotting_algorithms_for_the_Mandelbrot_set#Continuous_(smooth)_coloring
filtered_z = ifelse.(escaped_at .== 0, 10, abs.(z))
log_z = log.(filtered_z .* filtered_z) ./ 2
nu = log.(log_z ./ (log(2))) ./ log(2)
smooth_escaped_at = ifelse.(escaped_at .== 0, 0, escaped_at .+ 1 .- nu)
mandelbrot = map(interpolate_color, smooth_escaped_at)
mandelbrot = colorview(RGB, mandelbrot)
filename = @sprintf "img/mandelbrot_%03d.png" zoom
lock(png_lock) do
save(filename, mandelbrot)
end
end
@Mononofu
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment