hgeometry-0.8.0.0: test/Data/Geometry/KDTreeSpec.hs
{-# LANGUAGE ScopedTypeVariables #-}
module Data.Geometry.KDTreeSpec where
import Data.Ext
import qualified Data.Foldable as F
import Data.Geometry
import Data.Geometry.Box
import Data.Geometry.KDTree
import qualified Data.LSeq as LSeq
import qualified Data.Set as Set
import GHC.TypeLits
import Test.QuickCheck.HGeometryInstances()
import Test.Hspec
import Test.QuickCheck
--------------------------------------------------------------------------------
naive :: (Arity d, Ord r) => Box d q r -> [Point d r :+ p] -> [Point d r :+ p]
naive qr = filter (\(p :+ _) -> p `intersects` qr)
sameAsNaive :: (Ord r, Ord p, Arity d)
=> [Point d r :+ p] -> KDTree d p r -> Box d q r -> Bool
sameAsNaive pts t q = Set.fromList (searchKDTree q t) == Set.fromList (naive q pts)
allSameAsNaive :: (Ord r, Ord p, Arity d, 1 <= d, Foldable f)
=> f (Point d r :+ p) -> [Box d () r] -> Bool
allSameAsNaive pts = let pts' = F.toList pts
in all (sameAsNaive pts' $ buildKDTree pts')
allSame :: (Arity d, Eq a) => Vector d a -> Bool
allSame v = case F.toList v of
[] -> True
(x:xs) -> all (== x) xs
-- newtype Pts n d r = Pts (PointSet (LSeq.LSeq n) d () r)
-- deriving instance (Arity d, Show r) => Show (Pts n d r)
-- instance (KnownNat n, Arity d, KnownNat d, Arbitrary r, Ord r) => Arbitrary (Pts n d r) where
-- arbitrary = Pts . toPointSet . LSeq.toNonEmpty <$> arbitrary
spec :: Spec
spec = do
describe "splitOn" $ do
it "quickheck: left set same points" $
property $ \c (pts :: LSeq.LSeq 2 (Point 2 Int :+ ())) ->
let (l,_,_) = splitOn (toEnum c) (toPointSet pts)
in allSame . fmap (Set.fromList . F.toList) $ l
it "quickheck: right set same points" $
property $ \c (pts :: LSeq.LSeq 2 (Point 2 Int :+ ())) ->
let (_,_,r) = splitOn (toEnum c) (toPointSet pts)
in allSame . fmap (Set.fromList . F.toList) $ r
describe "Same as Naive" $ do
it "quickcheck 1d" $
property $ \(pts :: Set.Set (Point 1 Int :+ ())) -> allSameAsNaive pts
it "quickcheck 2d" $
property $ \(pts :: Set.Set (Point 2 Int :+ ())) -> allSameAsNaive pts
it "quickcheck 3d" $
property $ \(pts :: Set.Set (Point 3 Int :+ ())) -> allSameAsNaive pts
it "quickcheck 8d" $
property $ \(pts :: Set.Set (Point 8 Int :+ ())) -> allSameAsNaive pts
-- pts = map ext [point2 (-2) 2, point2 5 (-1)]
-- boxx = box (ext $ point2 3 (-4)) (ext $ point2 5 4)