## Poisson disk samples generated via Bridson algorithm ¶

In :
using PlotlyJS
import StaticArrays:SVector, @SVector


The WebIO Jupyter extension was not detected. See the WebIO Jupyter integration documentation for more information.

In :
function distsq(A::SVector{2, T}, B::SVector{2, T}) where T <: Real
return (A-B)^2 + (A-B)^2
end

function grid_idxs(point:: SVector{2, T}, cellsize::T) where T <: Real
""" Returns cell indices, (i,j)=(row, col) for  point """
return ceil(Int, point / cellsize) + 1, ceil(Int, point / cellsize) + 1
end

function ispoint_inrectangle(point::SVector{2, T}, rlims::Tuple{T, T}) where T <: Real
"""
Check whether a point is within the rectangle
[0, rlims] x [0, rlims];
here rlims =(width, height)
"""
return (0 <= point <= rlims) && (0 <= point <= rlims)
end

k=30) where T <: Real
"""
Samples  uniformly k points from the annulus of center, center,
"""
angle = 2π * rand(k)
x, y = center .+ rad .* cos.(angle), center .+ rad .*sin.(angle)
return [@SVector([xi, yi]) for (xi, yi) in zip(x,y)]
end

Out:
unif_sampling_annulus (generic function with 1 method)
In :
function Poisson_disk_sampling(;width =1.0, height=1.0, radius=0.05, k=30)
"""
Bridson Algorithm to generate  Poisson disk samples
within a 2D rectangle, [0, width] x [0, height]
Ref: R Bridson, Fast Poisson disk sampling in arbitrary dimensions,
in  SIGGRAPH '07: ACM SIGGRAPH 2007 sketches
https://www.cs.ubc.ca/~rbridson/docs/bridson-siggraph07-poissondisk.pdf
"""
function  is_accepted(point:: SVector{2, T})  where T <: Real
"""
Check whether the point, point can be added to the active_list
"""
i, j = grid_idxs(point, cellsize)
m, n = maximum([i-2, 1]), maximum([j-2, 1])
p, q = minimum([i+2, grows]), minimum([j+2, gcols])
for k in n:q
for l in m:p
gpoint = grid[(k-1) * grows + l]
if ismissing(gpoint)
continue
end
if distsq(point, gpoint) <= r2
return false
end
end
end
return true
end

gcols = ceil(Int, width / cellsize) + 1
grows = ceil(Int, height / cellsize) + 1

grid = Vector{Any}(missing, grows*gcols)
active_list = SVector{2, Float64}[]

#generate a random point within the rectangle of interest
# and  insert it into the active_list and grid
point = @SVector([width*rand(1), height*rand(1)])
push!(active_list, point)
i, j = grid_idxs(point, cellsize)
grid[(j-1)*grows+i] = point

while length(active_list) > 0
i = rand(1:length(active_list), 1)
pt = active_list[i]
active_list  =  active_list[1:end .!= i] #removes the point in pos i
for rp in rpoints
if !ispoint_inrectangle(rp, (width, height)) || !is_accepted(rp)
continue
end
push!(active_list, rp)
i, j = grid_idxs(rp, cellsize)
grid[(j-1)*grows+i] = rp
end
end
return filter(x->!ismissing(x), grid)
end

Out:
Poisson_disk_sampling (generic function with 1 method)
In :
vector_of_samples = Poisson_disk_sampling(;width =5.0, height=3.0, radius=0.045, k=30)
xcoords = [p for p in vector_of_samples]
ycoords = [p for p in vector_of_samples]
fig1 = Plot(scatter(x=xcoords, y=ycoords, mode="markers", marker_size=3),
Layout(width=600, height=400,
xaxis_showgrid=false, yaxis_showgrid=false))
display(fig1)

In :
vector_of_samples = Poisson_disk_sampling(;width=4.0, height=4.0, radius=0.05, k=30)
#perform a translation of the default rectangle [0, width] x [0, height] to [3, 3+]x  [-2, -2+height]
xcoords = [p for p in vector_of_samples] .+ 3.0
ycoords = [p for p in vector_of_samples] .- 2.0
fig2 = Plot(scatter(x=xcoords, y=ycoords, mode="markers", marker_size=3),
Layout(width=500, height=500,
xaxis_showgrid=false, yaxis_showgrid=false,
xaxis_zeroline=false, yaxis_zeroline=false ))
display(fig2)

In [ ]: