{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
module Diagrams.Deform
( Deformation(..)
, Deformable(..)
, asDeformation
) where
import Control.Lens (mapped, over, _Wrapped)
import Data.Monoid hiding ((<>))
import Data.Semigroup
import Prelude
import Diagrams.Core
import Diagrams.Located
import Diagrams.Parametric
import Diagrams.Path
import Diagrams.Segment
import Diagrams.Trail
import Linear.Affine
import Linear.Metric
import Linear.Vector
newtype Deformation v u n = Deformation (Point v n -> Point u n)
instance Semigroup (Deformation v v n) where
(Deformation Point v n -> Point v n
p1) <> :: Deformation v v n -> Deformation v v n -> Deformation v v n
<> (Deformation Point v n -> Point v n
p2) = (Point v n -> Point v n) -> Deformation v v n
forall (v :: * -> *) (u :: * -> *) n.
(Point v n -> Point u n) -> Deformation v u n
Deformation (Point v n -> Point v n
p1 (Point v n -> Point v n)
-> (Point v n -> Point v n) -> Point v n -> Point v n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Point v n -> Point v n
p2)
instance Monoid (Deformation v v n) where
mappend :: Deformation v v n -> Deformation v v n -> Deformation v v n
mappend = Deformation v v n -> Deformation v v n -> Deformation v v n
forall a. Semigroup a => a -> a -> a
(<>)
mempty :: Deformation v v n
mempty = (Point v n -> Point v n) -> Deformation v v n
forall (v :: * -> *) (u :: * -> *) n.
(Point v n -> Point u n) -> Deformation v u n
Deformation Point v n -> Point v n
forall a. a -> a
id
class Deformable a b where
deform' :: N a -> Deformation (V a) (V b) (N a) -> a -> b
deform :: Deformation (V a) (V b) (N a) -> a -> b
asDeformation :: (Additive v, Num n) => Transformation v n -> Deformation v v n
asDeformation :: Transformation v n -> Deformation v v n
asDeformation Transformation v n
t = (Point v n -> Point v n) -> Deformation v v n
forall (v :: * -> *) (u :: * -> *) n.
(Point v n -> Point u n) -> Deformation v u n
Deformation (Transformation v n -> Point v n -> Point v n
forall (v :: * -> *) n.
(Additive v, Num n) =>
Transformation v n -> Point v n -> Point v n
papply Transformation v n
t)
instance r ~ Point u n => Deformable (Point v n) r where
deform' :: N (Point v n)
-> Deformation (V (Point v n)) (V r) (N (Point v n))
-> Point v n
-> r
deform' = (Deformation v u n -> Point v n -> Point u n)
-> n -> Deformation v u n -> Point v n -> Point u n
forall a b. a -> b -> a
const Deformation v u n -> Point v n -> Point u n
forall a b.
Deformable a b =>
Deformation (V a) (V b) (N a) -> a -> b
deform
deform :: Deformation (V (Point v n)) (V r) (N (Point v n)) -> Point v n -> r
deform (Deformation Point (V (Point v n)) (N (Point v n))
-> Point (V r) (N (Point v n))
l) = Point v n -> r
Point (V (Point v n)) (N (Point v n))
-> Point (V r) (N (Point v n))
l
deformSegment :: (Metric v, Metric u, OrderedField n)
=> n -> Deformation v u n -> FixedSegment v n -> [FixedSegment u n]
deformSegment :: n -> Deformation v u n -> FixedSegment v n -> [FixedSegment u n]
deformSegment n
epsilon Deformation v u n
t = Int -> FixedSegment v n -> [FixedSegment u n]
go (Int
0::Int)
where
go :: Int -> FixedSegment v n -> [FixedSegment u n]
go Int
n FixedSegment v n
s
| Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
100 = [Deformation v u n -> FixedSegment v n -> FixedSegment u n
forall (v :: * -> *) (u :: * -> *) n.
Deformation v u n -> FixedSegment v n -> FixedSegment u n
approx Deformation v u n
t FixedSegment v n
s]
| n -> Deformation v u n -> FixedSegment v n -> Bool
forall (v :: * -> *) (u :: * -> *) n.
(Metric v, Metric u, OrderedField n) =>
n -> Deformation v u n -> FixedSegment v n -> Bool
goodEnough n
epsilon Deformation v u n
t FixedSegment v n
s = [Deformation v u n -> FixedSegment v n -> FixedSegment u n
forall (v :: * -> *) (u :: * -> *) n.
Deformation v u n -> FixedSegment v n -> FixedSegment u n
approx Deformation v u n
t FixedSegment v n
s]
| Bool
otherwise = (FixedSegment v n -> [FixedSegment u n])
-> [FixedSegment v n] -> [FixedSegment u n]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Int -> FixedSegment v n -> [FixedSegment u n]
go (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1)) [FixedSegment v n
s1, FixedSegment v n
s2]
where
(FixedSegment v n
s1, FixedSegment v n
s2) = FixedSegment v n
-> N (FixedSegment v n) -> (FixedSegment v n, FixedSegment v n)
forall p. Sectionable p => p -> N p -> (p, p)
splitAtParam FixedSegment v n
s N (FixedSegment v n)
0.5
approx :: Deformation v u n -> FixedSegment v n -> FixedSegment u n
approx :: Deformation v u n -> FixedSegment v n -> FixedSegment u n
approx Deformation v u n
t (FLinear Point v n
p0 Point v n
p1) = Point u n -> Point u n -> FixedSegment u n
forall (v :: * -> *) n. Point v n -> Point v n -> FixedSegment v n
FLinear (Deformation (V (Point v n)) (V (Point u n)) (N (Point v n))
-> Point v n -> Point u n
forall a b.
Deformable a b =>
Deformation (V a) (V b) (N a) -> a -> b
deform Deformation v u n
Deformation (V (Point v n)) (V (Point u n)) (N (Point v n))
t Point v n
p0) (Deformation (V (Point v n)) (V (Point u n)) (N (Point v n))
-> Point v n -> Point u n
forall a b.
Deformable a b =>
Deformation (V a) (V b) (N a) -> a -> b
deform Deformation v u n
Deformation (V (Point v n)) (V (Point u n)) (N (Point v n))
t Point v n
p1)
approx Deformation v u n
t (FCubic Point v n
p0 Point v n
c1 Point v n
c2 Point v n
p1) = Point u n
-> Point u n -> Point u n -> Point u n -> FixedSegment u n
forall (v :: * -> *) n.
Point v n
-> Point v n -> Point v n -> Point v n -> FixedSegment v n
FCubic (Point v n -> Point u n
f Point v n
p0) (Point v n -> Point u n
f Point v n
c1) (Point v n -> Point u n
f Point v n
c2) (Point v n -> Point u n
f Point v n
p1)
where f :: Point v n -> Point u n
f = Deformation (V (Point v n)) (V (Point u n)) (N (Point v n))
-> Point v n -> Point u n
forall a b.
Deformable a b =>
Deformation (V a) (V b) (N a) -> a -> b
deform Deformation v u n
Deformation (V (Point v n)) (V (Point u n)) (N (Point v n))
t
goodEnough :: (Metric v, Metric u, OrderedField n) => n -> Deformation v u n -> FixedSegment v n -> Bool
goodEnough :: n -> Deformation v u n -> FixedSegment v n -> Bool
goodEnough n
e Deformation v u n
t FixedSegment v n
s =
(n -> Bool) -> [n] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (n -> n -> Bool
forall a. Ord a => a -> a -> Bool
< n
e) [u n -> n
forall (f :: * -> *) a. (Metric f, Floating a) => f a -> a
norm (u n -> n) -> u n -> n
forall a b. (a -> b) -> a -> b
$ Deformation (V (Point v n)) (V (Point u n)) (N (Point v n))
-> Point v n -> Point u n
forall a b.
Deformable a b =>
Deformation (V a) (V b) (N a) -> a -> b
deform Deformation v u n
Deformation (V (Point v n)) (V (Point u n)) (N (Point v n))
t (FixedSegment v n
s FixedSegment v n
-> N (FixedSegment v n)
-> Codomain (FixedSegment v n) (N (FixedSegment v n))
forall p. Parametric p => p -> N p -> Codomain p (N p)
`atParam` n
N (FixedSegment v n)
u) Point u n -> Point u n -> Diff (Point u) n
forall (p :: * -> *) a. (Affine p, Num a) => p a -> p a -> Diff p a
.-. Deformation v u n -> FixedSegment v n -> FixedSegment u n
forall (v :: * -> *) (u :: * -> *) n.
Deformation v u n -> FixedSegment v n -> FixedSegment u n
approx Deformation v u n
t FixedSegment v n
s FixedSegment u n
-> N (FixedSegment u n)
-> Codomain (FixedSegment u n) (N (FixedSegment u n))
forall p. Parametric p => p -> N p -> Codomain p (N p)
`atParam` n
N (FixedSegment u n)
u
| n
u <- [n
0.25, n
0.5, n
0.75]]
instance (Metric v, Metric u, OrderedField n, r ~ Located (Trail u n))
=> Deformable (Located (Trail v n)) r where
deform' :: N (Located (Trail v n))
-> Deformation
(V (Located (Trail v n))) (V r) (N (Located (Trail v n)))
-> Located (Trail v n)
-> r
deform' N (Located (Trail v n))
eps Deformation
(V (Located (Trail v n))) (V r) (N (Located (Trail v n)))
p Located (Trail v n)
t
| Trail v n -> Bool
forall (v :: * -> *) n. Trail v n -> Bool
isLine (Trail v n -> Bool) -> Trail v n -> Bool
forall a b. (a -> b) -> a -> b
$ Located (Trail v n) -> Trail v n
forall a. Located a -> a
unLoc Located (Trail v n)
t = Trail u n
line Trail u n
-> Point (V (Trail u n)) (N (Trail u n)) -> Located (Trail u n)
forall a. a -> Point (V a) (N a) -> Located a
`at` Point u n
Point (V (Trail u n)) (N (Trail u n))
p0
| Bool
otherwise = Trail u n -> Trail u n
forall (v :: * -> *) n.
(Metric v, OrderedField n) =>
Trail v n -> Trail v n
glueTrail Trail u n
line Trail u n
-> Point (V (Trail u n)) (N (Trail u n)) -> Located (Trail u n)
forall a. a -> Point (V a) (N a) -> Located a
`at` Point u n
Point (V (Trail u n)) (N (Trail u n))
p0
where
segs :: [FixedSegment u n]
segs = (FixedSegment v n -> [FixedSegment u n])
-> [FixedSegment v n] -> [FixedSegment u n]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (n -> Deformation v u n -> FixedSegment v n -> [FixedSegment u n]
forall (v :: * -> *) (u :: * -> *) n.
(Metric v, Metric u, OrderedField n) =>
n -> Deformation v u n -> FixedSegment v n -> [FixedSegment u n]
deformSegment n
N (Located (Trail v n))
eps Deformation v u n
Deformation
(V (Located (Trail v n))) (V r) (N (Located (Trail v n)))
p) ([FixedSegment v n] -> [FixedSegment u n])
-> [FixedSegment v n] -> [FixedSegment u n]
forall a b. (a -> b) -> a -> b
$ Located (Trail v n) -> [FixedSegment v n]
forall (v :: * -> *) n.
(Metric v, OrderedField n) =>
Located (Trail v n) -> [FixedSegment v n]
fixTrail Located (Trail v n)
t
p0 :: Point u n
p0 = case [FixedSegment u n]
segs of
(FLinear Point u n
start Point u n
_:[FixedSegment u n]
_) -> Point u n
start
(FCubic Point u n
start Point u n
_ Point u n
_ Point u n
_:[FixedSegment u n]
_) -> Point u n
start
[FixedSegment u n]
_ -> Deformation (V (Point v n)) (V (Point u n)) (N (Point v n))
-> Point v n -> Point u n
forall a b.
Deformable a b =>
Deformation (V a) (V b) (N a) -> a -> b
deform Deformation (V (Point v n)) (V (Point u n)) (N (Point v n))
Deformation
(V (Located (Trail v n))) (V r) (N (Located (Trail v n)))
p (Located (Trail v n) -> Point (V (Trail v n)) (N (Trail v n))
forall a. Located a -> Point (V a) (N a)
loc Located (Trail v n)
t)
line :: Trail u n
line = [Segment Closed u n] -> Trail u n
forall (v :: * -> *) n.
(Metric v, OrderedField n) =>
[Segment Closed v n] -> Trail v n
trailFromSegments ([Segment Closed u n] -> Trail u n)
-> [Segment Closed u n] -> Trail u n
forall a b. (a -> b) -> a -> b
$ (FixedSegment u n -> Segment Closed u n)
-> [FixedSegment u n] -> [Segment Closed u n]
forall a b. (a -> b) -> [a] -> [b]
map (Located (Segment Closed u n) -> Segment Closed u n
forall a. Located a -> a
unLoc (Located (Segment Closed u n) -> Segment Closed u n)
-> (FixedSegment u n -> Located (Segment Closed u n))
-> FixedSegment u n
-> Segment Closed u n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FixedSegment u n -> Located (Segment Closed u n)
forall n (v :: * -> *).
(Num n, Additive v) =>
FixedSegment v n -> Located (Segment Closed v n)
fromFixedSeg) [FixedSegment u n]
segs
deform :: Deformation
(V (Located (Trail v n))) (V r) (N (Located (Trail v n)))
-> Located (Trail v n) -> r
deform Deformation
(V (Located (Trail v n))) (V r) (N (Located (Trail v n)))
p Located (Trail v n)
t = N (Located (Trail v n))
-> Deformation
(V (Located (Trail v n))) (V r) (N (Located (Trail v n)))
-> Located (Trail v n)
-> r
forall a b.
Deformable a b =>
N a -> Deformation (V a) (V b) (N a) -> a -> b
deform' (n
0.01 n -> n -> n
forall a. Num a => a -> a -> a
* n
extent) Deformation
(V (Located (Trail v n))) (V r) (N (Located (Trail v n)))
p Located (Trail v n)
t
where
extent :: n
extent = [n] -> n
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum ([n] -> n)
-> (Located (Trail v n) -> [n]) -> Located (Trail v n) -> n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Point v n -> n) -> [Point v n] -> [n]
forall a b. (a -> b) -> [a] -> [b]
map Point v n -> n
dist ([Point v n] -> [n])
-> (Located (Trail v n) -> [Point v n])
-> Located (Trail v n)
-> [n]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Located (Trail v n) -> [Point v n]
forall (v :: * -> *) n.
(Metric v, OrderedField n) =>
Located (Trail v n) -> [Point v n]
trailVertices (Located (Trail v n) -> n) -> Located (Trail v n) -> n
forall a b. (a -> b) -> a -> b
$ Located (Trail v n)
t
dist :: Point v n -> n
dist Point v n
pt = v n -> n
forall (f :: * -> *) a. (Metric f, Floating a) => f a -> a
norm (v n -> n) -> v n -> n
forall a b. (a -> b) -> a -> b
$ Point v n
pt Point v n -> Point v n -> Diff (Point v) n
forall (p :: * -> *) a. (Affine p, Num a) => p a -> p a -> Diff p a
.-. Located (Trail v n) -> Point (V (Trail v n)) (N (Trail v n))
forall a. Located a -> Point (V a) (N a)
loc Located (Trail v n)
t
instance (Metric v, Metric u, OrderedField n, r ~ Path u n) => Deformable (Path v n) r where
deform' :: N (Path v n)
-> Deformation (V (Path v n)) (V r) (N (Path v n)) -> Path v n -> r
deform' N (Path v n)
eps Deformation (V (Path v n)) (V r) (N (Path v n))
p = ASetter (Path v n) r (Located (Trail v n)) (Located (Trail u n))
-> (Located (Trail v n) -> Located (Trail u n)) -> Path v n -> r
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
over (([Located (Trail v n)] -> Identity [Located (Trail u n)])
-> Path v n -> Identity (Path u n)
forall s t. Rewrapping s t => Iso s t (Unwrapped s) (Unwrapped t)
_Wrapped (([Located (Trail v n)] -> Identity [Located (Trail u n)])
-> Path v n -> Identity (Path u n))
-> ((Located (Trail v n) -> Identity (Located (Trail u n)))
-> [Located (Trail v n)] -> Identity [Located (Trail u n)])
-> (Located (Trail v n) -> Identity (Located (Trail u n)))
-> Path v n
-> Identity (Path u n)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Located (Trail v n) -> Identity (Located (Trail u n)))
-> [Located (Trail v n)] -> Identity [Located (Trail u n)]
forall (f :: * -> *) a b. Functor f => Setter (f a) (f b) a b
mapped) (N (Located (Trail v n))
-> Deformation
(V (Located (Trail v n)))
(V (Located (Trail u n)))
(N (Located (Trail v n)))
-> Located (Trail v n)
-> Located (Trail u n)
forall a b.
Deformable a b =>
N a -> Deformation (V a) (V b) (N a) -> a -> b
deform' N (Located (Trail v n))
N (Path v n)
eps Deformation
(V (Located (Trail v n)))
(V (Located (Trail u n)))
(N (Located (Trail v n)))
Deformation (V (Path v n)) (V r) (N (Path v n))
p)
deform :: Deformation (V (Path v n)) (V r) (N (Path v n)) -> Path v n -> r
deform Deformation (V (Path v n)) (V r) (N (Path v n))
p = ASetter (Path v n) r (Located (Trail v n)) (Located (Trail u n))
-> (Located (Trail v n) -> Located (Trail u n)) -> Path v n -> r
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
over (([Located (Trail v n)] -> Identity [Located (Trail u n)])
-> Path v n -> Identity (Path u n)
forall s t. Rewrapping s t => Iso s t (Unwrapped s) (Unwrapped t)
_Wrapped (([Located (Trail v n)] -> Identity [Located (Trail u n)])
-> Path v n -> Identity (Path u n))
-> ((Located (Trail v n) -> Identity (Located (Trail u n)))
-> [Located (Trail v n)] -> Identity [Located (Trail u n)])
-> (Located (Trail v n) -> Identity (Located (Trail u n)))
-> Path v n
-> Identity (Path u n)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Located (Trail v n) -> Identity (Located (Trail u n)))
-> [Located (Trail v n)] -> Identity [Located (Trail u n)]
forall (f :: * -> *) a b. Functor f => Setter (f a) (f b) a b
mapped) (Deformation
(V (Located (Trail v n)))
(V (Located (Trail u n)))
(N (Located (Trail v n)))
-> Located (Trail v n) -> Located (Trail u n)
forall a b.
Deformable a b =>
Deformation (V a) (V b) (N a) -> a -> b
deform Deformation
(V (Located (Trail v n)))
(V (Located (Trail u n)))
(N (Located (Trail v n)))
Deformation (V (Path v n)) (V r) (N (Path v n))
p)