added random points with minimum distance between them
This commit is contained in:
parent
96a141b63b
commit
17b433b01c
2 changed files with 83 additions and 1 deletions
|
|
@ -50,7 +50,7 @@ executable image-triangles
|
||||||
main-is: Main.hs
|
main-is: Main.hs
|
||||||
|
|
||||||
-- Modules included in this executable, other than Main.
|
-- Modules included in this executable, other than Main.
|
||||||
other-modules: Triangles
|
other-modules: Triangles, MinDistanceSample
|
||||||
|
|
||||||
-- LANGUAGE extensions used by modules in this package.
|
-- LANGUAGE extensions used by modules in this package.
|
||||||
default-extensions: ScopedTypeVariables,
|
default-extensions: ScopedTypeVariables,
|
||||||
|
|
@ -76,6 +76,7 @@ executable image-triangles
|
||||||
-- Other library packages from which modules are imported.
|
-- Other library packages from which modules are imported.
|
||||||
build-depends: base
|
build-depends: base
|
||||||
, random
|
, random
|
||||||
|
, array
|
||||||
, hip
|
, hip
|
||||||
, vector-th-unbox
|
, vector-th-unbox
|
||||||
, colour
|
, colour
|
||||||
|
|
|
||||||
81
src/MinDistanceSample.hs
Normal file
81
src/MinDistanceSample.hs
Normal file
|
|
@ -0,0 +1,81 @@
|
||||||
|
module MinDistanceSample where
|
||||||
|
|
||||||
|
import qualified Data.Array as A
|
||||||
|
import qualified Data.Bifunctor as B
|
||||||
|
import qualified Data.List as L
|
||||||
|
import qualified Data.List.NonEmpty as NE
|
||||||
|
import qualified Data.Maybe as My
|
||||||
|
import Diagrams.Prelude
|
||||||
|
import System.Random.Stateful
|
||||||
|
import qualified Control.Monad as M
|
||||||
|
|
||||||
|
k :: Int
|
||||||
|
k = 30
|
||||||
|
|
||||||
|
randomPolarCoord :: StdGen -> (V2 Double, StdGen)
|
||||||
|
randomPolarCoord gen = (view (from r2PolarIso) (distance, angle @@ turn), gen'')
|
||||||
|
where
|
||||||
|
angle :: Double
|
||||||
|
(angle, gen') = uniformR (0, 1) gen
|
||||||
|
|
||||||
|
distance :: Double
|
||||||
|
(distance, gen'') = uniformR (1, 2) gen
|
||||||
|
|
||||||
|
randomValueFrom :: NE.NonEmpty a -> StdGen -> (a, StdGen)
|
||||||
|
randomValueFrom xs gen = B.first (xs NE.!!) (uniformR (0, pred . length $ xs) gen)
|
||||||
|
|
||||||
|
randomPoints :: P2 Double -> Double -> StdGen -> [P2 Double]
|
||||||
|
randomPoints dims minDistance gen = map (fmap (* bucketSize)) $ randomPointsRec [] (A.listArray (mkP2 0 0, fmap (ceiling . (/ bucketSize)) dims) (repeat Nothing)) gen
|
||||||
|
where
|
||||||
|
|
||||||
|
bucketSize :: Double
|
||||||
|
bucketSize = minDistance / (sqrt 2)
|
||||||
|
|
||||||
|
randomPointsRec :: [Point V2 Double] -> A.Array (P2 Word) (Maybe (P2 Double)) -> StdGen -> [P2 Double]
|
||||||
|
randomPointsRec [] _ _ = []
|
||||||
|
randomPointsRec (x : xs') grid gen =
|
||||||
|
maybe [] randomPoints'
|
||||||
|
. L.find isValidPoint
|
||||||
|
$ candidates
|
||||||
|
where
|
||||||
|
|
||||||
|
xs :: NE.NonEmpty (Point V2 Double)
|
||||||
|
xs = x NE.:| xs'
|
||||||
|
|
||||||
|
randomPoints' :: P2 Double -> [P2 Double]
|
||||||
|
randomPoints' p = (p :) $ randomPointsRec xs'' (grid A.// [(floor <$> p, Just p)]) gen''
|
||||||
|
|
||||||
|
(candidate, gen') = randomValueFrom xs gen
|
||||||
|
|
||||||
|
xs'' = NE.filter (/= candidate) xs
|
||||||
|
|
||||||
|
unitVectorsAround =
|
||||||
|
V2
|
||||||
|
<$> [-1, 0, 1]
|
||||||
|
<*> [-1, 0, 1]
|
||||||
|
|
||||||
|
candidates :: [P2 Double]
|
||||||
|
(candidates, (_, gen'') : _) =
|
||||||
|
B.first (map ((candidate .-^) . fst))
|
||||||
|
. splitAt k
|
||||||
|
. iterate (randomPolarCoord . snd)
|
||||||
|
$ (unitX, gen')
|
||||||
|
|
||||||
|
newPoint :: Maybe (P2 Double)
|
||||||
|
newPoint = L.find isValidPoint candidates
|
||||||
|
|
||||||
|
isValidPoint :: Point V2 Double -> Bool
|
||||||
|
isValidPoint p =
|
||||||
|
all ((>= 1) . abs . norm . (p .-.))
|
||||||
|
. My.mapMaybe
|
||||||
|
( M.join
|
||||||
|
. (grid !?)
|
||||||
|
. fmap floor
|
||||||
|
. (p .-^)
|
||||||
|
)
|
||||||
|
$ unitVectorsAround
|
||||||
|
|
||||||
|
arr !? index | index >= minBound && (index <= maxBound) = Just (arr A.! index)
|
||||||
|
where
|
||||||
|
(minBound, maxBound) = A.bounds arr
|
||||||
|
_ !? _ = Nothing
|
||||||
Loading…
Add table
Add a link
Reference in a new issue