Mandelbrot set: Difference between revisions
m
Added comments and explanations about the Stripe Average algorithm.
m (Made two small cuts.) |
m (Added comments and explanations about the Stripe Average algorithm.) |
||
Line 8,037:
'''Smoothing, Normalization and Distance Estimation'''
This is a translation of the corresponding Python section: see there for more explanations. The ''e^(-|z|)-smoothing'', ''normalized iteration count'' and ''exterior distance estimation'' algorithms are used
<syntaxhighlight lang="julia">using Plots
gr(aspect_ratio=:equal, axis=true, ticks=true, legend=false, dpi=200)
Line 8,082:
'''Normal Map Effect and Stripe Average Coloring'''
The Mandelbrot set is represented using Normal Maps and Stripe Average Coloring by Jussi Härkönen (cf. Arnaud Chéritat: [https://www.math.univ-toulouse.fr/~cheritat/wiki-draw/index.php/Mandelbrot_set#Normal_map_effect ''Normal map effect'']). See also the picture in section [https://www.math.univ-toulouse.fr/~cheritat/wiki-draw/index.php/Mandelbrot_set#Mixing_it_all ''Mixing it all''] and [https://www.shadertoy.com/view/wtscDX Julia Stripes] on Shadertoy. To get a stripe pattern similar to that of Arnaud Chéritat, the stripe density can be increased to 8, cos can be used instead of sin, and the color map can be set to binary instead of bone_1.
<syntaxhighlight lang="julia">using Plots
gr(aspect_ratio=:equal, axis=true, ticks=true, legend=false, dpi=200)
Line 8,103:
for k in 1:n
M = abs.(Z) .< r
S[M], T[M] = S[M] .+
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 # basic normal map effect
P, Q = S[N] ./ T[N], (S[N] .+
U, V = Z[N] ./ dZ[N], 1 .+ (
U, v = U ./ abs.(U), exp(direction / 180 * pi * im) # unit normal vectors
D[N] = max.((real.(U) .* real(v) .+ imag.(U) .* imag(v) .+ V .* height) ./ (1 + height), 0)
Line 8,116:
savefig("Mandelbrot_normal_map_1.png")
N = abs.(Z) .> 2 # advanced normal map effect
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 normal vectors
D[N] = max.((real.(U) .* real(v) .+ imag.(U) .* imag(v) .+ height) ./ (1 + height), 0)
Line 8,133:
n, r = 8000, 10000 # number of iterations and escape radius (r > 2)
a = -.743643887037158704752191506114774 #
b = 0.131825904205311970493132056385139 #
x = range(0, 2, length=d+1)
Line 11,055:
'''Normal Map Effect and Stripe Average Coloring'''
The Mandelbrot set is represented using Normal Maps and Stripe Average Coloring by Jussi Härkönen (cf. Arnaud Chéritat: [https://www.math.univ-toulouse.fr/~cheritat/wiki-draw/index.php/Mandelbrot_set#Normal_map_effect ''Normal map effect'']). Note that the second derivative (ddZ) grows very fast, so the second method can only be used for small iteration numbers (n <= 400). See also the picture in section [https://www.math.univ-toulouse.fr/~cheritat/wiki-draw/index.php/Mandelbrot_set#Mixing_it_all ''Mixing it all''] and [https://www.shadertoy.com/view/wtscDX Julia Stripes] on Shadertoy. To get a stripe pattern similar to that of Arnaud Chéritat, the stripe density can be increased to 8, cos can be used instead of sin, and the color map can be set to binary instead of bone.
<syntaxhighlight lang="python">import numpy as np
import matplotlib.pyplot as plt
Line 11,076:
for k in range(n):
M = abs(Z) < r
S[M], T[M] = S[M] + np.
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])
N = abs(Z) >= r # basic normal map effect
P, Q = S[N] / T[N], (S[N] + np.
U, V = Z[N] / dZ[N], 1 + (
U, v = U / abs(U), np.exp(direction / 180 * np.pi * 1j) # unit normal vectors
D[N] = np.maximum((U.real * v.real + U.imag * v.imag + V * height) / (1 + height), 0)
Line 11,088:
plt.savefig("Mandelbrot_normal_map_1.png", dpi=200)
N = abs(Z) > 2 # advanced normal map effect
U = Z[N] * dZ[N] * ((1 + np.log(abs(Z[N]))) * np.conj(dZ[N] ** 2) - np.log(abs(Z[N])) * np.conj(Z[N] * ddZ[N]))
U, v = U / abs(U), np.exp(direction / 180 * np.pi * 1j) # unit normal vectors
D[N] = np.maximum((U.real * v.real + U.imag * v.imag + height) / (1 + height), 0)
Line 11,105:
n, r = 8000, 10000 # number of iterations and escape radius (r > 2)
a = -.743643887037158704752191506114774 #
b = 0.131825904205311970493132056385139 #
x = np.linspace(0, 2, num=d+1)
|