Maintainer | diagrams-discuss@googlegroups.com |
---|---|
Safe Haskell | None |
A segment is a translation-invariant, atomic path. There are two types: linear (i.e. just a straight line to the endpoint) and cubic Bézier curves (i.e. a curve to an endpoint with two control points). This module contains tools for creating and manipulating segments, as well as a definition of segments with a fixed location (useful for backend implementors).
Generally speaking, casual users of diagrams should not need this module; the higher-level functionality provided by Diagrams.Path should usually suffice instead. However, directly manipulating segments can occasionally be useful.
- data Segment v
- straight :: v -> Segment v
- bezier3 :: v -> v -> v -> Segment v
- atParam :: (VectorSpace v, Num (Scalar v)) => Segment v -> Scalar v -> v
- segOffset :: Segment v -> v
- reverseSegment :: AdditiveGroup v => Segment v -> Segment v
- splitAtParam :: VectorSpace v => Segment v -> Scalar v -> (Segment v, Segment v)
- arcLength :: (InnerSpace v, Floating (Scalar v), Ord (Scalar v)) => Segment v -> Scalar v -> Scalar v
- arcLengthToParam :: (InnerSpace v, Floating (Scalar v), Ord (Scalar v), AdditiveGroup v) => Segment v -> Scalar v -> Scalar v -> Scalar v
- adjustSegment :: (InnerSpace v, OrderedField (Scalar v)) => Segment v -> AdjustOpts v -> Segment v
- data AdjustOpts v = ALO {
- adjMethod :: AdjustMethod v
- adjSide :: AdjustSide
- adjEps :: Scalar v
- adjOptsvProxy__ :: Proxy v
- data AdjustMethod v
- = ByParam (Scalar v)
- | ByAbsolute (Scalar v)
- | ToAbsolute (Scalar v)
- data AdjustSide
- adjustSegmentToParams :: (Fractional (Scalar v), VectorSpace v) => Segment v -> Scalar v -> Scalar v -> Segment v
- data FixedSegment v
- mkFixedSeg :: AdditiveGroup v => Point v -> Segment v -> FixedSegment v
- fromFixedSeg :: AdditiveGroup v => FixedSegment v -> (Point v, Segment v)
- fAtParam :: VectorSpace v => FixedSegment v -> Scalar v -> Point v
Constructing segments
The atomic constituents of paths are segments, which are single straight lines or cubic Bézier curves. Segments are translationally invariant, that is, they have no particular "location" and are unaffected by translations. They are, however, affected by other transformations such as rotations and scales.
Linear v | A linear segment with given offset. |
Cubic v v v | A cubic Bézier segment specified by three offsets from the starting point to the first control point, second control point, and ending point, respectively. |
Functor Segment | |
Eq v => Eq (Segment v) | |
(Eq (Segment v), Ord v) => Ord (Segment v) | |
Show v => Show (Segment v) | |
(InnerSpace (V (Segment v)), OrderedField (Scalar (V (Segment v))), InnerSpace v, OrderedField (Scalar v)) => Enveloped (Segment v) | The envelope for a segment is based at the segment's start. |
Traced (Segment R2) | |
(HasLinearMap (V (Segment v)), HasLinearMap v) => Transformable (Segment v) | |
(Transformable (Segment v), HasLinearMap v) => Renderable (Segment v) NullBackend | |
(Transformable (Segment v), Show v, HasLinearMap v) => Renderable (Segment v) ShowBackend |
straight :: v -> Segment vSource
constructs a translationally invariant linear
segment with direction and length given by the vector straight
vv
.
bezier3 :: v -> v -> v -> Segment vSource
bezier3 v1 v2 v3
constructs a translationally invariant cubic
Bézier curve where the offsets from the first endpoint to the
first and second control point and endpoint are respectively
given by v1
, v2
, and v3
.
Computing with segments
segOffset :: Segment v -> vSource
Compute the offset from the start of a segment to the
end. Note that in the case of a Bézier segment this is not the
same as the length of the curve itself; for that, see arcLength
.
reverseSegment :: AdditiveGroup v => Segment v -> Segment vSource
Reverse the direction of a segment.
splitAtParam :: VectorSpace v => Segment v -> Scalar v -> (Segment v, Segment v)Source
splitAtParam
splits a segment s
into two new segments (l,r)
at the parameter t
where l
corresponds to the portion of
s
for parameter values from 0
to t
and r
for s
from t
to 1
.
The following should hold for splitting:
paramSplit s t u | u < t = atParam s u == atParam l (u / t) | otherwise = atParam s u == atParam s t ^+^ atParam l ((u - t) / (1.0 - t)) where (l,r) = splitAtParam s t
That is to say, the parameterization scales linearly with splitting.
splitAtParam
can also be used with parameters outside the range
(0,1). For example, using the parameter 2
gives two result
segments where the first is the original segment extended to the
parameter 2, and the second result segment travels backwards
from the end of the first to the end of the original segment.
arcLength :: (InnerSpace v, Floating (Scalar v), Ord (Scalar v)) => Segment v -> Scalar v -> Scalar vSource
arcLengthToParam :: (InnerSpace v, Floating (Scalar v), Ord (Scalar v), AdditiveGroup v) => Segment v -> Scalar v -> Scalar v -> Scalar vSource
converts the absolute arc length arcLengthToParam
s l ml
,
measured from the segment starting point, to a parameter on the
segment s
, with accuracy of at least plus or minus m
. Works
for any arc length, and may return any parameter value (not
just parameters between 0 and 1).
Adjusting segments
adjustSegment :: (InnerSpace v, OrderedField (Scalar v)) => Segment v -> AdjustOpts v -> Segment vSource
Adjust the length of a segment. The second parameter is an
option record which controls how the adjustment should be
performed; see AdjustOpts
.
data AdjustOpts v Source
How should a segment, trail, or path be adjusted?
ALO | |
|
Fractional (Scalar v) => Default (AdjustOpts v) |
data AdjustMethod v Source
What method should be used for adjusting a segment, trail, or path?
ByParam (Scalar v) | Extend by the given parameter value (use a negative parameter to shrink) |
ByAbsolute (Scalar v) | Extend by the given arc length (use a negative length to shrink) |
ToAbsolute (Scalar v) | Extend or shrink to the given arc length |
Fractional (Scalar v) => Default (AdjustMethod v) |
data AdjustSide Source
Which side of a segment, trail, or path should be adjusted?
adjustSegmentToParams :: (Fractional (Scalar v), VectorSpace v) => Segment v -> Scalar v -> Scalar v -> Segment vSource
Given a segment and parameters t1
, t2
, produce the segment
which lies on the (infinitely extended) original segment
beginning at t1
and ending at t2
.
Fixed (absolutely located) segments
data FixedSegment v Source
FixedSegment
s are like Segment
s except that they have
absolute locations.
Show v => Show (FixedSegment v) | |
(InnerSpace (V (FixedSegment v)), OrderedField (Scalar (V (FixedSegment v))), InnerSpace v, OrderedField (Scalar v)) => Enveloped (FixedSegment v) | |
Traced (FixedSegment R2) | |
(HasLinearMap (V (FixedSegment v)), HasLinearMap v) => Transformable (FixedSegment v) | |
(VectorSpace (V (FixedSegment v)), VectorSpace v) => HasOrigin (FixedSegment v) |
mkFixedSeg :: AdditiveGroup v => Point v -> Segment v -> FixedSegment vSource
Create a FixedSegment
from a starting point and a Segment
.
fromFixedSeg :: AdditiveGroup v => FixedSegment v -> (Point v, Segment v)Source
Decompose a FixedSegment
into a starting point and a Segment
.
fAtParam :: VectorSpace v => FixedSegment v -> Scalar v -> Point vSource
Compute the point on a fixed segment at a given parameter. A parameter of 0 corresponds to the starting point and 1 corresponds to the ending point.