module Apecs.Physics.Geometry where

import Apecs.Physics.Types
import Linear

vertices :: Convex -> [BVec]
vertices :: Convex -> [BVec]
vertices (Convex [BVec]
s Double
_) = [BVec]
s

-- | Map a function over all vertices
mapVertices :: (BVec -> BVec) -> Convex -> Convex
mapVertices :: (BVec -> BVec) -> Convex -> Convex
mapVertices BVec -> BVec
f (Convex [BVec]
s Double
r) = [BVec] -> Double -> Convex
Convex (BVec -> BVec
f forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [BVec]
s) Double
r

-- | Translates all vertices. The name shift is to prevent collisions with gloss
shift :: BVec -> Convex -> Convex
shift :: BVec -> Convex -> Convex
shift = (BVec -> BVec) -> Convex -> Convex
mapVertices forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Num a => a -> a -> a
(+)

getRadius :: Convex -> Double
getRadius :: Convex -> Double
getRadius (Convex [BVec]
_ Double
r) = Double
r

setRadius :: Double -> Convex -> Convex
setRadius :: Double -> Convex -> Convex
setRadius Double
r (Convex [BVec]
s Double
_) = [BVec] -> Double -> Convex
Convex [BVec]
s Double
r

cCircle, zCircle :: Double -> Convex
cCircle :: Double -> Convex
cCircle Double
r = BVec -> Double -> Convex
oCircle BVec
0 Double
r
zCircle :: Double -> Convex
zCircle = Double -> Convex
cCircle

oCircle :: BVec -> Double -> Convex
oCircle :: BVec -> Double -> Convex
oCircle BVec
o Double
r = [BVec] -> Double -> Convex
Convex [BVec
o] Double
r

hLine, vLine :: Double -> Convex
hLine :: Double -> Convex
hLine Double
l = [BVec] -> Double -> Convex
Convex [forall a. a -> a -> V2 a
V2 (-Double
lforall a. Fractional a => a -> a -> a
/Double
2) Double
0, forall a. a -> a -> V2 a
V2 (Double
lforall a. Fractional a => a -> a -> a
/Double
2) Double
0] Double
0
vLine :: Double -> Convex
vLine Double
l = [BVec] -> Double -> Convex
Convex [forall a. a -> a -> V2 a
V2 Double
0 (Double
lforall a. Fractional a => a -> a -> a
/Double
2), forall a. a -> a -> V2 a
V2 Double
0 (-Double
lforall a. Fractional a => a -> a -> a
/Double
2)] Double
0

-- | Centered rectangle with a given size
cRectangle :: BVec -> Convex
cRectangle :: BVec -> Convex
cRectangle BVec
s = BVec -> BVec -> Convex
oRectangle (-BVec
sforall a. Num a => a -> a -> a
*BVec
0.5) BVec
s

-- | Rectangle with a given origin and size
oRectangle :: BVec -> BVec -> Convex
oRectangle :: BVec -> BVec -> Convex
oRectangle (V2 Double
x Double
y) (V2 Double
w Double
h) = [BVec] -> Double -> Convex
Convex [forall a. a -> a -> V2 a
V2 Double
x Double
y, forall a. a -> a -> V2 a
V2 Double
x (Double
yforall a. Num a => a -> a -> a
+Double
h), forall a. a -> a -> V2 a
V2 (Double
xforall a. Num a => a -> a -> a
+Double
w) (Double
yforall a. Num a => a -> a -> a
+Double
h), forall a. a -> a -> V2 a
V2 (Double
xforall a. Num a => a -> a -> a
+Double
w) Double
y] Double
0

-- | Rectangle with origin 0 and given size
zRectangle :: BVec -> Convex
zRectangle :: BVec -> Convex
zRectangle BVec
s = BVec -> BVec -> Convex
oRectangle BVec
0 BVec
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 -> [Convex]
toEdges (Convex [] Double
_) = []
toEdges (Convex [BVec
_] Double
_) = []
toEdges (Convex [BVec]
vs Double
r) = forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (\BVec
h BVec
t -> [BVec] -> Double -> Convex
Convex [BVec
h,BVec
t] Double
r) [BVec]
vs (forall a. [a] -> [a]
tail forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. [a] -> [a]
cycle forall a b. (a -> b) -> a -> b
$ [BVec]
vs)

-- | A set of lines forming a grid. Returns (r + c + 2) segments.
gridLines :: Vec -> Int -> Int -> [Convex]
gridLines :: BVec -> Int -> Int -> [Convex]
gridLines BVec
size Int
c Int
r =
  [ BVec -> Convex -> Convex
shift (forall a. a -> a -> V2 a
V2 Double
x Double
0) (Double -> Convex
vLine Double
h) | Double
x <- [Double]
xs ] forall a. [a] -> [a] -> [a]
++
  [ BVec -> Convex -> Convex
shift (forall a. a -> a -> V2 a
V2 Double
0 Double
y) (Double -> Convex
hLine Double
w) | Double
y <- [Double]
ys ]
  where
    V2 Double
w Double
h = BVec
size
    V2 Double
x Double
y = -BVec
sizeforall a. Num a => a -> a -> a
*BVec
0.5
    dx :: Double
dx = Double
wforall a. Fractional a => a -> a -> a
/forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
c
    dy :: Double
dy = Double
hforall a. Fractional a => a -> a -> a
/forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
r
    xs :: [Double]
xs = [Double
x forall a. Num a => a -> a -> a
+ forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
n forall a. Num a => a -> a -> a
* Double
dx | Int
n <- [Int
0..Int
c]]
    ys :: [Double]
ys = [Double
y forall a. Num a => a -> a -> a
+ forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
n forall a. Num a => a -> a -> a
* Double
dy | Int
n <- [Int
0..Int
r]]