{-# 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 [] = Located (Trail v n) -> t
Located (Trail (V t) (N t)) -> t
forall t. TrailLike t => Located (Trail (V t) (N t)) -> t
trailLike (Located (Trail v n) -> t)
-> (Located (Trail' Line v n) -> Located (Trail v n))
-> Located (Trail' Line v n)
-> t
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> Located (Trail' Line v n) -> Located (Trail v n)
forall (v :: * -> *) n.
(Metric v, OrderedField n) =>
Bool -> Located (Trail' Line v n) -> Located (Trail v n)
closeIf Bool
closed (Located (Trail' Line v n) -> t) -> Located (Trail' Line v n) -> t
forall a b. (a -> b) -> a -> b
$ Trail' Line v n
forall (v :: * -> *) n.
(Metric v, OrderedField n) =>
Trail' Line v n
emptyLine Trail' Line v n
-> Point (V (Trail' Line v n)) (N (Trail' Line v n))
-> Located (Trail' Line v n)
forall a. a -> Point (V a) (N a) -> Located a
`at` Point v n
Point (V (Trail' Line v n)) (N (Trail' Line v n))
forall (f :: * -> *) a. (Additive f, Num a) => Point f a
origin
cubicSpline Bool
closed [Point v n
p] = Located (Trail v n) -> t
Located (Trail (V t) (N t)) -> t
forall t. TrailLike t => Located (Trail (V t) (N t)) -> t
trailLike (Located (Trail v n) -> t)
-> (Located (Trail' Line v n) -> Located (Trail v n))
-> Located (Trail' Line v n)
-> t
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> Located (Trail' Line v n) -> Located (Trail v n)
forall (v :: * -> *) n.
(Metric v, OrderedField n) =>
Bool -> Located (Trail' Line v n) -> Located (Trail v n)
closeIf Bool
closed (Located (Trail' Line v n) -> t) -> Located (Trail' Line v n) -> t
forall a b. (a -> b) -> a -> b
$ Trail' Line v n
forall (v :: * -> *) n.
(Metric v, OrderedField n) =>
Trail' Line v n
emptyLine Trail' Line v n
-> Point (V (Trail' Line v n)) (N (Trail' Line v n))
-> Located (Trail' Line v n)
forall a. a -> Point (V a) (N a) -> Located a
`at` Point v n
Point (V (Trail' Line v n)) (N (Trail' Line v n))
p
cubicSpline Bool
closed [Point v n]
ps = [[v n]] -> t
flattenBeziers ([[v n]] -> t) -> ([Point v n] -> [[v n]]) -> [Point v n] -> t
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([v n] -> [v n]) -> [[v n]] -> [[v n]]
forall a b. (a -> b) -> [a] -> [b]
map [v n] -> [v n]
forall {a}. Fractional a => [a] -> [a]
f ([[v n]] -> [[v n]])
-> ([Point v n] -> [[v n]]) -> [Point v n] -> [[v n]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> [v n] -> [[v n]]
forall a. Fractional a => Bool -> [a] -> [[a]]
solveCubicSplineCoefficients Bool
closed ([v n] -> [[v n]])
-> ([Point v n] -> [v n]) -> [Point v n] -> [[v n]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Point v n -> v n) -> [Point v n] -> [v n]
forall a b. (a -> b) -> [a] -> [b]
map (Getting (v n) (Point v n) (v n) -> Point v n -> v n
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting (v n) (Point v n) (v n)
forall (f1 :: * -> *) a (g :: * -> *) b (f2 :: * -> *).
Functor f2 =>
(f1 a -> f2 (g b)) -> Point f1 a -> f2 (Point g b)
lensP) ([Point v n] -> t) -> [Point v n] -> t
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
3a -> a -> a
forall a. Num a => a -> a -> a
*a
aa -> a -> a
forall a. Num a => a -> a -> a
+a
b)a -> a -> a
forall a. Fractional a => a -> a -> a
/a
3, (a
3a -> a -> a
forall a. Num a => a -> a -> a
*a
aa -> a -> a
forall a. Num a => a -> a -> a
+a
2a -> a -> a
forall a. Num a => a -> a -> a
*a
ba -> a -> a
forall a. Num a => a -> a -> a
+a
c)a -> a -> a
forall a. Fractional a => a -> a -> a
/a
3, a
aa -> a -> a
forall a. Num a => a -> a -> a
+a
ba -> a -> a
forall a. Num a => a -> a -> a
+a
ca -> a -> a
forall a. Num a => a -> a -> a
+a
d]
flattenBeziers :: [[v n]] -> t
flattenBeziers bs :: [[v n]]
bs@((v n
b:[v n]
_):[[v n]]
_)
= Located (Trail v n) -> t
Located (Trail (V t) (N t)) -> t
forall t. TrailLike t => Located (Trail (V t) (N t)) -> t
trailLike (Located (Trail v n) -> t)
-> (Located (Trail' Line v n) -> Located (Trail v n))
-> Located (Trail' Line v n)
-> t
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> Located (Trail' Line v n) -> Located (Trail v n)
forall (v :: * -> *) n.
(Metric v, OrderedField n) =>
Bool -> Located (Trail' Line v n) -> Located (Trail v n)
closeIf Bool
closed (Located (Trail' Line v n) -> t) -> Located (Trail' Line v n) -> t
forall a b. (a -> b) -> a -> b
$ [Segment Closed v n] -> Trail' Line v n
forall (v :: * -> *) n.
(Metric v, OrderedField n) =>
[Segment Closed v n] -> Trail' Line v n
lineFromSegments (([v n] -> Segment Closed v n) -> [[v n]] -> [Segment Closed v n]
forall a b. (a -> b) -> [a] -> [b]
map [v n] -> Segment Closed v n
forall {v :: * -> *} {n}. Num (v n) => [v n] -> Segment Closed v n
bez [[v n]]
bs) Trail' Line v n
-> Point (V (Trail' Line v n)) (N (Trail' Line v n))
-> Located (Trail' Line v n)
forall a. a -> Point (V a) (N a) -> Located a
`at` v n -> Point v n
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] = v n -> v n -> v n -> Segment Closed v n
forall (v :: * -> *) n. v n -> v n -> v n -> Segment Closed v n
bezier3 (v n
b v n -> v n -> v n
forall a. Num a => a -> a -> a
- v n
a) (v n
c v n -> v n -> v n
forall a. Num a => a -> a -> a
- v n
a) (v n
d v n -> v n -> v n
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 = (Trail' Line v n -> Trail v n)
-> Located (Trail' Line v n) -> Located (Trail v n)
forall a b. SameSpace a b => (a -> b) -> Located a -> Located b
mapLoc (if Bool
c then Trail' Loop v n -> Trail v n
forall (v :: * -> *) n. Trail' Loop v n -> Trail v n
wrapLoop (Trail' Loop v n -> Trail v n)
-> (Trail' Line v n -> Trail' Loop v n)
-> Trail' Line v n
-> Trail v n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Trail' Line v n -> Trail' Loop v n
forall (v :: * -> *) n.
(Metric v, OrderedField n) =>
Trail' Line v n -> Trail' Loop v n
glueLine else Trail' Line v n -> Trail v n
forall (v :: * -> *) n. Trail' Line v n -> Trail v n
wrapLine)