-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Efficient manipulating of 2D cubic bezier curves.
--   
--   This library supports efficient manipulating of 2D cubic bezier
--   curves, for use in graphics or typography. Supported features are:
--   
--   Evaluating bezier curves and derivatives, affine transformations on
--   bezier curves, arclength and inverse arclength, intersections between
--   two curves, intersection between a curve and a line, curvature and
--   radius of curvature, finding tangents parallel to a vector, finding
--   inflection points and cusps.
--   
--   It also supports polynomial root finding with Bernstein polynomials.
--   
--   The module <a>Geom2D.CubicBezier</a> exports all the cubic bezier
--   functions. The module <a>Geom2D</a> contains general 2D geometry
--   functions and transformations.
@package cubicbezier
@version 0.6.0.5


-- | Basic 2 dimensional geometry functions.
module Geom2D
class AffineTransform a b | a -> b
transform :: AffineTransform a b => Transform b -> a -> a
data Polygon a
Polygon :: [Point a] -> Polygon a
data Line a
Line :: (Point a) -> (Point a) -> Line a

-- | A transformation (x, y) -&gt; (ax + by + c, dx + ey + d)
data Transform a
Transform :: !a -> !a -> !a -> !a -> !a -> !a -> Transform a
[xformA] :: Transform a -> !a
[xformB] :: Transform a -> !a
[xformC] :: Transform a -> !a
[xformD] :: Transform a -> !a
[xformE] :: Transform a -> !a
[xformF] :: Transform a -> !a
type DPoint = Point Double
data Point a
Point :: !a -> !a -> Point a
[pointX] :: Point a -> !a
[pointY] :: Point a -> !a

-- | Operator for applying a transformation.
($*) :: AffineTransform a b => Transform b -> a -> a
infixr 5 $*

-- | Calculate the inverse of a transformation.
inverse :: (Eq a, Fractional a) => Transform a -> Maybe (Transform a)

-- | Return the parameters (a, b, c) for the normalised equation of the
--   line: <tt>a*x + b*y + c = 0</tt>.
lineEquation :: Floating t => Line t -> (t, t, t)

-- | Return the signed distance from a point to the line. If the distance
--   is negative, the point lies to the right of the line
lineDistance :: Floating a => Line a -> Point a -> a

-- | Return the point on the line closest to the given point.
closestPoint :: Fractional a => Line a -> Point a -> Point a

-- | Calculate the intersection of two lines. If the determinant is less
--   than tolerance (parallel or coincident lines), return Nothing.
lineIntersect :: (Ord a, Floating a) => Line a -> Line a -> a -> Maybe (Point a)

-- | The lenght of the vector.
vectorMag :: Floating a => Point a -> a

-- | The lenght of the vector.
vectorMagSquare :: Floating a => Point a -> a

-- | The angle of the vector, in the range <tt>(-<a>pi</a>,
--   <a>pi</a>]</tt>.
vectorAngle :: RealFloat a => Point a -> a

-- | The unitvector with the given angle.
dirVector :: Floating a => a -> Point a

-- | The unit vector with the same direction.
normVector :: Floating a => Point a -> Point a

-- | Dot product of two vectors.
(^.^) :: Num a => Point a -> Point a -> a

-- | Cross product of two vectors.
vectorCross :: Num a => Point a -> Point a -> a

-- | Distance between two vectors.
vectorDistance :: Floating a => Point a -> Point a -> a

-- | Interpolate between two vectors.
interpolateVector :: (Num a) => Point a -> Point a -> a -> Point a

-- | Create a transform that rotates by the angle of the given vector and
--   multiplies with the magnitude of the vector.
rotateScaleVec :: Num a => Point a -> Transform a

-- | reflect the vector over the X-axis.
flipVector :: (Num a) => Point a -> Point a
turnAround :: (Num a) => Point a -> Point a

-- | Create a transform that rotates by the angle of the given vector with
--   the x-axis
rotateVec :: Floating a => Point a -> Transform a

-- | Create a transform that rotates by the given angle (radians).
rotate :: Floating s => s -> Transform s

-- | Rotate vector 90 degrees left.
rotate90L :: Floating s => Transform s

-- | Rotate vector 90 degrees right.
rotate90R :: Floating s => Transform s

-- | Create a transform that translates by the given vector.
translate :: Num a => Point a -> Transform a

-- | The identity transformation.
idTrans :: Num a => Transform a
instance Data.Traversable.Traversable Geom2D.Polygon
instance Data.Foldable.Foldable Geom2D.Polygon
instance GHC.Base.Functor Geom2D.Polygon
instance GHC.Classes.Eq a => GHC.Classes.Eq (Geom2D.Polygon a)
instance GHC.Show.Show a => GHC.Show.Show (Geom2D.Polygon a)
instance Data.Traversable.Traversable Geom2D.Line
instance Data.Foldable.Foldable Geom2D.Line
instance GHC.Base.Functor Geom2D.Line
instance GHC.Classes.Eq a => GHC.Classes.Eq (Geom2D.Line a)
instance GHC.Show.Show a => GHC.Show.Show (Geom2D.Line a)
instance Data.Traversable.Traversable Geom2D.Transform
instance Data.Foldable.Foldable Geom2D.Transform
instance GHC.Base.Functor Geom2D.Transform
instance GHC.Show.Show a => GHC.Show.Show (Geom2D.Transform a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Geom2D.Transform a)
instance Data.Traversable.Traversable Geom2D.Point
instance Data.Foldable.Foldable Geom2D.Point
instance GHC.Base.Functor Geom2D.Point
instance GHC.Classes.Ord a => GHC.Classes.Ord (Geom2D.Point a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Geom2D.Point a)
instance GHC.Num.Num a => Geom2D.AffineTransform (Geom2D.Transform a) a
instance GHC.Num.Num a => Geom2D.AffineTransform (Geom2D.Point a) a
instance GHC.Num.Num a => Geom2D.AffineTransform (Geom2D.Polygon a) a
instance GHC.Show.Show a => GHC.Show.Show (Geom2D.Point a)
instance Data.Vector.Unboxed.Base.Unbox a => Data.Vector.Unboxed.Base.Unbox (Geom2D.Point a)
instance Data.Vector.Unboxed.Base.Unbox a => Data.Vector.Generic.Mutable.Base.MVector Data.Vector.Unboxed.Base.MVector (Geom2D.Point a)
instance Data.Vector.Unboxed.Base.Unbox a => Data.Vector.Generic.Base.Vector Data.Vector.Unboxed.Base.Vector (Geom2D.Point a)
instance GHC.Num.Num e => Data.AdditiveGroup.AdditiveGroup (Geom2D.Point e)
instance GHC.Num.Num e => Data.VectorSpace.VectorSpace (Geom2D.Point e)
instance (Data.AdditiveGroup.AdditiveGroup e, GHC.Num.Num e) => Data.VectorSpace.InnerSpace (Geom2D.Point e)
instance GHC.Float.Floating e => Data.Cross.HasNormal (Geom2D.Point e)


-- | Numerical computations used by the cubic bezier functions. Also
--   contains functions that aren't used anymore, but might be useful on
--   its own.
module Geom2D.CubicBezier.Numeric

-- | <tt>quadraticRoot a b c</tt> find the real roots of the quadratic
--   equation <tt>a x^2 + b x + c = 0</tt>. It will return one, two or zero
--   roots.
quadraticRoot :: Double -> Double -> Double -> [Double]
cubicRoot :: Double -> Double -> Double -> Double -> [Double]

-- | Find real roots from the normalized cubic equation.
cubicRootNorm :: Double -> Double -> Double -> [Double]

-- | <tt>solveLinear2x2 a b c d e f</tt> solves the linear equation with
--   two variables (x and y) and two systems:
--   
--   <pre>
--   a x + b y + c = 0
--   d x + e y + f = 0
--   </pre>
--   
--   Returns <tt>Nothing</tt> if no solution is found.
solveLinear2x2 :: (Eq a, Fractional a) => a -> a -> a -> a -> a -> a -> Maybe (a, a)
goldSearch :: (Ord a, Floating a) => (a -> a) -> Int -> a
makeSparse :: Unbox a => Vector Int -> Matrix a -> SparseMatrix a
data SparseMatrix a

-- | Multiply the vector by the transpose of the sparse matrix.
sparseMulT :: (Num a, Unbox a) => Vector a -> SparseMatrix a -> Vector a

-- | Sparse matrix * vector multiplication.
sparseMul :: (Num a, Unbox a) => SparseMatrix a -> Vector a -> Vector a
addMatrix :: (Num a, Unbox a) => Matrix a -> Matrix a -> Matrix a
addVec :: (Num a, Unbox a) => Vector a -> Vector a -> Vector a

-- | Given a rectangular matrix M, calculate the symmetric square matrix
--   MᵀM which can be used to find a least squares solution to the
--   overconstrained system.
lsqMatrix :: (Num a, Unbox a) => SparseMatrix a -> Matrix a

-- | <tt>lsqSolveDist rowStart M y</tt> Find a least squares solution of
--   the distance between the points.
lsqSolveDist :: (Fractional a, Unbox a) => SparseMatrix (a, a) -> Vector (a, a) -> Vector a

-- | LDL* decomposition of the sparse hermitian matrix. The first element
--   of each row is the diagonal component of the D matrix. The following
--   elements are the elements next to the diagonal in the L* matrix (the
--   diagonal components in L* are 1). For efficiency it mutates the matrix
--   inplace.
decompLDL :: (Fractional a, Unbox a) => Matrix a -> Matrix a

-- | <tt>lsqSolve rowStart M y</tt> Find a least squares solution x to the
--   system xM = y.
lsqSolve :: (Fractional a, Unbox a) => SparseMatrix a -> Vector a -> Vector a

-- | solve a tridiagonal system. see metafont the program: ¶ 283
solveTriDiagonal :: (Unbox a, Fractional a) => (a, a, a) -> Vector (a, a, a, a) -> Vector a

-- | solve a cyclic tridiagonal system. see metafont the program: ¶ 286
solveCyclicTriD :: (Unbox a, Fractional a) => Vector (a, a, a, a) -> Vector a


-- | Algebra on polynomials in the Bernstein form. It is based on the paper
--   /Algebraic manipulation in the Bernstein form made simple via
--   convolutions/ by J. Sanchez-Reyes. It's an efficient implementation
--   using the scaled basis, and using ghc rewrite rules to eliminate
--   intermediate polynomials.
module Math.BernsteinPoly
data BernsteinPoly a
BernsteinPoly :: Vector a -> BernsteinPoly a
[bernsteinCoeffs] :: BernsteinPoly a -> Vector a

-- | Return the subsegment between the two parameters.
bernsteinSubsegment :: (Unbox a, Ord a, Fractional a) => BernsteinPoly a -> a -> a -> BernsteinPoly a

-- | Create a bernstein polynomail from a list of coëfficients.
listToBernstein :: (Unbox a, Num a) => [a] -> BernsteinPoly a

-- | The constant zero.
zeroPoly :: (Num a, Unbox a) => BernsteinPoly a

-- | Multiply two bernstein polynomials using convolution. The final degree
--   will be the sum of either degrees. This operation takes O((n+m)^2)
--   with n and m the degree of the beziers. Note that convolution can be
--   done in O(n log n) using the FFT, which may be faster for large
--   polynomials.
(~*) :: (Unbox a, Fractional a) => BernsteinPoly a -> BernsteinPoly a -> BernsteinPoly a
infixl 7 ~*

-- | Scale a bernstein polynomial by a constant.
(*~) :: (Unbox a, Num a) => a -> BernsteinPoly a -> BernsteinPoly a
infixl 7 *~

-- | Sum two bernstein polynomials. The final degree will be the maximum of
--   either degrees.
(~+) :: (Unbox a, Fractional a) => BernsteinPoly a -> BernsteinPoly a -> BernsteinPoly a
infixl 6 ~+

-- | Subtract two bernstein polynomials. The final degree will be the
--   maximum of either degrees.
(~-) :: (Unbox a, Fractional a) => BernsteinPoly a -> BernsteinPoly a -> BernsteinPoly a
infixl 6 ~-
degreeElevate :: (Unbox a, Fractional a) => BernsteinPoly a -> Int -> BernsteinPoly a

-- | Split a bernstein polynomial
bernsteinSplit :: (Unbox a, Num a) => BernsteinPoly a -> a -> (BernsteinPoly a, BernsteinPoly a)

-- | Evaluate the bernstein polynomial using the horner rule adapted for
--   bernstein polynomials.
bernsteinEval :: (Unbox a, Fractional a) => BernsteinPoly a -> a -> a

-- | Evaluate the bernstein polynomial and first derivative
bernsteinEvalDeriv :: (Unbox t, Fractional t) => BernsteinPoly t -> t -> (t, t)

-- | Give the binomial coefficients of degree n.
binCoeff :: (Num a, Unbox a) => Int -> Vector a

-- | Calculate the convolution of two vectors.
convolve :: (Unbox a, Num a) => Vector a -> Vector a -> Vector a

-- | Evaluate the bernstein polynomial and its derivatives.
bernsteinEvalDerivs :: (Unbox t, Fractional t) => BernsteinPoly t -> t -> [t]

-- | Find the derivative of a bernstein polynomial.
bernsteinDeriv :: (Unbox a, Num a) => BernsteinPoly a -> BernsteinPoly a
instance (GHC.Show.Show a, Data.Vector.Unboxed.Base.Unbox a) => GHC.Show.Show (Math.BernsteinPoly.ScaledPoly a)
instance (GHC.Show.Show a, Data.Vector.Unboxed.Base.Unbox a) => GHC.Show.Show (Math.BernsteinPoly.BernsteinPoly a)

module Geom2D.CubicBezier.Basic

-- | A cubic bezier curve.
data CubicBezier a
CubicBezier :: !(Point a) -> !(Point a) -> !(Point a) -> !(Point a) -> CubicBezier a
[cubicC0] :: CubicBezier a -> !(Point a)
[cubicC1] :: CubicBezier a -> !(Point a)
[cubicC2] :: CubicBezier a -> !(Point a)
[cubicC3] :: CubicBezier a -> !(Point a)

-- | A quadratic bezier curve.
data QuadBezier a
QuadBezier :: !(Point a) -> !(Point a) -> !(Point a) -> QuadBezier a
[quadC0] :: QuadBezier a -> !(Point a)
[quadC1] :: QuadBezier a -> !(Point a)
[quadC2] :: QuadBezier a -> !(Point a)

-- | A bezier curve of any degree.
data AnyBezier a
AnyBezier :: (Vector (a, a)) -> AnyBezier a
class GenericBezier b
degree :: (GenericBezier b, (Unbox a)) => b a -> Int
toVector :: (GenericBezier b, (Unbox a)) => b a -> Vector (a, a)
unsafeFromVector :: (GenericBezier b, (Unbox a)) => Vector (a, a) -> b a
data PathJoin a
JoinLine :: PathJoin a
JoinCurve :: (Point a) -> (Point a) -> PathJoin a
data ClosedPath a
ClosedPath :: [(Point a, PathJoin a)] -> ClosedPath a
data OpenPath a
OpenPath :: [(Point a, PathJoin a)] -> (Point a) -> OpenPath a
class AffineTransform a b | a -> b
transform :: AffineTransform a b => Transform b -> a -> a

-- | safely convert from <a>AnyBezier</a> to <a>CubicBezier</a>
anyToCubic :: (Unbox a) => AnyBezier a -> Maybe (CubicBezier a)

-- | safely convert from <a>AnyBezier</a> to <a>QuadBezier</a>
anyToQuad :: (Unbox a) => AnyBezier a -> Maybe (QuadBezier a)

-- | Return the open path as a list of curves.
openPathCurves :: Fractional a => OpenPath a -> [CubicBezier a]

-- | Return the closed path as a list of curves
closedPathCurves :: Fractional a => ClosedPath a -> [CubicBezier a]

-- | Make an open path from a list of curves. The last control point of
--   each curve except the last is ignored.
curvesToOpen :: [CubicBezier a] -> OpenPath a

-- | Make an open path from a list of curves. The last control point of
--   each curve is ignored.
curvesToClosed :: [CubicBezier a] -> ClosedPath a

-- | construct an open path
consOpenPath :: Point a -> PathJoin a -> OpenPath a -> OpenPath a

-- | construct a closed path
consClosedPath :: Point a -> PathJoin a -> ClosedPath a -> ClosedPath a

-- | open a closed path
openClosedPath :: ClosedPath a -> OpenPath a

-- | close an open path, discarding the last point
closeOpenPath :: OpenPath a -> ClosedPath a

-- | Return True if the param lies on the curve, iff it's in the interval
--   <tt>[0, 1]</tt>.
bezierParam :: (Ord a, Num a) => a -> Bool

-- | Convert a tolerance from the codomain to the domain of the bezier
--   curve, by dividing by the maximum velocity on the curve. The estimate
--   is conservative, but holds for any value on the curve.
bezierParamTolerance :: (GenericBezier b) => b Double -> Double -> Double

-- | Reorient to the curve B(1-t).
reorient :: (GenericBezier b, Unbox a) => b a -> b a

-- | Give the bernstein polynomial for each coordinate.
bezierToBernstein :: (GenericBezier b, Unbox a) => b a -> (BernsteinPoly a, BernsteinPoly a)

-- | Evaluate the bezier and all its derivatives using the modified horner
--   algorithm.
evalBezierDerivs :: (GenericBezier b, Unbox a, Fractional a) => b a -> a -> [Point a]

-- | Calculate a value on the bezier curve.
evalBezier :: (GenericBezier b, Unbox a, Fractional a) => b a -> a -> Point a

-- | Calculate a value and the first derivative on the curve.
evalBezierDeriv :: (Unbox a, Fractional a) => GenericBezier b => b a -> a -> (Point a, Point a)

-- | <tt>findBezierTangent p b</tt> finds the parameters where the tangent
--   of the bezier curve <tt>b</tt> has the same direction as vector p.
findBezierTangent :: DPoint -> CubicBezier Double -> [Double]

-- | Convert a quadratic bezier to a cubic bezier.
quadToCubic :: (Fractional a) => QuadBezier a -> CubicBezier a

-- | Find the parameter where the bezier curve is horizontal.
bezierHoriz :: CubicBezier Double -> [Double]

-- | Find the parameter where the bezier curve is vertical.
bezierVert :: CubicBezier Double -> [Double]

-- | Find inflection points on the curve. Use the formula B_x''(t) *
--   B_y'(t) - B_y''(t) * B_x'(t) = 0 with B_x'(t) the x value of the first
--   derivative at t, B_y''(t) the y value of the second derivative at t
findBezierInflection :: CubicBezier Double -> [Double]

-- | Find the cusps of a bezier.
findBezierCusp :: CubicBezier Double -> [Double]

-- | <tt>bezierArc startAngle endAngle</tt> approximates an arc on the unit
--   circle with a single cubic béziér curve. Maximum deviation is
--   &lt;0.03% for arcs 90° degrees or less.
bezierArc :: Double -> Double -> CubicBezier Double

-- | @arcLength c t tol finds the arclength of the bezier c at t, within
--   given tolerance tol.
arcLength :: CubicBezier Double -> Double -> Double -> Double

-- | arcLengthParam c len tol finds the parameter where the curve c has the
--   arclength len, within tolerance tol.
arcLengthParam :: CubicBezier Double -> Double -> Double -> Double

-- | Split a bezier curve into two curves.
splitBezier :: (Unbox a, Fractional a) => GenericBezier b => b a -> a -> (b a, b a)

-- | Return the subsegment between the two parameters.
bezierSubsegment :: (Ord a, Unbox a, Fractional a) => GenericBezier b => b a -> a -> a -> b a

-- | Split a bezier curve into a list of beziers The parameters should be
--   in ascending order or the result is unpredictable.
splitBezierN :: (Ord a, Unbox a, Fractional a) => GenericBezier b => b a -> [a] -> [b a]

-- | Return False if some points fall outside a line with a thickness of
--   the given tolerance.
colinear :: CubicBezier Double -> Double -> Bool

-- | Find the closest value on the bezier to the given point, within
--   tolerance. Return the first value found.
closest :: CubicBezier Double -> DPoint -> Double -> Double

-- | Find the x value of the cubic bezier. The bezier must be monotonically
--   increasing in the X coordinate.
findX :: CubicBezier Double -> Double -> Double -> Double
instance Data.Traversable.Traversable Geom2D.CubicBezier.Basic.ClosedPath
instance Data.Foldable.Foldable Geom2D.CubicBezier.Basic.ClosedPath
instance GHC.Base.Functor Geom2D.CubicBezier.Basic.ClosedPath
instance GHC.Show.Show a => GHC.Show.Show (Geom2D.CubicBezier.Basic.ClosedPath a)
instance Data.Traversable.Traversable Geom2D.CubicBezier.Basic.OpenPath
instance Data.Foldable.Foldable Geom2D.CubicBezier.Basic.OpenPath
instance GHC.Base.Functor Geom2D.CubicBezier.Basic.OpenPath
instance GHC.Show.Show a => GHC.Show.Show (Geom2D.CubicBezier.Basic.OpenPath a)
instance Data.Traversable.Traversable Geom2D.CubicBezier.Basic.PathJoin
instance Data.Foldable.Foldable Geom2D.CubicBezier.Basic.PathJoin
instance GHC.Base.Functor Geom2D.CubicBezier.Basic.PathJoin
instance GHC.Show.Show a => GHC.Show.Show (Geom2D.CubicBezier.Basic.PathJoin a)
instance Data.Traversable.Traversable Geom2D.CubicBezier.Basic.QuadBezier
instance Data.Foldable.Foldable Geom2D.CubicBezier.Basic.QuadBezier
instance GHC.Base.Functor Geom2D.CubicBezier.Basic.QuadBezier
instance GHC.Show.Show a => GHC.Show.Show (Geom2D.CubicBezier.Basic.QuadBezier a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Geom2D.CubicBezier.Basic.QuadBezier a)
instance Data.Traversable.Traversable Geom2D.CubicBezier.Basic.CubicBezier
instance Data.Foldable.Foldable Geom2D.CubicBezier.Basic.CubicBezier
instance GHC.Base.Functor Geom2D.CubicBezier.Basic.CubicBezier
instance GHC.Show.Show a => GHC.Show.Show (Geom2D.CubicBezier.Basic.CubicBezier a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Geom2D.CubicBezier.Basic.CubicBezier a)
instance GHC.Num.Num a => Geom2D.AffineTransform (Geom2D.CubicBezier.Basic.ClosedPath a) a
instance GHC.Base.Semigroup (Geom2D.CubicBezier.Basic.OpenPath a)
instance GHC.Base.Monoid (Geom2D.CubicBezier.Basic.OpenPath a)
instance GHC.Num.Num a => Geom2D.AffineTransform (Geom2D.CubicBezier.Basic.OpenPath a) a
instance GHC.Num.Num a => Geom2D.AffineTransform (Geom2D.CubicBezier.Basic.PathJoin a) a
instance Geom2D.CubicBezier.Basic.GenericBezier Geom2D.CubicBezier.Basic.CubicBezier
instance Geom2D.CubicBezier.Basic.GenericBezier Geom2D.CubicBezier.Basic.QuadBezier
instance Geom2D.CubicBezier.Basic.GenericBezier Geom2D.CubicBezier.Basic.AnyBezier
instance GHC.Num.Num a => Geom2D.AffineTransform (Geom2D.CubicBezier.Basic.QuadBezier a) a
instance GHC.Num.Num a => Geom2D.AffineTransform (Geom2D.CubicBezier.Basic.CubicBezier a) a


-- | This module implements an extension to paths as used in D.E.Knuth's
--   <i>Metafont</i>. 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 <i>The
--   MetafontBook</i>.
--   
--   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
--   <tt>TensionAtLeast</tt> instead of <tt>Tension</tt>, which will adjust
--   the length of the control points so they fall into the <i>bounding
--   triangle</i>, 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 <i>curl</i>, which is how much the point <i>curls</i> 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:
--   
--   <pre>
--   z0..z1..tension atleast 1..{curl 2}z2..z3{-1,-2}..tension 3 and 4..z4..controls z45 and z54..z5
--   </pre>
--   
--   This path is equivalent to:
--   
--   <pre>
--   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
--   </pre>
--   
--   This path can be used with the following datatype:
--   
--   <pre>
--   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
--   </pre>
--   
--   Cyclic paths are similar, but use the <tt>CyclicMetaPath</tt>
--   contructor. There is no ending point, since the ending point will be
--   the same as the first point.
module Geom2D.CubicBezier.MetaPath

-- | Create a normal path from a metapath.
unmetaOpen :: OpenMetaPath Double -> OpenPath Double
unmetaClosed :: ClosedMetaPath Double -> ClosedPath Double
data ClosedMetaPath a

-- | A metapath with cycles. The last join joins the last point with the
--   first.
ClosedMetaPath :: [(Point a, MetaJoin a)] -> ClosedMetaPath a
data OpenMetaPath a

-- | A metapath with endpoints
OpenMetaPath :: [(Point a, MetaJoin a)] -> (Point a) -> OpenMetaPath a
data MetaJoin a
MetaJoin :: MetaNodeType a -> Tension a -> Tension a -> MetaNodeType a -> MetaJoin a

-- | The nodetype going out of the previous point. The metafont default is
--   <tt>Open</tt>.
[metaTypeL] :: MetaJoin a -> MetaNodeType a

-- | The tension going out of the previous point. The metafont default is
--   1.
[tensionL] :: MetaJoin a -> Tension a

-- | The tension going into the next point. The metafont default is 1.
[tensionR] :: MetaJoin a -> Tension a

-- | The nodetype going into the next point. The metafont default is
--   <tt>Open</tt>.
[metaTypeR] :: MetaJoin a -> MetaNodeType a

-- | Specify the control points explicitly.
Controls :: (Point a) -> (Point a) -> MetaJoin a
data MetaNodeType a

-- | 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.
Open :: MetaNodeType a

-- | The node becomes and endpoint or a corner point. The curl specifies
--   how much the segment <tt>curves</tt>. A curl of <tt>gamma</tt> means
--   that the curvature is <tt>gamma</tt> times that of the following node.
Curl :: a -> MetaNodeType a
[curlgamma] :: MetaNodeType a -> a

-- | The node has a given direction.
Direction :: Point a -> MetaNodeType a
[nodedir] :: MetaNodeType a -> Point a
data Tension a

-- | The tension value specifies how <i>tense</i> 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.
Tension :: a -> Tension a
[tensionValue] :: Tension a -> a

-- | Like <tt>Tension</tt>, but keep the segment inside the bounding
--   triangle defined by the control points, if there is one.
TensionAtLeast :: a -> Tension a
[tensionValue] :: Tension a -> a
instance Data.Foldable.Foldable Geom2D.CubicBezier.MetaPath.OpenMetaPath
instance Data.Traversable.Traversable Geom2D.CubicBezier.MetaPath.OpenMetaPath
instance GHC.Base.Functor Geom2D.CubicBezier.MetaPath.OpenMetaPath
instance Data.Foldable.Foldable Geom2D.CubicBezier.MetaPath.ClosedMetaPath
instance Data.Traversable.Traversable Geom2D.CubicBezier.MetaPath.ClosedMetaPath
instance GHC.Base.Functor Geom2D.CubicBezier.MetaPath.ClosedMetaPath
instance GHC.Classes.Eq a => GHC.Classes.Eq (Geom2D.CubicBezier.MetaPath.ClosedMetaPath a)
instance Data.Foldable.Foldable Geom2D.CubicBezier.MetaPath.MetaJoin
instance Data.Traversable.Traversable Geom2D.CubicBezier.MetaPath.MetaJoin
instance GHC.Base.Functor Geom2D.CubicBezier.MetaPath.MetaJoin
instance GHC.Classes.Eq a => GHC.Classes.Eq (Geom2D.CubicBezier.MetaPath.MetaJoin a)
instance GHC.Show.Show a => GHC.Show.Show (Geom2D.CubicBezier.MetaPath.MetaJoin a)
instance Data.Traversable.Traversable Geom2D.CubicBezier.MetaPath.Tension
instance Data.Foldable.Foldable Geom2D.CubicBezier.MetaPath.Tension
instance GHC.Base.Functor Geom2D.CubicBezier.MetaPath.Tension
instance GHC.Show.Show a => GHC.Show.Show (Geom2D.CubicBezier.MetaPath.Tension a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Geom2D.CubicBezier.MetaPath.Tension a)
instance Data.Traversable.Traversable Geom2D.CubicBezier.MetaPath.MetaNodeType
instance Data.Foldable.Foldable Geom2D.CubicBezier.MetaPath.MetaNodeType
instance GHC.Base.Functor Geom2D.CubicBezier.MetaPath.MetaNodeType
instance GHC.Show.Show a => GHC.Show.Show (Geom2D.CubicBezier.MetaPath.MetaNodeType a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Geom2D.CubicBezier.MetaPath.MetaNodeType a)
instance (GHC.Show.Show a, GHC.Real.Real a) => GHC.Show.Show (Geom2D.CubicBezier.MetaPath.OpenMetaPath a)
instance (GHC.Show.Show a, GHC.Real.Real a) => GHC.Show.Show (Geom2D.CubicBezier.MetaPath.ClosedMetaPath a)


-- | Intersection routines using Bezier Clipping. Provides also functions
--   for finding the roots of onedimensional bezier curves. This can be
--   used as a general polynomial root solver by converting from the power
--   basis to the bernstein basis.
module Geom2D.CubicBezier.Intersection

-- | Find the intersections between two Bezier curves, using the Bezier
--   Clip algorithm. Returns the parameters for both curves.
bezierIntersection :: CubicBezier Double -> CubicBezier Double -> Double -> [(Double, Double)]

-- | Find the intersections of the curve with a line.
bezierLineIntersections :: CubicBezier Double -> Line Double -> Double -> [Double]

-- | Find the zero of a 1D bezier curve of any degree. Note that this can
--   be used as a bernstein polynomial root solver by converting from the
--   power basis to the bernstein basis.
bezierFindRoot :: BernsteinPoly Double -> Double -> Double -> Double -> [Double]

module Geom2D.CubicBezier.Overlap

-- | `O((n+m)*log(n+m))`, for <tt>n</tt> segments and <tt>m</tt>
--   intersections. Combine paths using the given boolean operation
boolPathOp :: (Bool -> Bool -> Bool) -> [ClosedPath Double] -> [ClosedPath Double] -> FillRule -> Double -> [ClosedPath Double]

-- | `O((n+m)*log(n+m))`, for <tt>n</tt> segments and <tt>m</tt>
--   intersections. Union of paths, removing overlap and rounding to the
--   given tolerance.
union :: [ClosedPath Double] -> FillRule -> Double -> [ClosedPath Double]

-- | path intersection
intersection :: [ClosedPath Double] -> [ClosedPath Double] -> FillRule -> Double -> [ClosedPath Double]

-- | path difference
difference :: [ClosedPath Double] -> [ClosedPath Double] -> FillRule -> Double -> [ClosedPath Double]

-- | path exclusion
exclusion :: [ClosedPath Double] -> [ClosedPath Double] -> FillRule -> Double -> [ClosedPath Double]
data FillRule
EvenOdd :: FillRule
NonZero :: FillRule
instance GHC.Classes.Eq Geom2D.CubicBezier.Overlap.Curve
instance GHC.Classes.Ord Geom2D.CubicBezier.Overlap.Curve
instance GHC.Show.Show Geom2D.CubicBezier.Overlap.Curve
instance GHC.Show.Show Geom2D.CubicBezier.Overlap.PointEvent
instance GHC.Classes.Eq Geom2D.CubicBezier.Overlap.PointEvent
instance GHC.Classes.Ord Geom2D.CubicBezier.Overlap.PointEvent

module Geom2D.CubicBezier.Curvature

-- | Curvature of the Bezier curve. A negative curvature means the curve
--   curves to the right.
curvature :: CubicBezier Double -> Double -> Double

-- | Radius of curvature of the Bezier curve. This is the reciprocal of the
--   curvature.
radiusOfCurvature :: CubicBezier Double -> Double -> Double

-- | Find extrema of the curvature, but not inflection points.
curvatureExtrema :: CubicBezier Double -> Double -> [Double]

-- | Find points on the curve that have a certain radius of curvature.
--   Values to the left and to the right of the curve are returned.
findRadius :: CubicBezier Double -> Double -> Double -> [Double]

module Geom2D.CubicBezier.Approximate

-- | Approximate a function with piecewise cubic bezier splines using a
--   least-squares fit, within the given tolerance. Each subcurve is
--   approximated by using a finite number of samples. It is recommended to
--   avoid changes in direction by subdividing the original function at
--   points of inflection.
approximatePath :: (Unbox a, Ord a, Floating a) => (a -> (Point a, Point a)) -> Int -> a -> a -> a -> Bool -> [CubicBezier a]

-- | Approximate a function with piecewise quadratic bezier splines using a
--   least-squares fit, within the given tolerance. It is recommended to
--   avoid changes in direction by subdividing the original function at
--   points of inflection.
approximateQuadPath :: (Show a, Unbox a, Ord a, Floating a) => (a -> (Point a, Point a)) -> a -> a -> a -> Bool -> [QuadBezier a]

-- | Like approximatePath, but limit the number of subcurves.
approximatePathMax :: (Unbox a, Floating a, Ord a) => Int -> (a -> (Point a, Point a)) -> Int -> a -> a -> a -> Bool -> [CubicBezier a]

-- | Like approximateQuadPath, but limit the number of subcurves.
approximateQuadPathMax :: (Unbox a, Show a, Floating a, Ord a) => Int -> (a -> (Point a, Point a)) -> a -> a -> a -> Bool -> [QuadBezier a]

-- | <tt>approximateCubic b pts maxiter</tt> finds the least squares fit of
--   a bezier curve to the points <tt>pts</tt>. The resulting bezier has
--   the same first and last control point as the curve <tt>b</tt>, and
--   have tangents colinear with <tt>b</tt>.
approximateCubic :: (Unbox a, Ord a, Floating a) => CubicBezier a -> Vector (Point a) -> Maybe (Vector a) -> Int -> (CubicBezier a, a)


-- | Offsetting bezier curves and stroking curves.
module Geom2D.CubicBezier.Outline

-- | Calculate an offset path from the bezier curve to within tolerance. If
--   the distance is positive offset to the left, otherwise to the right. A
--   smaller tolerance may require more bezier curves in the path to
--   approximate the offset curve
bezierOffset :: CubicBezier Double -> Double -> Maybe Int -> Double -> [CubicBezier Double]
bezierOffsetPoint :: CubicBezier Double -> Double -> Double -> (DPoint, DPoint)


-- | Export all the cubic bezier functions.
module Geom2D.CubicBezier

module Geom2D.CubicBezier.Stroke

-- | A circular pen with unit radius.
penCircle :: (Floating a) => Pen a

-- | Create a pen from a path. For predictable results the path should be
--   convex.
pathToPen :: (Floating a) => ClosedPath a -> Pen a
penStrokeOpen :: Int -> Double -> Bool -> Pen Double -> OpenPath Double -> [ClosedPath Double]
penStrokeClosed :: Int -> Double -> Bool -> Pen Double -> ClosedPath Double -> [ClosedPath Double]
data Pen a

-- | Calculate an offset path from the bezier curve to within tolerance. If
--   the distance is positive offset to the left, otherwise to the right. A
--   smaller tolerance may require more bezier curves in the path to
--   approximate the offset curve
bezierOffset :: CubicBezier Double -> Double -> Maybe Int -> Double -> Bool -> [CubicBezier Double]
instance (GHC.Float.Floating a, GHC.Classes.Eq a) => Geom2D.AffineTransform (Geom2D.CubicBezier.Stroke.Pen a) a
