Skip to content

Commit f5c3787

Browse files
committed
Fisher/Yates shuffle candidates in poisson disc sampling
1 parent 0e8ea89 commit f5c3787

1 file changed

Lines changed: 13 additions & 8 deletions

File tree

src/Geometry/Algorithms/Sampling/PoissonDisc.hs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ import qualified Data.Map as M
1515
import Data.Maybe
1616
import Data.Set (Set)
1717
import qualified Data.Set as S
18+
import Data.Vector (Vector)
19+
import qualified Data.Vector.Extended as V
1820
import System.Random.MWC
1921

2022
import Geometry
@@ -175,21 +177,24 @@ randomSetElement gen set = do
175177
pure (S.elemAt i set)
176178

177179
-- | http://extremelearning.com.au/an-improved-version-of-bridsons-algorithm-n-for-poisson-disc-sampling/
180+
--
181+
-- Enhanced by a random trial order so we don’t privilege clockwise selection
178182
candidatesAroundSample
179183
:: PrimMonad m
180184
=> Gen (PrimState m)
181185
-> Int -- ^ Number of attempts
182186
-> BoundingBox -- ^ Sampling region
183-
-> Double
184-
-> Vec2
185-
-> m [Vec2]
186-
candidatesAroundSample gen k shape r v = do
187+
-> Double -- ^ Poisson radius
188+
-> Vec2 -- ^ Point to generate candidates around
189+
-> m (Vector Vec2)
190+
candidatesAroundSample gen k bb r v = do
187191
phi0 <- rad <$> uniformRM (0, 2*pi) gen
188192
let deltaPhi = rad (2*pi / fromIntegral k)
189-
candidates = filter (`insideBoundingBox` shape)
190-
[ v +. polar (phi0 +. fromIntegral i *. deltaPhi) (r + 1e-6)
191-
| i <- [1..k] ]
192-
pure candidates
193+
circle = V.generate k (\i -> v +. polar (phi0 +. fromIntegral i *. deltaPhi) (r + 1e-6))
194+
inside = V.filter (`insideBoundingBox` bb) circle
195+
inside' <- V.thaw inside
196+
V.fisherYatesShuffle gen inside'
197+
V.freeze inside'
193198

194199
-- A cell in the grid has a side length of r/sqrt(2). If we’re somewhere in the X
195200
-- square and can only move at most a square diagonal, we only need to consider the

0 commit comments

Comments
 (0)