{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
{-# OPTIONS_GHC -fno-warn-unused-imports #-}
module Diagrams.TwoD.Shapes
(
hrule, vrule
, regPoly
, triangle
, eqTriangle
, square
, pentagon
, hexagon
, heptagon
, septagon
, octagon
, nonagon
, decagon
, hendecagon
, dodecagon
, unitSquare
, rect
, roundedRect
, RoundedRectOpts(..), radiusTL, radiusTR, radiusBL, radiusBR
, roundedRect'
) where
import Control.Lens (makeLenses, op, (&), (.~), (<>~), (^.))
import Data.Default.Class
import Data.Semigroup
import Diagrams.Core
import Diagrams.Angle
import Diagrams.Located (at)
import Diagrams.Path
import Diagrams.Segment
import Diagrams.Trail
import Diagrams.TrailLike
import Diagrams.TwoD.Arc
import Diagrams.TwoD.Polygons
import Diagrams.TwoD.Transform
import Diagrams.TwoD.Types
import Diagrams.TwoD.Vector
import Diagrams.Util
hrule :: (InSpace V2 n t, TrailLike t) => n -> t
hrule :: forall n t. (InSpace V2 n t, TrailLike t) => n -> t
hrule n
d = forall t. TrailLike t => Located (Trail (V t) (N t)) -> t
trailLike forall a b. (a -> b) -> a -> b
$ forall (v :: * -> *) n.
(Metric v, OrderedField n) =>
[Segment Closed v n] -> Trail v n
trailFromSegments [forall (v :: * -> *) n. v n -> Segment Closed v n
straight forall a b. (a -> b) -> a -> b
$ forall n. (n, n) -> V2 n
r2 (n
d, n
0)] forall a. a -> Point (V a) (N a) -> Located a
`at` forall n. (n, n) -> P2 n
p2 (-n
dforall a. Fractional a => a -> a -> a
/n
2,n
0)
vrule :: (InSpace V2 n t, TrailLike t) => n -> t
vrule :: forall n t. (InSpace V2 n t, TrailLike t) => n -> t
vrule n
d = forall t. TrailLike t => Located (Trail (V t) (N t)) -> t
trailLike forall a b. (a -> b) -> a -> b
$ forall (v :: * -> *) n.
(Metric v, OrderedField n) =>
[Segment Closed v n] -> Trail v n
trailFromSegments [forall (v :: * -> *) n. v n -> Segment Closed v n
straight forall a b. (a -> b) -> a -> b
$ forall n. (n, n) -> V2 n
r2 (n
0, -n
d)] forall a. a -> Point (V a) (N a) -> Located a
`at` forall n. (n, n) -> P2 n
p2 (n
0,n
dforall a. Fractional a => a -> a -> a
/n
2)
unitSquare :: (InSpace V2 n t, TrailLike t) => t
unitSquare :: forall n t. (InSpace V2 n t, TrailLike t) => t
unitSquare = forall n t. (InSpace V2 n t, TrailLike t) => PolygonOpts n -> t
polygon (forall a. Default a => a
def forall a b. a -> (a -> b) -> b
& forall n. Lens' (PolygonOpts n) (PolyType n)
polyType forall s t a b. ASetter s t a b -> b -> s -> t
.~ forall n. Int -> n -> PolyType n
PolyRegular Int
4 (forall a. Floating a => a -> a
sqrt n
2 forall a. Fractional a => a -> a -> a
/ n
2)
forall a b. a -> (a -> b) -> b
& forall n. Lens' (PolygonOpts n) (PolyOrientation n)
polyOrient forall s t a b. ASetter s t a b -> b -> s -> t
.~ forall n. PolyOrientation n
OrientH)
square :: (InSpace V2 n t, TrailLike t) => n -> t
square :: forall n t. (InSpace V2 n t, TrailLike t) => n -> t
square n
d = forall n t. (InSpace V2 n t, TrailLike t) => n -> n -> t
rect n
d n
d
rect :: (InSpace V2 n t, TrailLike t) => n -> n -> t
rect :: forall n t. (InSpace V2 n t, TrailLike t) => n -> n -> t
rect n
w n
h = forall t. TrailLike t => Located (Trail (V t) (N t)) -> t
trailLike forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. [a] -> a
head forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s. Wrapped s => (Unwrapped s -> s) -> s -> Unwrapped s
op forall (v :: * -> *) n. [Located (Trail v n)] -> Path v n
Path forall a b. (a -> b) -> a -> b
$ forall n t. (InSpace V2 n t, TrailLike t) => t
unitSquare forall a b. a -> (a -> b) -> b
# forall (v :: * -> *) n t.
(InSpace v n t, R2 v, Fractional n, Transformable t) =>
n -> t -> t
scaleX n
w forall a b. a -> (a -> b) -> b
# forall (v :: * -> *) n t.
(InSpace v n t, R2 v, Fractional n, Transformable t) =>
n -> t -> t
scaleY n
h
regPoly :: (InSpace V2 n t, TrailLike t) => Int -> n -> t
regPoly :: forall n t. (InSpace V2 n t, TrailLike t) => Int -> n -> t
regPoly Int
n n
l = forall n t. (InSpace V2 n t, TrailLike t) => PolygonOpts n -> t
polygon (forall a. Default a => a
def forall a b. a -> (a -> b) -> b
& forall n. Lens' (PolygonOpts n) (PolyType n)
polyType forall s t a b. ASetter s t a b -> b -> s -> t
.~
forall n. [Angle n] -> [n] -> PolyType n
PolySides
(forall a. a -> [a]
repeat (n
1forall a. Fractional a => a -> a -> a
/forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
n forall b a. b -> AReview a b -> a
@@ forall n. Floating n => Iso' (Angle n) n
turn))
(forall a. Int -> a -> [a]
replicate (Int
nforall a. Num a => a -> a -> a
-Int
1) n
l)
forall a b. a -> (a -> b) -> b
& forall n. Lens' (PolygonOpts n) (PolyOrientation n)
polyOrient forall s t a b. ASetter s t a b -> b -> s -> t
.~ forall n. PolyOrientation n
OrientH
)
eqTriangle :: (InSpace V2 n t, TrailLike t) => n -> t
eqTriangle :: forall n t. (InSpace V2 n t, TrailLike t) => n -> t
eqTriangle = forall n t. (InSpace V2 n t, TrailLike t) => n -> t
triangle
triangle :: (InSpace V2 n t, TrailLike t) => n -> t
triangle :: forall n t. (InSpace V2 n t, TrailLike t) => n -> t
triangle = forall n t. (InSpace V2 n t, TrailLike t) => Int -> n -> t
regPoly Int
3
pentagon :: (InSpace V2 n t, TrailLike t) => n -> t
pentagon :: forall n t. (InSpace V2 n t, TrailLike t) => n -> t
pentagon = forall n t. (InSpace V2 n t, TrailLike t) => Int -> n -> t
regPoly Int
5
hexagon :: (InSpace V2 n t, TrailLike t) => n -> t
hexagon :: forall n t. (InSpace V2 n t, TrailLike t) => n -> t
hexagon = forall n t. (InSpace V2 n t, TrailLike t) => Int -> n -> t
regPoly Int
6
heptagon :: (InSpace V2 n t, TrailLike t) => n -> t
heptagon :: forall n t. (InSpace V2 n t, TrailLike t) => n -> t
heptagon = forall n t. (InSpace V2 n t, TrailLike t) => Int -> n -> t
regPoly Int
7
septagon :: (InSpace V2 n t, TrailLike t) => n -> t
septagon :: forall n t. (InSpace V2 n t, TrailLike t) => n -> t
septagon = forall n t. (InSpace V2 n t, TrailLike t) => n -> t
heptagon
octagon :: (InSpace V2 n t, TrailLike t) => n -> t
octagon :: forall n t. (InSpace V2 n t, TrailLike t) => n -> t
octagon = forall n t. (InSpace V2 n t, TrailLike t) => Int -> n -> t
regPoly Int
8
nonagon :: (InSpace V2 n t, TrailLike t) => n -> t
nonagon :: forall n t. (InSpace V2 n t, TrailLike t) => n -> t
nonagon = forall n t. (InSpace V2 n t, TrailLike t) => Int -> n -> t
regPoly Int
9
decagon :: (InSpace V2 n t, TrailLike t) => n -> t
decagon :: forall n t. (InSpace V2 n t, TrailLike t) => n -> t
decagon = forall n t. (InSpace V2 n t, TrailLike t) => Int -> n -> t
regPoly Int
10
hendecagon :: (InSpace V2 n t, TrailLike t) => n -> t
hendecagon :: forall n t. (InSpace V2 n t, TrailLike t) => n -> t
hendecagon = forall n t. (InSpace V2 n t, TrailLike t) => Int -> n -> t
regPoly Int
11
dodecagon :: (InSpace V2 n t, TrailLike t) => n -> t
dodecagon :: forall n t. (InSpace V2 n t, TrailLike t) => n -> t
dodecagon = forall n t. (InSpace V2 n t, TrailLike t) => Int -> n -> t
regPoly Int
12
data RoundedRectOpts d = RoundedRectOpts { forall d. RoundedRectOpts d -> d
_radiusTL :: d
, forall d. RoundedRectOpts d -> d
_radiusTR :: d
, forall d. RoundedRectOpts d -> d
_radiusBL :: d
, forall d. RoundedRectOpts d -> d
_radiusBR :: d
}
makeLenses ''RoundedRectOpts
instance (Num d) => Default (RoundedRectOpts d) where
def :: RoundedRectOpts d
def = forall d. d -> d -> d -> d -> RoundedRectOpts d
RoundedRectOpts d
0 d
0 d
0 d
0
roundedRect :: (InSpace V2 n t, TrailLike t, RealFloat n) => n -> n -> n -> t
roundedRect :: forall n t.
(InSpace V2 n t, TrailLike t, RealFloat n) =>
n -> n -> n -> t
roundedRect n
w n
h n
r = forall n t.
(InSpace V2 n t, TrailLike t, RealFloat n) =>
n -> n -> RoundedRectOpts n -> t
roundedRect' n
w n
h (forall a. Default a => a
def forall a b. a -> (a -> b) -> b
& forall d. Lens' (RoundedRectOpts d) d
radiusTL forall s t a b. ASetter s t a b -> b -> s -> t
.~ n
r
forall a b. a -> (a -> b) -> b
& forall d. Lens' (RoundedRectOpts d) d
radiusBR forall s t a b. ASetter s t a b -> b -> s -> t
.~ n
r
forall a b. a -> (a -> b) -> b
& forall d. Lens' (RoundedRectOpts d) d
radiusTR forall s t a b. ASetter s t a b -> b -> s -> t
.~ n
r
forall a b. a -> (a -> b) -> b
& forall d. Lens' (RoundedRectOpts d) d
radiusBL forall s t a b. ASetter s t a b -> b -> s -> t
.~ n
r)
roundedRect' :: (InSpace V2 n t, TrailLike t, RealFloat n) => n -> n -> RoundedRectOpts n -> t
roundedRect' :: forall n t.
(InSpace V2 n t, TrailLike t, RealFloat n) =>
n -> n -> RoundedRectOpts n -> t
roundedRect' n
w n
h RoundedRectOpts n
opts
= forall t. TrailLike t => Located (Trail (V t) (N t)) -> t
trailLike
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall a. a -> Point (V a) (N a) -> Located a
`at` forall n. (n, n) -> P2 n
p2 (n
wforall a. Fractional a => a -> a -> a
/n
2, forall a. Num a => a -> a
abs n
rBR forall a. Num a => a -> a -> a
- n
hforall a. Fractional a => a -> a -> a
/n
2))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall l (v :: * -> *) n. Trail' l v n -> Trail v n
wrapTrail
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
forall a b. (a -> b) -> a -> b
$ (n, n) -> Trail' Line V2 n
seg (n
0, n
h forall a. Num a => a -> a -> a
- forall a. Num a => a -> a
abs n
rTR forall a. Num a => a -> a -> a
- forall a. Num a => a -> a
abs n
rBR)
forall a. Semigroup a => a -> a -> a
<> forall {a}.
(V a ~ V2, TrailLike a, RealFloat (N a), Monoid a) =>
N a -> N a -> a
mkCorner n
0 n
rTR
forall a. Semigroup a => a -> a -> a
<> (n, n) -> Trail' Line V2 n
seg (forall a. Num a => a -> a
abs n
rTR forall a. Num a => a -> a -> a
+ forall a. Num a => a -> a
abs n
rTL forall a. Num a => a -> a -> a
- n
w, n
0)
forall a. Semigroup a => a -> a -> a
<> forall {a}.
(V a ~ V2, TrailLike a, RealFloat (N a), Monoid a) =>
N a -> N a -> a
mkCorner n
1 n
rTL
forall a. Semigroup a => a -> a -> a
<> (n, n) -> Trail' Line V2 n
seg (n
0, forall a. Num a => a -> a
abs n
rTL forall a. Num a => a -> a -> a
+ forall a. Num a => a -> a
abs n
rBL forall a. Num a => a -> a -> a
- n
h)
forall a. Semigroup a => a -> a -> a
<> forall {a}.
(V a ~ V2, TrailLike a, RealFloat (N a), Monoid a) =>
N a -> N a -> a
mkCorner n
2 n
rBL
forall a. Semigroup a => a -> a -> a
<> (n, n) -> Trail' Line V2 n
seg (n
w forall a. Num a => a -> a -> a
- forall a. Num a => a -> a
abs n
rBL forall a. Num a => a -> a -> a
- forall a. Num a => a -> a
abs n
rBR, n
0)
forall a. Semigroup a => a -> a -> a
<> forall {a}.
(V a ~ V2, TrailLike a, RealFloat (N a), Monoid a) =>
N a -> N a -> a
mkCorner n
3 n
rBR
where seg :: (n, n) -> Trail' Line V2 n
seg = forall (v :: * -> *) n.
(Metric v, OrderedField n) =>
[v n] -> Trail' Line v n
lineFromOffsets forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall a. a -> [a] -> [a]
:[]) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall n. (n, n) -> V2 n
r2
diag :: n
diag = forall a. Floating a => a -> a
sqrt (n
w forall a. Num a => a -> a -> a
* n
w forall a. Num a => a -> a -> a
+ n
h forall a. Num a => a -> a -> a
* n
h)
rTL :: n
rTL = Getting n (RoundedRectOpts n) n
-> Getting n (RoundedRectOpts n) n
-> Getting n (RoundedRectOpts n) n
-> Getting n (RoundedRectOpts n) n
-> n
clampCnr forall d. Lens' (RoundedRectOpts d) d
radiusTR forall d. Lens' (RoundedRectOpts d) d
radiusBL forall d. Lens' (RoundedRectOpts d) d
radiusBR forall d. Lens' (RoundedRectOpts d) d
radiusTL
rBL :: n
rBL = Getting n (RoundedRectOpts n) n
-> Getting n (RoundedRectOpts n) n
-> Getting n (RoundedRectOpts n) n
-> Getting n (RoundedRectOpts n) n
-> n
clampCnr forall d. Lens' (RoundedRectOpts d) d
radiusBR forall d. Lens' (RoundedRectOpts d) d
radiusTL forall d. Lens' (RoundedRectOpts d) d
radiusTR forall d. Lens' (RoundedRectOpts d) d
radiusBL
rTR :: n
rTR = Getting n (RoundedRectOpts n) n
-> Getting n (RoundedRectOpts n) n
-> Getting n (RoundedRectOpts n) n
-> Getting n (RoundedRectOpts n) n
-> n
clampCnr forall d. Lens' (RoundedRectOpts d) d
radiusTL forall d. Lens' (RoundedRectOpts d) d
radiusBR forall d. Lens' (RoundedRectOpts d) d
radiusBL forall d. Lens' (RoundedRectOpts d) d
radiusTR
rBR :: n
rBR = Getting n (RoundedRectOpts n) n
-> Getting n (RoundedRectOpts n) n
-> Getting n (RoundedRectOpts n) n
-> Getting n (RoundedRectOpts n) n
-> n
clampCnr forall d. Lens' (RoundedRectOpts d) d
radiusBL forall d. Lens' (RoundedRectOpts d) d
radiusTR forall d. Lens' (RoundedRectOpts d) d
radiusTL forall d. Lens' (RoundedRectOpts d) d
radiusBR
clampCnr :: Getting n (RoundedRectOpts n) n
-> Getting n (RoundedRectOpts n) n
-> Getting n (RoundedRectOpts n) n
-> Getting n (RoundedRectOpts n) n
-> n
clampCnr Getting n (RoundedRectOpts n) n
rx Getting n (RoundedRectOpts n) n
ry Getting n (RoundedRectOpts n) n
ro Getting n (RoundedRectOpts n) n
r = let (n
rx',n
ry',n
ro',n
r') = (RoundedRectOpts n
optsforall s a. s -> Getting a s a -> a
^.Getting n (RoundedRectOpts n) n
rx, RoundedRectOpts n
optsforall s a. s -> Getting a s a -> a
^.Getting n (RoundedRectOpts n) n
ry, RoundedRectOpts n
optsforall s a. s -> Getting a s a -> a
^.Getting n (RoundedRectOpts n) n
ro, RoundedRectOpts n
optsforall s a. s -> Getting a s a -> a
^.Getting n (RoundedRectOpts n) n
r)
in n -> n -> n
clampDiag n
ro' forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {a}. (Ord a, Fractional a) => a -> a -> a -> a
clampAdj n
h n
ry' forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {a}. (Ord a, Fractional a) => a -> a -> a -> a
clampAdj n
w n
rx' forall a b. (a -> b) -> a -> b
$ n
r'
clampAdj :: a -> a -> a -> a
clampAdj a
len a
adj a
r = if forall a. Num a => a -> a
abs a
r forall a. Ord a => a -> a -> Bool
> a
lenforall a. Fractional a => a -> a -> a
/a
2
then forall {a} {a}. (Ord a, Num a, Num a) => a -> a
sign a
r forall a. Num a => a -> a -> a
* forall a. Ord a => a -> a -> a
max (a
lenforall a. Fractional a => a -> a -> a
/a
2) (forall a. Ord a => a -> a -> a
min (a
len forall a. Num a => a -> a -> a
- forall a. Num a => a -> a
abs a
adj) (forall a. Num a => a -> a
abs a
r))
else a
r
clampDiag :: n -> n -> n
clampDiag n
opp n
r = if n
r forall a. Ord a => a -> a -> Bool
< n
0 Bool -> Bool -> Bool
&& n
opp forall a. Ord a => a -> a -> Bool
< n
0 Bool -> Bool -> Bool
&& forall a. Num a => a -> a
abs n
r forall a. Ord a => a -> a -> Bool
> n
diag forall a. Fractional a => a -> a -> a
/ n
2
then forall {a} {a}. (Ord a, Num a, Num a) => a -> a
sign n
r forall a. Num a => a -> a -> a
* forall a. Ord a => a -> a -> a
max (n
diag forall a. Fractional a => a -> a -> a
/ n
2) (forall a. Ord a => a -> a -> a
min (forall a. Num a => a -> a
abs n
r) (n
diag forall a. Num a => a -> a -> a
+ n
opp))
else n
r
sign :: a -> a
sign a
n = if a
n forall a. Ord a => a -> a -> Bool
< a
0 then -a
1 else a
1
mkCorner :: N a -> N a -> a
mkCorner N a
k N a
r | N a
r forall a. Eq a => a -> a -> Bool
== N a
0 = forall a. Monoid a => a
mempty
| N a
r forall a. Ord a => a -> a -> Bool
< N a
0 = N a -> N a -> a
doArc N a
3 (-N a
1)
| Bool
otherwise = N a -> N a -> a
doArc N a
0 N a
1
where
doArc :: N a -> N a -> a
doArc N a
d N a
s =
forall n t.
(InSpace V2 n t, OrderedField n, TrailLike t) =>
n -> Direction V2 n -> Angle n -> t
arc' N a
r (forall (v :: * -> *) n. (R1 v, Additive v, Num n) => Direction v n
xDir forall a b. a -> (a -> b) -> b
& forall (t :: * -> *) n.
(HasTheta t, RealFloat n) =>
Lens' (t n) (Angle n)
_theta forall a s t. Semigroup a => ASetter s t a a -> a -> s -> t
<>~ ((N a
kforall a. Num a => a -> a -> a
+N a
d)forall a. Fractional a => a -> a -> a
/N a
4 forall b a. b -> AReview a b -> a
@@ forall n. Floating n => Iso' (Angle n) n
turn)) (N a
sforall a. Fractional a => a -> a -> a
/N a
4 forall b a. b -> AReview a b -> a
@@ forall n. Floating n => Iso' (Angle n) n
turn)