Use tasty for tests, fix bug in circOnLine

This commit is contained in:
2021-12-14 11:50:01 +00:00
parent ec51efabca
commit 47391f3850
19 changed files with 143 additions and 113 deletions
+9 -4
View File
@@ -23,12 +23,12 @@ dependencies:
- base >= 4.7 && < 5 - base >= 4.7 && < 5
- containers - containers
- unordered-containers - unordered-containers
- heap #- heap
- sdl2 - sdl2
- sdl2-mixer - sdl2-mixer
- text
- OpenGL - OpenGL
- OpenGLRaw - OpenGLRaw
- text
- raw-strings-qq - raw-strings-qq
- bytestring - bytestring
- lens - lens
@@ -36,7 +36,7 @@ dependencies:
- fgl - fgl
- random - random
- bmp - bmp
- monad-loops #- monad-loops
- JuicyPixels - JuicyPixels
- vector - vector
- dlist - dlist
@@ -46,7 +46,6 @@ dependencies:
- linear - linear
- aeson - aeson
- directory - directory
- QuickCheck
- extra - extra
- primitive - primitive
- streaming - streaming
@@ -54,6 +53,12 @@ dependencies:
- monad-parallel - monad-parallel
- parallel - parallel
- Clipboard - Clipboard
# testing
- tasty
- tasty-hunit
- tasty-quickcheck
#- QuickCheck
#- HUnit
library: library:
source-dirs: src source-dirs: src
+17 -24
View File
@@ -3,8 +3,7 @@ module Dodge.Item.Weapon.BatteryGuns
, teslaGun , teslaGun
, tractorGun , tractorGun
, makeLaserAt , makeLaserAt
) ) where
where
import Dodge.Data import Dodge.Data
import Dodge.Creature.HandPos import Dodge.Creature.HandPos
import Dodge.Particle.TeslaArc import Dodge.Particle.TeslaArc
@@ -27,11 +26,9 @@ import ShapePicture
import Dodge.Picture import Dodge.Picture
import LensHelp import LensHelp
--import Data.Function
--import qualified Data.Sequence as Seq
import Data.List import Data.List
import Data.Bifunctor
import System.Random import System.Random
--import Data.Maybe
import Data.Tuple import Data.Tuple
import qualified Data.IntMap.Strict as IM import qualified Data.IntMap.Strict as IM
teslaGun :: Item teslaGun :: Item
@@ -161,7 +158,7 @@ aTeslaArc cr w = set randGen g w
aLaser :: Item -> Creature -> World -> World aLaser :: Item -> Creature -> World -> World
aLaser it cr = particles .:~ makeLaserAt phasev pos dir aLaser it cr = particles .:~ makeLaserAt phasev pos dir
where where
pos = _crPos cr +.+ (aimingMuzzlePos cr it) *.* unitVectorAtAngle dir pos = _crPos cr +.+ aimingMuzzlePos cr it *.* unitVectorAtAngle dir
dir = _crDir cr dir = _crDir cr
phasev = _phaseV . _itParams $ _crInv cr IM.! j phasev = _phaseV . _itParams $ _crInv cr IM.! j
j = _crInvSel cr j = _crInvSel cr
@@ -171,34 +168,34 @@ makeLaserAt phasev pos dir = Particle
{ _ptDraw = const blank { _ptDraw = const blank
, _ptUpdate = moveLaser phasev pos dir , _ptUpdate = moveLaser phasev pos dir
} }
moveLaser moveLaser :: Float -- ^ Phase velocity, controls deflection through windows
:: Float -- ^ Phase velocity, controls deflection through windows
-> Point2 -> Point2
-> Float -> Float
-> World -> World
-> Particle -> Particle
-> (World, Maybe Particle) -> (World, Maybe Particle)
moveLaser phasev pos dir w pt moveLaser phasev pos dir w pt
= ( hitEffect w = ( damThingHitWith (Lasering 19) pos xp thHit w
, Just pt {_ptDraw = const pic ,_ptUpdate = ptSimpleTime 0 } , Just pt {_ptDraw = const pic ,_ptUpdate = ptSimpleTime 0 }
) )
where where
xp = pos +.+ 800 *.* unitVectorAtAngle dir xp = pos +.+ 800 *.* unitVectorAtAngle dir
(thHit, ps) = f [] pos xp
f :: [Wall] -> Point2 -> Point2 -> (Maybe (Point2,Either Creature Wall),[Point2]) f :: [Wall] -> Point2 -> Point2 -> (Maybe (Point2,Either Creature Wall),[Point2])
f seenWs x y = case find (h' seenWs) $ thingsHitExceptCrLongLine Nothing x y w of f seenWs x y = case find (notseen seenWs) $ thingsHitExceptCrLongLine Nothing x y w of
--f seenWs x y = case find (h' seenWs) $ thingsHitExceptCr Nothing x y w of --f seenWs x y = case find (notseen seenWs) $ thingsHitExceptCr Nothing x y w of
Just (p,Right wl) Just (p,Right wl)
| _wlOpacity wl == SeeThrough -> addPoint p $ f (wl:seenWs) p (h x y wl p) | _wlOpacity wl == SeeThrough -> second (p:) $ f (wl:seenWs) p (refract x y wl p)
| otherwise -> (Just (p,Right wl), [p]) | otherwise -> (Just (p,Right wl), [p])
Just (p,obj) -> (Just (p,obj), [p]) Just (p,obj) -> (Just (p,obj), [p])
Nothing -> (Nothing, [y]) Nothing -> (Nothing, [y])
addPoint p (x,ps') = (x,p:ps') refract x y wl p
h x y wl p | isEntering = p +.+ rotateV angleRef (normalDist wlNormal)
| isEntering = p +.+ rotateV angleRef normalDist | otherwise = p +.+ rotateV angleRef' (normalDist wlNormal')
| otherwise = p +.+ rotateV angleRef' normalDist'
where where
wlNormal = vNormal $ uncurry (-.-) $ swap (_wlLine wl) wlNormal = vNormal $ uncurry (-.-) $ swap (_wlLine wl)
normalDist = magV (p -.- y) *.* normalizeV wlNormal wlNormal' = vNormal $ uncurry (-.-) (_wlLine wl)
normalDist wlnormal = magV (p -.- y) *.* normalizeV wlnormal
angleInc = piRange $ argV wlNormal - argV (x -.- y) angleInc = piRange $ argV wlNormal - argV (x -.- y)
angleRef angleRef
| reflectExternal = angleInc | reflectExternal = angleInc
@@ -208,8 +205,6 @@ moveLaser phasev pos dir w pt
| a' > negate pi = a' | a' > negate pi = a'
| otherwise = a' + 2 * pi | otherwise = a' + 2 * pi
isEntering = not $ isLeftOf (x -.- y) (uncurry (-.-) (_wlLine wl)) isEntering = not $ isLeftOf (x -.- y) (uncurry (-.-) (_wlLine wl))
wlNormal' = vNormal $ uncurry (-.-) (_wlLine wl)
normalDist' = magV (p -.- y) *.* normalizeV wlNormal'
angleInc' = piRange $ argV wlNormal' - argV (x -.- y) angleInc' = piRange $ argV wlNormal' - argV (x -.- y)
angleRef' angleRef'
| reflectInternal = angleInc' | reflectInternal = angleInc'
@@ -217,10 +212,8 @@ moveLaser phasev pos dir w pt
reflectInternal = 1 < abs (phasev * sin angleInc') reflectInternal = 1 < abs (phasev * sin angleInc')
reflectExternal = 1 < abs (sin angleInc / phasev) reflectExternal = 1 < abs (sin angleInc / phasev)
h' ws (_,Right wl) = not $ any (\w' -> _wlID w' == _wlID wl) ws notseen ws (_,Right wl) = not $ any (\w' -> _wlID w' == _wlID wl) ws
h' _ _ = True notseen _ _ = True
(thHit, ps) = f [] pos xp
hitEffect = damThingHitWith (Lasering 19) pos xp thHit
pic = setLayer 1 $ pictures pic = setLayer 1 $ pictures
[ setDepth 19 . color (brightX 0 0.5 yellow) $ lineOfThickness 20 (pos:ps) [ setDepth 19 . color (brightX 0 0.5 yellow) $ lineOfThickness 20 (pos:ps)
, setDepth 19.5 . color (brightX 10 1 yellow) $ lineOfThickness 3 (pos:ps) , setDepth 19.5 . color (brightX 10 1 yellow) $ lineOfThickness 3 (pos:ps)
+1 -1
View File
@@ -67,7 +67,7 @@ updateTurret rotSpeed mc w
cid = IM.newKey (_creatures w') cid = IM.newKey (_creatures w')
thecreature = defaultCreature thecreature = defaultCreature
& crID .~ cid & crID .~ cid
& crInv . at 0 ?~ (_tuWeapon (_mcType mc) & itDimension . dimPortage . handlePos -~ 20 & crInv . at 0 ?~ (_tuWeapon (_mcType mc) & itDimension . dimPortage . handlePos -~ 10
& itConsumption . ammoLoaded .~ 1 & itConsumption . ammoLoaded .~ 1
) )
& crPos .~ mcpos & crPos .~ mcpos
+2 -1
View File
@@ -21,10 +21,11 @@ import Dodge.Room.Door
import Dodge.Room.Airlock import Dodge.Room.Airlock
import Geometry import Geometry
import Tile import Tile
import MonadHelp
import Control.Lens import Control.Lens
import Control.Monad.State import Control.Monad.State
import Control.Monad.Loops --import Control.Monad.Loops
import System.Random import System.Random
import Data.Maybe import Data.Maybe
import Data.Tree import Data.Tree
+2 -1
View File
@@ -127,5 +127,6 @@ thingsHitLongLine sp ep w
-- $ creaturesAlongLine sp ep w -- $ creaturesAlongLine sp ep w
crPs = map (\cr -> ssaTriPoint ep (_crPos cr) sp (_crRad cr)) hitCrs crPs = map (\cr -> ssaTriPoint ep (_crPos cr) sp (_crRad cr)) hitCrs
wls = zip (map (fromJust . hitPoint) hitWls) (map Right hitWls) wls = zip (map (fromJust . hitPoint) hitWls) (map Right hitWls)
hitWls = wallsOnLine sp ep $ wallsAlongLine sp ep w --hitWls = wallsOnLine sp ep $ wallsAlongLine sp ep w
hitWls = wallsOnLine sp ep $ _walls w
hitPoint wl = uncurry (intersectSegSeg sp ep) (_wlLine wl) hitPoint wl = uncurry (intersectSegSeg sp ep) (_wlLine wl)
+4 -2
View File
@@ -193,8 +193,10 @@ circOnSeg :: Point2 -> Point2 -> Point2 -> Float -> Bool
{-# INLINE circOnSeg #-} {-# INLINE circOnSeg #-}
circOnSeg !p1 !p2 !c !rad = magV (p1 -.- c) <= rad circOnSeg !p1 !p2 !c !rad = magV (p1 -.- c) <= rad
|| magV (p2 -.- c) <= rad || magV (p2 -.- c) <= rad
|| isJustTrue (fmap (\p -> magV (p -.- c) < rad) y) -- || isJustTrue (fmap (\p -> magV (p -.- c) < rad) y)
|| intersectSegSegTest p1 p2 (c -.- thenormal) (c +.+ thenormal)
where where
thenormal = rad *.* vNormal (normalizeV $ p1 -.- p2)
y = intersectSegLine p1 p2 c (c +.+ vNormal (p1 -.- p2)) y = intersectSegLine p1 p2 c (c +.+ vNormal (p1 -.- p2))
isJustTrue (Just True) = True isJustTrue (Just True) = True
isJustTrue _ = False isJustTrue _ = False
@@ -279,7 +281,7 @@ diffAngles x y
-- Note this doesn't necessarily find ALL solutions, asin is a map not a function. -- Note this doesn't necessarily find ALL solutions, asin is a map not a function.
ssaTri :: Float -> Float -> Float -> Float ssaTri :: Float -> Float -> Float -> Float
ssaTri ab bc a ssaTri ab bc a
| sin a == 0 = 0 | sin a == 0 = ab - bc
| bc == 0 = ab | bc == 0 = ab
| otherwise = | otherwise =
let c = asin ( (ab * sin a)/bc) let c = asin ( (ab * sin a)/bc)
+5 -4
View File
@@ -77,6 +77,7 @@ intersectSegLine (V2 x1 y1) (V2 x2 y2) (V2 x3 y3) (V2 x4 y4)
--u' = (y1-y2)*(x1-x3) - (x1-x2)*(y1-y3) --u' = (y1-y2)*(x1-x3) - (x1-x2)*(y1-y3)
-- | It is not always necessary to find a point of intersection, sometimes a -- | It is not always necessary to find a point of intersection, sometimes a
-- test may suffice. -- test may suffice.
-- IS THIS CORRECT? -- TODO tests
intersectSegSegTest intersectSegSegTest
:: Point2 :: Point2
-> Point2 -> Point2
@@ -84,11 +85,11 @@ intersectSegSegTest
-> Point2 -> Point2
-> Bool -> Bool
{-# INLINE intersectSegSegTest #-} {-# INLINE intersectSegSegTest #-}
intersectSegSegTest a' b' c' d' intersectSegSegTest x y z w
= f a' b' c' d' && f c' d' a' b' = f x y z w && f z w x y
where where
f a b c d = ( isLHS a b c && not (isLHS a b d) ) f a b c d = ( not (isRHS a b c) && not (isLHS a b d) )
|| ( not (isLHS a b c) && isLHS a b d ) || ( not (isLHS a b c) && not (isRHS a b d) )
intersectSegSegPreTest intersectSegSegPreTest
:: Point2 :: Point2
-> Point2 -> Point2
+1 -1
View File
@@ -3,7 +3,7 @@ module Geometry.LHS
, isRHS , isRHS
) where ) where
import Geometry.Data import Geometry.Data
-- | Test whether a point is on the LHS of a line. -- | Test whether a point is stricly on the LHS of a line.
-- Returns False if the line is of zero length. -- Returns False if the line is of zero length.
isLHS isLHS
:: Point2 -- ^ First line point. :: Point2 -- ^ First line point.
+1 -2
View File
@@ -5,8 +5,7 @@ module IntMapHelp
, insertWithNewKeys , insertWithNewKeys
, swapKeys , swapKeys
, findIndex , findIndex
) ) where
where
--import Data.List hiding (foldr,insert) --import Data.List hiding (foldr,insert)
import Data.IntMap.Strict import Data.IntMap.Strict
{- | Find a key value one higher than any key in the map, or zero if the map is {- | Find a key value one higher than any key in the map, or zero if the map is
+10
View File
@@ -15,3 +15,13 @@ untilJustCount m = go 0
case mayx of case mayx of
Nothing -> go (i+1) Nothing -> go (i+1)
Just x -> return (x,i) Just x -> return (x,i)
iterateUntil :: Monad m => (a -> Bool) -> m a -> m a
iterateUntil t m = do
x <- m
if t x
then return x
else iterateUntil t m
iterateWhile :: Monad m => (a -> Bool) -> m a -> m a
iterateWhile t = iterateUntil (not . t)
+1 -2
View File
@@ -8,8 +8,7 @@ module Polyhedra
, boxXYZnobase , boxXYZnobase
, polyToGeoRender , polyToGeoRender
, polysToPic , polysToPic
) ) where
where
import Geometry import Geometry
import Polyhedra.Data import Polyhedra.Data
import Picture.Data import Picture.Data
+1 -2
View File
@@ -1,7 +1,6 @@
module Quaternion module Quaternion
( rotateToZ ( rotateToZ
) ) where
where
import Geometry.Data import Geometry.Data
import Geometry.Vector3D import Geometry.Vector3D
import qualified Linear.Quaternion as Q import qualified Linear.Quaternion as Q
+2 -2
View File
@@ -6,8 +6,7 @@ module Render
, pingPongBetween , pingPongBetween
, bindTO , bindTO
, bindFBO , bindFBO
) ) where
where
import Shader import Shader
import Shader.ExtraPrimitive import Shader.ExtraPrimitive
import Shader.Data import Shader.Data
@@ -49,6 +48,7 @@ createLightMap pdata lightPoints nWalls nSils nCaps toPos = do
-- for each of the lights: -- for each of the lights:
-- 1. stencil out the walls from this light's point of view -- 1. stencil out the walls from this light's point of view
-- 2. calculate lighting based on each fragment's position -- 2. calculate lighting based on each fragment's position
-- to consider: adding normals/a "material" for each fragment
blendFunc $= (Zero, OneMinusSrcColor) blendFunc $= (Zero, OneMinusSrcColor)
stencilTest $= Enabled stencilTest $= Enabled
flip VS.mapM_ (VS.fromList lightPoints) $ \(V3 x y z,rad,V3 r g b) -> do flip VS.mapM_ (VS.fromList lightPoints) $ \(V3 x y z,rad,V3 r g b) -> do
+1 -2
View File
@@ -15,8 +15,7 @@ module Shape
, scaleSH , scaleSH
, colorSH , colorSH
, overPosSH , overPosSH
) ) where
where
import Geometry import Geometry
import Shape.Data import Shape.Data
import Color import Color
+6 -5
View File
@@ -1,3 +1,4 @@
{-# LANGUAGE TupleSections #-}
module ShapePicture module ShapePicture
( emptyBlank ( emptyBlank
, translateSPf , translateSPf
@@ -8,8 +9,7 @@ module ShapePicture
, noShape , noShape
, _spShape , _spShape
, _spPicture , _spPicture
) ) where
where
import Shape import Shape
import Picture import Picture
import Geometry import Geometry
@@ -18,11 +18,12 @@ import Data.Bifunctor
type SPic = (Shape, Picture) type SPic = (Shape, Picture)
-- should all this be inlined/inlinable?
noPic :: Shape -> SPic noPic :: Shape -> SPic
noPic sh = (sh,mempty) noPic = (,mempty)
noShape :: Picture -> SPic noShape :: Picture -> SPic
noShape pic = (mempty,pic) noShape = (mempty,)
_spShape :: SPic -> Shape _spShape :: SPic -> Shape
_spShape = fst _spShape = fst
@@ -30,7 +31,7 @@ _spPicture :: SPic -> Picture
_spPicture = snd _spPicture = snd
emptyBlank :: SPic emptyBlank :: SPic
emptyBlank = (emptySH,blank) emptyBlank = mempty
translateSPf :: Float -> Float -> SPic -> SPic translateSPf :: Float -> Float -> SPic -> SPic
translateSPf x y = bimap (translateSH (V3 x y 0)) (translate x y) translateSPf x y = bimap (translateSH (V3 x y 0)) (translate x y)
+7 -11
View File
@@ -118,14 +118,13 @@ cleanupHalted s = do
----------------------------------------------------------------- -----------------------------------------------------------------
{- | Play sounds from a list of indices. {- | Play sounds from a list of indices.
For each index, the corresponding sound starts playing if there is a free channel. For each index, the corresponding sound starts playing if there is a free channel.
Use this if you don't care about timing, overlapping, fading, or sound positions. Use this if you don't care about timing, overlapping, fading, or sound positions. -}
-}
playSoundQueue :: IM.IntMap Mix.Chunk -> [Int] -> IO () playSoundQueue :: IM.IntMap Mix.Chunk -> [Int] -> IO ()
playSoundQueue chunkMap ns = forM_ ns $ \n -> runMaybeT $ playIfFree (chunkMap IM.! n) Mix.Once --playSoundQueue chunkMap ns = forM_ ns $ \n -> runMaybeT $ playIfFree (chunkMap IM.! n) Mix.Once
playSoundQueue chunkMap = mapM_ $ \n -> runMaybeT $ playIfFree (chunkMap IM.! n) Mix.Once
{- | Given a chunk, attempt to play this on a free channel a given number of {- | Given a chunk, attempt to play this on a free channel a given number of
times. Returns 'Just' the channel if succeeds. times. Returns 'Just' the channel if succeeds. -}
-}
playIfFree :: Mix.Chunk -> Mix.Times -> MaybeT IO Mix.Channel playIfFree :: Mix.Chunk -> Mix.Times -> MaybeT IO Mix.Channel
playIfFree c times = do playIfFree c times = do
i <- MaybeT $ Mix.getAvailable Mix.DefaultGroup i <- MaybeT $ Mix.getAvailable Mix.DefaultGroup
@@ -133,8 +132,7 @@ playIfFree c times = do
----------------------------------------------------------------- -----------------------------------------------------------------
{- | Play sounds from a list of index/position pairs. {- | Play sounds from a list of index/position pairs.
As for 'playSoundQueue', but with positional information in the form of an Int16. As for 'playSoundQueue', but with positional information in the form of an Int16. -}
-}
playPositionalSoundQueue :: IM.IntMap Mix.Chunk -> [(Int,Int16)] -> IO () playPositionalSoundQueue :: IM.IntMap Mix.Chunk -> [(Int,Int16)] -> IO ()
playPositionalSoundQueue chunkMap = VS.mapM_ ( \(n,a) -> playPositionalSoundQueue chunkMap = VS.mapM_ ( \(n,a) ->
runMaybeT $ playIfFree (chunkMap IM.! n) Mix.Once >>= setChannelPos a ) runMaybeT $ playIfFree (chunkMap IM.! n) Mix.Once >>= setChannelPos a )
@@ -146,13 +144,11 @@ setChannelPos a i = do
return i return i
----------------------------------------------------------------- -----------------------------------------------------------------
{- | Set the volume for all sound channels. {- | Set the volume for all sound channels.
Behind the scenes, scales a float [0,1] to an Int [0..128]. Behind the scenes, scales a float [0,1] to an Int [0..128]. -}
-}
setSoundVolume :: Float -> IO () setSoundVolume :: Float -> IO ()
setSoundVolume x = Mix.setVolume (round (x * 128)) Mix.AllChannels setSoundVolume x = Mix.setVolume (round (x * 128)) Mix.AllChannels
{- | Set the music volume. {- | Set the music volume.
Behind the scenes, scales a float [0,1] to an Int [0..128]. Behind the scenes, scales a float [0,1] to an Int [0..128]. -}
-}
setMusicVolume :: Float -> IO () setMusicVolume :: Float -> IO ()
setMusicVolume x = Mix.setMusicVolume (round (x * 128)) setMusicVolume x = Mix.setMusicVolume (round (x * 128))
+1 -2
View File
@@ -1,5 +1,4 @@
module StrictHelp module StrictHelp where
where
{- | In order to force a list, apply with seq. -} {- | In order to force a list, apply with seq. -}
forceSpine :: Foldable t => t a -> () forceSpine :: Foldable t => t a -> ()
+4 -6
View File
@@ -10,19 +10,17 @@ tileToRenderList t = polyToTris $ zip ps3 coords3
where where
ps = _tilePoly t ps = _tilePoly t
coords = map (calcTexCoord (_tileZero t) (_tileX t)) ps coords = map (calcTexCoord (_tileZero t) (_tileX t)) ps
ps3 = map (addToV2 0) ps ps3 = map (addZ 0) ps
coords3 = map (addToV2 (_tileZ t)) coords coords3 = map (addZ (_tileZ t)) coords
addToV2 :: a -> V2 a -> V3 a
addToV2 z (V2 x y) = V3 x y z
calcTexCoord calcTexCoord
:: Point2 -- ^ tile (0,0) :: Point2 -- ^ tile (0,0)
-> Point2 -- ^ tile (1,0) -> Point2 -- ^ tile (1,0)
-> Point2 -- ^ world point -> Point2 -- ^ world point
-> Point2 -> Point2
calcTexCoord c p x = V2 (0.02 * dotV (p -.- c) xdir) (0.02 * dotV (p -.- c) ydir) calcTexCoord c p x = V2 (vectorAmountIn xdir) (vectorAmountIn ydir)
where where
vectorAmountIn dir = 0.02 * dotV (p -.- c) dir
xdir = x -.- c xdir = x -.- c
ydir = vNormal xdir ydir = vNormal xdir
+68 -41
View File
@@ -1,51 +1,79 @@
import Test.QuickCheck --import Test.HUnit
import Test.HUnit import Test.Tasty
import Test.Tasty.QuickCheck
import Test.Tasty.HUnit
import Dodge.Room.CheckConsistency import Dodge.Room.CheckConsistency
import Geometry
import Dodge.LevelGen.StaticWalls import Dodge.LevelGen.StaticWalls
import Geometry import Geometry
main :: IO () main :: IO ()
main = do main = defaultMain $
putStrLn "Running tests:" testGroup "Tests"
quickCheck prop_looping [testGroup "Geometry tests" geometryTests]
nextPair :: Eq a => (a,a) -> [(a,a)] -> [(a,a)] geometryTests =
nextPair (_,y) = filter (\(x,_) -> x == y) [ testCase "intersectSegSegTest cross intersect" $
intersectSegSegTest (V2 1 0) (V2 1 2) (V2 0 1) (V2 2 1)
@?= True
, testCase "intersectSegSegTest v intersect" $
intersectSegSegTest (V2 0 0) (V2 1 0) (V2 0 0) (V2 0 1)
@?= True
, testCase "intersectSegSegTest miss" $
intersectSegSegTest (V2 1 0) (V2 1 2) (V2 0 0) (V2 0 2)
@?= False
, testCase "circOnSeg endpoint1" $
circOnSeg (V2 0 0) (V2 10 10) (V2 (-1) (-1)) 2
@?= True
, testCase "circOnSeg endpoint2" $
circOnSeg (V2 0 0) (V2 10 10) (V2 11 10) 2
@?= True
, testCase "circOnSeg mid" $
circOnSeg (V2 0 0) (V2 10 10) (V2 5 5) 2
@?= True
, testCase "circOnSeg mid" $
circOnSeg (V2 0 0) (V2 10 10) (V2 5 4) 2
@?= True
, testCase "circOnSeg miss endpoint1" $
circOnSeg (V2 0 0) (V2 10 10) (V2 (-1) (-1)) 1
@?= False
, testCase "circOnSeg miss endpoint2" $
circOnSeg (V2 0 0) (V2 10 10) (V2 11 10) 0.9
@?= False
, testCase "circOnSeg miss mid" $
circOnSeg (V2 0 0) (V2 10 10) (V2 7 3) 0.9
@?= False
]
isLooping :: Eq a => [(a,a)] -> Bool --nextPair :: Eq a => (a,a) -> [(a,a)] -> [(a,a)]
isLooping xs = all (( == 1) . length . flip nextPair xs) xs --nextPair (_,y) = filter (\(x,_) -> x == y)
--
isLooping' :: Eq a => [(a,a)] -> Bool --isLooping :: Eq a => [(a,a)] -> Bool
isLooping' xs = all (f xs) xs --isLooping xs = all (( == 1) . length . flip nextPair xs) xs
where --
f ys (x,y) = length ins == length outs && length rins == length routs --isLooping' :: Eq a => [(a,a)] -> Bool
where --isLooping' xs = all (f xs) xs
ins = filter (\(a,b) -> a == x) ys -- where
outs = filter (\(a,b) -> b == x) ys -- f ys (x,y) = length ins == length outs && length rins == length routs
rins = filter (\(a,b) -> a == y) ys -- where
routs = filter (\(a,b) -> b == y) ys -- ins = filter (\(a,b) -> a == x) ys
-- outs = filter (\(a,b) -> b == x) ys
polygonStrictlyConvex :: [Point2] -> Bool -- rins = filter (\(a,b) -> a == y) ys
polygonStrictlyConvex ps = True -- routs = filter (\(a,b) -> b == y) ys
--
--prop_looping :: [Point2] -> [WallP] -> Bool --polygonStrictlyConvex :: [Point2] -> Bool
--polygonStrictlyConvex ps = True
prop_looping = forAllShrink genTris shrinkTris $ \tris -> --
not (any ( \[a,b,c] -> isOnSeg a b c --
|| isOnSeg a c b --shrinkTris [] = []
|| isOnSeg b c a --shrinkTris (x:xs) = xs : map (x :) (shrinkTris xs)
) tris) --
==> isLooping' (foldr cutWalls' [] tris) --genTri = zip <$> trip <*> trip
-- where
shrinkTris [] = [] -- trip = vectorOf 3 $ fromIntegral <$> choose (0,3::Int)
shrinkTris (x:xs) = xs : map (x :) (shrinkTris xs) --
--genTris = listOf genTri
genTri = zip <$> trip <*> trip
where
trip = vectorOf 3 $ fromIntegral <$> choose (0,3::Int)
genTris = listOf genTri
--extractLoops :: Eq a => [(a,a)] -> [[(a,a)]] --extractLoops :: Eq a => [(a,a)] -> [[(a,a)]]
--extractLoops [] = [] --extractLoops [] = []
@@ -54,4 +82,3 @@ genTris = listOf genTri
-- --
--[[(0.0,1.0),(3.0,4.0),(5.0,5.0)],[(2.0,0.0),(2.0,4.0),(1.0,1.0)],[(5.0,5.0),(2.0,2.0),(1.0,3.0)]] --[[(0.0,1.0),(3.0,4.0),(5.0,5.0)],[(2.0,0.0),(2.0,4.0),(1.0,1.0)],[(5.0,5.0),(2.0,2.0),(1.0,3.0)]]
-- --
testRoom rm = TestCase "Room links connected" (linksOnPath rm)