Portability | GHC |
---|---|

Stability | highly unstable |

Maintainer | Stephen Tetley <stephen.tetley@gmail.com> |

Absolute path type - this should be more amenable for building complex drawings than the PrimPath type in Wumpus-Core.

- data AbsPath u
- type DAbsPath = AbsPath Double
- empty :: Floating u => Point2 u -> AbsPath u
- line1 :: Floating u => Point2 u -> Point2 u -> AbsPath u
- curve1 :: (Floating u, Ord u, Tolerance u) => Point2 u -> Point2 u -> Point2 u -> Point2 u -> AbsPath u
- vertexPath :: (Floating u, Ord u, Tolerance u) => [Point2 u] -> AbsPath u
- curvePath :: (Floating u, Ord u, Tolerance u) => [Point2 u] -> AbsPath u
- controlCurve :: (Floating u, Ord u, Tolerance u) => Point2 u -> Radian -> Radian -> Point2 u -> AbsPath u
- null :: AbsPath u -> Bool
- length :: Num u => AbsPath u -> u
- append :: (Floating u, Ord u, Tolerance u) => AbsPath u -> AbsPath u -> AbsPath u
- consLineTo :: Floating u => Point2 u -> AbsPath u -> AbsPath u
- snocLineTo :: Floating u => AbsPath u -> Point2 u -> AbsPath u
- consCurveTo :: (Floating u, Ord u, Tolerance u) => Point2 u -> Point2 u -> Point2 u -> AbsPath u -> AbsPath u
- snocCurveTo :: (Floating u, Ord u, Tolerance u) => AbsPath u -> Point2 u -> Point2 u -> Point2 u -> AbsPath u
- pathconcat :: (Floating u, Ord u, Tolerance u) => AbsPath u -> [AbsPath u] -> AbsPath u
- toPrimPath :: InterpretUnit u => AbsPath u -> Query PrimPath
- shortenPath :: (Real u, Floating u) => u -> u -> AbsPath u -> AbsPath u
- shortenL :: (Real u, Floating u) => u -> AbsPath u -> AbsPath u
- shortenR :: (Real u, Floating u) => u -> AbsPath u -> AbsPath u
- tipL :: AbsPath u -> Point2 u
- tipR :: AbsPath u -> Point2 u
- directionL :: (Real u, Floating u) => AbsPath u -> Radian
- directionR :: (Real u, Floating u) => AbsPath u -> Radian
- midway :: (Real u, Floating u) => AbsPath u -> (Point2 u, Radian)
- midway_ :: (Real u, Floating u) => AbsPath u -> Point2 u
- atstart :: (Real u, Floating u) => AbsPath u -> (Point2 u, Radian)
- atstart_ :: AbsPath u -> Point2 u
- atend :: (Real u, Floating u) => AbsPath u -> (Point2 u, Radian)
- atend_ :: AbsPath u -> Point2 u
- data PathViewL u
- = PathOneL (PathSegment u)
- | (PathSegment u) :<< (AbsPath u)

- type DPathViewL = PathViewL Double
- data PathViewR u
- = PathOneR (PathSegment u)
- | (AbsPath u) :>> (PathSegment u)

- type DPathViewR = PathViewR Double
- data PathSegment u
- type DPathSegment = PathSegment Double
- pathViewL :: Num u => AbsPath u -> PathViewL u
- pathViewR :: Num u => AbsPath u -> PathViewR u
- roundTrail :: (Real u, Floating u, Tolerance u) => u -> [Point2 u] -> AbsPath u
- roundInterior :: (Real u, Floating u, Tolerance u) => u -> [Point2 u] -> AbsPath u

# Absolute path type

Absolute path data type.

# Construction

empty :: Floating u => Point2 u -> AbsPath uSource

Create the empty path.

Note - an absolute path needs *locating* and cannot be built
without a start point. Figuratively, the empty path is a path
from the start point to the start point.

Thus AbsPath operates as a semigroup but not a monoid.

line1 :: Floating u => Point2 u -> Point2 u -> AbsPath uSource

Create an absolute path as a straight line between the supplied points.

curve1 :: (Floating u, Ord u, Tolerance u) => Point2 u -> Point2 u -> Point2 u -> Point2 u -> AbsPath uSource

Create an absolute path from a single cubic Bezier curve.

vertexPath :: (Floating u, Ord u, Tolerance u) => [Point2 u] -> AbsPath uSource

`vertexPath`

throws a runtime error if the supplied list
is empty.

curvePath :: (Floating u, Ord u, Tolerance u) => [Point2 u] -> AbsPath uSource

`curvePath`

consumes 4 points from the list on the
intial step (start, control1, control2, end) then steps
through the list taking 3 points at a time thereafter
(control1,control2, end). Leftover points are discarded.

`curvePath`

throws a runtime error if the supplied list
is has less than 4 elements (start, control1, control2, end).

controlCurve :: (Floating u, Ord u, Tolerance u) => Point2 u -> Radian -> Radian -> Point2 u -> AbsPath uSource

This is not an arc...

# Queries

length :: Num u => AbsPath u -> uSource

Length of the Path.

Length is the length of the path as it is drawn, it is not a count of the number or path segments.

Length is cached so this operation is cheap - though this put a tax on the build operations.

# Concat and extension

append :: (Floating u, Ord u, Tolerance u) => AbsPath u -> AbsPath u -> AbsPath uSource

Append two AbsPaths.

If the end of the first path and the start of the second path coalesce then the paths are joined directly, otherwise, a straight line segment is added to join the paths.

Neither path is *moved*. Consider `RelPath`

if you need
different concatenation.

consLineTo :: Floating u => Point2 u -> AbsPath u -> AbsPath uSource

Prefix the path with a straight line segment from the supplied point.

snocLineTo :: Floating u => AbsPath u -> Point2 u -> AbsPath uSource

Suffix the path with a straight line segment to the supplied point.

consCurveTo :: (Floating u, Ord u, Tolerance u) => Point2 u -> Point2 u -> Point2 u -> AbsPath u -> AbsPath uSource

Prefix the path with a Bezier curve segment formed by the supplied points.

snocCurveTo :: (Floating u, Ord u, Tolerance u) => AbsPath u -> Point2 u -> Point2 u -> Point2 u -> AbsPath uSource

Suffix the path with a Bezier curve segment formed by the supplied points.

pathconcat :: (Floating u, Ord u, Tolerance u) => AbsPath u -> [AbsPath u] -> AbsPath uSource

Concat the list of paths onto the intial path.

Because a true empty path cannot be constructed (i.e. the
*empty* path needs a start point even if it has no segments) -
the list is in *destructor form*. Client code has to decide
how to handle the empty list case, e.g.:

case paths of (x:xs) -> Just $ pathconcat x xs [] -> Nothing

# Conversion

toPrimPath :: InterpretUnit u => AbsPath u -> Query PrimPathSource

Turn a Path into an ordinary PrimPath.

Assumes path is properly formed - i.e. end point of one segment is the same point as the start point of the next segment.

# Shortening

shortenPath :: (Real u, Floating u) => u -> u -> AbsPath u -> AbsPath uSource

`sortenPath`

: ` left_dist * right_dist * path -> Path `

shortenL :: (Real u, Floating u) => u -> AbsPath u -> AbsPath uSource

Note - shortening a line from the left by greater-than-or-equal its length is operationally equivalent to making a zero-length line at the end point.

shortenR :: (Real u, Floating u) => u -> AbsPath u -> AbsPath uSource

Note - shortening a line from the right by greater-than-or-equal its length is operationally equivalent to making a zero-length line at the start point.

# Tips and direction

directionL :: (Real u, Floating u) => AbsPath u -> RadianSource

Direction of empty path is considered to be 0.

directionR :: (Real u, Floating u) => AbsPath u -> RadianSource

Direction of empty path is considered to be 0.

# Path anchors

# Views

PathOneL (PathSegment u) | |

(PathSegment u) :<< (AbsPath u) |

type DPathViewL = PathViewL DoubleSource

PathOneR (PathSegment u) | |

(AbsPath u) :>> (PathSegment u) |

type DPathViewR = PathViewR DoubleSource

data PathSegment u Source

Functor PathSegment | |

(Ord u, Tolerance u) => Eq (PathSegment u) | |

Show u => Show (PathSegment u) |

type DPathSegment = PathSegment DoubleSource

roundTrail :: (Real u, Floating u, Tolerance u) => u -> [Point2 u] -> AbsPath uSource

`roundTrail`

: ` rounding_distance * [point] -> Path `

Build a path from the list of vertices, all the interior corners are rounded by the rounding distance *and* final round corner is created "incorporating" the start point (as the start point becomes a rounded corner the actual path will not intersect it).

It is expected that this function will be used to create round cornered shapes.

`roundTrail`

throws a runtime error if the input list is empty.
If the list has one element *the null path* is built, if the
list has two elements a straight line is built.

roundInterior :: (Real u, Floating u, Tolerance u) => u -> [Point2 u] -> AbsPath uSource

`roundInterior`

: ` rounding_distance * [point] -> Path `

Build a path from the list of vertices, all the interior
corners are rounded by the rounding distance. Unlike
`roundTrail`

there is no *loop around* to the start point,
and start path will begin exactly on the start point and end
exactly on the end point.

`roundInterior`

throws a runtime error if the input list is
empty. If the list has one element *the null path* is built,
if the list has two elements a straight line is built.