{-# LINE 1 "src/Chiphunk/Low/Helper.chs" #-}
module Chiphunk.Low.Helper
  ( momentForCircle
  , momentForSegment
  , momentForPoly
  , momentForBox
  , areaForCircle
  , areaForSegment
  , areaForPoly
  , centroidForPoly
  , convexHull
  ) where
import qualified Foreign.C.Types as C2HSImp
import qualified Foreign.Ptr as C2HSImp
import qualified System.IO.Unsafe as C2HSImp
import Data.VectorSpace
import Foreign
import System.IO.Unsafe
import Chiphunk.Low.Internal
import Chiphunk.Low.Types
{-# LINE 21 "src/Chiphunk/Low/Helper.chs" #-}
momentForCircle
  :: Double 
  -> Double 
  -> Double 
  -> Vect   
  -> Double
momentForCircle m r1 r2 offs = m * (0.5 * (r1 * r1 + r2 * r2) + magnitudeSq offs)
momentForSegment
  :: Double 
  -> Vect   
  -> Vect   
  -> Double 
  -> Double
momentForSegment m a b r = m * ((len * len + 4 * r * r) / 12 + magnitudeSq offs)
  where
    offs = lerp a b 0.5
    len  = magnitude (b ^-^ a) + 2 * r
momentForPoly :: (Double) 
 -> ([Vect]) 
 -> (Vect) 
 -> (Double) 
 -> (Double)
momentForPoly a1 a2 a3 a4 =
  C2HSImp.unsafePerformIO $
  let {a1' = realToFrac a1} in
  withList a2 $ \(a2'1, a2'2) ->
  with a3 $ \a3' ->
  let {a4' = realToFrac a4} in
  momentForPoly'_ a1' a2'1  a2'2 a3' a4' >>= \res ->
  let {res' = realToFrac res} in
  return (res')
{-# LINE 55 "src/Chiphunk/Low/Helper.chs" #-}
momentForBox
  :: Double 
  -> Double 
  -> Double 
  -> Double
momentForBox m w h = m * (w * w + h * h) / 12
areaForCircle
  :: Double 
  -> Double 
  -> Double
areaForCircle r1 r2 = pi * abs (r1 * r1 - r2 * r2)
areaForSegment
  :: Vect   
  -> Vect   
  -> Double 
  -> Double
areaForSegment v1 v2 r = magnitude (v1 ^-^ v2) * 2 * r + pi * r * r
areaForPoly :: ([Vect]) 
 -> (Double) 
 -> (Double)
areaForPoly a1 a2 =
  C2HSImp.unsafePerformIO $
  withList a1 $ \(a1'1, a1'2) ->
  let {a2' = realToFrac a2} in
  areaForPoly'_ a1'1  a1'2 a2' >>= \res ->
  let {res' = realToFrac res} in
  return (res')
{-# LINE 84 "src/Chiphunk/Low/Helper.chs" #-}
centroidForPoly :: ([Vect]) -> (Vect)
centroidForPoly a1 =
  C2HSImp.unsafePerformIO $
  withList a1 $ \(a1'1, a1'2) ->
  alloca $ \a2' ->
  centroidForPoly'_ a1'1  a1'2 a2' >>
  peek  a2'>>= \a2'' ->
  return (a2'')
{-# LINE 87 "src/Chiphunk/Low/Helper.chs" #-}
convexHull
  :: [Vect]        
  -> Double        
  -> ([Vect], Int) 
convexHull vs tol = unsafePerformIO $
  withArray vs $ \pVs ->
  allocaArray (length vs) $ \pRes ->
  alloca $ \pFst -> do
    n <- c_convexHull (fromIntegral $ length vs) pVs pRes pFst (realToFrac tol)
    (,) <$> peekArray (fromIntegral n) pRes <*> (fromIntegral <$> peek pFst)
foreign import ccall unsafe "Chiphunk/Low/Helper.chs.h __c2hs_wrapped__cpMomentForPoly"
  momentForPoly'_ :: (C2HSImp.CDouble -> (C2HSImp.CInt -> ((VectPtr) -> ((VectPtr) -> (C2HSImp.CDouble -> (IO C2HSImp.CDouble))))))
foreign import ccall unsafe "Chiphunk/Low/Helper.chs.h cpAreaForPoly"
  areaForPoly'_ :: (C2HSImp.CInt -> ((VectPtr) -> (C2HSImp.CDouble -> (IO C2HSImp.CDouble))))
foreign import ccall unsafe "Chiphunk/Low/Helper.chs.h w_cpCentroidForPoly"
  centroidForPoly'_ :: (C2HSImp.CInt -> ((VectPtr) -> ((VectPtr) -> (IO ()))))
foreign import ccall safe "Chiphunk/Low/Helper.chs.h cpConvexHull"
  c_convexHull :: (C2HSImp.CInt -> ((VectPtr) -> ((VectPtr) -> ((C2HSImp.Ptr C2HSImp.CInt) -> (C2HSImp.CDouble -> (IO C2HSImp.CInt))))))