{-# LANGUAGE FlexibleContexts      #-}
{-# LANGUAGE FlexibleInstances     #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies          #-}
{-# LANGUAGE TypeSynonymInstances  #-}
-----------------------------------------------------------------------------
-- |
-- Module      :  Diagrams.TwoD.Path.Turtle
-- Copyright   :  (c) 2011 Michael Sloan
-- License     :  BSD-style (see LICENSE)
-- Maintainer  :  Michael Sloan <mgsloan at gmail>,  Deepak Jois <deepak.jois@gmail.com>
-- Authors     :  Michael Sloan <mgsloan at gmail>, Deepak Jois <deepak.jois@gmail.com>
--
-- A module consisting of core types and functions to represent and operate on
-- a \"turtle\".
--
-- More info about turtle graphics:
-- <http://en.wikipedia.org/wiki/Turtle_graphics>
--
-----------------------------------------------------------------------------

module Diagrams.TwoD.Path.Turtle.Internal
  (
    -- * Turtle data types and accessors
    TurtleState(..), TurtlePath(..), PenStyle(..)

    -- * Motion commands
  , forward, backward, left, right

    -- * Pen style commands
  , setPenColor, setPenColour, setPenWidth

    -- * State setters
  , startTurtle, setHeading, towards
  , setPenPos

    -- * Drawing control
  , penUp, penDown, penHop, closeCurrent

    -- * Diagram related
  , getTurtleDiagram
  , getTurtlePath
  ) where

import           Diagrams.Prelude

-- | Style attributes associated with the turtle pen
data PenStyle n = PenStyle
  { forall n. PenStyle n -> Measure n
penWidth :: Measure n -- ^ Width of pen. Default is 1.0
  , forall n. PenStyle n -> Colour Double
penColor :: Colour Double  -- ^ Color of pen. Default is @black@
  }

-- | Turtle path type that captures a list of paths and the style attributes
-- associated with them
data TurtlePath n = TurtlePath
  { forall n. TurtlePath n -> PenStyle n
penStyle    :: PenStyle n            -- ^ Style
  , forall n. TurtlePath n -> Located (Trail V2 n)
turtleTrail :: Located (Trail V2 n)  -- ^ Path
  }

-- | Core turtle data type. A turtle needs to keep track of its current
-- position, like its position, heading etc., and all the paths that it has
-- traversed so far.
--
-- We need to record a new path, everytime an attribute like style, pen position
-- etc changes, so that we can separately track styles for each portion of the
-- eventual path that the turtle took.
data TurtleState n = TurtleState
  { -- | State of the pen. @False@ means that turtle movements will not draw
    -- anything
    forall n. TurtleState n -> Bool
isPenDown    :: Bool
     -- | Current position. This is updated everytime the turtle moves
  , forall n. TurtleState n -> P2 n
penPos       :: P2 n
     -- | Orientation of the turtle in 2D space, given in degrees
  , forall n. TurtleState n -> Angle n
heading      :: Angle n
     -- | Path traversed by the turtle so far, without any style or pen
     -- attributes changing
  , forall n. TurtleState n -> Located (Trail' Line V2 n)
currTrail    :: Located (Trail' Line V2 n)
     -- | Current style of the pen
  , forall n. TurtleState n -> PenStyle n
currPenStyle :: PenStyle n
     -- | List of paths along with style information, traversed by the turtle
     -- previously
  , forall n. TurtleState n -> [TurtlePath n]
paths        :: [TurtlePath n]
  }

-- | Default pen style, with @penWidth@ set to 1.0 and @penColor@ set to black
defaultPenStyle :: (Floating n, Ord n) => PenStyle n
defaultPenStyle :: forall n. (Floating n, Ord n) => PenStyle n
defaultPenStyle = forall n. Measure n -> Colour Double -> PenStyle n
PenStyle (forall n. Num n => n -> Measure n
normalized n
0.004 forall n. Ord n => Measure n -> Measure n -> Measure n
`atLeast` forall n. n -> Measure n
output n
0.5) forall a. Num a => Colour a
black

-- | The initial state of turtle. The turtle is located at the origin, at an
-- orientation of 0 degrees with its pen position down. The pen style is
-- @defaultPenStyle@.
startTurtle :: (Floating n, Ord n) => TurtleState n
startTurtle :: forall n. (Floating n, Ord n) => TurtleState n
startTurtle = forall n.
Bool
-> P2 n
-> Angle n
-> Located (Trail' Line V2 n)
-> PenStyle n
-> [TurtlePath n]
-> TurtleState n
TurtleState Bool
True forall (f :: * -> *) a. (Additive f, Num a) => Point f a
origin forall (f :: * -> *) a. (Additive f, Num a) => f a
zero (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) forall n. (Floating n, Ord n) => PenStyle n
defaultPenStyle []

-- | Draw a segment along the turtle’s path and update its position. If the pen
-- is up, only the position is updated.
moveTurtle :: (Floating n, Ord n) => Segment Closed V2 n -- ^ Segment representing the path to travel
           -> TurtleState n       -- ^ Turtle to move
           -> TurtleState n       -- ^ Resulting turtle
moveTurtle :: forall n.
(Floating n, Ord n) =>
Segment Closed V2 n -> TurtleState n -> TurtleState n
moveTurtle Segment Closed V2 n
s t :: TurtleState n
t@(TurtleState Bool
pd P2 n
pos Angle n
h Located (Trail' Line V2 n)
tr PenStyle n
_ [TurtlePath n]
_) =
 if Bool
pd
   -- Add segment to current trail and update position
   then TurtleState n
t { currTrail :: Located (Trail' Line V2 n)
currTrail = Located (Trail' Line V2 n)
newTrail
          , penPos :: P2 n
penPos = P2 n
newPenPos
          }
   -- Update position only
   else TurtleState n
t { penPos :: P2 n
penPos = P2 n
newPenPos }
 where
   -- Rotate segment by orientation before adding to trail
   rotatedSeg :: Segment Closed V2 n
rotatedSeg  =  forall n t.
(InSpace V2 n t, Transformable t, Floating n) =>
Angle n -> t -> t
rotate Angle n
h Segment Closed V2 n
s
   newTrail :: Located (Trail' Line V2 n)
newTrail    =  forall a b. SameSpace a b => (a -> b) -> Located a -> Located b
mapLoc (forall a. Semigroup a => a -> a -> a
<> forall t. TrailLike t => [Segment Closed (V t) (N t)] -> t
fromSegments [Segment Closed V2 n
rotatedSeg]) Located (Trail' Line V2 n)
tr
   -- Calculate the new position along the segment
   newPenPos :: P2 n
newPenPos   =  P2 n
pos forall (p :: * -> *) a. (Affine p, Num a) => p a -> Diff p a -> p a
.+^ forall (v :: * -> *) n. Segment Closed v n -> v n
segOffset Segment Closed V2 n
rotatedSeg

-- | Move the turtle forward by @x@ units
forward :: (Floating n, Ord n) => n -- ^ Distance to move
        -> TurtleState n  -- ^ Turtle to move
        -> TurtleState n -- ^ Resulting turtle
forward :: forall n.
(Floating n, Ord n) =>
n -> TurtleState n -> TurtleState n
forward n
x = forall n.
(Floating n, Ord n) =>
Segment Closed V2 n -> TurtleState n -> TurtleState n
moveTurtle (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
x,n
0))

-- | Move the turtle backward by @x@ units
backward :: (Floating n, Ord n) => n -- ^ Distance to move
         -> TurtleState n -- ^ Turtle to move
         -> TurtleState n -- ^ Resulting turtle
backward :: forall n.
(Floating n, Ord n) =>
n -> TurtleState n -> TurtleState n
backward n
x = forall n.
(Floating n, Ord n) =>
Segment Closed V2 n -> TurtleState n -> TurtleState n
moveTurtle (forall (v :: * -> *) n. v n -> Segment Closed v n
straight forall a b. (a -> b) -> a -> b
$ forall n. (n, n) -> V2 n
r2 (forall a. Num a => a -> a
negate n
x, n
0))

-- | Turn the turtle by applying the given function to its current orientation
-- (in degrees)
turnTurtle :: (Angle n -> Angle n)   -- ^ Transformation to apply on current orientation
           -> TurtleState n    -- ^ Turtle to turn
           -> TurtleState n    -- ^ Resulting turtle
turnTurtle :: forall n. (Angle n -> Angle n) -> TurtleState n -> TurtleState n
turnTurtle Angle n -> Angle n
f t :: TurtleState n
t@(TurtleState Bool
_ P2 n
_ Angle n
h Located (Trail' Line V2 n)
_ PenStyle n
_ [TurtlePath n]
_) = TurtleState n
t { heading :: Angle n
heading = Angle n -> Angle n
f Angle n
h  }

-- | Turn the turtle anti-clockwise (left)
left :: Floating n
     => n              -- ^ Degree of turn
     -> TurtleState n  -- ^ Turtle to turn
     -> TurtleState n  -- ^ Resulting turtle
left :: forall n. Floating n => n -> TurtleState n -> TurtleState n
left n
d = forall n. (Angle n -> Angle n) -> TurtleState n -> TurtleState n
turnTurtle (forall (f :: * -> *) a. (Additive f, Num a) => f a -> f a -> f a
^+^ (n
d forall b a. b -> AReview a b -> a
@@ forall n. Floating n => Iso' (Angle n) n
deg))

-- | Turn the turtle clockwise (right)
right :: Floating n
      => n              -- ^ Degree of turn
      -> TurtleState n  -- ^ Turtle to turn
      -> TurtleState n  -- ^ Resulting turtle
right :: forall n. Floating n => n -> TurtleState n -> TurtleState n
right n
d = forall n. (Angle n -> Angle n) -> TurtleState n -> TurtleState n
turnTurtle (forall (f :: * -> *) a. (Additive f, Num a) => f a -> f a -> f a
^-^ (n
d forall b a. b -> AReview a b -> a
@@ forall n. Floating n => Iso' (Angle n) n
deg))

-- | Turn the turtle to the given orientation, in degrees
setHeading :: Floating n
           => n              -- ^ Degree of orientation
           -> TurtleState n  -- ^ Turtle to orient
           -> TurtleState n  -- ^ Resulting turtle
setHeading :: forall n. Floating n => n -> TurtleState n -> TurtleState n
setHeading n
d = forall n. (Angle n -> Angle n) -> TurtleState n -> TurtleState n
turnTurtle (forall a b. a -> b -> a
const forall a b. (a -> b) -> a -> b
$ n
d forall b a. b -> AReview a b -> a
@@ forall n. Floating n => Iso' (Angle n) n
deg)

-- | Sets the turtle orientation towards a given location.
towards :: RealFloat n =>
           P2 n           -- ^ Point to orient turtle towards
        -> TurtleState n  -- ^ Turtle to orient
        -> TurtleState n  -- ^ Resulting turtle
towards :: forall n. RealFloat n => P2 n -> TurtleState n -> TurtleState n
towards P2 n
p  = forall n. Floating n => n -> TurtleState n -> TurtleState n
setHeading forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< (n
360 forall a. Num a => a -> a -> a
*) forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall a. Fractional a => a -> a -> a
/ forall a. Floating a => a
tau) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry forall a. RealFloat a => a -> a -> a
atan2 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall n. V2 n -> (n, n)
unr2 forall b c a. (b -> c) -> (a -> b) -> a -> c
. (P2 n
p forall (p :: * -> *) a. (Affine p, Num a) => p a -> p a -> Diff p a
.-.) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall n. TurtleState n -> P2 n
penPos

-- | Puts the turtle pen in “Up” mode. Turtle movements will not draw anything
--
-- Does nothing if the pen was already up. Otherwise, it creates a turtle with
-- the current trail added to @paths@.
penUp :: (Ord n, Floating n) => TurtleState n  -- ^ Turtle to modify
      -> TurtleState n  -- ^ Resulting turtle
penUp :: forall n. (Ord n, Floating n) => TurtleState n -> TurtleState n
penUp TurtleState n
t
 | forall n. TurtleState n -> Bool
isPenDown TurtleState n
t = TurtleState n
t forall a b. a -> (a -> b) -> b
# forall n. (Ord n, Floating n) => TurtleState n -> TurtleState n
makeNewTrail forall a b. a -> (a -> b) -> b
#  \TurtleState n
t' -> TurtleState n
t' { isPenDown :: Bool
isPenDown = Bool
False }
 | Bool
otherwise   = TurtleState n
t

-- | Puts the turtle pen in “Down” mode. Turtle movements will cause drawing to
-- happen
--
-- Does nothing if the pen was already down. Otherwise, starts a new trail
-- starting at the current position.
penDown :: (Ord n, Floating n) => TurtleState n  -- ^ Turtle to modify
        -> TurtleState n  -- ^ Resulting turtle
penDown :: forall n. (Ord n, Floating n) => TurtleState n -> TurtleState n
penDown TurtleState n
t
  | forall n. TurtleState n -> Bool
isPenDown TurtleState n
t = TurtleState n
t
  | Bool
otherwise   = TurtleState n
t forall a b. a -> (a -> b) -> b
# forall n. (Ord n, Floating n) => TurtleState n -> TurtleState n
makeNewTrail forall a b. a -> (a -> b) -> b
#  \TurtleState n
t' -> TurtleState n
t' { isPenDown :: Bool
isPenDown = Bool
True }

-- Start a new trail at current position
penHop :: (Ord n, Floating n) => TurtleState n
       -> TurtleState n
penHop :: forall n. (Ord n, Floating n) => TurtleState n -> TurtleState n
penHop TurtleState n
t = TurtleState n
t forall a b. a -> (a -> b) -> b
# forall n. (Ord n, Floating n) => TurtleState n -> TurtleState n
makeNewTrail

-- Closes the current path, to the starting position of the current
-- trail. Has no effect when the pen is up.
closeCurrent :: (Floating n, Ord n) => TurtleState n
             -> TurtleState n
closeCurrent :: forall n. (Floating n, Ord n) => TurtleState n -> TurtleState n
closeCurrent TurtleState n
t
  | forall n. TurtleState n -> Bool
isPenDown TurtleState n
t = TurtleState n
t forall a b. a -> (a -> b) -> b
# TurtleState n -> TurtleState n
closeTTrail
  | Bool
otherwise   = TurtleState n
t
 where startPos :: P2 n
startPos = forall a. Located a -> Point (V a) (N a)
loc forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall n. TurtleState n -> Located (Trail' Line V2 n)
currTrail forall a b. (a -> b) -> a -> b
$ TurtleState n
t
       closeTTrail :: TurtleState n -> TurtleState n
closeTTrail TurtleState n
t'  = TurtleState n
t' { penPos :: P2 n
penPos    = P2 n
startPos
                            , currTrail :: Located (Trail' Line V2 n)
currTrail = forall a. Monoid a => a
mempty forall a. a -> Point (V a) (N a) -> Located a
`at` P2 n
startPos
                            , paths :: [TurtlePath n]
paths     = forall n.
(Ord n, Floating n) =>
TurtleState n -> Located (Trail V2 n) -> [TurtlePath n]
addTrailToPath TurtleState n
t'
                                            (forall a b. SameSpace a b => (a -> b) -> Located a -> Located b
mapLoc (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. Trail' Line v n -> Trail' Loop v n
closeLine) forall a b. (a -> b) -> a -> b
$ forall n. TurtleState n -> Located (Trail' Line V2 n)
currTrail TurtleState n
t)
                            }

-- | Set the turtle X/Y position.
--
-- If pen is down and the current trail is non-empty, this will also add the
-- current trail to the @paths@ field.
setPenPos :: (Ord n, Floating n) => P2 n           -- ^ Position to place true
          -> TurtleState n  -- ^ Turtle to position
          -> TurtleState n  -- ^ Resulting turtle
setPenPos :: forall n.
(Ord n, Floating n) =>
P2 n -> TurtleState n -> TurtleState n
setPenPos P2 n
newPos TurtleState n
t = TurtleState n
t {penPos :: P2 n
penPos = P2 n
newPos } forall a b. a -> (a -> b) -> b
# forall n. (Ord n, Floating n) => TurtleState n -> TurtleState n
makeNewTrail

-- | Set a new pen width for turtle.
--
-- If pen is down, this adds the current trail to @paths@ and starts a new empty
-- trail.
setPenWidth :: (Ord n, Floating n) => Measure n -- ^ Width of Pen
            -> TurtleState n  -- ^ Turtle to change
            -> TurtleState n  -- ^ Resulting Turtle
setPenWidth :: forall n.
(Ord n, Floating n) =>
Measure n -> TurtleState n -> TurtleState n
setPenWidth Measure n
w = forall n.
(Floating n, Ord n) =>
(PenStyle n -> PenStyle n) -> TurtleState n -> TurtleState n
modifyCurrStyle (\PenStyle n
s -> PenStyle n
s { penWidth :: Measure n
penWidth = Measure n
w })
-- | Set a new pen color for turtle.
--
-- If pen is down, this adds the current trail to @paths@ and starts a new empty
-- trail.
setPenColour :: (Ord n, Floating n) => Colour Double  -- ^ Width of Pen
             -> TurtleState n    -- ^ Turtle to change
             -> TurtleState n    -- ^ Resulting Turtle
setPenColour :: forall n.
(Ord n, Floating n) =>
Colour Double -> TurtleState n -> TurtleState n
setPenColour Colour Double
c = forall n.
(Floating n, Ord n) =>
(PenStyle n -> PenStyle n) -> TurtleState n -> TurtleState n
modifyCurrStyle (\PenStyle n
s -> PenStyle n
s { penColor :: Colour Double
penColor = Colour Double
c })

-- | alias of @setPenColour@
setPenColor ::  (Ord n, Floating n) => Colour Double  -- ^ Width of Pen
            -> TurtleState n    -- ^ Turtle to change
            -> TurtleState n    -- ^ Resulting Turtle
setPenColor :: forall n.
(Ord n, Floating n) =>
Colour Double -> TurtleState n -> TurtleState n
setPenColor = forall n.
(Ord n, Floating n) =>
Colour Double -> TurtleState n -> TurtleState n
setPenColour

-- | Creates a diagram from a turtle
--
-- Applies the styles to each trails in @paths@ separately and combines them
-- into a single diagram
getTurtleDiagram :: (Renderable (Path V2 n) b, TypeableFloat n)
                 => TurtleState n
                 -> QDiagram b V2 n Any
getTurtleDiagram :: forall n b.
(Renderable (Path V2 n) b, TypeableFloat n) =>
TurtleState n -> QDiagram b V2 n Any
getTurtleDiagram TurtleState n
t =
  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 n b.
(Renderable (Path V2 n) b, TypeableFloat n) =>
TurtlePath n -> QDiagram b V2 n Any
turtlePathToStroke forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  forall n. TurtleState n -> [TurtlePath n]
paths forall a b. (a -> b) -> a -> b
$ TurtleState n
t forall a b. a -> (a -> b) -> b
# forall n. (Ord n, Floating n) => TurtleState n -> TurtleState n
penUp -- Do a penUp to add @currTrail@ to @paths@

-- | Creates a path from a turtle, ignoring the styles.
getTurtlePath :: (Floating n, Ord n) => TurtleState n -> Path V2 n
getTurtlePath :: forall n. (Floating n, Ord n) => TurtleState n -> Path V2 n
getTurtlePath = 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 t n. (V t ~ V2, N t ~ n, TrailLike t) => TurtlePath n -> t
turtlePathToTrailLike forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall n. TurtleState n -> [TurtlePath n]
paths forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall n. (Ord n, Floating n) => TurtleState n -> TurtleState n
penUp

-- * Helper functions

-- Makes a "TurtlePath" from a "Turtle"’s @currTrail@ field
makeTurtlePath :: TurtleState n
               -> Located (Trail V2 n)
               -> TurtlePath n
makeTurtlePath :: forall n. TurtleState n -> Located (Trail V2 n) -> TurtlePath n
makeTurtlePath TurtleState n
t Located (Trail V2 n)
tr = forall n. PenStyle n -> Located (Trail V2 n) -> TurtlePath n
TurtlePath (forall n. TurtleState n -> PenStyle n
currPenStyle TurtleState n
t) Located (Trail V2 n)
tr

-- Returns a list of paths, with current trail added to a "Turtle"’s @paths@ field
addTrailToPath :: (Ord n, Floating n) => TurtleState n
               -> Located (Trail V2 n)
               -> [TurtlePath n]
addTrailToPath :: forall n.
(Ord n, Floating n) =>
TurtleState n -> Located (Trail V2 n) -> [TurtlePath n]
addTrailToPath TurtleState n
t Located (Trail V2 n)
tr
  | forall (v :: * -> *) n.
(Metric v, OrderedField n) =>
Trail v n -> Bool
isTrailEmpty (forall a. Located a -> a
unLoc Located (Trail V2 n)
tr) = forall n. TurtleState n -> [TurtlePath n]
paths TurtleState n
t
  | Bool
otherwise               = forall n. TurtleState n -> Located (Trail V2 n) -> TurtlePath n
makeTurtlePath TurtleState n
t Located (Trail V2 n)
tr forall a. a -> [a] -> [a]
: forall n. TurtleState n -> [TurtlePath n]
paths TurtleState n
t

-- Starts a new trail and adds current trail to path
makeNewTrail :: (Ord n, Floating n) => TurtleState n
             -> TurtleState n
makeNewTrail :: forall n. (Ord n, Floating n) => TurtleState n -> TurtleState n
makeNewTrail TurtleState n
t = TurtleState n
t { currTrail :: Located (Trail' Line V2 n)
currTrail = forall a. Monoid a => a
mempty forall a. a -> Point (V a) (N a) -> Located a
`at` forall n. TurtleState n -> P2 n
penPos TurtleState n
t
                   , paths :: [TurtlePath n]
paths = forall n.
(Ord n, Floating n) =>
TurtleState n -> Located (Trail V2 n) -> [TurtlePath n]
addTrailToPath TurtleState n
t (forall a b. SameSpace a b => (a -> b) -> Located a -> Located b
mapLoc forall l (v :: * -> *) n. Trail' l v n -> Trail v n
wrapTrail (forall n. TurtleState n -> Located (Trail' Line V2 n)
currTrail TurtleState n
t))
                   }

-- Modifies the current style after starting a new trail
modifyCurrStyle :: (Floating n, Ord n) =>
                   (PenStyle n -> PenStyle n)
                -> TurtleState n
                -> TurtleState n
modifyCurrStyle :: forall n.
(Floating n, Ord n) =>
(PenStyle n -> PenStyle n) -> TurtleState n -> TurtleState n
modifyCurrStyle PenStyle n -> PenStyle n
f TurtleState n
t =  TurtleState n
t forall a b. a -> (a -> b) -> b
# forall n. (Ord n, Floating n) => TurtleState n -> TurtleState n
makeNewTrail forall a b. a -> (a -> b) -> b
# \TurtleState n
t' -> TurtleState n
t' { currPenStyle :: PenStyle n
currPenStyle = (PenStyle n -> PenStyle n
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall n. TurtleState n -> PenStyle n
currPenStyle) TurtleState n
t' }

-- Creates any TrailLike from a TurtlePath.
turtlePathToTrailLike :: (V t ~ V2, N t ~ n, TrailLike t) => TurtlePath n -> t
turtlePathToTrailLike :: forall t n. (V t ~ V2, N t ~ n, TrailLike t) => TurtlePath n -> t
turtlePathToTrailLike (TurtlePath PenStyle n
_ Located (Trail V2 n)
t) = forall t. TrailLike t => Located (Trail (V t) (N t)) -> t
trailLike Located (Trail V2 n)
t

-- Creates a diagram from a TurtlePath using the provided styles
turtlePathToStroke :: (Renderable (Path V2 n) b, TypeableFloat n) =>
                      TurtlePath n
                   -> QDiagram b V2 n Any
turtlePathToStroke :: forall n b.
(Renderable (Path V2 n) b, TypeableFloat n) =>
TurtlePath n -> QDiagram b V2 n Any
turtlePathToStroke t :: TurtlePath n
t@(TurtlePath (PenStyle Measure n
lineWidth_  Colour Double
lineColor_) Located (Trail V2 n)
_) = QDiagram b V2 n Any
d
 where d :: QDiagram b V2 n Any
d = forall n a.
(InSpace V2 n a, Typeable n, Floating n, HasStyle a) =>
Colour Double -> a -> a
lc Colour Double
lineColor_ forall b c a. (b -> c) -> (a -> b) -> a -> c
.
           forall a n.
(N a ~ n, HasStyle a, Typeable n) =>
Measure n -> a -> a
lw Measure n
lineWidth_ forall b c a. (b -> c) -> (a -> b) -> a -> c
.
           forall n b.
(TypeableFloat n, Renderable (Path V2 n) b) =>
Located (Trail V2 n) -> QDiagram b V2 n Any
strokeLocTrail forall a b. (a -> b) -> a -> b
$ forall t n. (V t ~ V2, N t ~ n, TrailLike t) => TurtlePath n -> t
turtlePathToTrailLike TurtlePath n
t