Clarify circle segment intersection
This commit is contained in:
@@ -53,15 +53,16 @@ import Geometry
|
|||||||
|
|
||||||
collidePoint :: Point2 -> Point2 -> [Wall] -> (Point2, Maybe Wall)
|
collidePoint :: Point2 -> Point2 -> [Wall] -> (Point2, Maybe Wall)
|
||||||
{-# INLINE collidePoint #-}
|
{-# INLINE collidePoint #-}
|
||||||
collidePoint sp ep = foldl' findPoint (ep, Nothing)
|
collidePoint sp ep = foldl' f (ep, Nothing)
|
||||||
where
|
where
|
||||||
findPoint (p, mwl) wl = maybe (p, mwl) (,Just wl) . uncurry (intersectSegSeg sp p) . _wlLine $ wl
|
f (p, mwl) wl
|
||||||
|
= maybe (p, mwl) (,Just wl) . uncurry (intersectSegSeg sp p) . _wlLine $ wl
|
||||||
|
|
||||||
overlapSegCrs :: Point2 -> Point2 -> [Creature] -> [(Point2, Creature)]
|
overlapSegCrs :: Point2 -> Point2 -> [Creature] -> [(Point2, Creature)]
|
||||||
{-# INLINE overlapSegCrs #-}
|
{-# INLINE overlapSegCrs #-}
|
||||||
overlapSegCrs sp ep =
|
overlapSegCrs sp ep =
|
||||||
mapMaybe
|
mapMaybe
|
||||||
(\cr -> (,cr) <$> listToMaybe (intersectCircSeg (cr ^. crPos . _xy) (crRad $ cr ^. crType) sp ep))
|
(\cr -> (,cr) <$> fst (intersectCircSeg (cr ^. crPos . _xy) (crRad $ cr ^. crType) sp ep))
|
||||||
|
|
||||||
doBounce :: Float -> Point2 -> Point2 -> (Point2, Maybe Wall) -> Maybe (Point2, Point2)
|
doBounce :: Float -> Point2 -> Point2 -> (Point2, Maybe Wall) -> Maybe (Point2, Point2)
|
||||||
{-# INLINE doBounce #-}
|
{-# INLINE doBounce #-}
|
||||||
@@ -126,10 +127,9 @@ collide3 sp ep w =
|
|||||||
|
|
||||||
-- Just (hitpoint,normaltosurface)
|
-- Just (hitpoint,normaltosurface)
|
||||||
collide3Walls :: Point3 -> World -> (Point3, MPO) -> (Point3, MPO)
|
collide3Walls :: Point3 -> World -> (Point3, MPO) -> (Point3, MPO)
|
||||||
collide3Walls sp w e@(ep, _) = foldl' f e wls
|
collide3Walls sp w e@(ep, _) = foldl' f e $ wlsNearSeg (xyV3 sp) (xyV3 ep) w
|
||||||
where
|
where
|
||||||
f x wl = collide3Wall sp wl x
|
f x wl = collide3Wall sp wl x
|
||||||
wls = wlsNearSeg (xyV3 sp) (xyV3 ep) w
|
|
||||||
|
|
||||||
collide3Floors ::
|
collide3Floors ::
|
||||||
Point3 ->
|
Point3 ->
|
||||||
|
|||||||
@@ -100,5 +100,5 @@ wallBlips :: Point2 -> Float -> World -> ([Point2], S.Set (Point2, Point2))
|
|||||||
wallBlips p r = foldMap f . wlsNearCirc p r
|
wallBlips p r = foldMap f . wlsNearCirc p r
|
||||||
where
|
where
|
||||||
f wl = case uncurry (intersectCircSeg p r) $ _wlLine wl of
|
f wl = case uncurry (intersectCircSeg p r) $ _wlLine wl of
|
||||||
[] -> mempty
|
(Nothing,Nothing) -> mempty
|
||||||
xs -> (xs, S.singleton (wl ^. wlLine))
|
(a,b) -> (maybeToList a <> maybeToList b, S.singleton (wl ^. wlLine))
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ pbsHit sp ep w
|
|||||||
| sp == ep = mempty
|
| sp == ep = mempty
|
||||||
| otherwise =
|
| otherwise =
|
||||||
sortOn (dist sp . fst)
|
sortOn (dist sp . fst)
|
||||||
. mapMaybe (\pb -> (,pb) <$> listToMaybe (intersectCircSeg (_pbPos pb) 8 sp ep))
|
. mapMaybe (\pb -> (,pb) <$> fst (intersectCircSeg (_pbPos pb) 8 sp ep))
|
||||||
. IM.elems
|
. IM.elems
|
||||||
$ w ^. cWorld . lWorld . pulseBalls
|
$ w ^. cWorld . lWorld . pulseBalls
|
||||||
|
|
||||||
|
|||||||
+20
-13
@@ -7,7 +7,6 @@ module Geometry.Intersect where
|
|||||||
import Control.Applicative
|
import Control.Applicative
|
||||||
import Control.Lens
|
import Control.Lens
|
||||||
import Control.Monad
|
import Control.Monad
|
||||||
import Data.List
|
|
||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
import Geometry.Data
|
import Geometry.Data
|
||||||
import Geometry.LHS
|
import Geometry.LHS
|
||||||
@@ -348,18 +347,26 @@ inSegArea a b c = param >= 0 && param <= dotV (b -.- a) (b -.- a)
|
|||||||
where
|
where
|
||||||
param = dotV (b -.- a) (c -.- a)
|
param = dotV (b -.- a) (c -.- a)
|
||||||
|
|
||||||
-- I suspect that this may not be correct...
|
intersectCircSeg :: Point2 -> Float -> Point2 -> Point2 -> (Maybe Point2,Maybe Point2)
|
||||||
-- it should probably use closestPointOnSeg
|
intersectCircSeg c r s e = intersectCircLineAlong c r s e
|
||||||
intersectCircSeg :: Point2 -> Float -> Point2 -> Point2 -> [Point2]
|
& g
|
||||||
intersectCircSeg c r a b
|
& each %~ f
|
||||||
| y < 0 = []
|
|
||||||
| otherwise = nub $ filter (inSegArea a b) [d -.- v, d +.+ v]
|
|
||||||
where
|
where
|
||||||
d = closestPointOnLine a b c
|
f (Just x) | x >= 0 && x < 1 = Just $ s + x *^ (e - s)
|
||||||
x = dist d c
|
f _ = Nothing
|
||||||
y = r ^ (2 :: Int) - x ^ (2 :: Int)
|
g Nothing = (Nothing,Nothing)
|
||||||
z = sqrt y
|
g (Just (x,y)) = (Just x,Just y)
|
||||||
v = z *.* normalizeV (b -.- a)
|
|
||||||
|
--intersectCircSeg :: Point2 -> Float -> Point2 -> Point2 -> [Point2]
|
||||||
|
--intersectCircSeg c r a b
|
||||||
|
-- | y < 0 = []
|
||||||
|
-- | otherwise = nub $ filter (inSegArea a b) [d -.- v, d +.+ v]
|
||||||
|
-- where
|
||||||
|
-- d = closestPointOnLine a b c
|
||||||
|
-- x = dist d c
|
||||||
|
-- y = r ^ (2 :: Int) - x ^ (2 :: Int)
|
||||||
|
-- z = sqrt y
|
||||||
|
-- v = z *.* normalizeV (b -.- a)
|
||||||
|
|
||||||
intersectCircLineAlong :: Point2 -> Float -> Point2 -> Point2 -> Maybe (Float, Float)
|
intersectCircLineAlong :: Point2 -> Float -> Point2 -> Point2 -> Maybe (Float, Float)
|
||||||
intersectCircLineAlong p r x y = do
|
intersectCircLineAlong p r x y = do
|
||||||
@@ -415,4 +422,4 @@ intersectCircSegTest c r x y =
|
|||||||
z = r *.* vNormal (normalizeV x - y)
|
z = r *.* vNormal (normalizeV x - y)
|
||||||
|
|
||||||
intersectCircSegFirst :: Point2 -> Float -> Point2 -> Point2 -> Maybe Point2
|
intersectCircSegFirst :: Point2 -> Float -> Point2 -> Point2 -> Maybe Point2
|
||||||
intersectCircSegFirst c r a = listToMaybe . intersectCircSeg c r a
|
intersectCircSegFirst c r a = fst . intersectCircSeg c r a
|
||||||
|
|||||||
Reference in New Issue
Block a user