imj-base-0.1.0.2: src/Imj/Graphics/Interpolation/SequentiallyInterpolatedList.hs
{-# OPTIONS_HADDOCK hide #-}
{-# LANGUAGE NoImplicitPrelude #-}
module Imj.Graphics.Interpolation.SequentiallyInterpolatedList(
SequentiallyInterpolatedList(..)
) where
import Imj.Prelude
import Data.List(length, mapAccumL)
import Imj.Graphics.Class.DiscreteInterpolation
import Imj.Util
-- | A 'List'-like type to interpolate sequentially (one index at a time) between same-index elements.
newtype SequentiallyInterpolatedList a =
SequentiallyInterpolatedList [a]
deriving(Eq, Ord, Show)
-- | Interpolation between 2 'SequentiallyInterpolatedList', occuring sequentially
-- i.e interpolating between one pair of same-index elements at a time, starting with
-- 0 index and increasing.
-- Prerequisite : lists have the same lengths.
instance (DiscreteDistance a)
=> DiscreteDistance (SequentiallyInterpolatedList a) where
distance (SequentiallyInterpolatedList l) (SequentiallyInterpolatedList l') =
succ $ sum $ zipWith (\x y -> pred $ distance x y) l (assert (length l' == length l) l')
-- | Interpolation between 2 'SequentiallyInterpolatedList', occuring sequentially
-- i.e interpolating between one pair of same-index elements at a time, starting with
-- 0 index and increasing.
-- Prerequisite : lists have the same lengths.
instance (DiscreteInterpolation a)
=> DiscreteInterpolation (SequentiallyInterpolatedList a) where
interpolate (SequentiallyInterpolatedList l) (SequentiallyInterpolatedList l') progress =
SequentiallyInterpolatedList $ snd $
mapAccumL
(\acc (e,e') ->
let d = pred $ distance e e'
r = interpolate e e' $ clamp acc 0 d
in (acc-d, r))
progress
$ zip l (assert (length l' == length l) l')