Skip to content

Instantly share code, notes, and snippets.

@Klafyvel
Last active January 5, 2020 00:11
Show Gist options
  • Save Klafyvel/52be5c4e968b6f2975d2b855c5c0eb04 to your computer and use it in GitHub Desktop.
Save Klafyvel/52be5c4e968b6f2975d2b855c5c0eb04 to your computer and use it in GitHub Desktop.
# Made by Hugo 'klafyvel' Levy-Falk, under MIT License
using Plots, Interact, Mux, Logging
@info "Dummy noise server started"
module Noise2D
using Plots, Random, FFTW
r(u,v) = √(u^2+v^2)
circ(r) = if abs(r)<=1 1 else 0 end
function make_distribution(e,a,b)
(u,v) -> r(u,v)^e * circ(r(u,v)/b) * (1 - circ(r(u,v)/a))
end
normalize(::Val, A) = A
function normalize(::Val{:one}, A)
norm = max(abs(maximum(A)), abs(minimum(A)))
A ./ norm
end
function normalize(::Val{:probability}, A)
M,m = maximum(A), minimum(A)
B = if M*m < 0 A .- m else A end
B ./ sum(B)
end
PICTURE_SIDE = 128
u = range(-2,2,length=PICTURE_SIDE)
v = range(-2,2,length=PICTURE_SIDE)
U = repeat(reshape(u, 1, :), length(v), 1)
V = repeat(v, 1, length(u));
function show_distribution(slope, a, b; seed, norm=:none)
Random.seed!(seed)
distrib = make_distribution(slope,a/PICTURE_SIDE,b/PICTURE_SIDE)
w = map(distrib,U,V)
p = heatmap(w, aspect_ratio=1, title="Fourier (norm)", xlabel="u", ylabel="v")
phases = 2π .* rand(PICTURE_SIDE, PICTURE_SIDE)
p_phases = heatmap(phases, aspect_ratio=1, title="Fourier (phase)", xlabel="u", ylabel="v")
z = normalize(Val(norm), real.(fftshift(ifft(ifftshift(w) .* exp.(1im .* phases)))))
cut_u = plot(u, distrib.(u,0), title="plane v=0", legend=false, xlabel="u")
cut_v = plot(v, distrib.(0,v), title="plane u=0", legend=false, xlabel="v")
plot(
p, p_phases, cut_u, cut_v,
heatmap(z, aspect_ratio=1, title="Noise produced"), surface(z, title="Noise produced (3d)"),
layout=(2,3),
size=(1200,400)
)
end
end
function main(port)
@info "Creating ui."
seed = spinbox(label="Random seed", value=1234)
slope = slider([-2:0.01:2...], label="Exponent", value=-0.7)
a = slider([0:Noise2D.PICTURE_SIDE...], label="Minimum frequency", value=1)
b = slider([0:2*Noise2D.PICTURE_SIDE...], label="Maximum frequency", value=32)
update(::Any=nothing) = Noise2D.show_distribution(slope[], a[], b[], seed=seed[], norm=:probability)
plt = Observable{Any}(update())
map!(update, plt, seed)
map!(update, plt, slope)
map!(update, plt, a)
map!(update, plt, b)
ctrl = hbox(seed,slope,a,b)
ui = vbox(ctrl, plt)
@info "Serving page on port $port."
WebIO.webio_serve(page("/", req -> ui), port)
end
if ! isinteractive()
fetch(main(parse(Int, ARGS[1])))
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment