smoothie 0.3.3.3 → 0.4
raw patch · 4 files changed
+56/−23 lines, 4 filesdep +text
Dependencies added: text
Files
- CHANGELOG.md +15/−0
- smoothie.cabal +3/−2
- src/Data/Spline/Curve.hs +17/−12
- src/Data/Spline/Key.hs +21/−9
CHANGELOG.md view
@@ -1,3 +1,18 @@+## 0.4++### Breaking changes++- Removed `splineSampler` from `Spline`. It has to be passed to `spline`+ explicitely now on.++### Non-breaking changes++- Added ToJSON instances for Spline.+- Added ToJSON instances for Key.+- Added the keyInterpolation function to get a Text version of the+ interpolation of a Key.+- `Eq`, `Functor` and `Show` instances for `Spline`.+ ## 0.3.3.3 - Support for vector-0.11.
smoothie.cabal view
@@ -1,7 +1,7 @@ name: smoothie -version: 0.3.3.3 +version: 0.4 synopsis: Smooth curves via several interpolation modes -description: This package exports several splines you can use +description: This package exports several splines you can use to interpolate points in between. It includes instances for <https://hackage.haskell.org/package/aeson aeson> so that you can quickly store the splines and restore them. @@ -39,6 +39,7 @@ , linear >= 1.16 && < 1.20 , vector >= 0.10 && < 0.12 , aeson >= 0.9 && < 0.10 + , text >= 1.2 && < 1.3 hs-source-dirs: src
src/Data/Spline/Curve.hs view
@@ -17,7 +17,6 @@ -- * Splines Spline , splineKeys- , splineSampler -- * Building splines , spline -- * Sampling splines@@ -42,19 +41,19 @@ -- Thus, the interpolation mode of the latest key might be ignored. There’s an -- exception, though, when using the 'Bezier' interpolation mode. Feel free -- to dig in the "Key" documentation.-data Spline a s = Spline {+newtype Spline a s = Spline { -- |Extract the 'Key's. splineKeys :: Vector (Key (a s))- -- |Extract the sampler. The sampler is a function used to extract a- -- reference value used to perform several operations on the 'Key's.- , splineSampler :: a s -> s- }+ } deriving (Eq,Functor,Show) instance (FromJSON (a s), Ord s) => FromJSON ((a s -> s) -> Spline a s) where- parseJSON = withObject "spline" $ \o -> do- keys <- o .: "keys"+ parseJSON value = do+ keys <- parseJSON value pure $ \sampler -> spline sampler keys +instance (ToJSON (a s)) => ToJSON (Spline a s) where+ toJSON = Array . fmap toJSON . splineKeys+ -- |Build a @'Spline' a s@. -- -- @a s@ is the type held by 'Key's. For instance, @'V2' Float@.@@ -67,13 +66,19 @@ => (a s -> s) -> [Key (a s)] -> Spline a s-spline sampler keys =- Spline (fromList $ sortBy (comparing $ sampler . keyValue) keys) sampler+spline sampler = Spline . fromList . sortBy (comparing $ sampler . keyValue) -- |Sample a 'Spline' at a given 's' sampling value. If no sample exists, -- yields 'Nothing'.-sample :: (Additive a,Floating s,Ord s) => Spline a s -> s -> Maybe (a s)-sample (Spline keys sampler) at = do+--+-- The first parameter is a /sampler/ function used to extract a comparison+-- value. For most curves, the reflected value should be the time or the frame.+sample :: (Additive a,Floating s,Ord s)+ => (a s -> s)+ -> Spline a s+ -> s+ -> Maybe (a s)+sample sampler (Spline keys) at = do i <- bsearchLower (\k -> compare at (sampler $ keyValue k)) keys k0 <- keys !? i k1 <- keys !? (i + 1)
src/Data/Spline/Key.hs view
@@ -20,6 +20,7 @@ ) where import Data.Aeson+import Data.Text ( Text ) import Linear -- |A 'Key' is a point on the spline with extra information added. It can be,@@ -45,15 +46,7 @@ | Cosine a | CubicHermite a | Bezier a a a- deriving (Eq,Show)--instance Functor Key where- fmap f k = case k of- Hold a -> Hold (f a)- Linear a -> Linear (f a)- Cosine a -> Cosine (f a)- CubicHermite a -> CubicHermite (f a)- Bezier l a r -> Bezier (f l) (f a) (f r)+ deriving (Eq,Functor,Show) instance (FromJSON a) => FromJSON (Key a) where parseJSON = withObject "key" $ \o -> do@@ -70,6 +63,16 @@ pure $ Bezier left value right | otherwise -> fail "unknown interpolation mode" +instance (ToJSON a) => ToJSON (Key a) where+ toJSON k = object $+ ["value" .= value,"interpolation" .= interpolation] ++ tangents+ where+ value = keyValue k+ interpolation = keyInterpolation k+ tangents = case k of+ Bezier l _ r -> ["left" .= l,"right" .= r]+ _ -> []+ -- |Extract the value out of a 'Key'. keyValue :: Key a -> a keyValue k = case k of@@ -78,6 +81,15 @@ Cosine a -> a CubicHermite a -> a Bezier _ a _ -> a++-- |Extract the interpolation mode from a 'Key'.+keyInterpolation :: Key a -> Text+keyInterpolation k = case k of+ Hold{} -> "hold"+ Linear{} -> "linear"+ Cosine{} -> "cosine"+ CubicHermite{} -> "cubic-hermite"+ Bezier{} -> "bezier" -- |@'interpolateKeys' t start end@ interpolates between 'start' and 'end' using -- 's' as a normalized sampling value.