41 lines
1.7 KiB
Text
41 lines
1.7 KiB
Text
using Plots
|
|
gr(aspect_ratio=:equal, axis=true, ticks=true, legend=false, dpi=200)
|
|
|
|
d, h = 800, 500 # pixel density (= image width) and image height
|
|
n, r = 200, 500 # number of iterations and escape radius (r > 2)
|
|
|
|
direction, height = 45, 1.5 # direction and height of the incoming light
|
|
stripes, damping = 4.0, 2.0 # stripe density and damping parameter
|
|
|
|
x = range(0, 2, length=d+1)
|
|
y = range(0, 2 * h / d, length=h+1)
|
|
|
|
A, B = collect(x) .- 1, collect(y) .- h / d
|
|
C = (2.0 + 1.0im) .* (A' .+ B .* im) .- 0.5
|
|
|
|
Z, dZ, ddZ = zero(C), zero(C), zero(C)
|
|
D, S, T = zeros(size(C)), zeros(size(C)), zeros(size(C))
|
|
|
|
for k in 1:n
|
|
M = abs.(Z) .< r
|
|
S[M], T[M] = S[M] .+ cos.(stripes .* angle.(Z[M])), T[M] .+ 1
|
|
Z[M], dZ[M], ddZ[M] = Z[M] .^ 2 .+ C[M], 2 .* Z[M] .* dZ[M] .+ 1, 2 .* (dZ[M] .^ 2 .+ Z[M] .* ddZ[M])
|
|
end
|
|
|
|
N = abs.(Z) .>= r # normal map effect 1 (equipotential lines)
|
|
P, Q = S[N] ./ T[N], (S[N] .+ cos.(stripes .* angle.(Z[N]))) ./ (T[N] .+ 1)
|
|
R = Q .+ (P .- Q) .* log2.(log.(abs.(Z[N])) ./ log(r)) # linear interpolation
|
|
U, V = Z[N] ./ dZ[N], 1 .+ R ./ damping # normal vectors and variations in inclination
|
|
U, v = U ./ abs.(U), exp(direction / 180 * pi * im) # unit vectors
|
|
D[N] = max.((real.(U) .* real(v) .+ imag.(U) .* imag(v) .+ V .* height) ./ (1 + height), 0)
|
|
|
|
heatmap(D .^ 1.0, c=:bone_1)
|
|
savefig("Mandelbrot_normal_map_1.png")
|
|
|
|
N = abs.(Z) .> 2 # normal map effect 2 (equidistant lines)
|
|
U = Z[N] .* dZ[N] .* ((1 .+ log.(abs.(Z[N]))) .* conj.(dZ[N] .^ 2) .- log.(abs.(Z[N])) .* conj.(Z[N] .* ddZ[N]))
|
|
U, v = U ./ abs.(U), exp(direction / 180 * pi * im) # unit vectors
|
|
D[N] = max.((real.(U) .* real(v) .+ imag.(U) .* imag(v) .+ height) ./ (1 + height), 0)
|
|
|
|
heatmap(D .^ 1.0, c=:afmhot)
|
|
savefig("Mandelbrot_normal_map_2.png")
|