@@ -15,6 +15,8 @@ import qualified Data.Map as M
1515import Data.Maybe
1616import Data.Set (Set )
1717import qualified Data.Set as S
18+ import Data.Vector (Vector )
19+ import qualified Data.Vector.Extended as V
1820import System.Random.MWC
1921
2022import 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
178182candidatesAroundSample
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