diagrams-core-1.4: Core libraries for diagrams EDSL

Diagrams.Core.Trace

Description

diagrams-core defines the core library of primitives forming the basis of an embedded domain-specific 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

# 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 # SortedList forms a semigroup with merge as composition. Methods(<>) :: 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 # SortedList forms a monoid with merge and the empty list. Methodsmappend :: 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 order-preserving list function to a SortedList. No sorts or checks are done.

# Traces

newtype Trace v n Source #

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).

Constructors

 Trace FieldsappTrace :: Point v n -> v n -> SortedList n

Instances

 Show (Trace v n) Source # MethodsshowsPrec :: Int -> Trace v n -> ShowS #show :: Trace v n -> String #showList :: [Trace v n] -> ShowS # Ord n => Semigroup (Trace v n) Source # Methods(<>) :: Trace v n -> Trace v n -> Trace v n #sconcat :: NonEmpty (Trace v n) -> Trace v n #stimes :: Integral b => b -> Trace v n -> Trace v n # Ord n => Monoid (Trace v n) Source # Methodsmempty :: Trace v n #mappend :: Trace v n -> Trace v n -> Trace v n #mconcat :: [Trace v n] -> Trace v n # Wrapped (Trace v n) Source # Associated Typestype Unwrapped (Trace v n) :: * # Methods_Wrapped' :: Iso' (Trace v n) (Unwrapped (Trace v n)) # (Additive v, Num n) => HasOrigin (Trace v n) Source # MethodsmoveOriginTo :: Point (V (Trace v n)) (N (Trace v n)) -> Trace v n -> Trace v n Source # (Additive v, Num n) => Transformable (Trace v n) Source # Methodstransform :: Transformation (V (Trace v n)) (N (Trace v n)) -> Trace v n -> Trace v n Source # (Additive v, Ord n) => Traced (Trace v n) Source # MethodsgetTrace :: Trace v n -> Trace (V (Trace v n)) (N (Trace v n)) Source # Rewrapped (Trace v n) (Trace v' n') Source # type Unwrapped (Trace v n) Source # type Unwrapped (Trace v n) = Point v n -> v n -> SortedList n type N (Trace v n) Source # type N (Trace v n) = n type V (Trace v n) Source # type V (Trace v n) = v

mkTrace :: (Point v n -> v n -> SortedList n) -> Trace v n Source #

# Traced class

class (Additive (V a), Ord (N a)) => Traced a where Source #

Traced abstracts over things which have a trace.

Minimal complete definition

getTrace

Methods

getTrace :: a -> Trace (V a) (N a) Source #

Compute the trace of an object.

Instances

 Traced b => Traced [b] Source # MethodsgetTrace :: [b] -> Trace (V [b]) (N [b]) Source # Traced b => Traced (Set b) Source # MethodsgetTrace :: Set b -> Trace (V (Set b)) (N (Set b)) Source # Traced t => Traced (TransInv t) Source # MethodsgetTrace :: TransInv t -> Trace (V (TransInv t)) (N (TransInv t)) Source # (Traced a, Traced b, SameSpace a b) => Traced (a, b) Source # MethodsgetTrace :: (a, b) -> Trace (V (a, b)) (N (a, b)) Source # Traced b => Traced (Map k b) Source # MethodsgetTrace :: Map k b -> Trace (V (Map k b)) (N (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 floating-point inaccuracy this is problematic. Note that the envelope for a single point is not the empty envelope (see Diagrams.Core.Envelope). MethodsgetTrace :: Point v n -> Trace (V (Point v n)) (N (Point v n)) Source # (Additive v, Ord n) => Traced (Trace v n) Source # MethodsgetTrace :: Trace v n -> Trace (V (Trace v n)) (N (Trace v n)) Source # (OrderedField n, Metric v, Semigroup m) => Traced (Subdiagram b v n m) Source # MethodsgetTrace :: 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 # MethodsgetTrace :: QDiagram b v n m -> Trace (V (QDiagram b v n m)) (N (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.)

getRayTrace :: (n ~ N a, Traced a, Num n) => a -> Trace (V a) n Source #

Get a modified Trace for an object which only returns positive boundary points, i.e. those boundary points given by a positive scalar multiple of the direction vector. Note, this property will be destroyed if the resulting Trace is translated at all.

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.

maxRayTraceV :: (n ~ N a, Traced a, Num n) => Point (V a) n -> V a n -> a -> Maybe (V a n) Source #

Like rayTraceV, but computes a vector to the "largest" boundary point instead of the smallest. Considers only positive boundary points.

maxRayTraceP :: (n ~ N a, Traced a, Num n) => Point (V a) n -> V a n -> a -> Maybe (Point (V a) n) Source #

Like rayTraceP, but computes the "largest" boundary point instead of the smallest. Considers only positive boundary points.