{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
module Diagrams.TwoD.Model
(
showOrigin
, showOrigin'
, OriginOpts(..), oColor, oScale, oMinSize
, showEnvelope
, showEnvelope'
, EnvelopeOpts(..), eColor, eLineWidth, ePoints
, showTrace
, showTrace'
, TraceOpts(..), tColor, tScale, tMinSize, tPoints
, showLabels
) where
import Control.Arrow (second)
import Control.Lens (makeLenses, (^.))
import Data.Colour (Colour)
import Data.Colour.Names
import Data.Default.Class
import Data.List (intercalate)
import qualified Data.Map as M
import Data.Maybe (catMaybes)
import Data.Semigroup
import Diagrams.Attributes
import Diagrams.Combinators (atPoints)
import Diagrams.Core
import Diagrams.Core.Names
import Diagrams.CubicSpline
import Diagrams.Path
import Diagrams.TwoD.Attributes
import Diagrams.TwoD.Ellipse
import Diagrams.TwoD.Path
import Diagrams.TwoD.Text
import Diagrams.TwoD.Transform (rotateBy)
import Diagrams.TwoD.Types
import Diagrams.TwoD.Vector (unitX)
import Diagrams.Util
import Linear.Affine
import Linear.Vector
data OriginOpts n = OriginOpts
{ forall n. OriginOpts n -> Colour Double
_oColor :: Colour Double
, forall n. OriginOpts n -> n
_oScale :: n
, forall n. OriginOpts n -> n
_oMinSize :: n
}
makeLenses ''OriginOpts
instance Fractional n => Default (OriginOpts n) where
def :: OriginOpts n
def = forall n. Colour Double -> n -> n -> OriginOpts n
OriginOpts forall a. (Ord a, Floating a) => Colour a
red (n
1forall a. Fractional a => a -> a -> a
/n
50) n
0.001
data EnvelopeOpts n = EnvelopeOpts
{ forall n. EnvelopeOpts n -> Colour Double
_eColor :: Colour Double
, forall n. EnvelopeOpts n -> Measure n
_eLineWidth :: Measure n
, forall n. EnvelopeOpts n -> Int
_ePoints :: Int
}
makeLenses ''EnvelopeOpts
instance OrderedField n => Default (EnvelopeOpts n) where
def :: EnvelopeOpts n
def = forall n. Colour Double -> Measure n -> Int -> EnvelopeOpts n
EnvelopeOpts forall a. (Ord a, Floating a) => Colour a
red forall n. OrderedField n => Measure n
medium Int
32
data TraceOpts n = TraceOpts
{ forall n. TraceOpts n -> Colour Double
_tColor :: Colour Double
, forall n. TraceOpts n -> n
_tScale :: n
, forall n. TraceOpts n -> n
_tMinSize :: n
, forall n. TraceOpts n -> Int
_tPoints :: Int
}
makeLenses ''TraceOpts
instance Floating n => Default (TraceOpts n) where
def :: TraceOpts n
def = forall n. Colour Double -> n -> n -> Int -> TraceOpts n
TraceOpts forall a. (Ord a, Floating a) => Colour a
red (n
1forall a. Fractional a => a -> a -> a
/n
100) n
0.001 Int
64
showOrigin :: (TypeableFloat n, Renderable (Path V2 n) b, Monoid' m)
=> QDiagram b V2 n m -> QDiagram b V2 n m
showOrigin :: forall n b m.
(TypeableFloat n, Renderable (Path V2 n) b, Monoid' m) =>
QDiagram b V2 n m -> QDiagram b V2 n m
showOrigin = forall n b m.
(TypeableFloat n, Renderable (Path V2 n) b, Monoid' m) =>
OriginOpts n -> QDiagram b V2 n m -> QDiagram b V2 n m
showOrigin' forall a. Default a => a
def
showOrigin' :: (TypeableFloat n, Renderable (Path V2 n) b, Monoid' m)
=> OriginOpts n -> QDiagram b V2 n m -> QDiagram b V2 n m
showOrigin' :: forall n b m.
(TypeableFloat n, Renderable (Path V2 n) b, Monoid' m) =>
OriginOpts n -> QDiagram b V2 n m -> QDiagram b V2 n m
showOrigin' OriginOpts n
oo QDiagram b V2 n m
d = QDiagram b V2 n m
o forall a. Semigroup a => a -> a -> a
<> QDiagram b V2 n m
d
where o :: QDiagram b V2 n m
o = forall n b.
(TypeableFloat n, Renderable (Path V2 n) b) =>
Path V2 n -> QDiagram b V2 n Any
strokeP (forall t n.
(TrailLike t, V t ~ V2, N t ~ n, Transformable t) =>
n -> t
circle n
sz)
# fc (oo^.oColor)
# lw none
# fmap (const mempty)
V2 n
w n
h = OriginOpts n
ooforall s a. s -> Getting a s a -> a
^.forall n. Lens' (OriginOpts n) n
oScale forall (f :: * -> *) a. (Functor f, Num a) => a -> f a -> f a
*^ forall a (v :: * -> *) n.
(V a ~ v, N a ~ n, Enveloped a, HasBasis v) =>
a -> v n
size QDiagram b V2 n m
d
sz :: n
sz = forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum [n
w, n
h, OriginOpts n
ooforall s a. s -> Getting a s a -> a
^.forall n. Lens' (OriginOpts n) n
oMinSize]
showEnvelope' :: (Enum n, TypeableFloat n, Renderable (Path V2 n) b)
=> EnvelopeOpts n -> QDiagram b V2 n Any -> QDiagram b V2 n Any
showEnvelope' :: forall n b.
(Enum n, TypeableFloat n, Renderable (Path V2 n) b) =>
EnvelopeOpts n -> QDiagram b V2 n Any -> QDiagram b V2 n Any
showEnvelope' EnvelopeOpts n
opts QDiagram b V2 n Any
d = forall t (v :: * -> *) n.
(V t ~ v, N t ~ n, TrailLike t, Fractional (v n)) =>
Bool -> [Point v n] -> t
cubicSpline Bool
True [Point V2 n]
pts forall a b. a -> (a -> b) -> b
# forall n a.
(InSpace V2 n a, Typeable n, Floating n, HasStyle a) =>
Colour Double -> a -> a
lc (EnvelopeOpts n
optsforall s a. s -> Getting a s a -> a
^.forall n. Lens' (EnvelopeOpts n) (Colour Double)
eColor)
# lw w <> d
where
pts :: [Point V2 n]
pts = forall a. [Maybe a] -> [a]
catMaybes [forall a (v :: * -> *) n.
(V a ~ v, N a ~ n, Enveloped a) =>
v n -> a -> Maybe (Point v n)
envelopePMay V2 n
v QDiagram b V2 n Any
d | V2 n
v <- forall a b. (a -> b) -> [a] -> [b]
map (forall n t.
(InSpace V2 n t, Transformable t, Floating n) =>
n -> t -> t
`rotateBy` forall (v :: * -> *) n. (R1 v, Additive v, Num n) => v n
unitX) [n
0,n
inc..n
top]]
w :: Measure n
w = EnvelopeOpts n
opts forall s a. s -> Getting a s a -> a
^. forall n n.
Lens (EnvelopeOpts n) (EnvelopeOpts n) (Measure n) (Measure n)
eLineWidth
inc :: n
inc = n
1 forall a. Fractional a => a -> a -> a
/ forall a b. (Integral a, Num b) => a -> b
fromIntegral (EnvelopeOpts n
optsforall s a. s -> Getting a s a -> a
^.forall n. Lens' (EnvelopeOpts n) Int
ePoints)
top :: n
top = n
1 forall a. Num a => a -> a -> a
- n
inc
showEnvelope :: (Enum n, TypeableFloat n, Renderable (Path V2 n) b)
=> QDiagram b V2 n Any -> QDiagram b V2 n Any
showEnvelope :: forall n b.
(Enum n, TypeableFloat n, Renderable (Path V2 n) b) =>
QDiagram b V2 n Any -> QDiagram b V2 n Any
showEnvelope = forall n b.
(Enum n, TypeableFloat n, Renderable (Path V2 n) b) =>
EnvelopeOpts n -> QDiagram b V2 n Any -> QDiagram b V2 n Any
showEnvelope' forall a. Default a => a
def
showTrace' :: (Enum n, TypeableFloat n, Renderable (Path V2 n) b)
=> TraceOpts n -> QDiagram b V2 n Any -> QDiagram b V2 n Any
showTrace' :: forall n b.
(Enum n, TypeableFloat n, Renderable (Path V2 n) b) =>
TraceOpts n -> QDiagram b V2 n Any -> QDiagram b V2 n Any
showTrace' TraceOpts n
opts QDiagram b V2 n Any
d = forall (v :: * -> *) n a.
(InSpace v n a, HasOrigin a, Monoid' a) =>
[Point v n] -> [a] -> a
atPoints [Point V2 n]
ps (forall a. a -> [a]
repeat QDiagram b V2 n Any
pt) forall a. Semigroup a => a -> a -> a
<> QDiagram b V2 n Any
d
where
ps :: [Point V2 n]
ps = forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap forall {f :: * -> *} {a}.
(Additive f, Num a) =>
([a], f a) -> [Point f a]
p [([n], V2 n)]
ts
ts :: [([n], V2 n)]
ts = forall a b. [a] -> [b] -> [(a, b)]
zip [[n]]
rs [V2 n]
vs
p :: ([a], f a) -> [Point f a]
p ([a]
r, f a
v) = [forall (f :: * -> *) a. (Additive f, Num a) => Point f a
origin forall (p :: * -> *) a. (Affine p, Num a) => p a -> Diff p a -> p a
.+^ (a
s forall (f :: * -> *) a. (Functor f, Num a) => a -> f a -> f a
*^ f a
v) | a
s <- [a]
r]
vs :: [V2 n]
vs = forall a b. (a -> b) -> [a] -> [b]
map (forall n t.
(InSpace V2 n t, Transformable t, Floating n) =>
n -> t -> t
`rotateBy` forall (v :: * -> *) n. (R1 v, Additive v, Num n) => v n
unitX) [n
0, n
inc..n
top]
rs :: [[n]]
rs = [forall a. SortedList a -> [a]
getSortedList forall a b. (a -> b) -> a -> b
$ (forall (v :: * -> *) n.
Trace v n -> Point v n -> v n -> SortedList n
appTrace forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Traced a => a -> Trace (V a) (N a)
getTrace) QDiagram b V2 n Any
d forall (f :: * -> *) a. (Additive f, Num a) => Point f a
origin V2 n
v | V2 n
v <- [V2 n]
vs]
pt :: QDiagram b V2 n Any
pt = forall t n.
(TrailLike t, V t ~ V2, N t ~ n, Transformable t) =>
n -> t
circle n
sz forall a b. a -> (a -> b) -> b
# forall n a.
(InSpace V2 n a, Floating n, Typeable n, HasStyle a) =>
Colour Double -> a -> a
fc (TraceOpts n
optsforall s a. s -> Getting a s a -> a
^.forall n. Lens' (TraceOpts n) (Colour Double)
tColor) forall a b. a -> (a -> b) -> b
# forall a n.
(N a ~ n, HasStyle a, Typeable n) =>
Measure n -> a -> a
lw forall n. OrderedField n => Measure n
none
V2 n
w n
h = TraceOpts n
optsforall s a. s -> Getting a s a -> a
^.forall n. Lens' (TraceOpts n) n
tScale forall (f :: * -> *) a. (Functor f, Num a) => a -> f a -> f a
*^ forall a (v :: * -> *) n.
(V a ~ v, N a ~ n, Enveloped a, HasBasis v) =>
a -> v n
size QDiagram b V2 n Any
d
sz :: n
sz = forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum [n
w, n
h, TraceOpts n
optsforall s a. s -> Getting a s a -> a
^.forall n. Lens' (TraceOpts n) n
tMinSize]
inc :: n
inc = n
1 forall a. Fractional a => a -> a -> a
/ forall a b. (Integral a, Num b) => a -> b
fromIntegral (TraceOpts n
optsforall s a. s -> Getting a s a -> a
^.forall n. Lens' (TraceOpts n) Int
tPoints)
top :: n
top = n
1 forall a. Num a => a -> a -> a
- n
inc
showTrace :: (Enum n, TypeableFloat n, Renderable (Path V2 n) b)
=> QDiagram b V2 n Any -> QDiagram b V2 n Any
showTrace :: forall n b.
(Enum n, TypeableFloat n, Renderable (Path V2 n) b) =>
QDiagram b V2 n Any -> QDiagram b V2 n Any
showTrace = forall n b.
(Enum n, TypeableFloat n, Renderable (Path V2 n) b) =>
TraceOpts n -> QDiagram b V2 n Any -> QDiagram b V2 n Any
showTrace' forall a. Default a => a
def
showLabels :: (TypeableFloat n, Renderable (Text n) b, Semigroup m)
=> QDiagram b V2 n m -> QDiagram b V2 n Any
showLabels :: forall n b m.
(TypeableFloat n, Renderable (Text n) b, Semigroup m) =>
QDiagram b V2 n m -> QDiagram b V2 n Any
showLabels QDiagram b V2 n m
d =
( forall a. Monoid a => [a] -> a
mconcat
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map (\(Name
n,Point V2 n
p) -> forall n b.
(TypeableFloat n, Renderable (Text n) b) =>
String -> QDiagram b V2 n Any
text (Name -> String
simpleName Name
n) forall a b. a -> (a -> b) -> b
# forall t. Transformable t => Vn t -> t -> t
translate (Point V2 n
p forall (p :: * -> *) a. (Affine p, Num a) => p a -> p a -> Diff p a
.-. forall (f :: * -> *) a. (Additive f, Num a) => Point f a
origin))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (\(Name
n,[Point V2 n]
ps) -> forall a b. [a] -> [b] -> [(a, b)]
zip (forall a. a -> [a]
repeat Name
n) [Point V2 n]
ps)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall a b. (a -> b) -> [a] -> [b]
map forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (d, b) (d, c)
second forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map) forall (v :: * -> *) n b m.
(Additive v, Num n) =>
Subdiagram b v n m -> Point v n
location
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k a. Map k a -> [(k, a)]
M.assocs
forall a b. (a -> b) -> a -> b
$ Map Name [Subdiagram b V2 n m]
m
) forall a. Semigroup a => a -> a -> a
<>
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall a b. a -> b -> a
const (Bool -> Any
Any Bool
False)) QDiagram b V2 n m
d
where
SubMap Map Name [Subdiagram b V2 n m]
m = QDiagram b V2 n m
dforall s a. s -> Getting a s a -> a
^.forall (v :: * -> *) m n b.
(Metric v, Semigroup m, OrderedField n) =>
Lens' (QDiagram b v n m) (SubMap b v n m)
subMap
simpleName :: Name -> String
simpleName (Name [AName]
ns) = forall a. [a] -> [[a]] -> [a]
intercalate String
" .> " forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map AName -> String
simpleAName [AName]
ns
simpleAName :: AName -> String
simpleAName (AName a
n) = forall a. Show a => a -> String
show a
n