Copyright  (c) 20122015 diagramscore team (see LICENSE) 

License  BSDstyle (see LICENSE) 
Maintainer  diagramsdiscuss@googlegroups.com 
Safe Haskell  None 
Language  Haskell2010 
diagramscore
defines the core library of primitives
forming the basis of an embedded domainspecific language for
describing and rendering diagrams.
The Trace
module defines a data type and type class for
"traces", aka functional boundaries, essentially corresponding to
embedding a raytracer with each diagram.
Synopsis
 data SortedList a
 mkSortedList :: Ord a => [a] > SortedList a
 getSortedList :: SortedList a > [a]
 onSortedList :: Ord b => ([a] > [b]) > SortedList a > SortedList b
 unsafeOnSortedList :: ([a] > [b]) > SortedList a > SortedList b
 newtype Trace v n = Trace (Point v n > v n > SortedList n)
 appTrace :: Trace v n > Point v n > v n > SortedList n
 mkTrace :: (Point v n > v n > SortedList n) > Trace v n
 class (Additive (V a), Ord (N a)) => Traced a where
 traceV :: (n ~ N a, Num n, Traced a) => Point (V a) n > V a n > a > Maybe (V a n)
 traceP :: (n ~ N a, Traced a, Num n) => Point (V a) n > V a n > a > Maybe (Point (V a) n)
 maxTraceV :: (n ~ N a, Num n, Traced a) => Point (V a) n > V a n > a > Maybe (V a n)
 maxTraceP :: (n ~ N a, Num n, Traced a) => Point (V a) n > V a n > a > Maybe (Point (V a) n)
 getRayTrace :: (n ~ N a, Traced a, Num n) => a > Trace (V a) n
 rayTraceV :: (n ~ N a, Traced a, Num n) => Point (V a) n > V a n > a > Maybe (V a n)
 rayTraceP :: (n ~ N a, Traced a, Num n) => Point (V a) n > V a n > a > Maybe (Point (V a) n)
 maxRayTraceV :: (n ~ N a, Traced a, Num n) => Point (V a) n > V a n > a > Maybe (V a n)
 maxRayTraceP :: (n ~ N a, Traced a, Num n) => Point (V a) n > V a n > a > Maybe (Point (V a) n)
SortedList
data SortedList a Source #
A newtype wrapper around a list which maintains the invariant
that the list is sorted. The constructor is not exported; use
the smart constructor mkSortedList
(which sorts the given list)
instead.
Instances
Ord a => Semigroup (SortedList a) Source # 

Defined in Diagrams.Core.Trace (<>) :: SortedList a > SortedList a > SortedList a # sconcat :: NonEmpty (SortedList a) > SortedList a # stimes :: Integral b => b > SortedList a > SortedList a #  
Ord a => Monoid (SortedList a) Source # 

Defined in Diagrams.Core.Trace mempty :: SortedList a # mappend :: SortedList a > SortedList a > SortedList a # mconcat :: [SortedList a] > SortedList a # 
mkSortedList :: Ord a => [a] > SortedList a Source #
A smart constructor for the SortedList
type, which sorts the
input to ensure the SortedList
invariant.
getSortedList :: SortedList a > [a] Source #
Project the (guaranteed sorted) list out of a SortedList
wrapper.
onSortedList :: Ord b => ([a] > [b]) > SortedList a > SortedList b Source #
Apply a list function to a SortedList
. The function need not
result in a sorted list; the result will be sorted before being
rewrapped as a SortedList
.
unsafeOnSortedList :: ([a] > [b]) > SortedList a > SortedList b Source #
Apply an orderpreserving list function to a SortedList
. No
sorts or checks are done.
Traces
Every diagram comes equipped with a trace. Intuitively, the trace for a diagram is like a raytracer: given a line (represented as a base point and a direction vector), the trace computes a sorted list of signed distances from the base point to all intersections of the line with the boundary of the diagram.
Note that the outputs are not absolute distances, but multipliers
relative to the input vector. That is, if the base point is p
and direction vector is v
, and one of the output scalars is
s
, then there is an intersection at the point p .+^ (s *^ v)
.
Trace (Point v n > v n > SortedList n) 
Instances
Action Name (Trace v n) Source #  
Show (Trace v n) Source #  
Ord n => Semigroup (Trace v n) Source #  Traces form a semigroup with pointwise minimum as composition.
Hence, if 
Ord n => Monoid (Trace v n) Source #  
Wrapped (Trace v n) Source #  
(Additive v, Num n) => HasOrigin (Trace v n) Source #  
(Additive v, Num n) => Transformable (Trace v n) Source #  
(Additive v, Ord n) => Traced (Trace v n) Source #  
Rewrapped (Trace v n) (Trace v' n') Source #  
Defined in Diagrams.Core.Trace  
type Unwrapped (Trace v n) Source #  
Defined in Diagrams.Core.Trace  
type N (Trace v n) Source #  
Defined in Diagrams.Core.Trace  
type V (Trace v n) Source #  
Defined in Diagrams.Core.Trace 
Traced class
class (Additive (V a), Ord (N a)) => Traced a where Source #
Traced
abstracts over things which have a trace.
Instances
Traced b => Traced [b] Source #  
Traced b => Traced (Set b) Source #  
Traced t => Traced (TransInv t) Source #  
(Traced a, Traced b, SameSpace a b) => Traced (a, b) Source #  
Traced b => Traced (Map k b) Source #  
(Additive v, Ord n) => Traced (Point v n) Source #  The trace of a single point is the empty trace, i.e. the one which returns no intersection points for every query. Arguably it should return a single finite distance for vectors aimed directly at the given point, but due to floatingpoint inaccuracy this is problematic. Note that the envelope for a single point is not the empty envelope (see Diagrams.Core.Envelope). 
(Additive v, Ord n) => Traced (Trace v n) Source #  
(OrderedField n, Metric v, Semigroup m) => Traced (Subdiagram b v n m) Source #  
Defined in Diagrams.Core.Types getTrace :: Subdiagram b v n m > Trace (V (Subdiagram b v n m)) (N (Subdiagram b v n m)) Source #  
(Metric v, OrderedField n, Semigroup m) => Traced (QDiagram b v n m) Source #  
Computing with traces
traceV :: (n ~ N a, Num n, Traced a) => Point (V a) n > V a n > a > Maybe (V a n) Source #
Compute the vector from the given point p
to the "smallest"
boundary intersection along the given vector v
. The
"smallest" boundary intersection is defined as the one given by
p .+^ (s *^ v)
for the smallest (most negative) value of
s
. Return Nothing
if there is no intersection. See also
traceP
.
See also rayTraceV
which uses the smallest positive
intersection, which is often more intuitive behavior.
traceP :: (n ~ N a, Traced a, Num n) => Point (V a) n > V a n > a > Maybe (Point (V a) n) Source #
Compute the "smallest" boundary point along the line determined
by the given point p
and vector v
. The "smallest" boundary
point is defined as the one given by p .+^ (s *^ v)
for
the smallest (most negative) value of s
. Return Nothing
if
there is no such boundary point. See also traceV
.
See also rayTraceP
which uses the smallest positive
intersection, which is often more intuitive behavior.
maxTraceV :: (n ~ N a, Num n, Traced a) => Point (V a) n > V a n > a > Maybe (V a n) Source #
Like traceV
, but computes a vector to the "largest" boundary
point instead of the smallest. (Note, however, the "largest"
boundary point may still be in the opposite direction from the
given vector, if all the boundary points are, as in the third
example shown below.)
maxTraceP :: (n ~ N a, Num n, Traced a) => Point (V a) n > V a n > a > Maybe (Point (V a) n) Source #
Like traceP
, but computes the "largest" boundary point
instead of the smallest. (Note, however, the "largest" boundary
point may still be in the opposite direction from the given
vector, if all the boundary points are.)
rayTraceV :: (n ~ N a, Traced a, Num n) => Point (V a) n > V a n > a > Maybe (V a n) Source #
Compute the vector from the given point to the closest boundary
point of the given object in the given direction, or Nothing
if
there is no such boundary point (as in the third example
below). Note that unlike traceV
, only positive boundary
points are considered, i.e. boundary points corresponding to a
positive scalar multiple of the direction vector. This is
intuitively the "usual" behavior of a raytracer, which only
considers intersections "in front of" the camera. Compare the
second example diagram below with the second example shown for
traceV
.
rayTraceP :: (n ~ N a, Traced a, Num n) => Point (V a) n > V a n > a > Maybe (Point (V a) n) Source #
Compute the boundary point on an object which is closest to the
given base point in the given direction, or Nothing
if there is
no such boundary point. Note that unlike traceP
, only positive
boundary points are considered, i.e. boundary points
corresponding to a positive scalar multiple of the direction
vector. This is intuitively the "usual" behavior of a raytracer,
which only considers intersection points "in front of" the
camera.