{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE ViewPatterns #-}
{-# OPTIONS_GHC -fno-warn-unused-imports #-}
module Diagrams.TwoD.Offset
(
offsetSegment
, OffsetOpts(..), offsetJoin, offsetMiterLimit, offsetEpsilon
, offsetTrail
, offsetTrail'
, offsetPath
, offsetPath'
, ExpandOpts(..), expandJoin, expandMiterLimit, expandCap, expandEpsilon
, expandTrail
, expandTrail'
, expandPath
, expandPath'
) where
import Control.Applicative
import Control.Lens hiding (at)
import Prelude
import Data.Maybe (catMaybes)
import Data.Monoid
import Data.Monoid.Inf
import Data.Default.Class
import Diagrams.Core
import Diagrams.Attributes
import Diagrams.Direction
import Diagrams.Located
import Diagrams.Parametric
import Diagrams.Path
import Diagrams.Segment
import Diagrams.Trail hiding (isLoop, offset)
import Diagrams.TrailLike
import Diagrams.TwoD.Arc
import Diagrams.TwoD.Curvature
import Diagrams.TwoD.Path ()
import Diagrams.TwoD.Types
import Diagrams.TwoD.Vector hiding (e)
import Linear.Affine
import Linear.Metric
import Linear.Vector
unitPerp :: OrderedField n => V2 n -> V2 n
unitPerp :: forall n. OrderedField n => V2 n -> V2 n
unitPerp = forall (f :: * -> *) a. (Metric f, Floating a) => f a -> f a
signorm forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Num a => V2 a -> V2 a
perp
perpAtParam :: OrderedField n => Segment Closed V2 n -> n -> V2 n
perpAtParam :: forall n. OrderedField n => Segment Closed V2 n -> n -> V2 n
perpAtParam (Linear (OffsetClosed V2 n
a)) n
_ = forall (f :: * -> *) a. (Functor f, Num a) => f a -> f a
negated forall a b. (a -> b) -> a -> b
$ forall n. OrderedField n => V2 n -> V2 n
unitPerp V2 n
a
perpAtParam Segment Closed V2 n
cubic n
t = forall (f :: * -> *) a. (Functor f, Num a) => f a -> f a
negated forall a b. (a -> b) -> a -> b
$ forall n. OrderedField n => V2 n -> V2 n
unitPerp V2 n
a
where
(Cubic V2 n
a V2 n
_ Offset Closed V2 n
_) = forall a b. (a, b) -> b
snd forall a b. (a -> b) -> a -> b
$ forall p. Sectionable p => p -> N p -> (p, p)
splitAtParam Segment Closed V2 n
cubic n
t
data OffsetOpts d = OffsetOpts
{ forall d. OffsetOpts d -> LineJoin
_offsetJoin :: LineJoin
, forall d. OffsetOpts d -> d
_offsetMiterLimit :: d
, forall d. OffsetOpts d -> d
_offsetEpsilon :: d
}
deriving instance Eq d => Eq (OffsetOpts d)
deriving instance Show d => Show (OffsetOpts d)
makeLensesWith (lensRules & generateSignatures .~ False) ''OffsetOpts
offsetJoin :: Lens' (OffsetOpts d) LineJoin
offsetMiterLimit :: Lens' (OffsetOpts d) d
offsetEpsilon :: Lens' (OffsetOpts d) d
instance Fractional d => Default (OffsetOpts d) where
def :: OffsetOpts d
def = forall d. LineJoin -> d -> d -> OffsetOpts d
OffsetOpts forall a. Default a => a
def d
10 d
0.01
data ExpandOpts d = ExpandOpts
{ forall d. ExpandOpts d -> LineJoin
_expandJoin :: LineJoin
, forall d. ExpandOpts d -> d
_expandMiterLimit :: d
, forall d. ExpandOpts d -> LineCap
_expandCap :: LineCap
, forall d. ExpandOpts d -> d
_expandEpsilon :: d
} deriving (ExpandOpts d -> ExpandOpts d -> Bool
forall d. Eq d => ExpandOpts d -> ExpandOpts d -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ExpandOpts d -> ExpandOpts d -> Bool
$c/= :: forall d. Eq d => ExpandOpts d -> ExpandOpts d -> Bool
== :: ExpandOpts d -> ExpandOpts d -> Bool
$c== :: forall d. Eq d => ExpandOpts d -> ExpandOpts d -> Bool
Eq, Int -> ExpandOpts d -> ShowS
forall d. Show d => Int -> ExpandOpts d -> ShowS
forall d. Show d => [ExpandOpts d] -> ShowS
forall d. Show d => ExpandOpts d -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ExpandOpts d] -> ShowS
$cshowList :: forall d. Show d => [ExpandOpts d] -> ShowS
show :: ExpandOpts d -> String
$cshow :: forall d. Show d => ExpandOpts d -> String
showsPrec :: Int -> ExpandOpts d -> ShowS
$cshowsPrec :: forall d. Show d => Int -> ExpandOpts d -> ShowS
Show)
makeLensesWith (lensRules & generateSignatures .~ False) ''ExpandOpts
expandJoin :: Lens' (ExpandOpts d) LineJoin
expandMiterLimit :: Lens' (ExpandOpts d) d
expandCap :: Lens' (ExpandOpts d) LineCap
expandEpsilon :: Lens' (ExpandOpts d) d
instance (Fractional d) => Default (ExpandOpts d) where
def :: ExpandOpts d
def = forall d. LineJoin -> d -> LineCap -> d -> ExpandOpts d
ExpandOpts forall a. Default a => a
def d
10 forall a. Default a => a
def d
0.01
offsetSegment :: RealFloat n
=> n
-> n
-> Segment Closed V2 n
-> Located (Trail V2 n)
offsetSegment :: forall n.
RealFloat n =>
n -> n -> Segment Closed V2 n -> Located (Trail V2 n)
offsetSegment n
_ n
r s :: Segment Closed V2 n
s@(Linear (OffsetClosed V2 n
a)) = forall (v :: * -> *) n.
(Metric v, OrderedField n) =>
[Segment Closed v n] -> Trail v n
trailFromSegments [Segment Closed V2 n
s] forall a. a -> Point (V a) (N a) -> Located a
`at` 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
.+^ V2 n
va
where va :: V2 n
va = (-n
r) forall (f :: * -> *) a. (Functor f, Num a) => a -> f a -> f a
*^ forall n. OrderedField n => V2 n -> V2 n
unitPerp V2 n
a
offsetSegment n
epsilon n
r s :: Segment Closed V2 n
s@(Cubic V2 n
a V2 n
b (OffsetClosed V2 n
c)) = Trail V2 n
t forall a. a -> Point (V a) (N a) -> Located a
`at` 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
.+^ V2 n
va
where
t :: Trail V2 n
t = forall (v :: * -> *) n.
(Metric v, OrderedField n) =>
[Segment Closed v n] -> Trail v n
trailFromSegments (Inf Pos n -> [Segment Closed V2 n]
go (forall n. RealFloat n => Segment Closed V2 n -> n -> PosInf n
radiusOfCurvature Segment Closed V2 n
s n
0.5))
va :: V2 n
va = (-n
r) forall (f :: * -> *) a. (Functor f, Num a) => a -> f a -> f a
*^ forall n. OrderedField n => V2 n -> V2 n
unitPerp V2 n
a
vc :: V2 n
vc = (-n
r) forall (f :: * -> *) a. (Functor f, Num a) => a -> f a -> f a
*^ forall n. OrderedField n => V2 n -> V2 n
unitPerp (V2 n
c forall (f :: * -> *) a. (Additive f, Num a) => f a -> f a -> f a
^-^ V2 n
b)
ss :: [Segment Closed V2 n]
ss = (\(Segment Closed V2 n
x,Segment Closed V2 n
y) -> [Segment Closed V2 n
x,Segment Closed V2 n
y]) forall a b. (a -> b) -> a -> b
$ forall p. Sectionable p => p -> N p -> (p, p)
splitAtParam Segment Closed V2 n
s n
0.5
subdivided :: [Segment Closed V2 n]
subdivided = forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (forall (v :: * -> *) n.
(Metric v, OrderedField n) =>
Trail v n -> [Segment Closed v n]
trailSegments forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Located a -> a
unLoc forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall n.
RealFloat n =>
n -> n -> Segment Closed V2 n -> Located (Trail V2 n)
offsetSegment n
epsilon n
r) [Segment Closed V2 n]
ss
offset :: n -> Segment Closed V2 n
offset n
factor = forall (v :: * -> *) n. v n -> v n -> v n -> Segment Closed v n
bezier3 (V2 n
aforall (f :: * -> *) a. (Functor f, Num a) => f a -> a -> f a
^*n
factor) ((V2 n
b forall (f :: * -> *) a. (Additive f, Num a) => f a -> f a -> f a
^-^ V2 n
c)forall (f :: * -> *) a. (Functor f, Num a) => f a -> a -> f a
^*n
factor forall (f :: * -> *) a. (Additive f, Num a) => f a -> f a -> f a
^+^ V2 n
c forall (f :: * -> *) a. (Additive f, Num a) => f a -> f a -> f a
^+^ V2 n
vc forall (f :: * -> *) a. (Additive f, Num a) => f a -> f a -> f a
^-^ V2 n
va) (V2 n
c forall (f :: * -> *) a. (Additive f, Num a) => f a -> f a -> f a
^+^ V2 n
vc forall (f :: * -> *) a. (Additive f, Num a) => f a -> f a -> f a
^-^ V2 n
va)
go :: Inf Pos n -> [Segment Closed V2 n]
go (Finite n
0) = [Segment Closed V2 n]
subdivided
go Inf Pos n
roc
| Bool
close = [Segment Closed V2 n
o]
| Bool
otherwise = [Segment Closed V2 n]
subdivided
where
o :: Segment Closed V2 n
o = n -> Segment Closed V2 n
offset forall a b. (a -> b) -> a -> b
$ case Inf Pos n
roc of
Inf Pos n
Infinity -> n
1
Finite n
sr -> n
1 forall a. Num a => a -> a -> a
+ n
r forall a. Fractional a => a -> a -> a
/ n
sr
close :: Bool
close = forall (t :: * -> *). Foldable t => t Bool -> Bool
and [n
epsilon forall a. Num a => a -> a -> a
* forall a. Num a => a -> a
abs n
r forall a. Ord a => a -> a -> Bool
> forall (f :: * -> *) a. (Metric f, Floating a) => f a -> a
norm (Segment Closed V2 n
-> Codomain (Segment Closed V2 n) (N (Segment Closed V2 n))
p Segment Closed V2 n
o forall (f :: * -> *) a. (Additive f, Num a) => f a -> f a -> f a
^+^ V2 n
va forall (f :: * -> *) a. (Additive f, Num a) => f a -> f a -> f a
^-^ Segment Closed V2 n
-> Codomain (Segment Closed V2 n) (N (Segment Closed V2 n))
p Segment Closed V2 n
s forall (f :: * -> *) a. (Additive f, Num a) => f a -> f a -> f a
^-^ Segment Closed V2 n -> V2 n
pp Segment Closed V2 n
s)
| n
t' <- [n
0.25, n
0.5, n
0.75]
, let p :: Segment Closed V2 n
-> Codomain (Segment Closed V2 n) (N (Segment Closed V2 n))
p = (forall p. Parametric p => p -> N p -> Codomain p (N p)
`atParam` n
t')
, let pp :: Segment Closed V2 n -> V2 n
pp = (n
r forall (f :: * -> *) a. (Functor f, Num a) => a -> f a -> f a
*^) forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall n. OrderedField n => Segment Closed V2 n -> n -> V2 n
`perpAtParam` n
t')
]
bindLoc :: (Transformable b, V a ~ V b, N a ~ N b, V a ~ V2, N a ~ n, Num n) => (a -> b) -> Located a -> b
bindLoc :: forall b a n.
(Transformable b, V a ~ V b, N a ~ N b, V a ~ V2, N a ~ n,
Num n) =>
(a -> b) -> Located a -> b
bindLoc a -> b
f = forall {t}.
(Transformable t, Additive (V t), Num (N t)) =>
Located t -> t
join' forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. SameSpace a b => (a -> b) -> Located a -> Located b
mapLoc a -> b
f
where
join' :: Located t -> t
join' (forall a. Located a -> (Point (V a) (N a), a)
viewLoc -> (Point (V t) (N t)
p,t
a)) = forall t. Transformable t => Vn t -> t -> t
translate (Point (V t) (N t)
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) t
a
locatedTrailSegments :: OrderedField n
=> Located (Trail V2 n) -> [Located (Segment Closed V2 n)]
locatedTrailSegments :: forall n.
OrderedField n =>
Located (Trail V2 n) -> [Located (Segment Closed V2 n)]
locatedTrailSegments Located (Trail V2 n)
t = forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith forall a. a -> Point (V a) (N a) -> Located a
at (forall (v :: * -> *) n.
(Metric v, OrderedField n) =>
Trail v n -> [Segment Closed v n]
trailSegments (forall a. Located a -> a
unLoc Located (Trail V2 n)
t)) (forall (v :: * -> *) n.
(Metric v, OrderedField n) =>
Located (Trail v n) -> [Point v n]
trailPoints Located (Trail V2 n)
t)
offsetTrail' :: RealFloat n
=> OffsetOpts n
-> n
-> Located (Trail V2 n)
-> Located (Trail V2 n)
offsetTrail' :: forall n.
RealFloat n =>
OffsetOpts n -> n -> Located (Trail V2 n) -> Located (Trail V2 n)
offsetTrail' OffsetOpts n
opts n
r Located (Trail V2 n)
t = forall n.
RealFloat n =>
n
-> (n
-> n
-> Point V2 n
-> Located (Trail V2 n)
-> Located (Trail V2 n)
-> Trail V2 n)
-> Bool
-> n
-> n
-> [Point V2 n]
-> [Located (Trail V2 n)]
-> Located (Trail V2 n)
joinSegments n
eps n
-> n
-> Point V2 n
-> Located (Trail V2 n)
-> Located (Trail V2 n)
-> Trail V2 n
j Bool
isLoop (OffsetOpts n
optsforall s a. s -> Getting a s a -> a
^.forall d. Lens' (OffsetOpts d) d
offsetMiterLimit) n
r [Point V2 n]
ends forall b c a. (b -> c) -> (a -> b) -> a -> c
. Located (Trail V2 n) -> [Located (Trail V2 n)]
offset forall a b. (a -> b) -> a -> b
$ Located (Trail V2 n)
t
where
eps :: n
eps = OffsetOpts n
optsforall s a. s -> Getting a s a -> a
^.forall d. Lens' (OffsetOpts d) d
offsetEpsilon
offset :: Located (Trail V2 n) -> [Located (Trail V2 n)]
offset = forall a b. (a -> b) -> [a] -> [b]
map (forall b a n.
(Transformable b, V a ~ V b, N a ~ N b, V a ~ V2, N a ~ n,
Num n) =>
(a -> b) -> Located a -> b
bindLoc (forall n.
RealFloat n =>
n -> n -> Segment Closed V2 n -> Located (Trail V2 n)
offsetSegment n
eps n
r)) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall n.
OrderedField n =>
Located (Trail V2 n) -> [Located (Segment Closed V2 n)]
locatedTrailSegments
ends :: [Point V2 n]
ends | Bool
isLoop = (\(Point V2 n
a:[Point V2 n]
as) -> [Point V2 n]
as forall a. [a] -> [a] -> [a]
++ [Point V2 n
a]) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> *) n.
(Metric v, OrderedField n) =>
Located (Trail v n) -> [Point v n]
trailPoints forall a b. (a -> b) -> a -> b
$ Located (Trail V2 n)
t
| Bool
otherwise = forall a. [a] -> [a]
tail forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> *) n.
(Metric v, OrderedField n) =>
Located (Trail v n) -> [Point v n]
trailPoints forall a b. (a -> b) -> a -> b
$ Located (Trail V2 n)
t
j :: n
-> n
-> Point V2 n
-> Located (Trail V2 n)
-> Located (Trail V2 n)
-> Trail V2 n
j = forall n.
RealFloat n =>
LineJoin
-> n
-> n
-> Point V2 n
-> Located (Trail V2 n)
-> Located (Trail V2 n)
-> Trail V2 n
fromLineJoin (OffsetOpts n
optsforall s a. s -> Getting a s a -> a
^.forall d. Lens' (OffsetOpts d) LineJoin
offsetJoin)
isLoop :: Bool
isLoop = forall (v :: * -> *) n r.
(Trail' Line v n -> r) -> (Trail' Loop v n -> r) -> Trail v n -> r
withTrail (forall a b. a -> b -> a
const Bool
False) (forall a b. a -> b -> a
const Bool
True) (forall a. Located a -> a
unLoc Located (Trail V2 n)
t)
offsetTrail :: RealFloat n => n -> Located (Trail V2 n) -> Located (Trail V2 n)
offsetTrail :: forall n.
RealFloat n =>
n -> Located (Trail V2 n) -> Located (Trail V2 n)
offsetTrail = forall n.
RealFloat n =>
OffsetOpts n -> n -> Located (Trail V2 n) -> Located (Trail V2 n)
offsetTrail' forall a. Default a => a
def
offsetPath' :: RealFloat n => OffsetOpts n -> n -> Path V2 n -> Path V2 n
offsetPath' :: forall n.
RealFloat n =>
OffsetOpts n -> n -> Path V2 n -> Path V2 n
offsetPath' OffsetOpts n
opts n
r = 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 b a n.
(Transformable b, V a ~ V b, N a ~ N b, V a ~ V2, N a ~ n,
Num n) =>
(a -> b) -> Located a -> b
bindLoc (forall t. TrailLike t => Located (Trail (V t) (N t)) -> t
trailLike forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall n.
RealFloat n =>
OffsetOpts n -> n -> Located (Trail V2 n) -> Located (Trail V2 n)
offsetTrail' OffsetOpts n
opts n
r) forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall a. a -> Point (V a) (N a) -> Located a
`at` forall (f :: * -> *) a. (Additive f, Num a) => Point f a
origin))
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
offsetPath :: RealFloat n => n -> Path V2 n -> Path V2 n
offsetPath :: forall n. RealFloat n => n -> Path V2 n -> Path V2 n
offsetPath = forall n.
RealFloat n =>
OffsetOpts n -> n -> Path V2 n -> Path V2 n
offsetPath' forall a. Default a => a
def
withTrailL :: (Located (Trail' Line V2 n) -> r) -> (Located (Trail' Loop V2 n) -> r) -> Located (Trail V2 n) -> r
withTrailL :: forall n r.
(Located (Trail' Line V2 n) -> r)
-> (Located (Trail' Loop V2 n) -> r) -> Located (Trail V2 n) -> r
withTrailL Located (Trail' Line V2 n) -> r
f Located (Trail' Loop V2 n) -> r
g Located (Trail V2 n)
l = forall (v :: * -> *) n r.
(Trail' Line v n -> r) -> (Trail' Loop v n -> r) -> Trail v n -> r
withTrail (Located (Trail' Line V2 n) -> r
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall a. a -> Point (V a) (N a) -> Located a
`at` Point (V (Trail V2 n)) (N (Trail V2 n))
p)) (Located (Trail' Loop V2 n) -> r
g forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall a. a -> Point (V a) (N a) -> Located a
`at` Point (V (Trail V2 n)) (N (Trail V2 n))
p)) (forall a. Located a -> a
unLoc Located (Trail V2 n)
l)
where
p :: Point (V (Trail V2 n)) (N (Trail V2 n))
p = forall a. Located a -> Point (V a) (N a)
loc Located (Trail V2 n)
l
expandTrail' :: (OrderedField n, RealFloat n, RealFrac n)
=> ExpandOpts n
-> n
-> Located (Trail V2 n)
-> Path V2 n
expandTrail' :: forall n.
(OrderedField n, RealFloat n, RealFrac n) =>
ExpandOpts n -> n -> Located (Trail V2 n) -> Path V2 n
expandTrail' ExpandOpts n
o n
r Located (Trail V2 n)
t
| n
r forall a. Ord a => a -> a -> Bool
< n
0 = forall a. HasCallStack => String -> a
error String
"expandTrail' with negative radius"
| Bool
otherwise = forall n r.
(Located (Trail' Line V2 n) -> r)
-> (Located (Trail' Loop V2 n) -> r) -> Located (Trail V2 n) -> r
withTrailL (forall (v :: * -> *) n.
(Metric v, OrderedField n) =>
Located (Trail v n) -> Path v n
pathFromLocTrail forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall n.
RealFloat n =>
ExpandOpts n
-> n -> Located (Trail' Line V2 n) -> Located (Trail V2 n)
expandLine ExpandOpts n
o n
r) (forall n.
RealFloat n =>
ExpandOpts n -> n -> Located (Trail' Loop V2 n) -> Path V2 n
expandLoop ExpandOpts n
o n
r) Located (Trail V2 n)
t
expandLine :: RealFloat n => ExpandOpts n -> n -> Located (Trail' Line V2 n) -> Located (Trail V2 n)
expandLine :: forall n.
RealFloat n =>
ExpandOpts n
-> n -> Located (Trail' Line V2 n) -> Located (Trail V2 n)
expandLine ExpandOpts n
opts n
r (forall a b. SameSpace a b => (a -> b) -> Located a -> Located b
mapLoc forall (v :: * -> *) n. Trail' Line v n -> Trail v n
wrapLine -> Located (Trail V2 n)
t) = forall n.
RealFloat n =>
(n -> Point V2 n -> Point V2 n -> Point V2 n -> Trail V2 n)
-> n
-> Point V2 n
-> Point V2 n
-> Located (Trail V2 n)
-> Located (Trail V2 n)
-> Located (Trail V2 n)
caps n -> Point V2 n -> Point V2 n -> Point V2 n -> Trail V2 n
cap n
r Codomain (Located (Trail V2 n)) (N (Located (Trail V2 n)))
s Codomain (Located (Trail V2 n)) (N (Located (Trail V2 n)))
e (n -> Located (Trail V2 n)
f n
r) (n -> Located (Trail V2 n)
f forall a b. (a -> b) -> a -> b
$ -n
r)
where
eps :: n
eps = ExpandOpts n
optsforall s a. s -> Getting a s a -> a
^.forall d. Lens' (ExpandOpts d) d
expandEpsilon
offset :: n -> Located (Trail V2 n) -> [Located (Trail V2 n)]
offset n
r' = forall a b. (a -> b) -> [a] -> [b]
map (forall b a n.
(Transformable b, V a ~ V b, N a ~ N b, V a ~ V2, N a ~ n,
Num n) =>
(a -> b) -> Located a -> b
bindLoc (forall n.
RealFloat n =>
n -> n -> Segment Closed V2 n -> Located (Trail V2 n)
offsetSegment n
eps n
r')) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall n.
OrderedField n =>
Located (Trail V2 n) -> [Located (Segment Closed V2 n)]
locatedTrailSegments
f :: n -> Located (Trail V2 n)
f n
r' = forall n.
RealFloat n =>
n
-> (n
-> n
-> Point V2 n
-> Located (Trail V2 n)
-> Located (Trail V2 n)
-> Trail V2 n)
-> Bool
-> n
-> n
-> [Point V2 n]
-> [Located (Trail V2 n)]
-> Located (Trail V2 n)
joinSegments n
eps (forall n.
RealFloat n =>
LineJoin
-> n
-> n
-> Point V2 n
-> Located (Trail V2 n)
-> Located (Trail V2 n)
-> Trail V2 n
fromLineJoin (ExpandOpts n
optsforall s a. s -> Getting a s a -> a
^.forall d. Lens' (ExpandOpts d) LineJoin
expandJoin)) Bool
False (ExpandOpts n
optsforall s a. s -> Getting a s a -> a
^.forall d. Lens' (ExpandOpts d) d
expandMiterLimit) n
r' [Point V2 n]
ends
forall b c a. (b -> c) -> (a -> b) -> a -> c
. n -> Located (Trail V2 n) -> [Located (Trail V2 n)]
offset n
r' forall a b. (a -> b) -> a -> b
$ Located (Trail V2 n)
t
ends :: [Point V2 n]
ends = forall a. [a] -> [a]
tail forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> *) n.
(Metric v, OrderedField n) =>
Located (Trail v n) -> [Point v n]
trailPoints forall a b. (a -> b) -> a -> b
$ Located (Trail V2 n)
t
s :: Codomain (Located (Trail V2 n)) (N (Located (Trail V2 n)))
s = forall p. EndValues p => p -> Codomain p (N p)
atStart Located (Trail V2 n)
t
e :: Codomain (Located (Trail V2 n)) (N (Located (Trail V2 n)))
e = forall p. EndValues p => p -> Codomain p (N p)
atEnd Located (Trail V2 n)
t
cap :: n -> Point V2 n -> Point V2 n -> Point V2 n -> Trail V2 n
cap = forall n.
RealFloat n =>
LineCap
-> n -> Point V2 n -> Point V2 n -> Point V2 n -> Trail V2 n
fromLineCap (ExpandOpts n
optsforall s a. s -> Getting a s a -> a
^.forall d. Lens' (ExpandOpts d) LineCap
expandCap)
expandLoop :: RealFloat n => ExpandOpts n -> n -> Located (Trail' Loop V2 n) -> Path V2 n
expandLoop :: forall n.
RealFloat n =>
ExpandOpts n -> n -> Located (Trail' Loop V2 n) -> Path V2 n
expandLoop ExpandOpts n
opts n
r (forall a b. SameSpace a b => (a -> b) -> Located a -> Located b
mapLoc forall (v :: * -> *) n. Trail' Loop v n -> Trail v n
wrapLoop -> Located (Trail V2 n)
t) = forall t. TrailLike t => Located (Trail (V t) (N t)) -> t
trailLike (n -> Located (Trail V2 n)
f n
r) forall a. Semigroup a => a -> a -> a
<> (forall t. TrailLike t => Located (Trail (V t) (N t)) -> t
trailLike forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall p. Sectionable p => p -> p
reverseDomain forall b c a. (b -> c) -> (a -> b) -> a -> c
. n -> Located (Trail V2 n)
f forall a b. (a -> b) -> a -> b
$ -n
r)
where
eps :: n
eps = ExpandOpts n
optsforall s a. s -> Getting a s a -> a
^.forall d. Lens' (ExpandOpts d) d
expandEpsilon
offset :: n -> Located (Trail V2 n) -> [Located (Trail V2 n)]
offset n
r' = forall a b. (a -> b) -> [a] -> [b]
map (forall b a n.
(Transformable b, V a ~ V b, N a ~ N b, V a ~ V2, N a ~ n,
Num n) =>
(a -> b) -> Located a -> b
bindLoc (forall n.
RealFloat n =>
n -> n -> Segment Closed V2 n -> Located (Trail V2 n)
offsetSegment n
eps n
r')) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall n.
OrderedField n =>
Located (Trail V2 n) -> [Located (Segment Closed V2 n)]
locatedTrailSegments
f :: n -> Located (Trail V2 n)
f n
r' = forall n.
RealFloat n =>
n
-> (n
-> n
-> Point V2 n
-> Located (Trail V2 n)
-> Located (Trail V2 n)
-> Trail V2 n)
-> Bool
-> n
-> n
-> [Point V2 n]
-> [Located (Trail V2 n)]
-> Located (Trail V2 n)
joinSegments n
eps (forall n.
RealFloat n =>
LineJoin
-> n
-> n
-> Point V2 n
-> Located (Trail V2 n)
-> Located (Trail V2 n)
-> Trail V2 n
fromLineJoin (ExpandOpts n
optsforall s a. s -> Getting a s a -> a
^.forall d. Lens' (ExpandOpts d) LineJoin
expandJoin)) Bool
True (ExpandOpts n
optsforall s a. s -> Getting a s a -> a
^.forall d. Lens' (ExpandOpts d) d
expandMiterLimit) n
r' [Point V2 n]
ends
forall b c a. (b -> c) -> (a -> b) -> a -> c
. n -> Located (Trail V2 n) -> [Located (Trail V2 n)]
offset n
r' forall a b. (a -> b) -> a -> b
$ Located (Trail V2 n)
t
ends :: [Point V2 n]
ends = (\(Point V2 n
a:[Point V2 n]
as) -> [Point V2 n]
as forall a. [a] -> [a] -> [a]
++ [Point V2 n
a]) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> *) n.
(Metric v, OrderedField n) =>
Located (Trail v n) -> [Point v n]
trailPoints forall a b. (a -> b) -> a -> b
$ Located (Trail V2 n)
t
expandTrail :: RealFloat n => n -> Located (Trail V2 n) -> Path V2 n
expandTrail :: forall n. RealFloat n => n -> Located (Trail V2 n) -> Path V2 n
expandTrail = forall n.
(OrderedField n, RealFloat n, RealFrac n) =>
ExpandOpts n -> n -> Located (Trail V2 n) -> Path V2 n
expandTrail' forall a. Default a => a
def
expandPath' :: RealFloat n => ExpandOpts n -> n -> Path V2 n -> Path V2 n
expandPath' :: forall n.
RealFloat n =>
ExpandOpts n -> n -> Path V2 n -> Path V2 n
expandPath' ExpandOpts n
opts n
r = 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 b a n.
(Transformable b, V a ~ V b, N a ~ N b, V a ~ V2, N a ~ n,
Num n) =>
(a -> b) -> Located a -> b
bindLoc (forall n.
(OrderedField n, RealFloat n, RealFrac n) =>
ExpandOpts n -> n -> Located (Trail V2 n) -> Path V2 n
expandTrail' ExpandOpts n
opts n
r) forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall a. a -> Point (V a) (N a) -> Located a
`at` forall (f :: * -> *) a. (Additive f, Num a) => Point f a
origin))
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
expandPath :: RealFloat n => n -> Path V2 n -> Path V2 n
expandPath :: forall n. RealFloat n => n -> Path V2 n -> Path V2 n
expandPath = forall n.
RealFloat n =>
ExpandOpts n -> n -> Path V2 n -> Path V2 n
expandPath' forall a. Default a => a
def
caps :: RealFloat n => (n -> Point V2 n -> Point V2 n -> Point V2 n -> Trail V2 n)
-> n -> Point V2 n -> Point V2 n -> Located (Trail V2 n) -> Located (Trail V2 n) -> Located (Trail V2 n)
caps :: forall n.
RealFloat n =>
(n -> Point V2 n -> Point V2 n -> Point V2 n -> Trail V2 n)
-> n
-> Point V2 n
-> Point V2 n
-> Located (Trail V2 n)
-> Located (Trail V2 n)
-> Located (Trail V2 n)
caps n -> Point V2 n -> Point V2 n -> Point V2 n -> Trail V2 n
cap n
r Point V2 n
s Point V2 n
e Located (Trail V2 n)
fs Located (Trail V2 n)
bs = forall a b. SameSpace a b => (a -> b) -> Located a -> Located b
mapLoc forall (v :: * -> *) n.
(Metric v, OrderedField n) =>
Trail v n -> Trail v n
glueTrail forall a b. (a -> b) -> a -> b
$ forall a. Monoid a => [a] -> a
mconcat
[ n -> Point V2 n -> Point V2 n -> Point V2 n -> Trail V2 n
cap n
r Point V2 n
s (forall p. EndValues p => p -> Codomain p (N p)
atStart Located (Trail V2 n)
bs) (forall p. EndValues p => p -> Codomain p (N p)
atStart Located (Trail V2 n)
fs)
, forall a. Located a -> a
unLoc Located (Trail V2 n)
fs
, n -> Point V2 n -> Point V2 n -> Point V2 n -> Trail V2 n
cap n
r Point V2 n
e (forall p. EndValues p => p -> Codomain p (N p)
atEnd Located (Trail V2 n)
fs) (forall p. EndValues p => p -> Codomain p (N p)
atEnd Located (Trail V2 n)
bs)
, forall p. Sectionable p => p -> p
reverseDomain (forall a. Located a -> a
unLoc Located (Trail V2 n)
bs)
] forall a. a -> Point (V a) (N a) -> Located a
`at` forall p. EndValues p => p -> Codomain p (N p)
atStart Located (Trail V2 n)
bs
fromLineCap :: RealFloat n => LineCap -> n -> Point V2 n -> Point V2 n -> Point V2 n -> Trail V2 n
fromLineCap :: forall n.
RealFloat n =>
LineCap
-> n -> Point V2 n -> Point V2 n -> Point V2 n -> Trail V2 n
fromLineCap LineCap
c = case LineCap
c of
LineCap
LineCapButt -> forall n.
RealFloat n =>
n -> Point V2 n -> Point V2 n -> Point V2 n -> Trail V2 n
capCut
LineCap
LineCapRound -> forall n.
RealFloat n =>
n -> Point V2 n -> Point V2 n -> Point V2 n -> Trail V2 n
capArc
LineCap
LineCapSquare -> forall n.
RealFloat n =>
n -> Point V2 n -> Point V2 n -> Point V2 n -> Trail V2 n
capSquare
capCut :: RealFloat n => n -> Point V2 n -> Point V2 n -> Point V2 n -> Trail V2 n
capCut :: forall n.
RealFloat n =>
n -> Point V2 n -> Point V2 n -> Point V2 n -> Trail V2 n
capCut n
_r Point V2 n
_c Point V2 n
a Point V2 n
b = forall t. TrailLike t => [Segment Closed (V t) (N t)] -> t
fromSegments [forall (v :: * -> *) n. v n -> Segment Closed v n
straight (Point V2 n
b forall (p :: * -> *) a. (Affine p, Num a) => p a -> p a -> Diff p a
.-. Point V2 n
a)]
capSquare :: RealFloat n => n -> Point V2 n -> Point V2 n -> Point V2 n -> Trail V2 n
capSquare :: forall n.
RealFloat n =>
n -> Point V2 n -> Point V2 n -> Point V2 n -> Trail V2 n
capSquare n
_r Point V2 n
c Point V2 n
a Point V2 n
b = forall a. Located a -> a
unLoc forall a b. (a -> b) -> a -> b
$ forall t. TrailLike t => [Point (V t) (N t)] -> t
fromVertices [ Point V2 n
a, Point V2 n
a forall (p :: * -> *) a. (Affine p, Num a) => p a -> Diff p a -> p a
.+^ V2 n
v, Point V2 n
b forall (p :: * -> *) a. (Affine p, Num a) => p a -> Diff p a -> p a
.+^ V2 n
v, Point V2 n
b ]
where
v :: V2 n
v = forall a. Num a => V2 a -> V2 a
perp (Point V2 n
a forall (p :: * -> *) a. (Affine p, Num a) => p a -> p a -> Diff p a
.-. Point V2 n
c)
capArc :: RealFloat n => n -> Point V2 n -> Point V2 n -> Point V2 n -> Trail V2 n
capArc :: forall n.
RealFloat n =>
n -> Point V2 n -> Point V2 n -> Point V2 n -> Trail V2 n
capArc n
r Point V2 n
c Point V2 n
a Point V2 n
b = forall t. TrailLike t => Located (Trail (V t) (N t)) -> t
trailLike forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> *) n t.
(InSpace v n t, HasOrigin t) =>
Point v n -> t -> t
moveTo Point V2 n
c forall a b. (a -> b) -> a -> b
$ Located (Trail V2 n)
fs
where
fs :: Located (Trail V2 n)
fs | n
r forall a. Ord a => a -> a -> Bool
< n
0 = forall (v :: * -> *) n a.
(InSpace v n a, Eq n, Fractional n, Transformable a) =>
n -> a -> a
scale (-n
r) forall a b. (a -> b) -> a -> b
$ forall n t.
(InSpace V2 n t, RealFloat n, TrailLike t) =>
Direction V2 n -> Direction V2 n -> t
arcCW (forall (v :: * -> *) n.
(Additive v, Num n) =>
Point v n -> Point v n -> Direction v n
dirBetween Point V2 n
c Point V2 n
a) (forall (v :: * -> *) n.
(Additive v, Num n) =>
Point v n -> Point v n -> Direction v n
dirBetween Point V2 n
c Point V2 n
b)
| Bool
otherwise = forall (v :: * -> *) n a.
(InSpace v n a, Eq n, Fractional n, Transformable a) =>
n -> a -> a
scale n
r forall a b. (a -> b) -> a -> b
$ forall n t.
(InSpace V2 n t, RealFloat n, TrailLike t) =>
Direction V2 n -> Direction V2 n -> t
arcCCW (forall (v :: * -> *) n.
(Additive v, Num n) =>
Point v n -> Point v n -> Direction v n
dirBetween Point V2 n
c Point V2 n
a) (forall (v :: * -> *) n.
(Additive v, Num n) =>
Point v n -> Point v n -> Direction v n
dirBetween Point V2 n
c Point V2 n
b)
joinSegments :: RealFloat n
=> n
-> (n -> n -> Point V2 n -> Located (Trail V2 n) -> Located (Trail V2 n) -> Trail V2 n)
-> Bool
-> n
-> n
-> [Point V2 n]
-> [Located (Trail V2 n)]
-> Located (Trail V2 n)
joinSegments :: forall n.
RealFloat n =>
n
-> (n
-> n
-> Point V2 n
-> Located (Trail V2 n)
-> Located (Trail V2 n)
-> Trail V2 n)
-> Bool
-> n
-> n
-> [Point V2 n]
-> [Located (Trail V2 n)]
-> Located (Trail V2 n)
joinSegments n
_ n
-> n
-> Point V2 n
-> Located (Trail V2 n)
-> Located (Trail V2 n)
-> Trail V2 n
_ Bool
_ n
_ n
_ [Point V2 n]
_ [] = forall a. Monoid a => a
mempty forall a. a -> Point (V a) (N a) -> Located a
`at` forall (f :: * -> *) a. (Additive f, Num a) => Point f a
origin
joinSegments n
_ n
-> n
-> Point V2 n
-> Located (Trail V2 n)
-> Located (Trail V2 n)
-> Trail V2 n
_ Bool
_ n
_ n
_ [] [Located (Trail V2 n)]
_ = forall a. Monoid a => a
mempty forall a. a -> Point (V a) (N a) -> Located a
`at` forall (f :: * -> *) a. (Additive f, Num a) => Point f a
origin
joinSegments n
epsilon n
-> n
-> Point V2 n
-> Located (Trail V2 n)
-> Located (Trail V2 n)
-> Trail V2 n
j Bool
isLoop n
ml n
r [Point V2 n]
es ts :: [Located (Trail V2 n)]
ts@(Located (Trail V2 n)
t:[Located (Trail V2 n)]
_) = Located (Trail V2 n)
t'
where
t' :: Located (Trail V2 n)
t' | Bool
isLoop = forall a b. SameSpace a b => (a -> b) -> Located a -> Located b
mapLoc (forall (v :: * -> *) n.
(Metric v, OrderedField n) =>
Trail v n -> Trail v n
glueTrail forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall a. Semigroup a => a -> a -> a
<> [Maybe (Trail V2 n)] -> Trail V2 n
f (forall a. Int -> [a] -> [a]
take (forall (t :: * -> *) a. Foldable t => t a -> Int
length [Located (Trail V2 n)]
ts forall a. Num a => a -> a -> a
* Int
2 forall a. Num a => a -> a -> a
- Int
1) forall a b. (a -> b) -> a -> b
$ [Point V2 n] -> [Located (Trail V2 n)] -> [Maybe (Trail V2 n)]
ss [Point V2 n]
es ([Located (Trail V2 n)]
ts forall a. [a] -> [a] -> [a]
++ [Located (Trail V2 n)
t])))) Located (Trail V2 n)
t
| Bool
otherwise = forall a b. SameSpace a b => (a -> b) -> Located a -> Located b
mapLoc (forall a. Semigroup a => a -> a -> a
<> [Maybe (Trail V2 n)] -> Trail V2 n
f ([Point V2 n] -> [Located (Trail V2 n)] -> [Maybe (Trail V2 n)]
ss [Point V2 n]
es [Located (Trail V2 n)]
ts)) Located (Trail V2 n)
t
ss :: [Point V2 n] -> [Located (Trail V2 n)] -> [Maybe (Trail V2 n)]
ss [Point V2 n]
es' [Located (Trail V2 n)]
ts' = forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[Located (Trail V2 n)
-> Located (Trail V2 n) -> Trail V2 n -> Maybe (Trail V2 n)
test Located (Trail V2 n)
a Located (Trail V2 n)
b forall a b. (a -> b) -> a -> b
$ n
-> n
-> Point V2 n
-> Located (Trail V2 n)
-> Located (Trail V2 n)
-> Trail V2 n
j n
ml n
r Point V2 n
e Located (Trail V2 n)
a Located (Trail V2 n)
b, forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a. Located a -> a
unLoc Located (Trail V2 n)
b] | (Point V2 n
e,(Located (Trail V2 n)
a,Located (Trail V2 n)
b)) <- forall a b. [a] -> [b] -> [(a, b)]
zip [Point V2 n]
es' forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall a b. [a] -> [b] -> [(a, b)]
zip forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. [a] -> [a]
tail) forall a b. (a -> b) -> a -> b
$ [Located (Trail V2 n)]
ts']
test :: Located (Trail V2 n)
-> Located (Trail V2 n) -> Trail V2 n -> Maybe (Trail V2 n)
test Located (Trail V2 n)
a Located (Trail V2 n)
b Trail V2 n
tj
| forall p. EndValues p => p -> Codomain p (N p)
atStart Located (Trail V2 n)
b forall (f :: * -> *) a. (Metric f, Floating a) => f a -> f a -> a
`distance` forall p. EndValues p => p -> Codomain p (N p)
atEnd Located (Trail V2 n)
a forall a. Ord a => a -> a -> Bool
> n
epsilon = forall a. a -> Maybe a
Just Trail V2 n
tj
| Bool
otherwise = forall a. Maybe a
Nothing
f :: [Maybe (Trail V2 n)] -> Trail V2 n
f = forall a. Monoid a => [a] -> a
mconcat forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. [Maybe a] -> [a]
catMaybes
fromLineJoin
:: RealFloat n => LineJoin -> n -> n -> Point V2 n -> Located (Trail V2 n) -> Located (Trail V2 n) -> Trail V2 n
fromLineJoin :: forall n.
RealFloat n =>
LineJoin
-> n
-> n
-> Point V2 n
-> Located (Trail V2 n)
-> Located (Trail V2 n)
-> Trail V2 n
fromLineJoin LineJoin
j = case LineJoin
j of
LineJoin
LineJoinMiter -> forall n.
RealFloat n =>
n
-> n
-> Point V2 n
-> Located (Trail V2 n)
-> Located (Trail V2 n)
-> Trail V2 n
joinSegmentIntersect
LineJoin
LineJoinRound -> forall n.
RealFloat n =>
n
-> n
-> Point V2 n
-> Located (Trail V2 n)
-> Located (Trail V2 n)
-> Trail V2 n
joinSegmentArc
LineJoin
LineJoinBevel -> forall n.
RealFloat n =>
n
-> n
-> Point V2 n
-> Located (Trail V2 n)
-> Located (Trail V2 n)
-> Trail V2 n
joinSegmentClip
joinSegmentClip :: RealFloat n
=> n -> n -> Point V2 n -> Located (Trail V2 n) -> Located (Trail V2 n) -> Trail V2 n
joinSegmentClip :: forall n.
RealFloat n =>
n
-> n
-> Point V2 n
-> Located (Trail V2 n)
-> Located (Trail V2 n)
-> Trail V2 n
joinSegmentClip n
_ n
_ Point V2 n
_ Located (Trail V2 n)
a Located (Trail V2 n)
b = forall t. TrailLike t => [Segment Closed (V t) (N t)] -> t
fromSegments [forall (v :: * -> *) n. v n -> Segment Closed v n
straight forall a b. (a -> b) -> a -> b
$ forall p. EndValues p => p -> Codomain p (N p)
atStart Located (Trail V2 n)
b forall (p :: * -> *) a. (Affine p, Num a) => p a -> p a -> Diff p a
.-. forall p. EndValues p => p -> Codomain p (N p)
atEnd Located (Trail V2 n)
a]
joinSegmentArc :: RealFloat n
=> n -> n -> Point V2 n -> Located (Trail V2 n) -> Located (Trail V2 n) -> Trail V2 n
joinSegmentArc :: forall n.
RealFloat n =>
n
-> n
-> Point V2 n
-> Located (Trail V2 n)
-> Located (Trail V2 n)
-> Trail V2 n
joinSegmentArc n
_ n
r Point V2 n
e Located (Trail V2 n)
a Located (Trail V2 n)
b = forall n.
RealFloat n =>
n -> Point V2 n -> Point V2 n -> Point V2 n -> Trail V2 n
capArc n
r Point V2 n
e (forall p. EndValues p => p -> Codomain p (N p)
atEnd Located (Trail V2 n)
a) (forall p. EndValues p => p -> Codomain p (N p)
atStart Located (Trail V2 n)
b)
joinSegmentIntersect
:: RealFloat n => n -> n -> Point V2 n -> Located (Trail V2 n) -> Located (Trail V2 n) -> Trail V2 n
joinSegmentIntersect :: forall n.
RealFloat n =>
n
-> n
-> Point V2 n
-> Located (Trail V2 n)
-> Located (Trail V2 n)
-> Trail V2 n
joinSegmentIntersect n
miterLimit n
r Point V2 n
e Located (Trail V2 n)
a Located (Trail V2 n)
b =
if n
cross forall a. Ord a => a -> a -> Bool
< n
0.000001
then Trail V2 n
clip
else case forall n a.
(n ~ N a, Traced a, Num n) =>
Point (V a) n -> V a n -> a -> Maybe (Point (V a) n)
traceP Codomain (Located (Trail V2 n)) (N (Located (Trail V2 n)))
pa V2 n
va Located (Segment Closed V2 n)
t of
Maybe (Point (V (Located (Segment Closed V2 n))) n)
Nothing -> Trail V2 n
clip
Just Point (V (Located (Segment Closed V2 n))) n
p
| Point (V (Located (Segment Closed V2 n))) n
p forall (f :: * -> *) a. (Metric f, Floating a) => f a -> f a -> a
`distance` Codomain (Located (Trail V2 n)) (N (Located (Trail V2 n)))
pb forall a. Ord a => a -> a -> Bool
> forall a. Num a => a -> a
abs (n
miterLimit forall a. Num a => a -> a -> a
* n
r) -> Trail V2 n
clip
| Bool
otherwise -> forall a. Located a -> a
unLoc forall a b. (a -> b) -> a -> b
$ forall t. TrailLike t => [Point (V t) (N t)] -> t
fromVertices [ Codomain (Located (Trail V2 n)) (N (Located (Trail V2 n)))
pa, Point (V (Located (Segment Closed V2 n))) n
p, Codomain (Located (Trail V2 n)) (N (Located (Trail V2 n)))
pb ]
where
t :: Located (Segment Closed V2 n)
t = forall (v :: * -> *) n. v n -> Segment Closed v n
straight (V2 n -> V2 n
miter V2 n
vb) forall a. a -> Point (V a) (N a) -> Located a
`at` Codomain (Located (Trail V2 n)) (N (Located (Trail V2 n)))
pb
va :: V2 n
va = forall n. OrderedField n => V2 n -> V2 n
unitPerp (Codomain (Located (Trail V2 n)) (N (Located (Trail V2 n)))
pa forall (p :: * -> *) a. (Affine p, Num a) => p a -> p a -> Diff p a
.-. Point V2 n
e)
vb :: V2 n
vb = forall (f :: * -> *) a. (Functor f, Num a) => f a -> f a
negated forall a b. (a -> b) -> a -> b
$ forall n. OrderedField n => V2 n -> V2 n
unitPerp (Codomain (Located (Trail V2 n)) (N (Located (Trail V2 n)))
pb forall (p :: * -> *) a. (Affine p, Num a) => p a -> p a -> Diff p a
.-. Point V2 n
e)
pa :: Codomain (Located (Trail V2 n)) (N (Located (Trail V2 n)))
pa = forall p. EndValues p => p -> Codomain p (N p)
atEnd Located (Trail V2 n)
a
pb :: Codomain (Located (Trail V2 n)) (N (Located (Trail V2 n)))
pb = forall p. EndValues p => p -> Codomain p (N p)
atStart Located (Trail V2 n)
b
miter :: V2 n -> V2 n
miter V2 n
v = forall a. Num a => a -> a
abs (n
miterLimit forall a. Num a => a -> a -> a
* n
r) forall (f :: * -> *) a. (Functor f, Num a) => a -> f a -> f a
*^ V2 n
v
clip :: Trail V2 n
clip = forall n.
RealFloat n =>
n
-> n
-> Point V2 n
-> Located (Trail V2 n)
-> Located (Trail V2 n)
-> Trail V2 n
joinSegmentClip n
miterLimit n
r Point V2 n
e Located (Trail V2 n)
a Located (Trail V2 n)
b
cross :: n
cross = let (n
xa,n
ya) = forall n. V2 n -> (n, n)
unr2 V2 n
va; (n
xb,n
yb) = forall n. V2 n -> (n, n)
unr2 V2 n
vb in forall a. Num a => a -> a
abs (n
xa forall a. Num a => a -> a -> a
* n
yb forall a. Num a => a -> a -> a
- n
xb forall a. Num a => a -> a -> a
* n
ya)