# Poisson-Disc Sampling?

**URL:** https://discourse.julialang.org/t/poisson-disc-sampling/85647
**Category:** General Usage
**Tags:** question, packages
**Created:** [August 12, 2022, 1:21am UTC](https://discourse.julialang.org/t/poisson-disc-sampling/85647 "2022-08-12T01:21:53Z")
**Posts on this page:** 15
**Page:** 1

<div class="post-metadata">

### Author: ![RobertGregg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/robertgregg/32/22105_2.png) [@RobertGregg](https://discourse.julialang.org/u/RobertGregg)
#### Post date: [August 12, 2022, 1:21am UTC](https://discourse.julialang.org/t/poisson-disc-sampling/85647/1 "2022-08-12T01:21:53Z")

</div>

Has anyone implemented a [Poisson-Disc Sampling](https://www.jasondavies.com/poisson-disc/) algorithm in Julia? I didn’t see anything with a quick google search or by looking through previous discussions.

---

<div class="post-metadata">

### Author: ![digital\_carver](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/digital_carver/32/33818_2.png) [@digital\_carver](https://discourse.julialang.org/u/digital_carver)
#### Post date: [August 12, 2022, 2:19am UTC](https://discourse.julialang.org/t/poisson-disc-sampling/85647/2 "2022-08-12T02:19:08Z")

</div>

“Poisson-disk” seems to be a more common spelling of it, and searching for that brings up [a function in MRIReco.jl](https://docs.juliahub.com/MRIReco/h2KbQ/0.5.0/API/#MRIReco.sample_poissondisk-Tuple%7BTuple%7BInt64,%20Int64%7D,%20Float64%7D) ([code](https://github.com/MagneticResonanceImaging/MRIReco.jl/blob/040d51ee38f50609bead454c262291273eede4db/src/Sampling/PoissonDisk.jl)), and [another in Meshes.jl](https://docs.juliahub.com/Meshes/FuRcu/0.22.9/algorithms/sampling.html#Meshes.MinDistanceSampling) ([code](https://github.com/JuliaGeometry/Meshes.jl/blob/8748131aa419b1396cd009b287e1e0aec681a138/src/sampling/mindistance.jl)).

---

<div class="post-metadata">

### Author: ![cormullion](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cormullion/32/49131_2.png) [@cormullion](https://discourse.julialang.org/u/cormullion)
#### Post date: [August 12, 2022, 7:10am UTC](https://discourse.julialang.org/t/poisson-disc-sampling/85647/3 "2022-08-12T07:10:10Z")

</div>

I wrote one too

[http://juliagraphics.github.io/Luxor.jl/dev/howto/geometrytools/](http://juliagraphics.github.io/Luxor.jl/dev/howto/geometrytools/)

[juliahub.com](http://juliahub.com)’s search doesn’t always find everything… 😉

---

<div class="post-metadata">

### Author: ![empet](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/empet/32/221303_2.png) [@empet](https://discourse.julialang.org/u/empet)
#### Post date: [August 12, 2022, 7:41am UTC](https://discourse.julialang.org/t/poisson-disc-sampling/85647/4 "2022-08-12T07:41:21Z")

</div>

A few months ago I also needed the Poisson disk sampling, and implemented the Bridson algorithm: [https://nbviewer.org/github/empet/PoissonDisk/blob/main/Bridson-algo-Poisson-disk.ipynb](https://nbviewer.org/github/empet/PoissonDisk/blob/main/Bridson-algo-Poisson-disk.ipynb)

---

<div class="post-metadata">

### Author: ![RobertGregg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/robertgregg/32/22105_2.png) [@RobertGregg](https://discourse.julialang.org/u/RobertGregg)
#### Post date: [August 12, 2022, 8:26am UTC](https://discourse.julialang.org/t/poisson-disc-sampling/85647/5 "2022-08-12T08:26:34Z")

</div>

Interesting. It seems like a decent number of people have needed this algorithm and implemented on their own. I wonder if it would be worth having some type of procedural noise package? Poisson-Disc sampling is a type of blue noise, you could add simplex noise, worley noise, perlin noise etc.

It looks like there is a [Noise.jl](https://github.com/roflmaostc/Noise.jl) package mainly for images and a [ProceduralNoise.jl](https://github.com/ararslan/ProceduralNoise.jl) package that has long been forgotten.

---

<div class="post-metadata">

### Author: ![digital\_carver](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/digital_carver/32/33818_2.png) [@digital\_carver](https://discourse.julialang.org/u/digital_carver)
#### Post date: [August 12, 2022, 11:24am UTC](https://discourse.julialang.org/t/poisson-disc-sampling/85647/6 "2022-08-12T11:24:07Z")

</div>

I came across [BlueNoise.jl](https://github.com/joshua-maros/BlueNoise.jl/) also, with pre-generated sources of blue noise.

Creating a new ProceduralNoise.jl seems like a good idea. The linked one seems pre-Julia 1.0 and doesn’t seem registered in General, so the name should be available for a fresh new package to use.

---

<div class="post-metadata">

### Author: ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)
#### Post date: [August 12, 2022, 11:58am UTC](https://discourse.julialang.org/t/poisson-disc-sampling/85647/7 "2022-08-12T11:58:52Z")

</div>

I like the idea of organizing these efforts into a common place. Just wondering if instead of creating a new package we could leverage the advanced mesh types in Meshes.jl for that. In particular, we did a huge amount of work to make these sampling methods work out of the box in unstructured meshes, images, or any type of geospatial domain. Besides, we have a well-defined interface already.

---

<div class="post-metadata">

### Author: ![cormullion](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cormullion/32/49131_2.png) [@cormullion](https://discourse.julialang.org/u/cormullion)
#### Post date: [August 12, 2022, 12:33pm UTC](https://discourse.julialang.org/t/poisson-disc-sampling/85647/8 "2022-08-12T12:33:44Z")

</div>

I might use a small focussed noise package - but I might not require meshes, so adding the Meshes.jl package as an additional dependency just to get a small piece of functionality isn’t ideal.

---

<div class="post-metadata">

### Author: ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)
#### Post date: [August 12, 2022, 12:45pm UTC](https://discourse.julialang.org/t/poisson-disc-sampling/85647/9 "2022-08-12T12:45:13Z")

</div>

Fair enough 🙂

Any effort to consolidate the different implementations would be great. In particular, I think we could still organize these sampling noise methods for images (or signals) and the wrap them up in Meshes.jl to generalize to the case of unstructured meshes. So users only interested in sampling within “boxes” will load this package X and users interested in more complicated domains can load Meshes.jl that in turn loads X and extends the functionality.

---

<div class="post-metadata">

### Author: ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)
#### Post date: [August 12, 2022, 12:52pm UTC](https://discourse.julialang.org/t/poisson-disc-sampling/85647/10 "2022-08-12T12:52:51Z")

</div>

Just for fun, here is an example of Poisson disk sampling over the mesh of Beethoven:

```julia
using Meshes
using PlyIO

# helper function to read *.ply files
function readply(fname)
  ply = load_ply(fname)
  x = ply["vertex"]["x"]
  y = ply["vertex"]["y"]
  z = ply["vertex"]["z"]
  points = Point3.(x, y, z)
  connec = [connect(Tuple(c.+1)) for c in ply["face"]["vertex_indices"]]
  SimpleMesh(points, connec)
end

# download mesh from the web
file = download(
  "https://raw.githubusercontent.com/juliohm/JuliaCon2021/master/data/beethoven.ply"
)

# read mesh from disk
mesh = readply(file)

# Poisson disk sampling with radius 1.0 and 0.5
pts1 = sample(mesh, MinDistanceSampling(1.0))
pts2 = sample(mesh, MinDistanceSampling(0.5))

```

```julia
using MeshViz
import GLMakie as Mke

viz(mesh)
viz!(pts1, color=:red)
viz!(pts2, color=:blue)

```

![image](https://global.discourse-cdn.com/julialang/original/3X/1/0/1013524da5f1309ab1dd2b0ec109fc9dc158c0e7.png)

and here is Poisson disk sampling on the first triangle of the mesh:

```julia
pts = sample(mesh[1], MinDistanceSampling(0.01))

viz(mesh[1])
viz!(pts, color=:red)

```

![image](https://global.discourse-cdn.com/julialang/original/3X/2/f/2f800efe4097785360feb01f1c493723d12967e6.png)

---

<div class="post-metadata">

### Author: ![cormullion](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cormullion/32/49131_2.png) [@cormullion](https://discourse.julialang.org/u/cormullion)
#### Post date: [August 12, 2022, 3:39pm UTC](https://discourse.julialang.org/t/poisson-disc-sampling/85647/11 "2022-08-12T15:39:08Z")

</div>

At the moment, while there’s still overhead in precompiling/loading packages, one has to think twice before adding dependencies. For example, if I wanted to use a small feature from Meshes.jl in Luxor.jl:

```julia
julia> @time using Luxor
  0.561545 seconds (1.03 M allocations: 71.399 MiB, 2.33% gc time, 
    6.37% compilation time)

julia> @time using Meshes
  2.713017 seconds (4.93 M allocations: 319.778 MiB, 4.18% gc time, 
     52.45% compilation time)

```

it could increase the TimeToFirstWhatever quite a bit. Whereas a smaller package that just does one thing - such as Distances.jl - is easy enough to add:

```julia
julia> @time using Distances
  0.008614 seconds (12.32 k allocations: 1.030 MiB, 
    22.47% compilation time)

```

---

<div class="post-metadata">

### Author: ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)
#### Post date: [August 12, 2022, 3:49pm UTC](https://discourse.julialang.org/t/poisson-disc-sampling/85647/12 "2022-08-12T15:49:35Z")

</div>

Yes, I am working on the assumption that precompilation will be a solved issue in the future. Basically betting on the work of the Julia core team and the community to build additional tooling to precompile these efforts easily and effortlessly. 🙏

In any case the proposed separation I shared above would work for both worlds.

---

<div class="post-metadata">

### Author: ![RobertGregg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/robertgregg/32/22105_2.png) [@RobertGregg](https://discourse.julialang.org/u/RobertGregg)
#### Post date: [August 12, 2022, 5:38pm UTC](https://discourse.julialang.org/t/poisson-disc-sampling/85647/13 "2022-08-12T17:38:04Z")

</div>

First off, the functionality of Meshes.jl looks amazing. The Poisson disk sampling on Beethoven head is both impressive and hilarious.

I like the suggestion @juliohm made about having a lightweight package just for people who want to do sampling within “boxes” that then generalizes to Meshes.jl. When I needed Poisson disk (disc? 🤷) sampling originally it was in a context far removed from mesh generation so I think that’s why I didn’t find it immediately. If such a package was created in the JuliaGeometry organization I would definitely contribute to it 😁

---

<div class="post-metadata">

### Author: ![mfiano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mfiano/32/37565_2.png) [@mfiano](https://discourse.julialang.org/u/mfiano)
#### Post date: [August 15, 2022, 1:40pm UTC](https://discourse.julialang.org/t/poisson-disc-sampling/85647/14 "2022-08-15T13:40:14Z")

</div>

I have been working on a procedural noise library for a couple weeks. It has many algorithms with a pipeline to compose and modify them in interesting ways. It is nearing completion, so expect an announcement soon.

---

<div class="post-metadata">

### Author: ![mfiano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mfiano/32/37565_2.png) [@mfiano](https://discourse.julialang.org/u/mfiano)
#### Post date: [August 17, 2022, 6:53am UTC](https://discourse.julialang.org/t/poisson-disc-sampling/85647/15 "2022-08-17T06:53:53Z")

</div>

> [@Announcing CoherentNoise.jl](https://discourse.julialang.org/t/announcing-coherentnoise-jl/85860):
>
> I am proud to announce the first version of [CoherentNoise.jl](https://github.com/mfiano/CoherentNoise.jl), a library consisting of several coherent noise algorithms and tools to compose them into interesting pipelines. This is actually my first real package, only having used Julia for about 2 months now. I am not a master yet, but if you find this useful and/or find some things that could be written more idiomatically, feel free to open an issue or pull request. I really look forward to learning more through discussion and collaboration. …
