-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | B-Splines, other splines, and NURBS. -- -- This is a fairly simple implementation of a general-purpose spline -- library, just to get the code out there. Its interface is still mildly -- unstable and may change (hopefully not drastically) as new needs or -- better style ideas come up. Patches, suggestions and/or feature -- requests are welcome. @package splines @version 0.3 module Math.Spline.Knots -- | Knot vectors - multisets of points in a 1-dimensional space. data Knots a -- | An empty knot vector empty :: Knots a isEmpty :: Knots a -> Bool -- | Create a knot vector consisting of one knot. knot :: Ord a => a -> Knots a -- | Create a knot vector consisting of one knot with the specified -- multiplicity. multipleKnot :: Ord a => a -> Int -> Knots a -- | Create a knot vector consisting of all the knots in a list. mkKnots :: Ord a => [a] -> Knots a -- | Create a knot vector consisting of all the knots and corresponding -- multiplicities in a list. fromList :: Ord k => [(k, Int)] -> Knots k -- | Returns the number of knots (not necessarily distinct) in a knot -- vector. numKnots :: Knots t -> Int lookupKnot :: Int -> Knots a -> Maybe a -- | Returns a list of all distinct knots in ascending order along with -- their multiplicities. toList :: Knots k -> [(k, Int)] -- | Returns the number of distinct knots in a knot vector. numDistinctKnots :: Knots t -> Int lookupDistinctKnot :: Int -> Knots a -> Maybe a -- | Returns a list of all knots (not necessarily distinct) of a knot -- vector in ascending order knots :: Knots t -> [t] -- | Returns a vector of all knots (not necessarily distinct) of a knot -- vector in ascending order knotsVector :: Knots t -> Vector t -- | Returns a list of all distinct knots of a knot vector in ascending -- order distinctKnots :: Knots t -> [t] -- | Returns a vector of all distinct knots of a knot vector in ascending -- order distinctKnotsVector :: Knots t -> Vector t toMap :: Knots k -> Map k Int fromMap :: Map k Int -> Knots k toVector :: Knots k -> Vector (k, Int) fromVector :: Ord k => Vector (k, Int) -> Knots k -- | splitLookup n kts: Split a knot vector kts into 3 -- parts (pre, mbKt, post) such that: -- -- splitLookup :: Int -> Knots a -> (Knots a, Maybe (a, Int), Knots a) takeKnots :: Int -> Knots a -> Knots a dropKnots :: Int -> Knots a -> Knots a splitKnotsAt :: Int -> Knots a -> (Knots a, Knots a) takeDistinctKnots :: Int -> Knots a -> Knots a dropDistinctKnots :: Int -> Knots a -> Knots a splitDistinctKnotsAt :: Int -> Knots a -> (Knots a, Knots a) maxMultiplicity :: Knots t -> Int -- | Looks up the multiplicity of a knot (which is 0 if the point is not a -- knot) knotMultiplicity :: Ord k => k -> Knots k -> Int -- | Returns a new knot vector with the given knot set to the specified -- multiplicity and all other knots unchanged. setKnotMultiplicity :: Ord k => k -> Int -> Knots k -> Knots k -- | Create a knot vector consisting of all the knots and corresponding -- multiplicities in a list ordered by the knots' Ord instance. -- The ordering precondition is not checked. fromAscList :: Eq k => [(k, Int)] -> Knots k -- | Create a knot vector consisting of all the knots and corresponding -- multiplicities in a list ordered by the knots' Ord instance -- with no duplicates. The preconditions are not checked. fromDistinctAscList :: [(k, Int)] -> Knots k -- | Check the internal consistency of a knot vector valid :: Ord k => Knots k -> Bool -- | knotSpan kts i j returns the knot span extending from the -- i'th knot to the j'th knot, if i <= j -- and both knots exist. knotSpan :: Knots a -> Int -> Int -> Maybe (a, a) -- | knotsInSpan kts i j returns the knots in the knot span -- extending from the i'th knot to the j'th knot knotsInSpan :: Knots a -> Int -> Int -> Knots a -- | knotSpans kts width returns all knot spans of a given width -- in ascending order. -- -- For example, knotSpans (mkKnots [1..5]) 2 yields [(1,3), -- (2,4), (3,5)]. knotSpans :: Knots a -> Int -> [(a, a)] -- | knotDomain kts p returns the domain of a B-spline or NURBS -- with knot vector kts and degree p. This is the -- subrange spanned by all except the first and last p knots. -- Outside this domain, the spline does not have a complete basis set. De -- Boor's algorithm assumes that the basis functions sum to 1, which is -- only true on this range, and so this is also precisely the domain on -- which de Boor's algorithm is valid. knotDomain :: Knots a -> Int -> Maybe (a, a) -- | uniform deg nPts (lo,hi) constructs a uniformly-spaced knot -- vector over the interval from lo to hi which, when -- used to construct a B-spline with nPts control points will -- yield a clamped spline with degree deg. uniform :: (Ord s, Fractional s) => Int -> Int -> (s, s) -> Knots s instance Eq a => Eq (Knots a) instance Ord a => Ord (Knots a) instance Foldable Knots instance Ord a => Monoid (Knots a) instance Show a => Show (Knots a) module Math.Spline.BSpline data BSpline t -- | bSpline kts cps creates a B-spline with the given knot vector -- and control points. The degree is automatically inferred as the -- difference between the number of spans in the knot vector -- (numKnots kts - 1) and the number of control points -- (length cps). bSpline :: Knots (Scalar a) -> Vector a -> BSpline a evalBSpline :: (Fractional (Scalar c), Ord (Scalar c), VectorSpace c) => BSpline c -> Scalar c -> c -- | Insert one knot into a BSpline insertKnot :: (VectorSpace a, Ord (Scalar a), Fractional (Scalar a)) => BSpline a -> Scalar a -> BSpline a splitBSpline :: (VectorSpace v, Ord (Scalar v), Fractional (Scalar v)) => BSpline v -> Scalar v -> Maybe (BSpline v, BSpline v) differentiateBSpline :: (VectorSpace v, Fractional (Scalar v), Ord (Scalar v)) => BSpline v -> BSpline v integrateBSpline :: (VectorSpace v, Fractional (Scalar v), Ord (Scalar v)) => BSpline v -> BSpline v instance (Ord (Scalar v), Ord v) => Ord (BSpline v) instance (Eq (Scalar v), Eq v) => Eq (BSpline v) instance (Show (Scalar v), Show v) => Show (BSpline v) -- | Reference implementation of B-Splines; very inefficient but -- "obviously" correct. module Math.Spline.BSpline.Reference bases :: (Fractional a, Ord a) => Knots a -> a -> [[a]] basisFunctions :: (Fractional a, Ord a) => Knots a -> [[a -> a]] basisPolynomials :: (Fractional a, Ord a) => Knots a -> [[[Poly a]]] basisPolynomialsAt :: (Fractional a, Ord a) => Knots a -> a -> [[Poly a]] module Math.Spline.Class -- | A spline is a piecewise polynomial vector-valued function. The -- necessary and sufficient instance definition is toBSpline. class (VectorSpace v, Fractional (Scalar v), Ord (Scalar v)) => Spline s v splineDomain :: Spline s v => s v -> Maybe (Scalar v, Scalar v) evalSpline :: Spline s v => s v -> Scalar v -> v splineDegree :: Spline s v => s v -> Int knotVector :: Spline s v => s v -> Knots (Scalar v) toBSpline :: Spline s v => s v -> BSpline v class Spline s v => ControlPoints s v controlPoints :: ControlPoints s v => s v -> Vector v instance Spline BSpline v => ControlPoints BSpline v instance (VectorSpace v, Fractional (Scalar v), Ord (Scalar v)) => Spline BSpline v module Math.Spline.BezierCurve -- | A BezierCurve curve on 0 <= x <= 1. data BezierCurve t -- | Construct a Bezier curve from a list of control points. The degree of -- the curve is one less than the number of control points. bezierCurve :: Vector t -> BezierCurve t -- | Split and rescale a Bezier curve. Given a BezierCurve -- b and a point t, splitBezierCurve b t -- creates 2 curves (b1, b2) such that (up to reasonable -- numerical accuracy expectations): -- --
--   evalSpline b1  x    == evalSpline b (x * t)
--   evalSpline b2 (x-t) == evalSpline b (x * (1-t))
--   
splitBezierCurve :: VectorSpace v => BezierCurve v -> Scalar v -> (BezierCurve v, BezierCurve v) evalSpline :: Spline s v => s v -> Scalar v -> v instance Eq t => Eq (BezierCurve t) instance Ord t => Ord (BezierCurve t) instance Spline BezierCurve v => ControlPoints BezierCurve v instance (VectorSpace v, Fractional (Scalar v), Ord (Scalar v)) => Spline BezierCurve v instance Show v => Show (BezierCurve v) module Math.Spline.MSpline -- | M-Splines are B-splines normalized so that the integral of each basis -- function over the spline domain is 1. data MSpline v -- | mSpline kts cps creates a M-spline with the given knot vector -- and control points. The degree is automatically inferred as the -- difference between the number of spans in the knot vector -- (numKnots kts - 1) and the number of control points -- (length cps). mSpline :: Knots (Scalar a) -> Vector a -> MSpline a toMSpline :: Spline s v => s v -> MSpline v evalSpline :: Spline s v => s v -> Scalar v -> v instance (Ord (Scalar v), Ord v) => Ord (MSpline v) instance (Eq (Scalar v), Eq v) => Eq (MSpline v) instance Spline MSpline v => ControlPoints MSpline v instance (VectorSpace v, Fractional (Scalar v), Ord (Scalar v)) => Spline MSpline v instance (Show (Scalar v), Show v) => Show (MSpline v) module Math.Spline.ISpline -- | The I-Spline basis functions are the integrals of the M-splines, or -- alternatively the integrals of the B-splines normalized to the range -- [0,1]. Every I-spline basis function increases monotonically from 0 to -- 1, thus it is useful as a basis for monotone functions. An I-Spline -- curve is monotone if and only if every non-zero control point has the -- same sign. data ISpline v -- | iSpline kts cps creates an I-spline with the given knot -- vector and control points. The degree is automatically inferred as the -- difference between the number of spans in the knot vector -- (numKnots kts - 1) and the number of control points -- (length cps). iSpline :: Knots (Scalar a) -> Vector a -> ISpline a toISpline :: (Spline s v, Eq v) => s v -> ISpline v evalSpline :: Spline s v => s v -> Scalar v -> v instance (Ord (Scalar v), Ord v) => Ord (ISpline v) instance (Eq (Scalar v), Eq v) => Eq (ISpline v) instance Spline ISpline v => ControlPoints ISpline v instance (VectorSpace v, Fractional (Scalar v), Ord (Scalar v)) => Spline ISpline v instance (Show (Scalar v), Show v) => Show (ISpline v) module Math.NURBS data NURBS v nurbs :: (VectorSpace v, (Scalar v) ~ w, VectorSpace w, (Scalar w) ~ w) => Knots (Scalar v) -> Vector (w, v) -> NURBS v toNURBS :: (Spline s v, (Scalar v) ~ (Scalar (Scalar v))) => s v -> NURBS v -- | Constructs the homogeneous-coordinates B-spline that corresponds to -- this NURBS curve -- -- Constructs the NURBS curve corresponding to a homogeneous-coordinates -- B-spline evalNURBS :: (VectorSpace v, (Scalar v) ~ w, VectorSpace w, (Scalar w) ~ w, Fractional w, Ord w) => NURBS v -> w -> v -- | Returns the domain of a NURBS - that is, the range of parameter values -- over which a spline with this degree and knot vector has a full basis -- set. nurbsDomain :: (Scalar v) ~ (Scalar (Scalar v)) => NURBS v -> Maybe (Scalar v, Scalar v) nurbsDegree :: NURBS v -> Int nurbsKnotVector :: (Scalar v) ~ (Scalar (Scalar v)) => NURBS v -> Knots (Scalar v) nurbsControlPoints :: NURBS v -> Vector (Scalar v, v) splitNURBS :: (VectorSpace v, (Scalar v) ~ w, VectorSpace w, (Scalar w) ~ w, Ord w, Fractional w) => NURBS v -> Scalar v -> Maybe (NURBS v, NURBS v) instance (Ord v, Ord (Scalar v), Ord (Scalar (Scalar v))) => Ord (NURBS v) instance (Eq v, Eq (Scalar v), Eq (Scalar (Scalar v))) => Eq (NURBS v) instance (Show v, Show (Scalar v), Show (Scalar (Scalar v))) => Show (NURBS v) module Math.Spline -- | A spline is a piecewise polynomial vector-valued function. The -- necessary and sufficient instance definition is toBSpline. class (VectorSpace v, Fractional (Scalar v), Ord (Scalar v)) => Spline s v splineDomain :: Spline s v => s v -> Maybe (Scalar v, Scalar v) evalSpline :: Spline s v => s v -> Scalar v -> v splineDegree :: Spline s v => s v -> Int knotVector :: Spline s v => s v -> Knots (Scalar v) toBSpline :: Spline s v => s v -> BSpline v class Spline s v => ControlPoints s v controlPoints :: ControlPoints s v => s v -> Vector v -- | Knot vectors - multisets of points in a 1-dimensional space. data Knots a -- | Create a knot vector consisting of all the knots in a list. mkKnots :: Ord a => [a] -> Knots a -- | Returns a list of all knots (not necessarily distinct) of a knot -- vector in ascending order knots :: Knots t -> [t] -- | A BezierCurve curve on 0 <= x <= 1. data BezierCurve t -- | Construct a Bezier curve from a list of control points. The degree of -- the curve is one less than the number of control points. bezierCurve :: Vector t -> BezierCurve t data BSpline t -- | bSpline kts cps creates a B-spline with the given knot vector -- and control points. The degree is automatically inferred as the -- difference between the number of spans in the knot vector -- (numKnots kts - 1) and the number of control points -- (length cps). bSpline :: Knots (Scalar a) -> Vector a -> BSpline a -- | M-Splines are B-splines normalized so that the integral of each basis -- function over the spline domain is 1. data MSpline v -- | mSpline kts cps creates a M-spline with the given knot vector -- and control points. The degree is automatically inferred as the -- difference between the number of spans in the knot vector -- (numKnots kts - 1) and the number of control points -- (length cps). mSpline :: Knots (Scalar a) -> Vector a -> MSpline a toMSpline :: Spline s v => s v -> MSpline v -- | The I-Spline basis functions are the integrals of the M-splines, or -- alternatively the integrals of the B-splines normalized to the range -- [0,1]. Every I-spline basis function increases monotonically from 0 to -- 1, thus it is useful as a basis for monotone functions. An I-Spline -- curve is monotone if and only if every non-zero control point has the -- same sign. data ISpline v -- | iSpline kts cps creates an I-spline with the given knot -- vector and control points. The degree is automatically inferred as the -- difference between the number of spans in the knot vector -- (numKnots kts - 1) and the number of control points -- (length cps). iSpline :: Knots (Scalar a) -> Vector a -> ISpline a toISpline :: (Spline s v, Eq v) => s v -> ISpline v