{-# OPTIONS_HADDOCK hide #-}
{-# LANGUAGE BangPatterns #-}
module Graphics.WorldTurtle.Internal.Coords
  ( module GPoint
  , module GArithmetic
  , module GVector
  , module GAngle
  , lerp
  , normalizeHeading
  ) where

import Prelude hiding ((-), (+))
import qualified Prelude as P

import Graphics.Gloss.Data.Point as GPoint
import Graphics.Gloss.Data.Point.Arithmetic as GArithmetic
import Graphics.Gloss.Data.Vector as GVector
import Graphics.Gloss.Geometry.Angle as GAngle

-- | What it says on the tin. A lerp function. 

lerp :: Float -- Coefficient between 0 and 1.

     -> Point -- Point /a/.

     -> Point -- Point /b/.

     -> Point -- new point some percentage value between /a/ and /b/.

lerp :: Float -> Point -> Point -> Point
lerp !Float
l !Point
a !Point
b = let (!Float
ux, !Float
uy) = (Float
1 Float -> Float -> Float
forall a. Num a => a -> a -> a
P.- Float
l) Float -> Point -> Point
`mulSV` Point
a
                    (!Float
vx, !Float
vy) = Float
l Float -> Point -> Point
`mulSV` Point
b
                    !n :: Point
n = (Float
ux Float -> Float -> Float
forall a. Num a => a -> a -> a
P.+ Float
vx, Float
uy Float -> Float -> Float
forall a. Num a => a -> a -> a
P.+ Float
vy)
               in Point
n

-- | Return a valid heading value between (0, 360].

--   We want 360 to be 360 (full rotation).

--   We want 361 to be 1 (wraparound rotation).

--   Special case: we want 0 to be 0 (no rotation). Though really 0 is equal to

--   360 we will let this special case slide as it helps in our time elapsed 

--   calculations.

normalizeHeading :: Float -> Float
normalizeHeading :: Float -> Float
normalizeHeading Float
0 = Float
0
normalizeHeading Float
f = let (Int
n, Float
b) = Float -> (Int, Float)
forall a b. (RealFrac a, Integral b) => a -> (b, a)
properFraction Float
f :: (Int, Float)
                         f' :: Float
f' = Int -> Float
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int
n Int -> Int -> Int
forall a. Integral a => a -> a -> a
`rem` Int
360) Float -> Float -> Float
forall a. Num a => a -> a -> a
P.+ Float
b
                      in if Float
f' Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
<= Float
0 then Float
f' Float -> Float -> Float
forall a. Num a => a -> a -> a
P.+ Float
360 else Float
f'