Safe Haskell  None 

Language  Haskell98 
This module implements an extension to paths as used in D.E.Knuth's Metafont. Metafont gives an alternate way to specify paths using bezier curves. I'll give a brief overview of the metafont curves. A more in depth explanation can be found in The MetafontBook.
Each spline has a tension parameter, which is a relative measure of
the length of the curve. You can specify the tension for the left
side and the right side of the spline separately. By default
metafont gives a tension of 1, which gives a good looking curve.
Tensions shouldn't be less than 3/4, but this implementation
doesn't check for it. If you want to avoid points of inflection on
the spline, you can use TensionAtLeast
instead of Tension
,
which will adjust the length of the control points so they fall
into the bounding triangle, if such a triangle exist.
You can either give directions for each node, or let metafont find them. Metafont will solve a set of equations to find the directions. You can also let metafont find directions at corner points by setting the curl, which is how much the point curls at that point. At endpoints a curl of 1 is implied when it is not given.
Metafont will then find the control points from the path for you. You can also specify the control points explicitly.
Here is an example path from the metafont program text:
z0..z1..tension atleast 1..{curl 2}z2..z3{1,2}..tension 3 and 4..z4..controls z45 and z54..z5
This path is equivalent to:
z0{curl 1}..tension atleast 1 and atleast 1..{curl 2}z2{curl 2}..tension 1 and 1.. {1,2}z3{1,2}..tension 3 and 4..z4..controls z45 and z54..z5
This path can be used with the following datatype:
OpenMetaPath [ (z0, MetaJoin Open (Tension 1) (Tension 1) Open) , (z1, MetaJoin Open (TensionAtLeast 1) (TensionAtLeast 1) (Curl 2)) , (z2, MetaJoin Open (Tension 1) (Tension 1) Open) , (z3, MetaJoin (Direction (Point (1) (2))) (Tension 3) (Tension 4) Open) , (z4, Controls z45 z54) ] z5
Cyclic paths are similar, but use the CyclicMetaPath
contructor.
There is no ending point, since the ending point will be the same
as the first point.
 unmetaOpen :: OpenMetaPath Double > OpenPath Double
 unmetaClosed :: ClosedMetaPath Double > ClosedPath Double
 data ClosedMetaPath a = ClosedMetaPath [(Point a, MetaJoin a)]
 data OpenMetaPath a = OpenMetaPath [(Point a, MetaJoin a)] (Point a)
 data MetaJoin a
 data MetaNodeType a
 data Tension
 = Tension { }
  TensionAtLeast { }
Documentation
unmetaOpen :: OpenMetaPath Double > OpenPath Double Source
Create a normal path from a metapath.
data ClosedMetaPath a Source
ClosedMetaPath [(Point a, MetaJoin a)]  A metapath with cycles. The last join joins the last point with the first. 
Functor ClosedMetaPath  
Eq a => Eq (ClosedMetaPath a)  
Show a => Show (ClosedMetaPath a) 
data OpenMetaPath a Source
OpenMetaPath [(Point a, MetaJoin a)] (Point a)  A metapath with endpoints 
Show a => Show (OpenMetaPath a) 
MetaJoin  
 
Controls (Point a) (Point a)  Specify the control points explicitly. 
data MetaNodeType a Source
Open  An open node has no direction specified. If it is an internal node, the curve will keep the same direction going into and going out from the node. If it is an endpoint or corner point, it will have curl of 1. 
Curl  The node becomes and endpoint or a corner
point. The curl specifies how much the segment

Direction  The node has a given direction. 
Functor MetaNodeType  
Eq a => Eq (MetaNodeType a)  
Show a => Show (MetaNodeType a) 
Tension  The tension value specifies how tense the curve is. A higher value means the curve approaches a line segment, while a lower value means the curve is more round. Metafont doesn't allow values below 3/4. 
TensionAtLeast  Like 