apecs-physics-0.2.0.0: src/Apecs/Physics/Geometry.hs
module Apecs.Physics.Geometry where
import Apecs.Physics.Types
import Linear
vertices :: Convex -> [BVec]
vertices (Convex s _) = s
-- | Map a function over all vertices
mapVertices :: (BVec -> BVec) -> Convex -> Convex
mapVertices f (Convex s r) = Convex (f <$> s) r
-- | Translates all vertices. The name shift is to prevent collisions with gloss
shift :: BVec -> Convex -> Convex
shift = mapVertices . (+)
getRadius :: Convex -> Double
getRadius (Convex _ r) = r
setRadius :: Double -> Convex -> Convex
setRadius r (Convex s _) = Convex s r
cCircle, zCircle :: Double -> Convex
cCircle r = oCircle 0 r
zCircle = cCircle
oCircle :: BVec -> Double -> Convex
oCircle o r = Convex [o] r
hLine, vLine :: Double -> Convex
hLine l = Convex [V2 (-l/2) 0, V2 (l/2) 0] 0
vLine l = Convex [V2 0 (l/2), V2 0 (-l/2)] 0
-- | Centered rectangle with a given size
cRectangle :: BVec -> Convex
cRectangle s = oRectangle (-s*0.5) s
-- | Rectangle with a given origin and size
oRectangle :: BVec -> BVec -> Convex
oRectangle (V2 x y) (V2 w h) = Convex [V2 x y, V2 x (y+h), V2 (x+w) (y+h), V2 (x+w) y] 0
-- | Rectangle with origin 0 and given size
zRectangle :: BVec -> Convex
zRectangle s = oRectangle 0 s
-- | Split a shape into its edges. Will return no edges for points, but returns 2 for a line (in opposite directions)
toEdges :: Convex -> [Convex]
toEdges (Convex [] _) = []
toEdges (Convex [_] _) = []
toEdges (Convex vs r) = zipWith (\h t -> Convex [h,t] r) vs (tail . cycle $ vs)
-- | A set of lines forming a grid. Returns (r + c + 2) segments.
gridLines :: Vec -> Int -> Int -> [Convex]
gridLines size c r =
[ shift (V2 x 0) (vLine h) | x <- xs ] ++
[ shift (V2 0 y) (hLine w) | y <- ys ]
where
V2 w h = size
V2 x y = -size*0.5
dx = w/fromIntegral c
dy = h/fromIntegral r
xs = [x + fromIntegral n * dx | n <- [0..c]]
ys = [y + fromIntegral n * dy | n <- [0..r]]