{-# LANGUAGE Arrows #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE TypeFamilies #-}
module FRP.Rhine.ResamplingBuffer.Interpolation where
import Data.Sequence
import Data.VectorSpace
import FRP.Rhine.ClSF
import FRP.Rhine.ResamplingBuffer
import FRP.Rhine.ResamplingBuffer.Util
import FRP.Rhine.ResamplingBuffer.KeepLast
linear
:: ( Monad m, Clock m cl1, Clock m cl2
, VectorSpace v
, Groundfield v ~ Diff (Time cl1)
, Groundfield v ~ Diff (Time cl2)
)
=> v
-> v
-> ResamplingBuffer m cl1 cl2 v v
linear initVelocity initPosition
= (derivativeFrom initPosition &&& clId) &&& timeInfoOf sinceInit
^->> keepLast ((initVelocity, initPosition), 0)
>>-^ proc ((velocity, lastPosition), sinceInit1) -> do
sinceInit2 <- timeInfoOf sinceInit -< ()
let diff = sinceInit2 - sinceInit1
returnA -< lastPosition ^+^ velocity ^* diff
sinc
:: ( Monad m, Clock m cl1, Clock m cl2
, VectorSpace v
, Ord (Groundfield v)
, Floating (Groundfield v)
, Groundfield v ~ Diff (Time cl1)
, Groundfield v ~ Diff (Time cl2)
)
=> Groundfield v
-> ResamplingBuffer m cl1 cl2 v v
sinc windowSize = historySince windowSize ^->> keepLast empty >>-^ proc as -> do
sinceInit2 <- sinceInitS -< ()
returnA -< vectorSum $ mkSinc sinceInit2 <$> as
where
mkSinc sinceInit2 (TimeInfo {..}, as)
= let t = pi * (sinceInit2 - sinceInit) / sinceLast
in as ^* (sin t / t)
vectorSum = foldr (^+^) zeroVector
cubic
:: ( Monad m
, VectorSpace v
, Groundfield v ~ Diff (Time cl1)
, Groundfield v ~ Diff (Time cl2)
)
=> ResamplingBuffer m cl1 cl2 v v
cubic = ((iPre zeroVector &&& threePointDerivative) &&& (sinceInitS >-> iPre 0))
>-> (clId &&& iPre (zeroVector, 0))
^->> keepLast ((zeroVector, 0), (zeroVector, 0))
>>-^ proc (((dv, v), t1), ((dv', v'), t1')) -> do
t2 <- sinceInitS -< ()
let
t = (t1 - t1') / (t2 - t1')
tsquared = t ^ 2
tcubed = t ^ 3
vInter = ( 2 * tcubed - 3 * tsquared + 1) *^ v'
^+^ ( tcubed - 2 * tsquared + t ) *^ dv'
^+^ (-2 * tcubed + 3 * tsquared ) *^ v
^+^ ( tcubed - tsquared ) *^ dv
returnA -< vInter