{-# LINE 1 "src/Chiphunk/Low/Vect.chs" #-}
module Chiphunk.Low.Vect
  ( Vect (..)
  , cpv
  , vZero
  , vEql
  , vAdd
  , vSub
  , vNeg
  , vMult
  , vDot
  , vCross
  , vPerp
  , vRPerp
  , vProject
  , vRotate
  , vUnRotate
  , vLength
  , vLengthSq
  , vLerp
  , vLerpConst
  , vSLerp
  , vSLerpConst
  , vNormalize
  , vClamp
  , vDist
  , vDistSq
  , vNear
  , vForAngle
  , vToAngle
  ) where
import qualified Foreign.C.Types as C2HSImp
import qualified System.IO.Unsafe as C2HSImp
import Data.Cross
import Data.VectorSpace
import Foreign
import Chiphunk.Low.Types
{-# LINE 42 "src/Chiphunk/Low/Vect.chs" #-}
cpv :: Double -> Double -> Vect
cpv = Vect
vZero :: Vect
vZero = zeroV
vEql :: Vect -> Vect -> Bool
vEql = (==)
vAdd :: Vect -> Vect -> Vect
vAdd = (^+^)
vSub :: Vect -> Vect -> Vect
vSub = (^-^)
vNeg :: Vect -> Vect
vNeg = negateV
vMult :: Vect -> Double -> Vect
vMult = (^*)
vDot :: Vect -> Vect -> Double
vDot = (<.>)
vCross :: Vect -> Vect -> Double
Vect x1 y1 `vCross` Vect x2 y2 = x1 * y2 - y1 * x2
vPerp :: Vect -> Vect
vPerp = cross2
vRPerp :: Vect -> Vect
vRPerp v = negateV $ cross2 v
vProject
  :: Vect 
  -> Vect 
  -> Vect
vProject = project
vRotate
  :: Vect 
  -> Vect 
  -> Vect
Vect x1 y1 `vRotate` Vect x2 y2 = Vect (x1 * x2 - y1 * y2) (x1 * y2 + x2 * y1)
vUnRotate :: Vect -> Vect -> Vect
Vect x1 y1 `vUnRotate` Vect x2 y2 = Vect (x1 * x2 + y1 * y2) (x2 * y1 - x1 * y2)
vLength :: Vect -> Double
vLength = magnitude
vLengthSq :: Vect -> Double
vLengthSq = magnitudeSq
vLerp
  :: Vect   
  -> Vect   
  -> Double
  -> Vect
vLerp = lerp
vLerpConst
  :: Vect   
  -> Vect   
  -> Double 
  -> Vect
vLerpConst a b l = a ^+^ vClamp (b ^-^ a) l
vSLerp :: (Vect) 
 -> (Vect) 
 -> (Double) -> (Vect)
vSLerp a1 a2 a3 =
  C2HSImp.unsafePerformIO $
  with a1 $ \a1' ->
  with a2 $ \a2' ->
  let {a3' = realToFrac a3} in
  alloca $ \a4' ->
  vSLerp'_ a1' a2' a3' a4' >>
  peek  a4'>>= \a4'' ->
  return (a4'')
{-# LINE 164 "src/Chiphunk/Low/Vect.chs" #-}
vSLerpConst :: (Vect) 
 -> (Vect) 
 -> (Double) 
 -> (Vect)
vSLerpConst a1 a2 a3 =
  C2HSImp.unsafePerformIO $
  with a1 $ \a1' ->
  with a2 $ \a2' ->
  let {a3' = realToFrac a3} in
  alloca $ \a4' ->
  vSLerpConst'_ a1' a2' a3' a4' >>
  peek  a4'>>= \a4'' ->
  return (a4'')
{-# LINE 172 "src/Chiphunk/Low/Vect.chs" #-}
vNormalize :: Vect -> Vect
vNormalize = normalized
vClamp
  :: Vect   
  -> Double 
  -> Vect
vClamp v l
  | magnitudeSq v > l * l = l *^ normalized v
  | otherwise             = v
vDist
  :: Vect   
  -> Vect   
  -> Double
vDist v1 v2 = magnitude $ v1 ^-^ v2
vDistSq
  :: Vect   
  -> Vect   
  -> Double
vDistSq v1 v2 = magnitudeSq $ v1 ^-^ v2
vNear
  :: Vect   
  -> Vect   
  -> Double 
  -> Bool
vNear v1 v2 d = vDistSq v1 v2 < d * d
vForAngle :: Double -> Vect
vForAngle alpha = Vect (cos alpha) (sin alpha)
vToAngle
  :: Vect   
  -> Double
vToAngle (Vect x y) = atan2 y x
foreign import ccall unsafe "Chiphunk/Low/Vect.chs.h __c2hs_wrapped__w_cpvslerp"
  vSLerp'_ :: ((VectPtr) -> ((VectPtr) -> (C2HSImp.CDouble -> ((VectPtr) -> (IO ())))))
foreign import ccall unsafe "Chiphunk/Low/Vect.chs.h __c2hs_wrapped__w_cpvslerpconst"
  vSLerpConst'_ :: ((VectPtr) -> ((VectPtr) -> (C2HSImp.CDouble -> ((VectPtr) -> (IO ())))))