diagrams-lib-1.1.0.4: Embedded domain-specific language for declarative graphics

Maintainerdiagrams-discuss@googlegroups.com
Safe HaskellNone

Diagrams.Parametric

Description

Type classes for things which are parameterized in some way, e.g. segments and trails.

Synopsis

Documentation

stdTolerance :: Fractional a => aSource

The standard tolerance used by std... functions (like stdArcLength and stdArcLengthToParam, currently set at 1e-6.

type family Codomain p :: *Source

Codomain of parametric classes. This is usually either (V p), for relative vector results, or (Point (V p)), for functions with absolute coordinates.

class Parametric p whereSource

Type class for parametric functions.

Methods

atParam :: p -> Scalar (V p) -> Codomain pSource

atParam yields a parameterized view of an object as a continuous function. It is designed to be used infix, like path `atParam` 0.5.

Instances

(~ * (Codomain a) (V a), AdditiveGroup (V a), Parametric a) => Parametric (Located a) 
VectorSpace v => Parametric (FixedSegment v) 
(InnerSpace v, OrderedField (Scalar v), RealFrac (Scalar v)) => Parametric (Trail v) 
(InnerSpace v, OrderedField (Scalar v), RealFrac (Scalar v)) => Parametric (GetSegment (Trail v)) 
(InnerSpace v, OrderedField (Scalar v), RealFrac (Scalar v)) => Parametric (GetSegment (Trail' Loop v))

The parameterization for loops wraps around, i.e. parameters are first reduced "mod 1".

(InnerSpace v, OrderedField (Scalar v)) => Parametric (GetSegment (Trail' Line v))

Parameters less than 0 yield the first segment; parameters greater than 1 yield the last. A parameter exactly at the junction of two segments yields the second segment (i.e. the one with higher parameter values).

(InnerSpace v, OrderedField (Scalar v), RealFrac (Scalar v)) => Parametric (SegTree v) 
Parametric (Tangent t) => Parametric (Tangent (Located t)) 
(VectorSpace v, Num (Scalar v)) => Parametric (Tangent (Segment Closed v)) 
(InnerSpace v, OrderedField (Scalar v), RealFrac (Scalar v)) => Parametric (Tangent (Trail v)) 
(Parametric (GetSegment (Trail' c v)), VectorSpace v, Num (Scalar v)) => Parametric (Tangent (Trail' c v)) 
(VectorSpace v, Num (Scalar v)) => Parametric (Segment Closed v)

atParam yields a parametrized view of segments as continuous functions [0,1] -> v, which give the offset from the start of the segment for each value of the parameter between 0 and 1. It is designed to be used infix, like seg `atParam` 0.5.

(InnerSpace v, OrderedField (Scalar v), RealFrac (Scalar v)) => Parametric (Trail' l v) 

class DomainBounds p whereSource

Type class for parametric functions with a bounded domain. The default bounds are [0,1].

Note that this domain indicates the main "interesting" portion of the function. It must be defined within this range, but for some instances may still have sensible values outside.

Methods

domainLower :: p -> Scalar (V p)Source

domainLower defaults to being constantly 0 (for vector spaces with numeric scalars).

domainUpper :: p -> Scalar (V p)Source

domainUpper defaults to being constantly 1 (for vector spaces with numeric scalars).

domainBounds :: DomainBounds p => p -> (Scalar (V p), Scalar (V p))Source

Return the lower and upper bounds of a parametric domain together as a pair.

class (Parametric p, DomainBounds p) => EndValues p whereSource

Type class for querying the values of a parametric object at the ends of its domain.

Methods

atStart :: p -> Codomain pSource

atStart is the value at the start of the domain. That is,

 atStart x = x `atParam` domainLower x

This is the default implementation, but some representations will have a more efficient and/or precise implementation.

atEnd :: p -> Codomain pSource

atEnd is the value at the end of the domain. That is,

 atEnd x = x `atParam` domainUpper x

This is the default implementation, but some representations will have a more efficient and/or precise implementation.

class DomainBounds p => Sectionable p whereSource

Type class for parametric objects which can be split into subobjects.

Minimal definition: Either splitAtParam or section, plus reverseDomain.

Methods

splitAtParam :: p -> Scalar (V p) -> (p, p)Source

splitAtParam splits an object p into two new objects (l,r) at the parameter t, where l corresponds to the portion of p for parameter values from 0 to t and r for to that from t to 1. The following property should hold:

 prop_splitAtParam f t u =
   | u < t     = atParam f u == atParam l (u / t)
   | otherwise = atParam f u == atParam f t ??? atParam l ((u - t) / (domainUpper f - t))
   where (l,r) = splitAtParam f t

where (???) = (^+^) if the codomain is a vector type, or const flip if the codomain is a point type. Stated more intuitively, all this is to say that the parameterization scales linearly with splitting.

splitAtParam can also be used with parameters outside the range of the domain. For example, using the parameter 2 with a path (where the domain is the default [0,1]) gives two result paths where the first is the original path extended to the parameter 2, and the second result path travels backwards from the end of the first to the end of the original path.

section :: p -> Scalar (V p) -> Scalar (V p) -> pSource

Extract a particular section of the domain, linearly reparameterized to the same domain as the original. Should satisfy the property:

 prop_section x l u t =
   let s = section x l u
   in     domainBounds x == domainBounds x
       && (x `atParam` lerp l u t) == (s `atParam` t)

That is, the section should have the same domain as the original, and the reparameterization should be linear.

reverseDomain :: p -> pSource

Flip the parameterization on the domain.

Instances

(~ * (Codomain a) (V a), Fractional (Scalar (V a)), AdditiveGroup (V a), Sectionable a, Parametric a) => Sectionable (Located a) 
(VectorSpace v, Fractional (Scalar v)) => Sectionable (FixedSegment v) 
(InnerSpace v, RealFrac (Scalar v), Floating (Scalar v)) => Sectionable (Trail v)

Note that there is no Sectionable instance for Trail' Loop, because it does not make sense (splitting a loop at a parameter results in a single line, not two loops). However, it's convenient to have a Sectionable instance for Trail; if the Trail contains a loop the loop will first be cut and then splitAtParam called on the resulting line. This is semantically a bit silly, so please don't rely on it. (*E.g.* if this is really the behavior you want, consider first calling cutLoop yourself.)

(InnerSpace v, RealFrac (Scalar v), Floating (Scalar v)) => Sectionable (SegTree v) 
(VectorSpace v, Fractional (Scalar v)) => Sectionable (Segment Closed v) 
(InnerSpace v, RealFrac (Scalar v), Floating (Scalar v)) => Sectionable (Trail' Line v) 

class Parametric p => HasArcLength p whereSource

Type class for parametric things with a notion of arc length.

Methods

arcLengthBounded :: Scalar (V p) -> p -> Interval (Scalar (V p))Source

arcLengthBounded eps x approximates the arc length of x. The true arc length is guaranteed to lie within the interval returned, which will have a size of at most eps.

arcLength :: Scalar (V p) -> p -> Scalar (V p)Source

arcLength eps s approximates the arc length of x up to the accuracy eps (plus or minus).

stdArcLength :: p -> Scalar (V p)Source

Approximate the arc length up to a standard accuracy of stdTolerance (1e-6).

arcLengthToParam :: Scalar (V p) -> p -> Scalar (V p) -> Scalar (V p)Source

arcLengthToParam eps s l converts the absolute arc length l, measured from the start of the domain, to a parameter on the object s. The true arc length at the parameter returned is guaranteed to be within eps of the requested arc length.

This should work for any arc length, and may return any parameter value (not just parameters in the domain).

stdArcLengthToParam :: p -> Scalar (V p) -> Scalar (V p)Source

A simple interface to convert arc length to a parameter, guaranteed to be accurate within stdTolerance, or 1e-6.