{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# OPTIONS_GHC -fno-warn-incomplete-patterns #-}
module Diagrams.CubicSpline
(
cubicSpline
, BSpline
, bspline
) where
import Control.Lens (view)
import Diagrams.Core
import Diagrams.CubicSpline.Boehm
import Diagrams.CubicSpline.Internal
import Diagrams.Located (Located, at, mapLoc)
import Diagrams.Segment
import Diagrams.Trail
import Diagrams.TrailLike (TrailLike (..))
import Linear.Affine
import Linear.Metric
cubicSpline :: (V t ~ v, N t ~ n, TrailLike t, Fractional (v n)) => Bool -> [Point v n] -> t
cubicSpline :: forall t (v :: * -> *) n.
(V t ~ v, N t ~ n, TrailLike t, Fractional (v n)) =>
Bool -> [Point v n] -> t
cubicSpline Bool
closed [] = forall t. TrailLike t => Located (Trail (V t) (N t)) -> t
trailLike forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> *) n.
(Metric v, OrderedField n) =>
Bool -> Located (Trail' Line v n) -> Located (Trail v n)
closeIf Bool
closed forall a b. (a -> b) -> a -> b
$ forall (v :: * -> *) n.
(Metric v, OrderedField n) =>
Trail' Line v n
emptyLine forall a. a -> Point (V a) (N a) -> Located a
`at` forall (f :: * -> *) a. (Additive f, Num a) => Point f a
origin
cubicSpline Bool
closed [Point v n
p] = forall t. TrailLike t => Located (Trail (V t) (N t)) -> t
trailLike forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> *) n.
(Metric v, OrderedField n) =>
Bool -> Located (Trail' Line v n) -> Located (Trail v n)
closeIf Bool
closed forall a b. (a -> b) -> a -> b
$ forall (v :: * -> *) n.
(Metric v, OrderedField n) =>
Trail' Line v n
emptyLine forall a. a -> Point (V a) (N a) -> Located a
`at` Point v n
p
cubicSpline Bool
closed [Point v n]
ps = [[v n]] -> t
flattenBeziers forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map forall {a}. Fractional a => [a] -> [a]
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Fractional a => Bool -> [a] -> [[a]]
solveCubicSplineCoefficients Bool
closed forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map (forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view forall (f :: * -> *) a (g :: * -> *) b.
Lens (Point f a) (Point g b) (f a) (g b)
lensP) forall a b. (a -> b) -> a -> b
$ [Point v n]
ps
where
f :: [a] -> [a]
f [a
a,a
b,a
c,a
d] = [a
a, (a
3forall a. Num a => a -> a -> a
*a
aforall a. Num a => a -> a -> a
+a
b)forall a. Fractional a => a -> a -> a
/a
3, (a
3forall a. Num a => a -> a -> a
*a
aforall a. Num a => a -> a -> a
+a
2forall a. Num a => a -> a -> a
*a
bforall a. Num a => a -> a -> a
+a
c)forall a. Fractional a => a -> a -> a
/a
3, a
aforall a. Num a => a -> a -> a
+a
bforall a. Num a => a -> a -> a
+a
cforall a. Num a => a -> a -> a
+a
d]
flattenBeziers :: [[v n]] -> t
flattenBeziers bs :: [[v n]]
bs@((v n
b:[v n]
_):[[v n]]
_)
= forall t. TrailLike t => Located (Trail (V t) (N t)) -> t
trailLike forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> *) n.
(Metric v, OrderedField n) =>
Bool -> Located (Trail' Line v n) -> Located (Trail v n)
closeIf Bool
closed forall a b. (a -> b) -> a -> b
$ forall (v :: * -> *) n.
(Metric v, OrderedField n) =>
[Segment Closed v n] -> Trail' Line v n
lineFromSegments (forall a b. (a -> b) -> [a] -> [b]
map forall {v :: * -> *} {n}. Num (v n) => [v n] -> Segment Closed v n
bez [[v n]]
bs) forall a. a -> Point (V a) (N a) -> Located a
`at` forall (f :: * -> *) a. f a -> Point f a
P v n
b
bez :: [v n] -> Segment Closed v n
bez [v n
a,v n
b,v n
c,v n
d] = forall (v :: * -> *) n. v n -> v n -> v n -> Segment Closed v n
bezier3 (v n
b forall a. Num a => a -> a -> a
- v n
a) (v n
c forall a. Num a => a -> a -> a
- v n
a) (v n
d forall a. Num a => a -> a -> a
- v n
a)
closeIf :: (Metric v, OrderedField n)
=> Bool -> Located (Trail' Line v n) -> Located (Trail v n)
closeIf :: forall (v :: * -> *) n.
(Metric v, OrderedField n) =>
Bool -> Located (Trail' Line v n) -> Located (Trail v n)
closeIf Bool
c = forall a b. SameSpace a b => (a -> b) -> Located a -> Located b
mapLoc (if Bool
c then forall (v :: * -> *) n. Trail' Loop v n -> Trail v n
wrapLoop forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> *) n.
(Metric v, OrderedField n) =>
Trail' Line v n -> Trail' Loop v n
glueLine else forall (v :: * -> *) n. Trail' Line v n -> Trail v n
wrapLine)