{-# LANGUAGE CPP #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
module Diagrams.Core.Envelope
(
Envelope(..)
, appEnvelope
, onEnvelope
, mkEnvelope
, pointEnvelope
, Enveloped(..)
, diameter
, radius
, extent
, size
, envelopeVMay
, envelopeV
, envelopePMay
, envelopeP
, envelopeSMay
, envelopeS
, OrderedField
) where
#if __GLASGOW_HASKELL__ < 710
import Control.Applicative ((<$>))
#endif
import Control.Lens (Rewrapped, Wrapped (..), iso, mapped,
op, over, (&), (.~), _Wrapping')
import Data.Functor.Rep
import qualified Data.Map as M
import Data.Maybe (fromMaybe)
import Data.Semigroup
import qualified Data.Set as S
import Diagrams.Core.HasOrigin
import Diagrams.Core.Points
import Diagrams.Core.Transform
import Diagrams.Core.V
import Linear.Metric
import Linear.Vector
newtype Envelope v n = Envelope (Maybe (v n -> Max n))
instance Wrapped (Envelope v n) where
type Unwrapped (Envelope v n) = Maybe (v n -> Max n)
_Wrapped' :: Iso' (Envelope v n) (Unwrapped (Envelope v n))
_Wrapped' = forall s a b t. (s -> a) -> (b -> t) -> Iso s t a b
iso (\(Envelope Maybe (v n -> Max n)
e) -> Maybe (v n -> Max n)
e) forall (v :: * -> *) n. Maybe (v n -> Max n) -> Envelope v n
Envelope
instance Rewrapped (Envelope v n) (Envelope v' n')
appEnvelope :: Envelope v n -> Maybe (v n -> n)
appEnvelope :: forall (v :: * -> *) n. Envelope v n -> Maybe (v n -> n)
appEnvelope (Envelope Maybe (v n -> Max n)
e) = (forall a. Max a -> a
getMax forall b c a. (b -> c) -> (a -> b) -> a -> c
.) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe (v n -> Max n)
e
onEnvelope :: ((v n -> n) -> v n -> n) -> Envelope v n -> Envelope v n
onEnvelope :: forall (v :: * -> *) n.
((v n -> n) -> v n -> n) -> Envelope v n -> Envelope v n
onEnvelope (v n -> n) -> v n -> n
t = forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
over (forall s. Wrapped s => (Unwrapped s -> s) -> Iso' s (Unwrapped s)
_Wrapping' forall (v :: * -> *) n. Maybe (v n -> Max n) -> Envelope v n
Envelope forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => Setter (f a) (f b) a b
mapped) ((forall a. a -> Max a
Max forall b c a. (b -> c) -> (a -> b) -> a -> c
.) forall b c a. (b -> c) -> (a -> b) -> a -> c
. (v n -> n) -> v n -> n
t forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall a. Max a -> a
getMax forall b c a. (b -> c) -> (a -> b) -> a -> c
.))
mkEnvelope :: (v n -> n) -> Envelope v n
mkEnvelope :: forall (v :: * -> *) n. (v n -> n) -> Envelope v n
mkEnvelope = forall (v :: * -> *) n. Maybe (v n -> Max n) -> Envelope v n
Envelope forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> Maybe a
Just forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall a. a -> Max a
Max forall b c a. (b -> c) -> (a -> b) -> a -> c
.)
pointEnvelope :: (Fractional n, Metric v) => Point v n -> Envelope v n
pointEnvelope :: forall n (v :: * -> *).
(Fractional n, Metric v) =>
Point v n -> Envelope v n
pointEnvelope Point v n
p = forall (v :: * -> *) n t.
(InSpace v n t, HasOrigin t) =>
Point v n -> t -> t
moveTo Point v n
p (forall (v :: * -> *) n. (v n -> n) -> Envelope v n
mkEnvelope forall a b. (a -> b) -> a -> b
$ forall a b. a -> b -> a
const n
0)
deriving instance Ord n => Semigroup (Envelope v n)
deriving instance Ord n => Monoid (Envelope v n)
type instance V (Envelope v n) = v
type instance N (Envelope v n) = n
instance Show (Envelope v n) where
show :: Envelope v n -> String
show Envelope v n
_ = String
"<envelope>"
instance (Metric v, Fractional n) => HasOrigin (Envelope v n) where
moveOriginTo :: Point (V (Envelope v n)) (N (Envelope v n))
-> Envelope v n -> Envelope v n
moveOriginTo (P V (Envelope v n) (N (Envelope v n))
u) = forall (v :: * -> *) n.
((v n -> n) -> v n -> n) -> Envelope v n -> Envelope v n
onEnvelope forall a b. (a -> b) -> a -> b
$ \v n -> n
oldEnv v n
v -> v n -> n
oldEnv v n
v forall a. Num a => a -> a -> a
- ((V (Envelope v n) (N (Envelope v n))
u forall (f :: * -> *) a.
(Functor f, Fractional a) =>
f a -> a -> f a
^/ (v n
v forall (f :: * -> *) a. (Metric f, Num a) => f a -> f a -> a
`dot` v n
v)) forall (f :: * -> *) a. (Metric f, Num a) => f a -> f a -> a
`dot` v n
v)
instance (Metric v, Floating n) => Transformable (Envelope v n) where
transform :: Transformation (V (Envelope v n)) (N (Envelope v n))
-> Envelope v n -> Envelope v n
transform Transformation (V (Envelope v n)) (N (Envelope v n))
t = forall t. HasOrigin t => Point (V t) (N t) -> t -> t
moveOriginTo (forall (f :: * -> *) a. f a -> Point f a
P forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a. (Functor f, Num a) => f a -> f a
negated forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> *) n. Transformation v n -> v n
transl forall a b. (a -> b) -> a -> b
$ Transformation (V (Envelope v n)) (N (Envelope v n))
t) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> *) n.
((v n -> n) -> v n -> n) -> Envelope v n -> Envelope v n
onEnvelope (v n -> n) -> v n -> n
g
where
g :: (v n -> n) -> v n -> n
g v n -> n
f v n
v = v n -> n
f v n
v' forall a. Fractional a => a -> a -> a
/ (v n
v' forall (f :: * -> *) a. (Metric f, Num a) => f a -> f a -> a
`dot` v n
vi)
where
v' :: v n
v' = forall (f :: * -> *) a. (Metric f, Floating a) => f a -> f a
signorm forall a b. (a -> b) -> a -> b
$ forall u v. (u :-: v) -> u -> v
lapp (forall (v :: * -> *) n. Transformation v n -> v n :-: v n
transp Transformation (V (Envelope v n)) (N (Envelope v n))
t) v n
v
vi :: v n
vi = forall (v :: * -> *) n. Transformation v n -> v n -> v n
apply (forall (v :: * -> *) n.
(Functor v, Num n) =>
Transformation v n -> Transformation v n
inv Transformation (V (Envelope v n)) (N (Envelope v n))
t) v n
v
type OrderedField s = (Floating s, Ord s)
class (Metric (V a), OrderedField (N a)) => Enveloped a where
getEnvelope :: a -> Envelope (V a) (N a)
instance (Metric v, OrderedField n) => Enveloped (Envelope v n) where
getEnvelope :: Envelope v n -> Envelope (V (Envelope v n)) (N (Envelope v n))
getEnvelope = forall a. a -> a
id
instance (OrderedField n, Metric v) => Enveloped (Point v n) where
getEnvelope :: Point v n -> Envelope (V (Point v n)) (N (Point v n))
getEnvelope Point v n
p = forall (v :: * -> *) n t.
(InSpace v n t, HasOrigin t) =>
Point v n -> t -> t
moveTo Point v n
p forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> *) n. (v n -> n) -> Envelope v n
mkEnvelope forall a b. (a -> b) -> a -> b
$ forall a b. a -> b -> a
const n
0
instance Enveloped t => Enveloped (TransInv t) where
getEnvelope :: TransInv t -> Envelope (V (TransInv t)) (N (TransInv t))
getEnvelope = forall a. Enveloped a => a -> Envelope (V a) (N a)
getEnvelope forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s. Wrapped s => (Unwrapped s -> s) -> s -> Unwrapped s
op forall t. t -> TransInv t
TransInv
instance (Enveloped a, Enveloped b, V a ~ V b, N a ~ N b) => Enveloped (a,b) where
getEnvelope :: (a, b) -> Envelope (V (a, b)) (N (a, b))
getEnvelope (a
x,b
y) = forall a. Enveloped a => a -> Envelope (V a) (N a)
getEnvelope a
x forall a. Semigroup a => a -> a -> a
<> forall a. Enveloped a => a -> Envelope (V a) (N a)
getEnvelope b
y
instance Enveloped b => Enveloped [b] where
getEnvelope :: [b] -> Envelope (V [b]) (N [b])
getEnvelope = 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 forall a. Enveloped a => a -> Envelope (V a) (N a)
getEnvelope
instance Enveloped b => Enveloped (M.Map k b) where
getEnvelope :: Map k b -> Envelope (V (Map k b)) (N (Map k b))
getEnvelope = 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 forall a. Enveloped a => a -> Envelope (V a) (N a)
getEnvelope forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k a. Map k a -> [a]
M.elems
instance Enveloped b => Enveloped (S.Set b) where
getEnvelope :: Set b -> Envelope (V (Set b)) (N (Set b))
getEnvelope = 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 forall a. Enveloped a => a -> Envelope (V a) (N a)
getEnvelope forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Set a -> [a]
S.elems
envelopeVMay :: Enveloped a => Vn a -> a -> Maybe (Vn a)
envelopeVMay :: forall a. Enveloped a => Vn a -> a -> Maybe (Vn a)
envelopeVMay Vn a
v = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((forall (f :: * -> *) a. (Functor f, Num a) => a -> f a -> f a
*^ Vn a
v) forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall a b. (a -> b) -> a -> b
$ Vn a
v)) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> *) n. Envelope v n -> Maybe (v n -> n)
appEnvelope forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Enveloped a => a -> Envelope (V a) (N a)
getEnvelope
envelopeV :: Enveloped a => Vn a -> a -> Vn a
envelopeV :: forall a. Enveloped a => Vn a -> a -> Vn a
envelopeV Vn a
v = forall a. a -> Maybe a -> a
fromMaybe forall (f :: * -> *) a. (Additive f, Num a) => f a
zero forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Enveloped a => Vn a -> a -> Maybe (Vn a)
envelopeVMay Vn a
v
envelopePMay :: (V a ~ v, N a ~ n, Enveloped a) => v n -> a -> Maybe (Point v n)
envelopePMay :: forall a (v :: * -> *) n.
(V a ~ v, N a ~ n, Enveloped a) =>
v n -> a -> Maybe (Point v n)
envelopePMay v n
v = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall (f :: * -> *) a. f a -> Point f a
P forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Enveloped a => Vn a -> a -> Maybe (Vn a)
envelopeVMay v n
v
envelopeP :: (V a ~ v, N a ~ n, Enveloped a) => v n -> a -> Point v n
envelopeP :: forall a (v :: * -> *) n.
(V a ~ v, N a ~ n, Enveloped a) =>
v n -> a -> Point v n
envelopeP v n
v = forall (f :: * -> *) a. f a -> Point f a
P forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Enveloped a => Vn a -> a -> Vn a
envelopeV v n
v
envelopeSMay :: (V a ~ v, N a ~ n, Enveloped a) => v n -> a -> Maybe n
envelopeSMay :: forall a (v :: * -> *) n.
(V a ~ v, N a ~ n, Enveloped a) =>
v n -> a -> Maybe n
envelopeSMay v n
v = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((forall a. Num a => a -> a -> a
* forall (f :: * -> *) a. (Metric f, Floating a) => f a -> a
norm v n
v) forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall a b. (a -> b) -> a -> b
$ v n
v)) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> *) n. Envelope v n -> Maybe (v n -> n)
appEnvelope forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Enveloped a => a -> Envelope (V a) (N a)
getEnvelope
envelopeS :: (V a ~ v, N a ~ n, Enveloped a) => v n -> a -> n
envelopeS :: forall a (v :: * -> *) n.
(V a ~ v, N a ~ n, Enveloped a) =>
v n -> a -> n
envelopeS v n
v = forall a. a -> Maybe a -> a
fromMaybe n
0 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a (v :: * -> *) n.
(V a ~ v, N a ~ n, Enveloped a) =>
v n -> a -> Maybe n
envelopeSMay v n
v
diameter :: (V a ~ v, N a ~ n, Enveloped a) => v n -> a -> n
diameter :: forall a (v :: * -> *) n.
(V a ~ v, N a ~ n, Enveloped a) =>
v n -> a -> n
diameter v n
v a
a = forall b a. b -> (a -> b) -> Maybe a -> b
maybe n
0 (\(n
lo,n
hi) -> (n
hi forall a. Num a => a -> a -> a
- n
lo) forall a. Num a => a -> a -> a
* forall (f :: * -> *) a. (Metric f, Floating a) => f a -> a
norm v n
v) (forall a (v :: * -> *) n.
(V a ~ v, N a ~ n, Enveloped a) =>
v n -> a -> Maybe (n, n)
extent v n
v a
a)
radius :: (V a ~ v, N a ~ n, Enveloped a) => v n -> a -> n
radius :: forall a (v :: * -> *) n.
(V a ~ v, N a ~ n, Enveloped a) =>
v n -> a -> n
radius v n
v = (n
0.5forall a. Num a => a -> a -> a
*) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a (v :: * -> *) n.
(V a ~ v, N a ~ n, Enveloped a) =>
v n -> a -> n
diameter v n
v
extent :: (V a ~ v, N a ~ n, Enveloped a) => v n -> a -> Maybe (n, n)
extent :: forall a (v :: * -> *) n.
(V a ~ v, N a ~ n, Enveloped a) =>
v n -> a -> Maybe (n, n)
extent v n
v a
a = (\v n -> n
f -> (-v n -> n
f (forall (f :: * -> *) a. (Functor f, Num a) => f a -> f a
negated v n
v), v n -> n
f v n
v)) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (forall (v :: * -> *) n. Envelope v n -> Maybe (v n -> n)
appEnvelope forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Enveloped a => a -> Envelope (V a) (N a)
getEnvelope forall a b. (a -> b) -> a -> b
$ a
a)
size :: (V a ~ v, N a ~ n, Enveloped a, HasBasis v) => a -> v n
size :: forall a (v :: * -> *) n.
(V a ~ v, N a ~ n, Enveloped a, HasBasis v) =>
a -> v n
size a
d = forall (f :: * -> *) a. Representable f => (Rep f -> a) -> f a
tabulate forall a b. (a -> b) -> a -> b
$ \(E forall x. Lens' (v x) x
l) -> forall a (v :: * -> *) n.
(V a ~ v, N a ~ n, Enveloped a) =>
v n -> a -> n
diameter (forall (f :: * -> *) a. (Additive f, Num a) => f a
zero forall a b. a -> (a -> b) -> b
& forall x. Lens' (v x) x
l forall s t a b. ASetter s t a b -> b -> s -> t
.~ n
1) a
d