-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Geometric Algorithms, Data structures, and Data types. -- -- HGeometry provides some basic geometry types, and geometric algorithms -- and data structures for them. The main two focusses are: (1) Strong -- type safety, and (2) implementations of geometric algorithms and data -- structures with good asymptotic running time guarantees. Note that -- HGeometry is still highly experimental, don't be surprised to find -- bugs. @package hgeometry @version 0.13 module Algorithms.Geometry.SoS.Symbolic data EpsFold i -- | Creates the term <math> eps :: i -> EpsFold i mkEpsFold :: Ord i => [i] -> EpsFold i -- | Test if the epsfold has no pertubation at all (i.e. if it is -- <math> hasNoPertubation :: EpsFold i -> Bool -- | Gets the factors factors :: EpsFold i -> Bag i -- | computes a base d that can be used as: -- -- <math> suitableBase :: EpsFold i -> Int -- | A term 'Term c es' represents a term: -- -- <math> -- -- for a constant c and an arbitrarily small value <math>, -- parameterized by i. data Term i r Term :: r -> EpsFold i -> Term i r -- | Creates a singleton term term :: r -> i -> Term i r -- | Lens to access the constant c in the term. constantFactor :: Lens' (Term i r) r -- | Represents a Sum of terms, i.e. a value that has the form: -- -- <math> -- -- The terms are represented in order of decreasing significance. -- -- The main idea in this type is that, if symbolic values contains -- <math> terms we can always order them. That is, two Symbolic -- terms will be equal only if: -- -- data Symbolic i r -- | Creates a constant symbolic value constant :: Ord i => r -> Symbolic i r -- | Creates a symbolic vlaue with a single indexed term. If you just need -- a constant (i.e. non-indexed), use constant symbolic :: Ord i => r -> i -> Symbolic i r -- | given the value c and the index i, creates the perturbed value -- <math> perturb :: (Num r, Ord i) => r -> i -> Symbolic i r -- | Produces a list of terms, in decreasing order of significance toTerms :: Symbolic i r -> [Term i r] -- | Computing the Sign of an expression. (Nothing represents zero) signOf :: (Num r, Eq r) => Symbolic i r -> Maybe Sign instance (GHC.Classes.Ord a, Test.QuickCheck.Arbitrary.Arbitrary a) => Test.QuickCheck.Arbitrary.Arbitrary (Algorithms.Geometry.SoS.Symbolic.Bag a) instance GHC.Classes.Ord a => GHC.Classes.Ord (Algorithms.Geometry.SoS.Symbolic.Bag a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Algorithms.Geometry.SoS.Symbolic.Bag a) instance GHC.Show.Show a => GHC.Show.Show (Algorithms.Geometry.SoS.Symbolic.Bag a) instance GHC.Classes.Ord i => GHC.Base.Monoid (Algorithms.Geometry.SoS.Symbolic.EpsFold i) instance GHC.Classes.Ord i => GHC.Base.Semigroup (Algorithms.Geometry.SoS.Symbolic.EpsFold i) instance GHC.Base.Functor (Algorithms.Geometry.SoS.Symbolic.Symbolic i) instance GHC.Base.Functor (Algorithms.Geometry.SoS.Symbolic.Term i) instance (GHC.Classes.Ord i, GHC.Classes.Eq r) => GHC.Classes.Eq (Algorithms.Geometry.SoS.Symbolic.Term i r) instance (GHC.Show.Show i, GHC.Show.Show r) => GHC.Show.Show (Algorithms.Geometry.SoS.Symbolic.Term i r) instance (GHC.Classes.Ord i, GHC.Classes.Ord r, GHC.Num.Num r) => GHC.Classes.Ord (Algorithms.Geometry.SoS.Symbolic.Term i r) instance (Test.QuickCheck.Arbitrary.Arbitrary r, Test.QuickCheck.Arbitrary.Arbitrary (Algorithms.Geometry.SoS.Symbolic.EpsFold i), GHC.Classes.Ord i) => Test.QuickCheck.Arbitrary.Arbitrary (Algorithms.Geometry.SoS.Symbolic.Term i r) instance (GHC.Classes.Ord i, GHC.Classes.Eq r, GHC.Num.Num r) => GHC.Classes.Eq (Algorithms.Geometry.SoS.Symbolic.Symbolic i r) instance (GHC.Classes.Ord i, GHC.Classes.Ord r, GHC.Num.Num r) => GHC.Classes.Ord (Algorithms.Geometry.SoS.Symbolic.Symbolic i r) instance (GHC.Classes.Ord i, GHC.Num.Num r, GHC.Classes.Eq r) => GHC.Num.Num (Algorithms.Geometry.SoS.Symbolic.Symbolic i r) instance (GHC.Show.Show i, GHC.Show.Show r) => GHC.Show.Show (Algorithms.Geometry.SoS.Symbolic.Symbolic i r) instance (Test.QuickCheck.Arbitrary.Arbitrary r, GHC.Classes.Ord i, Test.QuickCheck.Arbitrary.Arbitrary (Algorithms.Geometry.SoS.Symbolic.EpsFold i)) => Test.QuickCheck.Arbitrary.Arbitrary (Algorithms.Geometry.SoS.Symbolic.Symbolic i r) instance GHC.Show.Show i => GHC.Show.Show (Algorithms.Geometry.SoS.Symbolic.EpsFold i) instance GHC.Classes.Ord i => GHC.Classes.Eq (Algorithms.Geometry.SoS.Symbolic.EpsFold i) instance GHC.Classes.Ord i => GHC.Classes.Ord (Algorithms.Geometry.SoS.Symbolic.EpsFold i) instance (Test.QuickCheck.Arbitrary.Arbitrary i, GHC.Classes.Ord i) => Test.QuickCheck.Arbitrary.Arbitrary (Algorithms.Geometry.SoS.Symbolic.EpsFold i) instance Data.Foldable.Foldable Algorithms.Geometry.SoS.Symbolic.Bag instance GHC.Classes.Ord k => GHC.Base.Semigroup (Algorithms.Geometry.SoS.Symbolic.Bag k) instance GHC.Classes.Ord k => GHC.Base.Monoid (Algorithms.Geometry.SoS.Symbolic.Bag k) module Data.Geometry.Directions -- | The four cardinal directions. data CardinalDirection North :: CardinalDirection East :: CardinalDirection South :: CardinalDirection West :: CardinalDirection -- | Computes the direction opposite to the given one. oppositeDirection :: CardinalDirection -> CardinalDirection -- | Intercardinal directions data InterCardinalDirection NorthWest :: InterCardinalDirection NorthEast :: InterCardinalDirection SouthEast :: InterCardinalDirection SouthWest :: InterCardinalDirection -- | Get the two intercardinal directions, in increasing order, -- corresponding to the cardinal direction. interCardinalsOf :: CardinalDirection -> Two InterCardinalDirection instance GHC.Enum.Bounded Data.Geometry.Directions.CardinalDirection instance GHC.Enum.Enum Data.Geometry.Directions.CardinalDirection instance GHC.Classes.Ord Data.Geometry.Directions.CardinalDirection instance GHC.Classes.Eq Data.Geometry.Directions.CardinalDirection instance GHC.Read.Read Data.Geometry.Directions.CardinalDirection instance GHC.Show.Show Data.Geometry.Directions.CardinalDirection instance GHC.Generics.Generic Data.Geometry.Directions.InterCardinalDirection instance GHC.Enum.Enum Data.Geometry.Directions.InterCardinalDirection instance GHC.Classes.Ord Data.Geometry.Directions.InterCardinalDirection instance GHC.Classes.Eq Data.Geometry.Directions.InterCardinalDirection instance GHC.Read.Read Data.Geometry.Directions.InterCardinalDirection instance GHC.Show.Show Data.Geometry.Directions.InterCardinalDirection module Data.Geometry.Interval.Util -- | Open on left endpoint; so Closed before open newtype L r L :: EndPoint r -> L r [_unL] :: L r -> EndPoint r unL :: forall r_alAe r_am3R. Iso (L r_alAe) (L r_am3R) (EndPoint r_alAe) (EndPoint r_am3R) -- | Order on right endpoint; so Open before Closed newtype R r R :: EndPoint r -> R r [_unR] :: R r -> EndPoint r unR :: forall r_am3X r_amgQ. Iso (R r_am3X) (R r_amgQ) (EndPoint r_am3X) (EndPoint r_amgQ) instance Control.DeepSeq.NFData r => Control.DeepSeq.NFData (Data.Geometry.Interval.Util.R r) instance GHC.Generics.Generic (Data.Geometry.Interval.Util.R r) instance GHC.Classes.Ord r => GHC.Classes.Ord (Data.Geometry.Interval.Util.R r) instance GHC.Classes.Eq r => GHC.Classes.Eq (Data.Geometry.Interval.Util.R r) instance GHC.Show.Show r => GHC.Show.Show (Data.Geometry.Interval.Util.R r) instance GHC.Classes.Ord r => GHC.Classes.Ord (Data.Geometry.Interval.Util.L r) instance Control.DeepSeq.NFData r => Control.DeepSeq.NFData (Data.Geometry.Interval.Util.L r) instance GHC.Generics.Generic (Data.Geometry.Interval.Util.L r) instance GHC.Classes.Eq r => GHC.Classes.Eq (Data.Geometry.Interval.Util.L r) instance GHC.Show.Show r => GHC.Show.Show (Data.Geometry.Interval.Util.L r) -- | Defines some generic geometric properties e.g. Dimensions, NumType, -- and Intersection types. module Data.Geometry.Properties -- | A type family for types that are associated with a dimension. The -- dimension is the dimension of the geometry they are embedded in. type family Dimension t :: Nat -- | A type family for types that have an associated numeric type. type family NumType t :: * module Data.Geometry.Interval -- | An Interval is essentially a Range but with possible payload -- -- We can think of an interval being defined as: -- --
--   >>> data Interval a r = Interval (EndPoint (r :+ a)) (EndPoint (r :+ a))
--   
data Interval a r pattern Interval :: EndPoint (r :+ a) -> EndPoint (r :+ a) -> Interval a r pattern OpenInterval :: (r :+ a) -> (r :+ a) -> Interval a r pattern ClosedInterval :: (r :+ a) -> (r :+ a) -> Interval a r -- | Constrct an interval from a Range fromRange :: Range (r :+ a) -> Interval a r -- | Cast an interval to a range. toRange :: Interval a r -> Range (r :+ a) -- | Intervals and ranges are isomorphic. _Range :: Iso' (Interval a r) (Range (r :+ a)) class HasStart t where { type family StartCore t; type family StartExtra t; } start :: HasStart t => Lens' t (StartCore t :+ StartExtra t) class HasEnd t where { type family EndCore t; type family EndExtra t; } end :: HasEnd t => Lens' t (EndCore t :+ EndExtra t) -- | Test if a value lies in an interval. Note that the difference between -- inInterval and inRange is that the extra value is *not* used in the -- comparison with inInterval, whereas it is in inRange. inInterval :: Ord r => r -> Interval a r -> Bool -- | Shifts the interval to the left by delta shiftLeft' :: Num r => r -> Interval a r -> Interval a r -- | Makes sure the start and endpoint are oriented such that the starting -- value is smaller than the ending value. asProperInterval :: Ord r => Interval p r -> Interval p r -- | Flips the start and endpoint of the interval. flipInterval :: Interval a r -> Interval a r instance (Test.QuickCheck.Arbitrary.Arbitrary r, Test.QuickCheck.Arbitrary.Arbitrary a, GHC.Classes.Ord r, GHC.Classes.Ord a) => Test.QuickCheck.Arbitrary.Arbitrary (Data.Geometry.Interval.Interval a r) instance GHC.Generics.Generic (Data.Geometry.Interval.Interval a r) instance (GHC.Classes.Eq r, GHC.Classes.Eq a) => GHC.Classes.Eq (Data.Geometry.Interval.Interval a r) instance (Control.DeepSeq.NFData a, Control.DeepSeq.NFData r) => Control.DeepSeq.NFData (Data.Geometry.Interval.Interval a r) instance Data.Geometry.Interval.HasEnd (Data.Geometry.Interval.Interval a r) instance Data.Geometry.Interval.HasStart (Data.Geometry.Interval.Interval a r) instance (GHC.Show.Show a, GHC.Show.Show r) => GHC.Show.Show (Data.Geometry.Interval.Interval a r) instance GHC.Base.Functor (Data.Geometry.Interval.Interval a) instance Data.Foldable.Foldable (Data.Geometry.Interval.Interval a) instance Data.Traversable.Traversable (Data.Geometry.Interval.Interval a) instance Data.Bifunctor.Bifunctor Data.Geometry.Interval.Interval instance GHC.Classes.Ord r => Data.Intersection.HasIntersectionWith (Data.Geometry.Interval.Interval a r) (Data.Geometry.Interval.Interval a r) instance GHC.Classes.Ord r => Data.Intersection.IsIntersectableWith (Data.Geometry.Interval.Interval a r) (Data.Geometry.Interval.Interval a r) module Data.Geometry.IntervalTree -- | Information stored in a node of the Interval Tree data NodeData i r NodeData :: !r -> !Map (L r) [i] -> !Map (R r) [i] -> NodeData i r [_splitPoint] :: NodeData i r -> !r [_intervalsLeft] :: NodeData i r -> !Map (L r) [i] [_intervalsRight] :: NodeData i r -> !Map (R r) [i] splitPoint :: forall i_apju r_apjv. Lens' (NodeData i_apju r_apjv) r_apjv intervalsLeft :: forall i_apju r_apjv. Lens' (NodeData i_apju r_apjv) (Map (L r_apjv) [i_apju]) intervalsRight :: forall i_apju r_apjv. Lens' (NodeData i_apju r_apjv) (Map (R r_apjv) [i_apju]) -- | IntervalTree type, storing intervals of type i newtype IntervalTree i r IntervalTree :: BinaryTree (NodeData i r) -> IntervalTree i r [_unIntervalTree] :: IntervalTree i r -> BinaryTree (NodeData i r) unIntervalTree :: forall i_apsx r_apsy i_apzv r_apzw. Iso (IntervalTree i_apsx r_apsy) (IntervalTree i_apzv r_apzw) (BinaryTree (NodeData i_apsx r_apsy)) (BinaryTree (NodeData i_apzv r_apzw)) -- | Anything that looks like an interval class IntervalLike i asRange :: IntervalLike i => i -> Range (NumType i) -- | Given an ordered list of points, create an interval tree -- -- <math> createTree :: Ord r => [r] -> IntervalTree i r -- | Build an interval tree -- -- <math> fromIntervals :: (Ord r, IntervalLike i, NumType i ~ r) => [i] -> IntervalTree i r -- | Insert : pre: the interval intersects some midpoint in the tree -- -- <math> insert :: (Ord r, IntervalLike i, NumType i ~ r) => i -> IntervalTree i r -> IntervalTree i r -- | Delete an interval from the Tree -- -- <math> (under some general position assumption) delete :: (Ord r, IntervalLike i, NumType i ~ r, Eq i) => i -> IntervalTree i r -> IntervalTree i r -- | Find all intervals that stab x -- -- <math>, where k is the output size stab :: Ord r => r -> IntervalTree i r -> [i] -- | Find all intervals that stab x -- -- <math>, where k is the output size search :: Ord r => r -> IntervalTree i r -> [i] -- | Lists the intervals. We don't guarantee anything about the order -- -- running time: <math>. toList :: IntervalTree i r -> [i] instance Data.Geometry.IntervalTree.IntervalLike (Data.Range.Range r) instance Data.Geometry.IntervalTree.IntervalLike (Data.Geometry.Interval.Interval p r) instance (Control.DeepSeq.NFData i, Control.DeepSeq.NFData r) => Control.DeepSeq.NFData (Data.Geometry.IntervalTree.IntervalTree i r) instance GHC.Generics.Generic (Data.Geometry.IntervalTree.IntervalTree i r) instance (GHC.Classes.Eq r, GHC.Classes.Eq i) => GHC.Classes.Eq (Data.Geometry.IntervalTree.IntervalTree i r) instance (GHC.Show.Show r, GHC.Show.Show i) => GHC.Show.Show (Data.Geometry.IntervalTree.IntervalTree i r) instance (Control.DeepSeq.NFData i, Control.DeepSeq.NFData r) => Control.DeepSeq.NFData (Data.Geometry.IntervalTree.NodeData i r) instance GHC.Generics.Generic (Data.Geometry.IntervalTree.NodeData i r) instance (GHC.Classes.Ord r, GHC.Classes.Ord i) => GHC.Classes.Ord (Data.Geometry.IntervalTree.NodeData i r) instance (GHC.Classes.Eq r, GHC.Classes.Eq i) => GHC.Classes.Eq (Data.Geometry.IntervalTree.NodeData i r) instance (GHC.Show.Show r, GHC.Show.Show i) => GHC.Show.Show (Data.Geometry.IntervalTree.NodeData i r) module Data.Geometry.RangeTree.Measure class LabeledMeasure v labeledMeasure :: LabeledMeasure v => [a] -> v a newtype Report p Report :: [p] -> Report p [reportList] :: Report p -> [p] newtype Count a Count :: Int -> Count a [getCount] :: Count a -> Int type (:*:) l r = Product l r instance Data.Functor.Classes.Eq1 Data.Geometry.RangeTree.Measure.Report instance Data.Functor.Classes.Show1 Data.Geometry.RangeTree.Measure.Report instance GHC.Base.Monoid (Data.Geometry.RangeTree.Measure.Report p) instance GHC.Base.Semigroup (Data.Geometry.RangeTree.Measure.Report p) instance Data.Foldable.Foldable Data.Geometry.RangeTree.Measure.Report instance GHC.Base.Functor Data.Geometry.RangeTree.Measure.Report instance GHC.Classes.Ord p => GHC.Classes.Ord (Data.Geometry.RangeTree.Measure.Report p) instance GHC.Classes.Eq p => GHC.Classes.Eq (Data.Geometry.RangeTree.Measure.Report p) instance GHC.Show.Show p => GHC.Show.Show (Data.Geometry.RangeTree.Measure.Report p) instance forall k (a :: k). GHC.Classes.Ord (Data.Geometry.RangeTree.Measure.Count a) instance forall k (a :: k). GHC.Classes.Eq (Data.Geometry.RangeTree.Measure.Count a) instance forall k (a :: k). GHC.Read.Read (Data.Geometry.RangeTree.Measure.Count a) instance forall k (a :: k). GHC.Show.Show (Data.Geometry.RangeTree.Measure.Count a) instance (Data.Geometry.RangeTree.Measure.LabeledMeasure l, Data.Geometry.RangeTree.Measure.LabeledMeasure r) => Data.Geometry.RangeTree.Measure.LabeledMeasure (l Data.Geometry.RangeTree.Measure.:*: r) instance forall k (l :: k -> *) (a :: k) (r :: k -> *). (GHC.Base.Semigroup (l a), GHC.Base.Semigroup (r a)) => GHC.Base.Semigroup ((Data.Geometry.RangeTree.Measure.:*:) l r a) instance forall k (l :: k -> *) (a :: k) (r :: k -> *). (GHC.Base.Monoid (l a), GHC.Base.Monoid (r a)) => GHC.Base.Monoid ((Data.Geometry.RangeTree.Measure.:*:) l r a) instance Data.Functor.Classes.Show1 Data.Geometry.RangeTree.Measure.Count instance Data.Functor.Classes.Eq1 Data.Geometry.RangeTree.Measure.Count instance Data.Geometry.RangeTree.Measure.LabeledMeasure Data.Geometry.RangeTree.Measure.Count instance forall k (a :: k). GHC.Base.Monoid (Data.Geometry.RangeTree.Measure.Count a) instance forall k (a :: k). GHC.Base.Semigroup (Data.Geometry.RangeTree.Measure.Count a) instance Data.Measured.Class.Measured (Data.Geometry.RangeTree.Measure.Report p) (Data.Geometry.RangeTree.Measure.Report p) instance Data.Geometry.RangeTree.Measure.LabeledMeasure Data.Geometry.RangeTree.Measure.Report module Data.Geometry.RangeTree.Generic data NodeData v r NodeData :: !Min r -> !Max r -> !v -> NodeData v r [_minVal] :: NodeData v r -> !Min r [_maxVal] :: NodeData v r -> !Max r [_assoc] :: NodeData v r -> !v -- | A generic (1D) range tree. The r parameter indicates the type -- of the coordinates of the points. The q represents any -- associated data values with those points (stored in the leaves), and -- the v types represents the data stored at internal nodes. newtype RangeTree v q r RangeTree :: BinLeafTree (NodeData v r) (NodeData (v, q) r) -> RangeTree v q r [_unRangeTree] :: RangeTree v q r -> BinLeafTree (NodeData v r) (NodeData (v, q) r) -- | Creates a range tree createTree :: (Ord r, Measured v p, Semigroup p) => NonEmpty (r :+ p) -> RangeTree v p r -- | pre: input is sorted and grouped by x-coord createTree' :: (Ord r, Measured v p) => NonEmpty (r :+ p) -> RangeTree v p r -- | Lists all points in increasing order -- -- running time: <math> toAscList :: RangeTree v p r -> NonEmpty (r :+ p) -- | Range search -- -- running time: <math> search :: (Ord r, Monoid v) => Range r -> RangeTree v p r -> v -- | Range search, report the (associated data structures of the) -- <math> nodes that form the disjoint union of the range we are -- querying with. -- -- running time: <math> search' :: Ord r => Range r -> RangeTree v p r -> [v] -- | The actual search search'' :: Ord r => Range r -> BinLeafTree (NodeData v r) (NodeData (v, q) r) -> [v] -- | Helper function to get the range of a binary leaf tree rangeOf :: BinLeafTree (NodeData v r) (NodeData v' r) -> Range r -- | Get the range of a node rangeOf' :: NodeData v r -> Range r createReportingTree :: Ord r => NonEmpty (r :+ [p]) -> RangeTree (Report p) (Report p) r report :: Ord r => Range r -> RangeTree (Report p) q r -> [p] newtype CountOf p CountOf :: [p] -> CountOf p createCountingTree :: Ord r => NonEmpty (r :+ [p]) -> RangeTree (Count p) (CountOf p) r -- | Perform a counting query count :: Ord r => Range r -> RangeTree (Count p) q r -> Int instance GHC.Base.Functor (Data.Geometry.RangeTree.Generic.NodeData v) instance (GHC.Classes.Eq r, GHC.Classes.Eq v) => GHC.Classes.Eq (Data.Geometry.RangeTree.Generic.NodeData v r) instance (GHC.Show.Show r, GHC.Show.Show v) => GHC.Show.Show (Data.Geometry.RangeTree.Generic.NodeData v r) instance (GHC.Classes.Eq r, GHC.Classes.Eq v, GHC.Classes.Eq q) => GHC.Classes.Eq (Data.Geometry.RangeTree.Generic.RangeTree v q r) instance (GHC.Show.Show r, GHC.Show.Show v, GHC.Show.Show q) => GHC.Show.Show (Data.Geometry.RangeTree.Generic.RangeTree v q r) instance GHC.Base.Monoid (Data.Geometry.RangeTree.Generic.CountOf p) instance GHC.Base.Semigroup (Data.Geometry.RangeTree.Generic.CountOf p) instance Data.Foldable.Foldable Data.Geometry.RangeTree.Generic.CountOf instance GHC.Base.Functor Data.Geometry.RangeTree.Generic.CountOf instance GHC.Classes.Ord p => GHC.Classes.Ord (Data.Geometry.RangeTree.Generic.CountOf p) instance GHC.Classes.Eq p => GHC.Classes.Eq (Data.Geometry.RangeTree.Generic.CountOf p) instance GHC.Show.Show p => GHC.Show.Show (Data.Geometry.RangeTree.Generic.CountOf p) instance Data.Measured.Class.Measured (Data.Geometry.RangeTree.Measure.Count p) (Data.Geometry.RangeTree.Generic.CountOf p) instance (GHC.Base.Semigroup v, GHC.Classes.Ord r) => GHC.Base.Semigroup (Data.Geometry.RangeTree.Generic.NodeData v r) module Data.Geometry.SegmentTree.Generic -- | Internal nodes store a split point, the range, and an associated data -- structure data NodeData v r NodeData :: !EndPoint r -> !Range r -> !v -> NodeData v r [_splitPoint] :: NodeData v r -> !EndPoint r [_range] :: NodeData v r -> !Range r [_assoc] :: NodeData v r -> !v splitPoint :: forall v_auh4 r_auh5. Lens' (NodeData v_auh4 r_auh5) (EndPoint r_auh5) range :: forall v_auh4 r_auh5. Lens' (NodeData v_auh4 r_auh5) (Range r_auh5) assoc :: forall v_auh4 r_auh5 v_auo3. Lens (NodeData v_auh4 r_auh5) (NodeData v_auo3 r_auh5) v_auh4 v_auo3 -- | Leaf nodes store an atomic range, and an associated data structure. data LeafData v r LeafData :: !AtomicRange r -> !v -> LeafData v r [_atomicRange] :: LeafData v r -> !AtomicRange r [_leafAssoc] :: LeafData v r -> !v atomicRange :: forall v_auot r_auou r_auC0. Lens (LeafData v_auot r_auou) (LeafData v_auot r_auC0) (AtomicRange r_auou) (AtomicRange r_auC0) leafAssoc :: forall v_auot r_auou v_auC1. Lens (LeafData v_auot r_auou) (LeafData v_auC1 r_auou) v_auot v_auC1 -- | Segment tree on a Fixed set of endpoints newtype SegmentTree v r SegmentTree :: BinLeafTree (NodeData v r) (LeafData v r) -> SegmentTree v r [_unSegmentTree] :: SegmentTree v r -> BinLeafTree (NodeData v r) (LeafData v r) unSegmentTree :: forall v_auCf r_auCg v_auK5 r_auK6. Iso (SegmentTree v_auCf r_auCg) (SegmentTree v_auK5 r_auK6) (BinLeafTree (NodeData v_auCf r_auCg) (LeafData v_auCf r_auCg)) (BinLeafTree (NodeData v_auK5 r_auK6) (LeafData v_auK5 r_auK6)) -- | Class for associcated data structures class Measured v i => Assoc v i insertAssoc :: Assoc v i => i -> v -> v deleteAssoc :: Assoc v i => i -> v -> v -- | Given a sorted list of endpoints, without duplicates, construct a -- segment tree -- -- <math> time createTree :: NonEmpty r -> v -> SegmentTree v r -- | Build a SegmentTree -- -- <math> fromIntervals :: (Ord r, Eq p, Assoc v i, IntervalLike i, Monoid v, NumType i ~ r) => (Interval p r -> i) -> NonEmpty (Interval p r) -> SegmentTree v r -- | Pre: the interval should have one of the endpoints on which the tree -- is built. insert :: (Assoc v i, NumType i ~ r, Ord r, IntervalLike i) => i -> SegmentTree v r -> SegmentTree v r -- | Delete an interval from the tree -- -- pre: The segment is in the tree! delete :: (Assoc v i, NumType i ~ r, Ord r, IntervalLike i) => i -> SegmentTree v r -> SegmentTree v r -- | Search for all intervals intersecting x -- -- <math> where <math> is the output size search :: (Ord r, Monoid v) => r -> SegmentTree v r -> v -- | Returns the associated values of the nodes on the search path to x -- -- <math> stab :: Ord r => r -> SegmentTree v r -> [v] -- | Interval newtype I a I :: a -> I a [_unI] :: I a -> a fromIntervals' :: (Eq p, Ord r) => NonEmpty (Interval p r) -> SegmentTree [I (Interval p r)] r newtype Count Count :: Word -> Count [getCount] :: Count -> Word instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Geometry.SegmentTree.Generic.BuildLeaf a) instance GHC.Show.Show a => GHC.Show.Show (Data.Geometry.SegmentTree.Generic.BuildLeaf a) instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Data.Geometry.SegmentTree.Generic.I a) instance GHC.Generics.Generic (Data.Geometry.SegmentTree.Generic.I a) instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.Geometry.SegmentTree.Generic.I a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Geometry.SegmentTree.Generic.I a) instance GHC.Read.Read a => GHC.Read.Read (Data.Geometry.SegmentTree.Generic.I a) instance GHC.Show.Show a => GHC.Show.Show (Data.Geometry.SegmentTree.Generic.I a) instance Control.DeepSeq.NFData Data.Geometry.SegmentTree.Generic.Count instance GHC.Generics.Generic Data.Geometry.SegmentTree.Generic.Count instance GHC.Real.Real Data.Geometry.SegmentTree.Generic.Count instance GHC.Enum.Enum Data.Geometry.SegmentTree.Generic.Count instance GHC.Real.Integral Data.Geometry.SegmentTree.Generic.Count instance GHC.Num.Num Data.Geometry.SegmentTree.Generic.Count instance GHC.Classes.Ord Data.Geometry.SegmentTree.Generic.Count instance GHC.Classes.Eq Data.Geometry.SegmentTree.Generic.Count instance GHC.Show.Show Data.Geometry.SegmentTree.Generic.Count instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Data.Geometry.SegmentTree.Generic.C a) instance GHC.Generics.Generic (Data.Geometry.SegmentTree.Generic.C a) instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.Geometry.SegmentTree.Generic.C a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Geometry.SegmentTree.Generic.C a) instance GHC.Read.Read a => GHC.Read.Read (Data.Geometry.SegmentTree.Generic.C a) instance GHC.Show.Show a => GHC.Show.Show (Data.Geometry.SegmentTree.Generic.C a) instance Data.Measured.Class.Measured Data.Geometry.SegmentTree.Generic.Count (Data.Geometry.SegmentTree.Generic.C i) instance Data.Geometry.SegmentTree.Generic.Assoc Data.Geometry.SegmentTree.Generic.Count (Data.Geometry.SegmentTree.Generic.C i) instance GHC.Base.Semigroup Data.Geometry.SegmentTree.Generic.Count instance GHC.Base.Monoid Data.Geometry.SegmentTree.Generic.Count instance Data.Measured.Class.Measured [Data.Geometry.SegmentTree.Generic.I a] (Data.Geometry.SegmentTree.Generic.I a) instance GHC.Classes.Eq a => Data.Geometry.SegmentTree.Generic.Assoc [Data.Geometry.SegmentTree.Generic.I a] (Data.Geometry.SegmentTree.Generic.I a) instance Data.Geometry.IntervalTree.IntervalLike a => Data.Geometry.IntervalTree.IntervalLike (Data.Geometry.SegmentTree.Generic.I a) instance (Control.DeepSeq.NFData v, Control.DeepSeq.NFData r) => Control.DeepSeq.NFData (Data.Geometry.SegmentTree.Generic.SegmentTree v r) instance GHC.Generics.Generic (Data.Geometry.SegmentTree.Generic.SegmentTree v r) instance (GHC.Classes.Eq r, GHC.Classes.Eq v) => GHC.Classes.Eq (Data.Geometry.SegmentTree.Generic.SegmentTree v r) instance (GHC.Show.Show r, GHC.Show.Show v) => GHC.Show.Show (Data.Geometry.SegmentTree.Generic.SegmentTree v r) instance (Control.DeepSeq.NFData v, Control.DeepSeq.NFData r) => Control.DeepSeq.NFData (Data.Geometry.SegmentTree.Generic.LeafData v r) instance GHC.Generics.Generic (Data.Geometry.SegmentTree.Generic.AtomicRange r) instance GHC.Base.Functor Data.Geometry.SegmentTree.Generic.AtomicRange instance GHC.Classes.Eq r => GHC.Classes.Eq (Data.Geometry.SegmentTree.Generic.AtomicRange r) instance GHC.Show.Show r => GHC.Show.Show (Data.Geometry.SegmentTree.Generic.AtomicRange r) instance GHC.Generics.Generic (Data.Geometry.SegmentTree.Generic.LeafData v r) instance GHC.Base.Functor (Data.Geometry.SegmentTree.Generic.LeafData v) instance (GHC.Classes.Eq r, GHC.Classes.Eq v) => GHC.Classes.Eq (Data.Geometry.SegmentTree.Generic.LeafData v r) instance (GHC.Show.Show r, GHC.Show.Show v) => GHC.Show.Show (Data.Geometry.SegmentTree.Generic.LeafData v r) instance Control.DeepSeq.NFData r => Control.DeepSeq.NFData (Data.Geometry.SegmentTree.Generic.AtomicRange r) instance (Control.DeepSeq.NFData v, Control.DeepSeq.NFData r) => Control.DeepSeq.NFData (Data.Geometry.SegmentTree.Generic.NodeData v r) instance GHC.Generics.Generic (Data.Geometry.SegmentTree.Generic.NodeData v r) instance GHC.Base.Functor (Data.Geometry.SegmentTree.Generic.NodeData v) instance (GHC.Classes.Eq r, GHC.Classes.Eq v) => GHC.Classes.Eq (Data.Geometry.SegmentTree.Generic.NodeData v r) instance (GHC.Show.Show r, GHC.Show.Show v) => GHC.Show.Show (Data.Geometry.SegmentTree.Generic.NodeData v r) module Data.Geometry.SegmentTree module Data.Geometry.Vector.VectorFixed -- | A proxy which can be used for the coordinates. data C (n :: Nat) C :: C (n :: Nat) -- | Datatype representing d dimensional vectors. Our implementation wraps -- the implementation provided by fixed-vector. newtype Vector (d :: Nat) (r :: *) Vector :: Vec d r -> Vector (d :: Nat) (r :: *) [_unV] :: Vector (d :: Nat) (r :: *) -> Vec d r unV :: Lens' (Vector d r) (Vec d r) -- | Lens into the i th element element :: forall proxy i d r. (Arity d, Arity i, (i + 1) <= d) => proxy i -> Lens' (Vector d r) r -- | Similar to element above. Except that we don't have a static -- guarantee that the index is in bounds. Hence, we can only return a -- Traversal element' :: forall d r. Arity d => Int -> Traversal' (Vector d r) r vectorFromList :: Arity d => [a] -> Maybe (Vector d a) vectorFromListUnsafe :: Arity d => [a] -> Vector d a -- | Get the head and tail of a vector destruct :: (Arity d, Arity (d + 1), 1 <= (d + 1)) => Vector (d + 1) r -> (r, Vector d r) -- | Cross product of two three-dimensional vectors cross :: Num r => Vector 3 r -> Vector 3 r -> Vector 3 r -- | Vonversion to a Linear.V2 toV2 :: Vector 2 a -> V2 a -- | Conversion to a Linear.V3 toV3 :: Vector 3 a -> V3 a -- | Conversion from a Linear.V3 fromV3 :: V3 a -> Vector 3 a -- | Add an element at the back of the vector snoc :: (Arity (d + 1), Arity d) => Vector d r -> r -> Vector (d + 1) r -- | Get a vector of the first d - 1 elements. init :: (Arity d, Arity (d + 1)) => Vector (d + 1) r -> Vector d r last :: forall d r. (Arity d, Arity (d + 1)) => Vector (d + 1) r -> r -- | Get a prefix of i elements of a vector prefix :: forall i d r. (Arity d, Arity i, i <= d) => Vector d r -> Vector i r -- | Construct a 2 dimensional vector v2 :: r -> r -> Vector 2 r -- | Construct a 3 dimensional vector v3 :: r -> r -> r -> Vector 3 r -- | Destruct a 2 dim vector into a pair _unV2 :: Vector 2 r -> (r, r) _unV3 :: Vector 3 r -> (r, r, r) -- | Pattern synonym for two and three dim vectors pattern Vector2 :: r -> r -> Vector 2 r pattern Vector3 :: r -> r -> r -> Vector 3 r pattern Vector4 :: r -> r -> r -> r -> Vector 4 r instance GHC.Classes.Ord (Data.Geometry.Vector.VectorFixed.C n) instance GHC.Classes.Eq (Data.Geometry.Vector.VectorFixed.C n) instance GHC.Read.Read (Data.Geometry.Vector.VectorFixed.C n) instance GHC.Show.Show (Data.Geometry.Vector.VectorFixed.C n) instance GHC.Generics.Generic (Data.Geometry.Vector.VectorFixed.Vector d r) instance (GHC.Classes.Eq r, Data.Vector.Fixed.Cont.Arity d) => GHC.Classes.Eq (Data.Geometry.Vector.VectorFixed.Vector d r) instance (GHC.Classes.Ord r, Data.Vector.Fixed.Cont.Arity d) => GHC.Classes.Ord (Data.Geometry.Vector.VectorFixed.Vector d r) instance Data.Vector.Fixed.Cont.Arity d => Data.Foldable.Foldable (Data.Geometry.Vector.VectorFixed.Vector d) instance Data.Vector.Fixed.Cont.Arity d => GHC.Base.Applicative (Data.Geometry.Vector.VectorFixed.Vector d) instance (Data.Vector.Fixed.Cont.Arity d, Control.DeepSeq.NFData r) => Control.DeepSeq.NFData (Data.Geometry.Vector.VectorFixed.Vector d r) instance (GHC.Show.Show r, Data.Vector.Fixed.Cont.Arity d) => GHC.Show.Show (Data.Geometry.Vector.VectorFixed.Vector d r) instance Data.Vector.Fixed.Cont.Arity d => Data.Functor.Classes.Eq1 (Data.Geometry.Vector.VectorFixed.Vector d) instance Data.Vector.Fixed.Cont.Arity d => GHC.Base.Functor (Data.Geometry.Vector.VectorFixed.Vector d) instance Data.Vector.Fixed.Cont.Arity d => Data.Traversable.Traversable (Data.Geometry.Vector.VectorFixed.Vector d) instance Data.Vector.Fixed.Cont.Arity d => Linear.Vector.Additive (Data.Geometry.Vector.VectorFixed.Vector d) instance Data.Vector.Fixed.Cont.Arity d => Linear.Affine.Affine (Data.Geometry.Vector.VectorFixed.Vector d) instance Data.Vector.Fixed.Cont.Arity d => Linear.Metric.Metric (Data.Geometry.Vector.VectorFixed.Vector d) instance Data.Vector.Fixed.Cont.Arity d => Data.Vector.Fixed.Cont.Vector (Data.Geometry.Vector.VectorFixed.Vector d) r instance (Data.Aeson.Types.FromJSON.FromJSON r, Data.Vector.Fixed.Cont.Arity d, GHC.TypeNats.KnownNat d) => Data.Aeson.Types.FromJSON.FromJSON (Data.Geometry.Vector.VectorFixed.Vector d r) instance (Data.Aeson.Types.ToJSON.ToJSON r, Data.Vector.Fixed.Cont.Arity d) => Data.Aeson.Types.ToJSON.ToJSON (Data.Geometry.Vector.VectorFixed.Vector d r) module Data.Geometry.Vector.VectorFamilyPeano class (ImplicitPeano d, Arity (FromPeano d)) => ImplicitArity d -- | Datatype representing d dimensional vectors. The default -- implementation is based n VectorFixed. However, for small vectors we -- automatically select a more efficient representation. newtype VectorFamily (d :: PeanoNum) (r :: *) VectorFamily :: VectorFamilyF d r -> VectorFamily (d :: PeanoNum) (r :: *) -- | Mapping between the implementation type, and the actual -- implementation. type family VectorFamilyF (d :: PeanoNum) :: * -> * type family FromPeano (d :: PeanoNum) :: Nat type Two = S One instance (Data.Geometry.Vector.VectorFamilyPeano.ImplicitPeano d, Data.Vector.Fixed.Cont.Arity (Data.Geometry.Vector.VectorFamilyPeano.FromPeano d)) => Data.Geometry.Vector.VectorFamilyPeano.ImplicitArity d instance (GHC.Classes.Eq r, Data.Geometry.Vector.VectorFamilyPeano.ImplicitArity d) => GHC.Classes.Eq (Data.Geometry.Vector.VectorFamilyPeano.VectorFamily d r) instance Data.Geometry.Vector.VectorFamilyPeano.ImplicitArity d => Data.Functor.Classes.Eq1 (Data.Geometry.Vector.VectorFamilyPeano.VectorFamily d) instance (GHC.Classes.Ord r, Data.Geometry.Vector.VectorFamilyPeano.ImplicitArity d) => GHC.Classes.Ord (Data.Geometry.Vector.VectorFamilyPeano.VectorFamily d r) instance Data.Geometry.Vector.VectorFamilyPeano.ImplicitArity d => GHC.Base.Functor (Data.Geometry.Vector.VectorFamilyPeano.VectorFamily d) instance Data.Geometry.Vector.VectorFamilyPeano.ImplicitArity d => Data.Foldable.Foldable (Data.Geometry.Vector.VectorFamilyPeano.VectorFamily d) instance Data.Geometry.Vector.VectorFamilyPeano.ImplicitArity d => Data.Traversable.Traversable (Data.Geometry.Vector.VectorFamilyPeano.VectorFamily d) instance Data.Geometry.Vector.VectorFamilyPeano.ImplicitArity d => GHC.Base.Applicative (Data.Geometry.Vector.VectorFamilyPeano.VectorFamily d) instance Data.Geometry.Vector.VectorFamilyPeano.ImplicitArity d => Data.Vector.Fixed.Cont.Vector (Data.Geometry.Vector.VectorFamilyPeano.VectorFamily d) r instance (Data.Geometry.Vector.VectorFamilyPeano.ImplicitArity d, GHC.Show.Show r) => GHC.Show.Show (Data.Geometry.Vector.VectorFamilyPeano.VectorFamily d r) instance (Control.DeepSeq.NFData r, Data.Geometry.Vector.VectorFamilyPeano.ImplicitArity d) => Control.DeepSeq.NFData (Data.Geometry.Vector.VectorFamilyPeano.VectorFamily d r) instance Data.Geometry.Vector.VectorFamilyPeano.ImplicitArity d => Control.Lens.At.Ixed (Data.Geometry.Vector.VectorFamilyPeano.VectorFamily d r) instance Data.Geometry.Vector.VectorFamilyPeano.ImplicitArity d => Linear.Metric.Metric (Data.Geometry.Vector.VectorFamilyPeano.VectorFamily d) instance Data.Geometry.Vector.VectorFamilyPeano.ImplicitArity d => Linear.Vector.Additive (Data.Geometry.Vector.VectorFamilyPeano.VectorFamily d) instance Data.Geometry.Vector.VectorFamilyPeano.ImplicitArity d => Linear.Affine.Affine (Data.Geometry.Vector.VectorFamilyPeano.VectorFamily d) instance (Data.Aeson.Types.FromJSON.FromJSON r, Data.Geometry.Vector.VectorFamilyPeano.ImplicitArity d) => Data.Aeson.Types.FromJSON.FromJSON (Data.Geometry.Vector.VectorFamilyPeano.VectorFamily d r) instance (Data.Aeson.Types.ToJSON.ToJSON r, Data.Geometry.Vector.VectorFamilyPeano.ImplicitArity d) => Data.Aeson.Types.ToJSON.ToJSON (Data.Geometry.Vector.VectorFamilyPeano.VectorFamily d r) instance (Data.Geometry.Vector.VectorFamilyPeano.ImplicitPeano d, Data.Hashable.Class.Hashable r) => Data.Hashable.Class.Hashable (Data.Geometry.Vector.VectorFamilyPeano.VectorFamily d r) instance Data.Geometry.Vector.VectorFamilyPeano.ImplicitPeano 'Data.Vector.Fixed.Cont.Z instance Data.Geometry.Vector.VectorFamilyPeano.ImplicitPeano d => Data.Geometry.Vector.VectorFamilyPeano.ImplicitPeano ('Data.Vector.Fixed.Cont.S d) -- | Implementation of <math>-dimensional vectors. The implementation -- automatically selects an optimized representation for small (up to -- size 4) vectors. module Data.Geometry.Vector.VectorFamily -- | Datatype representing d dimensional vectors. The default -- implementation is based n VectorFixed. However, for small vectors we -- automatically select a more efficient representation. newtype Vector (d :: Nat) (r :: *) MKVector :: VectorFamily (Peano d) r -> Vector (d :: Nat) (r :: *) [_unV] :: Vector (d :: Nat) (r :: *) -> VectorFamily (Peano d) r -- | Vectors are isomorphic to a definition determined by -- VectorFamily. unV :: Iso (Vector d r) (Vector d s) (VectorFamily (Peano d) r) (VectorFamily (Peano d) s) class (ImplicitArity (Peano d), KnownNat d) => Arity d -- | Constant sized vector with d elements. pattern Vector :: VectorFamilyF (Peano d) r -> Vector d r -- | Constant sized vector with 1 element. pattern Vector1 :: r -> Vector 1 r -- | Constant sized vector with 2 elements. pattern Vector2 :: r -> r -> Vector 2 r -- | Constant sized vector with 3 elements. pattern Vector3 :: r -> r -> r -> Vector 3 r -- | Constant sized vector with 4 elements. pattern Vector4 :: r -> r -> r -> r -> Vector 4 r -- | <math> Convert from a list to a non-empty vector. vectorFromList :: Arity d => [r] -> Maybe (Vector d r) -- | <math> Convert from a list to a non-empty vector. vectorFromListUnsafe :: Arity d => [r] -> Vector d r -- | <math> Pop the first element off a vector. destruct :: (Arity d, Arity (d + 1)) => Vector (d + 1) r -> (r, Vector d r) -- | <math> First element. Since arity is at least 1, this function -- is total. head :: (Arity d, 1 <= d) => Vector d r -> r -- | Lens into the i th element element :: forall proxy i d r. (Arity d, KnownNat i, (i + 1) <= d) => proxy i -> Lens' (Vector d r) r -- | Similar to element above. Except that we don't have a static -- guarantee that the index is in bounds. Hence, we can only return a -- Traversal element' :: forall d r. Arity d => Int -> Traversal' (Vector d r) r -- | <math> Prepend an element. cons :: (Arity d, Arity (d + 1)) => r -> Vector d r -> Vector (d + 1) r -- | Add an element at the back of the vector snoc :: (Arity (d + 1), Arity d) => Vector d r -> r -> Vector (d + 1) r -- | Get a vector of the first d - 1 elements. init :: (Arity d, Arity (d + 1)) => Vector (d + 1) r -> Vector d r -- | <math> Last element. Since the vector is non-empty, runtime -- bounds checks are bypassed. last :: forall d r. (KnownNat d, Arity (d + 1)) => Vector (d + 1) r -> r -- | Get a prefix of i elements of a vector prefix :: forall i d r. (Arity d, Arity i, i <= d) => Vector d r -> Vector i r -- | Cross product of two three-dimensional vectors cross :: Num r => Vector 3 r -> Vector 3 r -> Vector 3 r instance (GHC.Classes.Eq r, Data.Geometry.Vector.VectorFamily.Arity d) => GHC.Classes.Eq (Data.Geometry.Vector.VectorFamily.Vector d r) instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Functor.Classes.Eq1 (Data.Geometry.Vector.VectorFamily.Vector d) instance (GHC.Classes.Ord r, Data.Geometry.Vector.VectorFamily.Arity d) => GHC.Classes.Ord (Data.Geometry.Vector.VectorFamily.Vector d r) instance Data.Geometry.Vector.VectorFamily.Arity d => GHC.Base.Functor (Data.Geometry.Vector.VectorFamily.Vector d) instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Foldable.Foldable (Data.Geometry.Vector.VectorFamily.Vector d) instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Traversable.Traversable (Data.Geometry.Vector.VectorFamily.Vector d) instance Data.Geometry.Vector.VectorFamily.Arity d => GHC.Base.Applicative (Data.Geometry.Vector.VectorFamily.Vector d) instance Data.Geometry.Vector.VectorFamily.Arity d => Linear.Vector.Additive (Data.Geometry.Vector.VectorFamily.Vector d) instance Data.Geometry.Vector.VectorFamily.Arity d => Linear.Metric.Metric (Data.Geometry.Vector.VectorFamily.Vector d) instance (Data.Geometry.Vector.VectorFamily.Arity d, Data.Hashable.Class.Hashable r) => Data.Hashable.Class.Hashable (Data.Geometry.Vector.VectorFamily.Vector d r) instance (Data.Aeson.Types.FromJSON.FromJSON r, Data.Geometry.Vector.VectorFamily.Arity d) => Data.Aeson.Types.FromJSON.FromJSON (Data.Geometry.Vector.VectorFamily.Vector d r) instance (Control.DeepSeq.NFData r, Data.Geometry.Vector.VectorFamily.Arity d) => Control.DeepSeq.NFData (Data.Geometry.Vector.VectorFamily.Vector d r) instance (Data.Geometry.Vector.VectorFamilyPeano.ImplicitArity (Data.Vector.Fixed.Cont.Peano d), GHC.TypeNats.KnownNat d) => Data.Geometry.Vector.VectorFamily.Arity d instance Data.Geometry.Vector.VectorFamily.Arity d => WithIndex.FunctorWithIndex GHC.Types.Int (Data.Geometry.Vector.VectorFamily.Vector d) instance Data.Geometry.Vector.VectorFamily.Arity d => WithIndex.FoldableWithIndex GHC.Types.Int (Data.Geometry.Vector.VectorFamily.Vector d) instance Data.Geometry.Vector.VectorFamily.Arity d => WithIndex.TraversableWithIndex GHC.Types.Int (Data.Geometry.Vector.VectorFamily.Vector d) instance Data.Geometry.Vector.VectorFamily.Arity d => Linear.Affine.Affine (Data.Geometry.Vector.VectorFamily.Vector d) instance Data.Geometry.Vector.VectorFamily.Arity d => Control.Lens.At.Ixed (Data.Geometry.Vector.VectorFamily.Vector d r) instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Vector.Fixed.Cont.Vector (Data.Geometry.Vector.VectorFamily.Vector d) r instance (GHC.Show.Show r, Data.Geometry.Vector.VectorFamily.Arity d) => GHC.Show.Show (Data.Geometry.Vector.VectorFamily.Vector d r) instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Functor.Classes.Show1 (Data.Geometry.Vector.VectorFamily.Vector d) instance (GHC.Read.Read r, Data.Geometry.Vector.VectorFamily.Arity d) => GHC.Read.Read (Data.Geometry.Vector.VectorFamily.Vector d r) instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Functor.Classes.Read1 (Data.Geometry.Vector.VectorFamily.Vector d) instance (Data.Aeson.Types.ToJSON.ToJSON r, Data.Geometry.Vector.VectorFamily.Arity d) => Data.Aeson.Types.ToJSON.ToJSON (Data.Geometry.Vector.VectorFamily.Vector d r) -- | <math>-dimensional vectors. module Data.Geometry.Vector -- | Outer (tensor) product of two vectors outer :: (Functor f, Functor g, Num a) => f a -> g a -> f (g a) -- | Create a unit vector. -- --
--   >>> unit _x :: V2 Int
--   V2 1 0
--   
unit :: (Additive t, Num a) => ASetter' (t a) a -> t a -- | Produce a diagonal (scale) matrix from a vector. -- --
--   >>> scaled (V2 2 3)
--   V2 (V2 2 0) (V2 0 3)
--   
scaled :: (Traversable t, Num a) => t a -> t (t a) -- | Produce a default basis for a vector space from which the argument is -- drawn. basisFor :: (Traversable t, Num a) => t b -> [t a] -- | Produce a default basis for a vector space. If the dimensionality of -- the vector space is not statically known, see basisFor. basis :: (Additive t, Traversable t, Num a) => [t a] -- | Compute division by a scalar on the right. (^/) :: (Functor f, Fractional a) => f a -> a -> f a infixl 7 ^/ -- | Compute the right scalar product -- --
--   >>> V2 3 4 ^* 2
--   V2 6 8
--   
(^*) :: (Functor f, Num a) => f a -> a -> f a infixl 7 ^* -- | Compute the left scalar product -- --
--   >>> 2 *^ V2 3 4
--   V2 6 8
--   
(*^) :: (Functor f, Num a) => a -> f a -> f a infixl 7 *^ -- | Sum over multiple vectors -- --
--   >>> sumV [V2 1 1, V2 3 4]
--   V2 4 5
--   
sumV :: (Foldable f, Additive v, Num a) => f (v a) -> v a -- | Compute the negation of a vector -- --
--   >>> negated (V2 2 4)
--   V2 (-2) (-4)
--   
negated :: (Functor f, Num a) => f a -> f a -- | A vector is an additive group with additional structure. class Functor f => Additive (f :: Type -> Type) -- | The zero vector zero :: (Additive f, Num a) => f a -- | Compute the sum of two vectors -- --
--   >>> V2 1 2 ^+^ V2 3 4
--   V2 4 6
--   
(^+^) :: (Additive f, Num a) => f a -> f a -> f a -- | Compute the difference between two vectors -- --
--   >>> V2 4 5 ^-^ V2 3 1
--   V2 1 4
--   
(^-^) :: (Additive f, Num a) => f a -> f a -> f a -- | Linearly interpolate between two vectors. lerp :: (Additive f, Num a) => a -> f a -> f a -> f a -- | Apply a function to merge the 'non-zero' components of two vectors, -- unioning the rest of the values. -- -- liftU2 :: Additive f => (a -> a -> a) -> f a -> f a -> f a -- | Apply a function to the components of two vectors. -- -- liftI2 :: Additive f => (a -> b -> c) -> f a -> f b -> f c infixl 6 ^-^ infixl 6 ^+^ -- | A proxy which can be used for the coordinates. data C (n :: Nat) C :: C (n :: Nat) -- | An affine space is roughly a vector space in which we have forgotten -- or at least pretend to have forgotten the origin. -- --
--   a .+^ (b .-. a)  =  b@
--   (a .+^ u) .+^ v  =  a .+^ (u ^+^ v)@
--   (a .-. b) ^+^ v  =  (a .+^ v) .-. q@
--   
class Additive Diff p => Affine (p :: Type -> Type) where { type family Diff (p :: Type -> Type) :: Type -> Type; } -- | Get the difference between two points as a vector offset. (.-.) :: (Affine p, Num a) => p a -> p a -> Diff p a -- | Add a vector offset to a point. (.+^) :: (Affine p, Num a) => p a -> Diff p a -> p a -- | Subtract a vector offset from a point. (.-^) :: (Affine p, Num a) => p a -> Diff p a -> p a infixl 6 .-. infixl 6 .+^ infixl 6 .-^ -- | Compute the squared norm. The name quadrance arises from Norman J. -- Wildberger's rational trigonometry. quadrance :: (Metric f, Num a) => f a -> a -- | Compute the quadrance of the difference (the square of the distance) qdA :: (Affine p, Foldable (Diff p), Num a) => p a -> p a -> a -- | Distance between two points in an affine space distanceA :: (Floating a, Foldable (Diff p), Affine p) => p a -> p a -> a -- | Compute the inner product of two vectors or (equivalently) convert a -- vector f a into a covector f a -> a. -- --
--   >>> V2 1 2 `dot` V2 3 4
--   11
--   
dot :: (Metric f, Num a) => f a -> f a -> a -- | Compute the norm of a vector in a metric space norm :: (Metric f, Floating a) => f a -> a -- | Convert a non-zero vector to unit vector. signorm :: (Metric f, Floating a) => f a -> f a -- | 'isScalarmultipleof u v' test if v is a scalar multiple of u. -- --
--   >>> Vector2 1 1 `isScalarMultipleOf` Vector2 10 10
--   True
--   
--   >>> Vector3 1 1 2 `isScalarMultipleOf` Vector3 10 10 20
--   True
--   
--   >>> Vector2 1 1 `isScalarMultipleOf` Vector2 10 1
--   False
--   
--   >>> Vector2 1 1 `isScalarMultipleOf` Vector2 (-1) (-1)
--   True
--   
--   >>> Vector2 1 1 `isScalarMultipleOf` Vector2 11.1 11.1
--   True
--   
--   >>> Vector2 1 1 `isScalarMultipleOf` Vector2 11.1 11.2
--   False
--   
--   >>> Vector2 2 1 `isScalarMultipleOf` Vector2 11.1 11.2
--   False
--   
--   >>> Vector2 2 1 `isScalarMultipleOf` Vector2 4 2
--   True
--   
--   >>> Vector2 2 1 `isScalarMultipleOf` Vector2 4 0
--   False
--   
--   >>> Vector3 2 1 0 `isScalarMultipleOf` Vector3 4 0 5
--   False
--   
--   >>> Vector3 0 0 0 `isScalarMultipleOf` Vector3 4 0 5
--   True
--   
isScalarMultipleOf :: (Eq r, Fractional r, Arity d) => Vector d r -> Vector d r -> Bool -- | scalarMultiple u v computes the scalar labmda s.t. v = lambda * u (if -- it exists) scalarMultiple :: (Eq r, Fractional r, Arity d) => Vector d r -> Vector d r -> Maybe r -- | Given two colinar vectors, u and v, test if they point in the same -- direction, i.e. iff scalarMultiple' u v == Just lambda, with lambda -- > 0 -- -- pre: u and v are colinear, u and v are non-zero sameDirection :: (Eq r, Num r, Arity d) => Vector d r -> Vector d r -> Bool -- | Replicate value n times. -- -- Examples: -- --
--   >>> import Data.Vector.Fixed.Boxed (Vec2)
--   
--   >>> replicate 1 :: Vec2 Int
--   fromList [1,1]
--   
-- --
--   >>> replicate 2 :: (Double,Double,Double)
--   (2.0,2.0,2.0)
--   
-- --
--   >>> import Data.Vector.Fixed.Boxed (Vec4)
--   
--   >>> replicate "foo" :: Vec4 String
--   fromList ["foo","foo","foo","foo"]
--   
replicate :: Vector v a => a -> v a -- | Shorthand to access the first component -- --
--   >>> Vector3 1 2 3 ^. xComponent
--   1
--   
--   >>> Vector2 1 2 & xComponent .~ 10
--   Vector2 10 2
--   
xComponent :: (1 <= d, Arity d) => Lens' (Vector d r) r -- | Shorthand to access the second component -- --
--   >>> Vector3 1 2 3 ^. yComponent
--   2
--   
--   >>> Vector2 1 2 & yComponent .~ 10
--   Vector2 1 10
--   
yComponent :: (2 <= d, Arity d) => Lens' (Vector d r) r -- | Shorthand to access the third component -- --
--   >>> Vector3 1 2 3 ^. zComponent
--   3
--   
--   >>> Vector3 1 2 3 & zComponent .~ 10
--   Vector3 1 2 10
--   
zComponent :: (3 <= d, Arity d) => Lens' (Vector d r) r instance GHC.Show.Show r => GHC.Show.Show (Data.Geometry.Vector.ScalarMultiple r) instance GHC.Classes.Eq r => GHC.Classes.Eq (Data.Geometry.Vector.ScalarMultiple r) instance GHC.Classes.Eq r => GHC.Base.Semigroup (Data.Geometry.Vector.ScalarMultiple r) instance GHC.Classes.Eq r => GHC.Base.Monoid (Data.Geometry.Vector.ScalarMultiple r) instance (Test.QuickCheck.Arbitrary.Arbitrary r, Data.Geometry.Vector.VectorFamily.Arity d) => Test.QuickCheck.Arbitrary.Arbitrary (Data.Geometry.Vector.VectorFamily.Vector d r) instance Data.Geometry.Vector.VectorFamily.Arity d => Test.QuickCheck.Arbitrary.Arbitrary1 (Data.Geometry.Vector.VectorFamily.Vector d) instance (System.Random.Random r, Data.Geometry.Vector.VectorFamily.Arity d) => System.Random.Random (Data.Geometry.Vector.VectorFamily.Vector d r) -- | <math>-dimensional points. module Data.Geometry.Point -- | A d-dimensional point. -- -- There are convenience pattern synonyms for 1, 2 and 3 dimensional -- points. -- --
--   >>> let f (Point1 x) = x in f (Point1 1)
--   1
--   
--   >>> let f (Point2 x y) = x in f (Point2 1 2)
--   1
--   
--   >>> let f (Point3 x y z) = z in f (Point3 1 2 3)
--   3
--   
--   >>> let f (Point3 x y z) = z in f (Point $ Vector3 1 2 3)
--   3
--   
newtype Point d r Point :: Vector d r -> Point d r [toVec] :: Point d r -> Vector d r -- | A bidirectional pattern synonym for 1 dimensional points. pattern Point1 :: r -> Point 1 r -- | A bidirectional pattern synonym for 2 dimensional points. pattern Point2 :: r -> r -> Point 2 r -- | A bidirectional pattern synonym for 3 dimensional points. pattern Point3 :: r -> r -> r -> Point 3 r -- | Point representing the origin in d dimensions -- --
--   >>> origin :: Point 4 Int
--   Point4 0 0 0 0
--   
origin :: (Arity d, Num r) => Point d r -- | Lens to access the vector corresponding to this point. -- --
--   >>> (Point3 1 2 3) ^. vector
--   Vector3 1 2 3
--   
--   >>> origin & vector .~ Vector3 1 2 3
--   Point3 1 2 3
--   
vector :: Lens (Point d r) (Point d r') (Vector d r) (Vector d r') -- | Constructs a point from a list of coordinates. The length of the list -- has to match the dimension exactly. -- --
--   >>> pointFromList [1,2,3] :: Maybe (Point 3 Int)
--   Just (Point3 1 2 3)
--   
--   >>> pointFromList [1] :: Maybe (Point 3 Int)
--   Nothing
--   
--   >>> pointFromList [1,2,3,4] :: Maybe (Point 3 Int)
--   Nothing
--   
pointFromList :: Arity d => [r] -> Maybe (Point d r) -- | Project a point down into a lower dimension. projectPoint :: (Arity i, Arity d, i <= d) => Point d r -> Point i r -- | Shorthand to access the first coordinate C 1 -- --
--   >>> Point3 1 2 3 ^. xCoord
--   1
--   
--   >>> Point2 1 2 & xCoord .~ 10
--   Point2 10 2
--   
xCoord :: (1 <= d, Arity d, AsAPoint point) => Lens' (point d r) r -- | Shorthand to access the second coordinate C 2 -- --
--   >>> Point2 1 2 ^. yCoord
--   2
--   
--   >>> Point3 1 2 3 & yCoord %~ (+1)
--   Point3 1 3 3
--   
yCoord :: (2 <= d, Arity d, AsAPoint point) => Lens' (point d r) r -- | Shorthand to access the third coordinate C 3 -- --
--   >>> Point3 1 2 3 ^. zCoord
--   3
--   
--   >>> Point3 1 2 3 & zCoord %~ (+1)
--   Point3 1 2 4
--   
zCoord :: (3 <= d, Arity d, AsAPoint point) => Lens' (point d r) r -- | Types that we can transform by mapping a function on each point in the -- structure class PointFunctor g pmap :: PointFunctor g => (Point (Dimension (g r)) r -> Point (Dimension (g s)) s) -> g r -> g s -- | Data type for expressing the orientation of three points, with the -- option of allowing Colinearities. data CCW -- | Given three points p q and r determine the orientation when going from -- p to r via q. -- -- Be vary of numerical instability: >>> ccw (Point2 0 0.3) -- (Point2 1 0.6) (Point2 2 (0.9::Double)) CCW -- --
--   >>> ccw (Point2 0 0.3) (Point2 1 0.6) (Point2 2 (0.9::Rational))
--   CoLinear
--   
-- -- If you can't use Rational, try SafeDouble instead of -- Double: >>> ccw (Point2 0 0.3) (Point2 1 0.6) (Point2 -- 2 (0.9::SafeDouble)) CoLinear ccw :: (Ord r, Num r) => Point 2 r -> Point 2 r -> Point 2 r -> CCW -- | Given three points p q and r determine the orientation when going from -- p to r via q. ccw' :: (Ord r, Num r) => (Point 2 r :+ a) -> (Point 2 r :+ b) -> (Point 2 r :+ c) -> CCW -- | Given three points p q and r determine if the line from p to r via q -- is straight/colinear. -- -- This is identical to `ccw p q r == CoLinear` but doesn't have the -- Ord constraint. isCoLinear :: (Eq r, Num r) => Point 2 r -> Point 2 r -> Point 2 r -> Bool -- | CounterClockwise orientation. Also called a left-turn. pattern CCW :: CCW -- | Clockwise orientation. Also called a right-turn. pattern CW :: CCW -- | CoLinear orientation. Also called a straight line. pattern CoLinear :: CCW -- | Counter clockwise ordering of the points around c. Points are ordered -- with respect to the positive x-axis. ccwCmpAround :: (Num r, Ord r) => Point 2 r -> Point 2 r -> Point 2 r -> Ordering -- | Counter clockwise ordering of the points around c. Points are ordered -- with respect to the positive x-axis. ccwCmpAround' :: (Num r, Ord r) => (Point 2 r :+ qc) -> (Point 2 r :+ p) -> (Point 2 r :+ q) -> Ordering -- | Clockwise ordering of the points around c. Points are ordered with -- respect to the positive x-axis. cwCmpAround :: (Num r, Ord r) => Point 2 r -> Point 2 r -> Point 2 r -> Ordering -- | Clockwise ordering of the points around c. Points are ordered with -- respect to the positive x-axis. cwCmpAround' :: (Num r, Ord r) => (Point 2 r :+ qc) -> (Point 2 r :+ p) -> (Point 2 r :+ q) -> Ordering -- | Given a zero vector z, a center c, and two points p and q, compute the -- ccw ordering of p and q around c with this vector as zero direction. -- -- pre: the points p,q /= c ccwCmpAroundWith :: (Ord r, Num r) => Vector 2 r -> Point 2 r -> Point 2 r -> Point 2 r -> Ordering -- | Given a zero vector z, a center c, and two points p and q, compute the -- ccw ordering of p and q around c with this vector as zero direction. -- -- pre: the points p,q /= c ccwCmpAroundWith' :: (Ord r, Num r) => Vector 2 r -> (Point 2 r :+ c) -> (Point 2 r :+ a) -> (Point 2 r :+ b) -> Ordering -- | Given a zero vector z, a center c, and two points p and q, compute the -- cw ordering of p and q around c with this vector as zero direction. -- -- pre: the points p,q /= c cwCmpAroundWith :: (Ord r, Num r) => Vector 2 r -> Point 2 r -> Point 2 r -> Point 2 r -> Ordering -- | Given a zero vector z, a center c, and two points p and q, compute the -- cw ordering of p and q around c with this vector as zero direction. -- -- pre: the points p,q /= c cwCmpAroundWith' :: (Ord r, Num r) => Vector 2 r -> (Point 2 r :+ a) -> (Point 2 r :+ b) -> (Point 2 r :+ c) -> Ordering -- | <math> Sort the points arround the given point p in counter -- clockwise order with respect to the rightward horizontal ray starting -- from p. If two points q and r are colinear with p, the closest one to -- p is reported first. sortAround :: (Ord r, Num r) => Point 2 r -> [Point 2 r] -> [Point 2 r] -- | <math> Sort the points arround the given point p in counter -- clockwise order with respect to the rightward horizontal ray starting -- from p. If two points q and r are colinear with p, the closest one to -- p is reported first. sortAround' :: (Ord r, Num r) => (Point 2 r :+ q) -> [Point 2 r :+ p] -> [Point 2 r :+ p] -- | <math> Given a center c, a new point p, and a list of points ps, -- sorted in counter clockwise order around c. Insert p into the cyclic -- order. The focus of the returned cyclic list is the new point p. insertIntoCyclicOrder :: (Ord r, Num r) => (Point 2 r :+ q) -> (Point 2 r :+ p) -> CList (Point 2 r :+ p) -> CList (Point 2 r :+ p) -- | Quadrants of two dimensional points. in CCW order data Quadrant TopRight :: Quadrant TopLeft :: Quadrant BottomLeft :: Quadrant BottomRight :: Quadrant -- | Quadrants around point c; quadrants are closed on their "previous" -- boundary (i..e the boundary with the previous quadrant in the CCW -- order), open on next boundary. The origin itself is assigned the -- topRight quadrant quadrantWith :: (Ord r, 1 <= d, 2 <= d, Arity d) => (Point d r :+ q) -> (Point d r :+ p) -> Quadrant -- | Quadrants with respect to the origin quadrant :: (Ord r, Num r, 1 <= d, 2 <= d, Arity d) => (Point d r :+ p) -> Quadrant -- | Given a center point c, and a set of points, partition the points into -- quadrants around c (based on their x and y coordinates). The quadrants -- are reported in the order topLeft, topRight, bottomLeft, bottomRight. -- The points are in the same order as they were in the original input -- lists. Points with the same x-or y coordinate as p, are "rounded" to -- above. partitionIntoQuadrants :: (Ord r, 1 <= d, 2 <= d, Arity d) => (Point d r :+ q) -> [Point d r :+ p] -> ([Point d r :+ p], [Point d r :+ p], [Point d r :+ p], [Point d r :+ p]) -- | Compare by distance to the first argument cmpByDistanceTo :: (Ord r, Num r, Arity d) => Point d r -> Point d r -> Point d r -> Ordering -- | Compare by distance to the first argument cmpByDistanceTo' :: (Ord r, Num r, Arity d) => (Point d r :+ c) -> (Point d r :+ p) -> (Point d r :+ q) -> Ordering -- | Squared Euclidean distance between two points squaredEuclideanDist :: (Num r, Arity d) => Point d r -> Point d r -> r -- | Euclidean distance between two points euclideanDist :: (Floating r, Arity d) => Point d r -> Point d r -> r -- | Get the coordinate in a given dimension -- --
--   >>> Point3 1 2 3 ^. coord (C :: C 2)
--   2
--   
--   >>> Point3 1 2 3 & coord (C :: C 1) .~ 10
--   Point3 10 2 3
--   
--   >>> Point3 1 2 3 & coord (C :: C 3) %~ (+1)
--   Point3 1 2 4
--   
coord :: (1 <= i, i <= d, KnownNat i, Arity d, AsAPoint p) => proxy i -> Lens' (p d r) r -- | Get the coordinate in a given dimension. This operation is unsafe in -- the sense that no bounds are checked. Consider using coord -- instead. -- --
--   >>> Point3 1 2 3 ^. unsafeCoord 2
--   2
--   
unsafeCoord :: (Arity d, AsAPoint p) => Int -> Lens' (p d r) r module Data.Geometry.RangeTree type RangeTree d = RT d d newtype RT i d v p r RangeTree :: RangeTree (Assoc i d v p r) (Leaf i d v p r) r -> RT i d v p r [_unRangeTree] :: RT i d v p r -> RangeTree (Assoc i d v p r) (Leaf i d v p r) r newtype Leaf i d v p r Leaf :: [Point d r :+ p] -> Leaf i d v p r [_getPts] :: Leaf i d v p r -> [Point d r :+ p] type family AssocT i d v p r newtype Assoc i d v p r Assoc :: AssocT i d v p r -> Assoc i d v p r [unAssoc] :: Assoc i d v p r -> AssocT i d v p r type RTMeasure v d p r = (LabeledMeasure v, Semigroup (v (Point d r :+ p))) createRangeTree' :: (Ord r, RTMeasure v d p r) => [Point d r :+ p] -> Maybe (RT i d v p r) createRangeTree :: (Ord r, RTMeasure v d p r) => NonEmpty (Point d r :+ p) -> RT i d v p r -- | Gets all points in the range tree toAscList :: RT i d v p r -> [Point d r :+ p] createRangeTree1 :: (Ord r, RTMeasure v d p r, 1 <= d, Arity d) => NonEmpty (Point d r :+ p) -> RT 1 d v p r createRangeTree2 :: forall v d r p. (Ord r, RTMeasure v d p r, Arity d, 2 <= d, 1 <= d) => NonEmpty (Point d r :+ p) -> RT 2 d v p r search :: (Ord r, Monoid (v (Point d r :+ p)), Query i d) => Vector d (Range r) -> RT i d v p r -> v (Point d r :+ p) class (i <= d, Arity d) => Query i d search' :: (Query i d, Ord r) => Vector d (Range r) -> RT i d v p r -> [v (Point d r :+ p)] instance forall k1 (i :: k1) (d :: GHC.Types.Nat) k2 (v :: k2) p r. GHC.Base.Monoid (Data.Geometry.RangeTree.Leaf i d v p r) instance forall k1 (i :: k1) (d :: GHC.Types.Nat) k2 (v :: k2) p r. GHC.Base.Semigroup (Data.Geometry.RangeTree.Leaf i d v p r) instance (GHC.Show.Show r, GHC.Show.Show (Data.Geometry.RangeTree.Assoc i d v p r), GHC.Show.Show (Data.Geometry.RangeTree.Leaf i d v p r)) => GHC.Show.Show (Data.Geometry.RangeTree.RT i d v p r) instance (GHC.Classes.Eq r, GHC.Classes.Eq (Data.Geometry.RangeTree.Assoc i d v p r), GHC.Classes.Eq (Data.Geometry.RangeTree.Leaf i d v p r)) => GHC.Classes.Eq (Data.Geometry.RangeTree.RT i d v p r) instance forall k1 k2 r p (d :: GHC.Types.Nat) (i :: k1) (v :: k2). (GHC.Show.Show r, GHC.Show.Show p, Data.Geometry.Vector.VectorFamily.Arity d) => GHC.Show.Show (Data.Geometry.RangeTree.Leaf i d v p r) instance forall k1 k2 r p (d :: GHC.Types.Nat) (i :: k1) (v :: k2). (GHC.Classes.Eq r, GHC.Classes.Eq p, Data.Geometry.Vector.VectorFamily.Arity d) => GHC.Classes.Eq (Data.Geometry.RangeTree.Leaf i d v p r) instance GHC.Show.Show (Data.Geometry.RangeTree.AssocT i d v p r) => GHC.Show.Show (Data.Geometry.RangeTree.Assoc i d v p r) instance GHC.Classes.Eq (Data.Geometry.RangeTree.AssocT i d v p r) => GHC.Classes.Eq (Data.Geometry.RangeTree.Assoc i d v p r) instance (1 GHC.TypeNats.<= d, Data.Geometry.Vector.VectorFamily.Arity d) => Data.Geometry.RangeTree.Query 1 d instance (1 GHC.TypeNats.<= d, i GHC.TypeNats.<= d, Data.Geometry.RangeTree.Query (i GHC.TypeNats.- 1) d, Data.Geometry.Vector.VectorFamily.Arity d, i GHC.Types.~ 2) => Data.Geometry.RangeTree.Query 2 d instance Data.Geometry.RangeTree.RTMeasure v d p r => GHC.Base.Semigroup (Data.Geometry.RangeTree.Assoc 1 d v p r) instance (Data.Geometry.RangeTree.RTMeasure v d p r, GHC.Classes.Ord r, 1 GHC.TypeNats.<= d, Data.Geometry.Vector.VectorFamily.Arity d) => GHC.Base.Semigroup (Data.Geometry.RangeTree.Assoc 2 d v p r) instance (Data.Geometry.RangeTree.RTMeasure v d p r, GHC.Classes.Ord r, 1 GHC.TypeNats.<= d, Data.Geometry.Vector.VectorFamily.Arity d) => GHC.Base.Monoid (Data.Geometry.RangeTree.Assoc 2 d v p r) instance Data.Geometry.RangeTree.RTMeasure v d p r => Data.Measured.Class.Measured (Data.Geometry.RangeTree.Assoc 1 d v p r) (Data.Geometry.RangeTree.Leaf 1 d v p r) instance (Data.Geometry.RangeTree.RTMeasure v d p r, GHC.Classes.Ord r, 1 GHC.TypeNats.<= d, Data.Geometry.Vector.VectorFamily.Arity d) => Data.Measured.Class.Measured (Data.Geometry.RangeTree.Assoc 2 d v p r) (Data.Geometry.RangeTree.Leaf 2 d v p r) -- | Implements a linear size data structure for three-sided range queries -- in <math>. See -- -- McCreight, Edward (May 1985). "Priority search trees". SIAM Journal on -- Scientific Computing. 14 (2): 257-276. -- -- for more details. module Data.Geometry.PrioritySearchTree -- | A priority search tree storing points in (mathbb{R}^2) that have an -- additional payload of type p. newtype PrioritySearchTree p r PrioritySearchTree :: BinLeafTree (NodeData p r) (LeafData p r) -> PrioritySearchTree p r [_unPrioritySearchTree] :: PrioritySearchTree p r -> BinLeafTree (NodeData p r) (LeafData p r) -- | Creates a Priority Search Tree for 3-sided range queries of the form -- <math>. -- -- the base tree will be static. -- -- pre: all points have unique x-coordinates -- -- running time: <math> createTree :: Ord r => NonEmpty (Point 2 r :+ p) -> PrioritySearchTree p r -- | Given a three sided range <math> report all points in the range -- <math>. The points are reported in decreasing order of -- <math>-coordinate. -- -- running time: <math>, where <math> is the number of -- reported points. queryRange :: Ord r => (Range r, r) -> PrioritySearchTree p r -> [Point 2 r :+ p] instance (GHC.Classes.Eq r, GHC.Classes.Eq p) => GHC.Classes.Eq (Data.Geometry.PrioritySearchTree.NodeData p r) instance (GHC.Show.Show r, GHC.Show.Show p) => GHC.Show.Show (Data.Geometry.PrioritySearchTree.NodeData p r) instance (GHC.Classes.Eq r, GHC.Classes.Eq p) => GHC.Classes.Eq (Data.Geometry.PrioritySearchTree.PrioritySearchTree p r) instance (GHC.Show.Show r, GHC.Show.Show p) => GHC.Show.Show (Data.Geometry.PrioritySearchTree.PrioritySearchTree p r) instance Data.Bifunctor.Bifunctor Data.Geometry.PrioritySearchTree.PrioritySearchTree instance Data.Bifunctor.Bifunctor Data.Geometry.PrioritySearchTree.NodeData module Algorithms.Geometry.FrechetDistance.Discrete -- | Returns the discrete frechet distance between two point sequences -- using the squared Euclidean distance. In other words, returns the -- square of the (Euclidean) frechet distance. -- -- running time: <math>, where <math> and <math> are -- the lengths of the sequences. discreteFrechetDistance :: (Foldable f, Foldable g, Functor f, Functor g, Ord r, Num r) => f (Point 2 r :+ p) -> g (Point 2 r :+ q) -> r -- | Returns the discrete frechet distance between two point sequences -- using the given distance measure. -- -- running time: <math>, where <math> and <math> are -- the lengths of the sequences (and assuming that a distance calculation -- takes constant time). discreteFrechetDistanceWith :: (Foldable f, Functor f, Functor g, Foldable g, Ord r) => (Point 2 r -> Point 2 r -> r) -> f (Point 2 r :+ p) -> g (Point 2 r :+ q) -> r instance GHC.Classes.Eq Algorithms.Geometry.FrechetDistance.Discrete.Loc instance GHC.Show.Show Algorithms.Geometry.FrechetDistance.Discrete.Loc -- | Classical <math> time divide and conquer algorithm to compute -- the closest pair among a set of <math> points in <math>. module Algorithms.Geometry.ClosestPair.DivideAndConquer -- | Classical divide and conquer algorithm to compute the closest pair -- among <math> points. -- -- running time: <math> closestPair :: (Ord r, Num r) => LSeq 2 (Point 2 r :+ p) -> Two (Point 2 r :+ p) -- | the closest pair and its (squared) distance type CP q r = Top (SP (Two q) r) -- | Type used in the closest pair computation. The fields represent the -- points ordered on increasing y-order and the closest pair (if we know -- it) data CCP p r CCP :: NonEmpty (Point 2 r :+ p) -> !CP (Point 2 r :+ p) r -> CCP p r -- | Function that does the actual merging work mergePairs :: forall p r. (Ord r, Num r) => CP (Point 2 r :+ p) r -> NonEmpty (Point 2 r :+ p) -> NonEmpty (Point 2 r :+ p) -> CP (Point 2 r :+ p) r instance (GHC.Classes.Eq r, GHC.Classes.Eq p) => GHC.Classes.Eq (Algorithms.Geometry.ClosestPair.DivideAndConquer.CCP p r) instance (GHC.Show.Show r, GHC.Show.Show p) => GHC.Show.Show (Algorithms.Geometry.ClosestPair.DivideAndConquer.CCP p r) instance (GHC.Num.Num r, GHC.Classes.Ord r) => GHC.Base.Semigroup (Algorithms.Geometry.ClosestPair.DivideAndConquer.CCP p r) -- | <math> time algorithm to compute the closest pair among a set of -- <math> points in <math>. module Algorithms.Geometry.ClosestPair -- | Classical divide and conquer algorithm to compute the closest pair -- among <math> points. -- -- running time: <math> closestPair :: (Ord r, Num r) => LSeq 2 (Point 2 r :+ p) -> Two (Point 2 r :+ p) -- | type-indexed matrices. module Data.Geometry.Matrix -- | A matrix of n rows, each of m columns, storing values of type r. newtype Matrix n m r Matrix :: Vector n (Vector m r) -> Matrix n m r -- | Produces the Identity Matrix. identityMatrix :: (Arity d, Num r) => Matrix d d r -- | Matrix product. multM :: (Arity r, Arity c, Arity c', Num a) => Matrix r c a -> Matrix c c' a -> Matrix r c' a -- | Matrix * column vector. mult :: (Arity m, Arity n, Num r) => Matrix n m r -> Vector m r -> Vector n r -- | Class of matrices that are invertible. class Invertible n r inverse' :: Invertible n r => Matrix n n r -> Matrix n n r -- | Class of matrices that have a determinant. class Arity d => HasDeterminant d det :: (HasDeterminant d, Num r) => Matrix d d r -> r instance (GHC.Show.Show r, Data.Geometry.Vector.VectorFamily.Arity n, Data.Geometry.Vector.VectorFamily.Arity m) => GHC.Show.Show (Data.Geometry.Matrix.Matrix n m r) instance (GHC.Classes.Eq r, Data.Geometry.Vector.VectorFamily.Arity n, Data.Geometry.Vector.VectorFamily.Arity m) => GHC.Classes.Eq (Data.Geometry.Matrix.Matrix n m r) instance (GHC.Classes.Ord r, Data.Geometry.Vector.VectorFamily.Arity n, Data.Geometry.Vector.VectorFamily.Arity m) => GHC.Classes.Ord (Data.Geometry.Matrix.Matrix n m r) instance (Data.Geometry.Vector.VectorFamily.Arity n, Data.Geometry.Vector.VectorFamily.Arity m) => GHC.Base.Functor (Data.Geometry.Matrix.Matrix n m) instance (Data.Geometry.Vector.VectorFamily.Arity n, Data.Geometry.Vector.VectorFamily.Arity m) => Data.Foldable.Foldable (Data.Geometry.Matrix.Matrix n m) instance (Data.Geometry.Vector.VectorFamily.Arity n, Data.Geometry.Vector.VectorFamily.Arity m) => Data.Traversable.Traversable (Data.Geometry.Matrix.Matrix n m) instance Data.Geometry.Matrix.HasDeterminant 1 instance Data.Geometry.Matrix.HasDeterminant 2 instance Data.Geometry.Matrix.HasDeterminant 3 instance Data.Geometry.Matrix.HasDeterminant 4 instance GHC.Real.Fractional r => Data.Geometry.Matrix.Invertible 2 r instance GHC.Real.Fractional r => Data.Geometry.Matrix.Invertible 3 r instance GHC.Real.Fractional r => Data.Geometry.Matrix.Invertible 4 r -- | <math>-dimensional lines. module Data.Geometry.Line.Internal -- | A line is given by an anchor point and a vector indicating the -- direction. data Line d r Line :: !Point d r -> !Vector d r -> Line d r [_anchorPoint] :: Line d r -> !Point d r [_direction] :: Line d r -> !Vector d r -- | Line anchor point. anchorPoint :: Lens' (Line d r) (Point d r) -- | Line direction. direction :: Lens' (Line d r) (Vector d r) -- | A line may be constructed from two points. lineThrough :: (Num r, Arity d) => Point d r -> Point d r -> Line d r -- | Vertical line with a given X-coordinate. verticalLine :: Num r => r -> Line 2 r -- | Horizontal line with a given Y-coordinate. horizontalLine :: Num r => r -> Line 2 r -- | Given a line l with anchor point p and vector v, get the line -- perpendicular to l that also goes through p. The resulting line m is -- oriented such that v points into the left halfplane of m. -- --
--   >>> perpendicularTo $ Line (Point2 3 4) (Vector2 (-1) 2)
--   Line (Point2 3 4) (Vector2 (-2) (-1))
--   
perpendicularTo :: Num r => Line 2 r -> Line 2 r -- | Test if a vector is perpendicular to the line. isPerpendicularTo :: (Num r, Eq r) => Vector 2 r -> Line 2 r -> Bool -- | Test if two lines are identical, meaning; if they have exactly the -- same anchor point and directional vector. isIdenticalTo :: (Eq r, Arity d) => Line d r -> Line d r -> Bool -- | Test if the two lines are parallel. -- --
--   >>> lineThrough origin (Point2 1 0) `isParallelTo` lineThrough (Point2 1 1) (Point2 2 1)
--   True
--   
--   >>> lineThrough origin (Point2 1 0) `isParallelTo` lineThrough (Point2 1 1) (Point2 2 2)
--   False
--   
isParallelTo :: (Eq r, Fractional r, Arity d) => Line d r -> Line d r -> Bool -- | Test if point p lies on line l -- --
--   >>> origin `onLine` lineThrough origin (Point2 1 0)
--   True
--   
--   >>> Point2 10 10 `onLine` lineThrough origin (Point2 2 2)
--   True
--   
--   >>> Point2 10 5 `onLine` lineThrough origin (Point2 2 2)
--   False
--   
onLine :: (Eq r, Fractional r, Arity d) => Point d r -> Line d r -> Bool -- | Specific 2d version of testing if apoint lies on a line. onLine2 :: (Ord r, Num r) => Point 2 r -> Line 2 r -> Bool -- | Get the point at the given position along line, where 0 corresponds to -- the anchorPoint of the line, and 1 to the point anchorPoint .+^ -- directionVector pointAt :: (Num r, Arity d) => r -> Line d r -> Point d r -- | Given point p and a line (Line q v), Get the scalar lambda s.t. p = q -- + lambda v. If p does not lie on the line this returns a Nothing. toOffset :: (Eq r, Fractional r, Arity d) => Point d r -> Line d r -> Maybe r -- | Given point p near a line (Line q v), get the scalar lambda s.t. the -- distance between p and 'q + lambda v' is minimized. -- --
--   >>> toOffset' (Point2 1 1) (lineThrough origin $ Point2 10 10)
--   0.1
--   
-- --
--   >>> toOffset' (Point2 5 5) (lineThrough origin $ Point2 10 10)
--   0.5
--   
-- -- <6,4> is not on the line but we can still point closest to it. -- >>> toOffset' (Point2 6 4) (lineThrough origin $ Point2 10 -- 10) 0.5 toOffset' :: (Eq r, Fractional r, Arity d) => Point d r -> Line d r -> r -- | Squared distance from point p to line l sqDistanceTo :: (Fractional r, Arity d) => Point d r -> Line d r -> r -- | The squared distance between the point p and the line l, and the point -- m realizing this distance. sqDistanceToArg :: (Fractional r, Arity d) => Point d r -> Line d r -> (r, Point d r) -- | Types for which we can compute a supporting line, i.e. a line that -- contains the thing of type t. class HasSupportingLine t supportingLine :: HasSupportingLine t => t -> Line (Dimension t) (NumType t) -- | Create a line from the linear function ax + b fromLinearFunction :: Num r => r -> r -> Line 2 r -- | get values a,b s.t. the input line is described by y = ax + b. returns -- Nothing if the line is vertical toLinearFunction :: forall r. (Fractional r, Eq r) => Line 2 r -> Maybe (r, r) -- | Given a point p and a line l, computes the point q on l closest to p. pointClosestTo :: (Fractional r, Arity d) => Point d r -> Line d r -> Point d r -- | Result of a side test data SideTestUpDown Below :: SideTestUpDown On :: SideTestUpDown Above :: SideTestUpDown class OnSideUpDownTest t onSideUpDown :: (OnSideUpDownTest t, d ~ Dimension t, r ~ NumType t, Ord r, Num r) => Point d r -> t -> SideTestUpDown -- | Result of a side test data SideTest LeftSide :: SideTest OnLine :: SideTest RightSide :: SideTest -- | Given a point q and a line l, compute to which side of l q lies. For -- vertical lines the left side of the line is interpeted as below. -- --
--   >>> Point2 10 10 `onSide` (lineThrough origin $ Point2 10 5)
--   LeftSide
--   
--   >>> Point2 10 10 `onSide` (lineThrough origin $ Point2 (-10) 5)
--   RightSide
--   
--   >>> Point2 5 5 `onSide` (verticalLine 10)
--   LeftSide
--   
--   >>> Point2 5 5 `onSide` (lineThrough origin $ Point2 (-3) (-3))
--   OnLine
--   
onSide :: (Ord r, Num r) => Point 2 r -> Line 2 r -> SideTest -- | Test if the query point q lies (strictly) above line l liesAbove :: (Ord r, Num r) => Point 2 r -> Line 2 r -> Bool -- | Test if the query point q lies (strictly) above line l liesBelow :: (Ord r, Num r) => Point 2 r -> Line 2 r -> Bool -- | Get the bisector between two points bisector :: Fractional r => Point 2 r -> Point 2 r -> Line 2 r -- | Compares the lines on slope. Vertical lines are considered larger than -- anything else. -- --
--   >>> (Line origin (Vector2 5 1)) `cmpSlope` (Line origin (Vector2 3 3))
--   LT
--   
--   >>> (Line origin (Vector2 5 1)) `cmpSlope` (Line origin (Vector2 (-3) 3))
--   GT
--   
--   >>> (Line origin (Vector2 5 1)) `cmpSlope` (Line origin (Vector2 0 1))
--   LT
--   
cmpSlope :: (Num r, Ord r) => Line 2 r -> Line 2 r -> Ordering instance GHC.Generics.Generic (Data.Geometry.Line.Internal.Line d r) instance GHC.Classes.Ord Data.Geometry.Line.Internal.SideTestUpDown instance GHC.Classes.Eq Data.Geometry.Line.Internal.SideTestUpDown instance GHC.Read.Read Data.Geometry.Line.Internal.SideTestUpDown instance GHC.Show.Show Data.Geometry.Line.Internal.SideTestUpDown instance GHC.Classes.Ord Data.Geometry.Line.Internal.SideTest instance GHC.Classes.Eq Data.Geometry.Line.Internal.SideTest instance GHC.Read.Read Data.Geometry.Line.Internal.SideTest instance GHC.Show.Show Data.Geometry.Line.Internal.SideTest instance (Control.DeepSeq.NFData r, Data.Geometry.Vector.VectorFamily.Arity d) => Control.DeepSeq.NFData (Data.Geometry.Line.Internal.Line d r) instance Data.Geometry.Vector.VectorFamily.Arity d => GHC.Base.Functor (Data.Geometry.Line.Internal.Line d) instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Foldable.Foldable (Data.Geometry.Line.Internal.Line d) instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Traversable.Traversable (Data.Geometry.Line.Internal.Line d) instance Data.Geometry.Line.Internal.OnSideUpDownTest (Data.Geometry.Line.Internal.Line 2 r) instance Data.Geometry.Line.Internal.HasSupportingLine (Data.Geometry.Line.Internal.Line d r) instance (GHC.Show.Show r, Data.Geometry.Vector.VectorFamily.Arity d) => GHC.Show.Show (Data.Geometry.Line.Internal.Line d r) instance (Data.Geometry.Vector.VectorFamily.Arity d, GHC.Classes.Eq r, GHC.Real.Fractional r) => GHC.Classes.Eq (Data.Geometry.Line.Internal.Line d r) instance (Test.QuickCheck.Arbitrary.Arbitrary r, Data.Geometry.Vector.VectorFamily.Arity d, GHC.Num.Num r, GHC.Classes.Eq r) => Test.QuickCheck.Arbitrary.Arbitrary (Data.Geometry.Line.Internal.Line d r) instance (GHC.Classes.Eq r, GHC.Real.Fractional r) => Data.Intersection.HasIntersectionWith (Data.Geometry.Line.Internal.Line 2 r) (Data.Geometry.Line.Internal.Line 2 r) instance (GHC.Classes.Eq r, GHC.Real.Fractional r) => Data.Intersection.IsIntersectableWith (Data.Geometry.Line.Internal.Line 2 r) (Data.Geometry.Line.Internal.Line 2 r) -- | SubLine; a part of a line module Data.Geometry.SubLine -- | Part of a line. The interval is ranged based on the vector of the line -- l, and s.t.t zero is the anchorPoint of l. data SubLine d p s r SubLine :: Line d r -> Interval p s -> SubLine d p s r [_line] :: SubLine d p s r -> Line d r [_subRange] :: SubLine d p s r -> Interval p s -- | Line part of SubLine. line :: Lens (SubLine d1 p s r1) (SubLine d2 p s r2) (Line d1 r1) (Line d2 r2) -- | Interval part of SubLine. subRange :: Lens (SubLine d p1 s1 r) (SubLine d p2 s2 r) (Interval p1 s1) (Interval p2 s2) -- | Annotate the subRange with the actual ending points fixEndPoints :: (Num r, Arity d) => SubLine d p r r -> SubLine d (Point d r :+ p) r r -- | forget the extra information stored at the endpoints of the subline. dropExtra :: SubLine d p s r -> SubLine d () s r -- | Prism for downcasting an unbounded subline to a subline. _unBounded :: Prism' (SubLine d p (UnBounded r) r) (SubLine d p r r) -- | Transform into an subline with a potentially unbounded interval toUnbounded :: SubLine d p r r -> SubLine d p (UnBounded r) r -- | Try to make a potentially unbounded subline into a bounded one. fromUnbounded :: SubLine d p (UnBounded r) r -> Maybe (SubLine d p r r) -- | given point p, and a Subline l r such that p lies on line l, test if -- it lies on the subline, i.e. in the interval r onSubLine :: (Ord r, Fractional r, Arity d) => Point d r -> SubLine d p r r -> Bool -- | given point p, and a Subline l r such that p lies on line l, test if -- it lies on the subline, i.e. in the interval r onSubLineUB :: (Ord r, Fractional r) => Point 2 r -> SubLine 2 p (UnBounded r) r -> Bool -- | given point p, and a Subline l r such that p lies on line l, test if -- it lies on the subline, i.e. in the interval r onSubLine2 :: (Ord r, Num r) => Point 2 r -> SubLine 2 p r r -> Bool -- | given point p, and a Subline l r such that p lies on line l, test if -- it lies on the subline, i.e. in the interval r onSubLine2UB :: (Ord r, Fractional r) => Point 2 r -> SubLine 2 p (UnBounded r) r -> Bool -- | Get the endpoints of an unbounded interval getEndPointsUnBounded :: (Num r, Arity d) => SubLine d p (UnBounded r) r -> Interval p (UnBounded (Point d r)) -- | Create a SubLine that covers the original line from -infinity to -- +infinity. fromLine :: Arity d => Line d r -> SubLine d () (UnBounded r) r instance (GHC.Show.Show r, GHC.Show.Show s, GHC.Show.Show p, Data.Geometry.Vector.VectorFamily.Arity d) => GHC.Show.Show (Data.Geometry.SubLine.SubLine d p s r) instance (GHC.Classes.Eq r, GHC.Classes.Eq s, GHC.Real.Fractional r, GHC.Classes.Eq p, Data.Geometry.Vector.VectorFamily.Arity d) => GHC.Classes.Eq (Data.Geometry.SubLine.SubLine d p s r) instance Data.Geometry.Vector.VectorFamily.Arity d => GHC.Base.Functor (Data.Geometry.SubLine.SubLine d p s) instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Foldable.Foldable (Data.Geometry.SubLine.SubLine d p s) instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Traversable.Traversable (Data.Geometry.SubLine.SubLine d p s) instance (Test.QuickCheck.Arbitrary.Arbitrary r, Test.QuickCheck.Arbitrary.Arbitrary p, Test.QuickCheck.Arbitrary.Arbitrary s, Data.Geometry.Vector.VectorFamily.Arity d, GHC.Classes.Ord r, GHC.Classes.Ord s, GHC.Classes.Ord p, GHC.Num.Num r) => Test.QuickCheck.Arbitrary.Arbitrary (Data.Geometry.SubLine.SubLine d p s r) instance (GHC.Classes.Ord r, GHC.Real.Fractional r) => Data.Intersection.HasIntersectionWith (Data.Geometry.SubLine.SubLine 2 p r r) (Data.Geometry.SubLine.SubLine 2 p r r) instance (GHC.Classes.Ord r, GHC.Real.Fractional r) => Data.Intersection.IsIntersectableWith (Data.Geometry.SubLine.SubLine 2 p r r) (Data.Geometry.SubLine.SubLine 2 p r r) instance (GHC.Classes.Ord r, GHC.Real.Fractional r) => Data.Intersection.HasIntersectionWith (Data.Geometry.SubLine.SubLine 2 p (Data.UnBounded.UnBounded r) r) (Data.Geometry.SubLine.SubLine 2 p (Data.UnBounded.UnBounded r) r) instance (GHC.Classes.Ord r, GHC.Real.Fractional r) => Data.Intersection.IsIntersectableWith (Data.Geometry.SubLine.SubLine 2 p (Data.UnBounded.UnBounded r) r) (Data.Geometry.SubLine.SubLine 2 p (Data.UnBounded.UnBounded r) r) -- | Orthogonal <math>-dimensiontal boxes (e.g. rectangles) module Data.Geometry.Box.Internal -- | Coordinate wize minimum newtype CWMin a CWMin :: a -> CWMin a [_cwMin] :: CWMin a -> a cwMin :: forall a_a1jIc a_a1jX7. Iso (CWMin a_a1jIc) (CWMin a_a1jX7) a_a1jIc a_a1jX7 -- | Coordinate wize maximum newtype CWMax a CWMax :: a -> CWMax a [_cwMax] :: CWMax a -> a cwMax :: forall a_a1jXd a_a1kem. Iso (CWMax a_a1jXd) (CWMax a_a1kem) a_a1jXd a_a1kem data Box d p r Box :: !CWMin (Point d r) :+ p -> !CWMax (Point d r) :+ p -> Box d p r [_minP] :: Box d p r -> !CWMin (Point d r) :+ p [_maxP] :: Box d p r -> !CWMax (Point d r) :+ p minP :: forall d_a1ket p_a1keu r_a1kev. Lens' (Box d_a1ket p_a1keu r_a1kev) ((:+) (CWMin (Point d_a1ket r_a1kev)) p_a1keu) maxP :: forall d_a1ket p_a1keu r_a1kev. Lens' (Box d_a1ket p_a1keu r_a1kev) ((:+) (CWMax (Point d_a1ket r_a1kev)) p_a1keu) -- | Given the point with the lowest coordinates and the point with highest -- coordinates, create a box. box :: (Point d r :+ p) -> (Point d r :+ p) -> Box d p r -- | grows the box by x on all sides grow :: (Num r, Arity d) => r -> Box d p r -> Box d p r -- | Build a d dimensional Box given d ranges. fromExtent :: Arity d => Vector d (Range r) -> Box d () r -- | Given a center point and a vector specifying the box width's, -- construct a box. fromCenter :: (Arity d, Fractional r) => Point d r -> Vector d r -> Box d () r -- | Center of the box centerPoint :: (Arity d, Fractional r) => Box d p r -> Point d r minPoint :: Box d p r -> Point d r :+ p maxPoint :: Box d p r -> Point d r :+ p -- | Check if a point lies a box -- --
--   >>> origin `inBox` (boundingBoxList' [Point3 1 2 3, Point3 10 20 30] :: Box 3 () Int)
--   False
--   
--   >>> origin `inBox` (boundingBoxList' [Point3 (-1) (-2) (-3), Point3 10 20 30] :: Box 3 () Int)
--   True
--   
inBox :: (Arity d, Ord r) => Point d r -> Box d p r -> Bool -- | Check if a point lies strictly inside a box (i.e. not on its boundary) -- --
--   >>> origin `inBox` (boundingBoxList' [Point3 1 2 3, Point3 10 20 30] :: Box 3 () Int)
--   False
--   
--   >>> origin `inBox` (boundingBoxList' [Point3 (-1) (-2) (-3), Point3 10 20 30] :: Box 3 () Int)
--   True
--   
insideBox :: (Arity d, Ord r) => Point d r -> Box d p r -> Bool -- | Get a vector with the extent of the box in each dimension. Note that -- the resulting vector is 0 indexed whereas one would normally count -- dimensions starting at zero. -- --
--   >>> extent (boundingBoxList' [Point3 1 2 3, Point3 10 20 30] :: Box 3 () Int)
--   Vector3 (Range (Closed 1) (Closed 10)) (Range (Closed 2) (Closed 20)) (Range (Closed 3) (Closed 30))
--   
extent :: Arity d => Box d p r -> Vector d (Range r) -- | Get the size of the box (in all dimensions). Note that the resulting -- vector is 0 indexed whereas one would normally count dimensions -- starting at zero. -- --
--   >>> size (boundingBoxList' [origin, Point3 1 2 3] :: Box 3 () Int)
--   Vector3 1 2 3
--   
size :: (Arity d, Num r) => Box d p r -> Vector d r -- | Given a dimension, get the width of the box in that dimension. -- Dimensions are 1 indexed. -- --
--   >>> widthIn (C :: C 1) (boundingBoxList' [origin, Point3 1 2 3] :: Box 3 () Int)
--   1
--   
--   >>> widthIn (C :: C 3) (boundingBoxList' [origin, Point3 1 2 3] :: Box 3 () Int)
--   3
--   
widthIn :: forall proxy p i d r. (Arity d, Arity (i - 1), Num r, ((i - 1) + 1) <= d) => proxy i -> Box d p r -> r -- | Same as widthIn but with a runtime int instead of a static -- dimension. -- --
--   >>> widthIn' 1 (boundingBoxList' [origin, Point3 1 2 3] :: Box 3 () Int)
--   Just 1
--   
--   >>> widthIn' 3 (boundingBoxList' [origin, Point3 1 2 3] :: Box 3 () Int)
--   Just 3
--   
--   >>> widthIn' 10 (boundingBoxList' [origin, Point3 1 2 3] :: Box 3 () Int)
--   Nothing
--   
widthIn' :: (Arity d, Num r) => Int -> Box d p r -> Maybe r type Rectangle = Box 2 -- |
--   >>> width (boundingBoxList' [origin, Point2 1 2] :: Rectangle () Int)
--   1
--   
--   >>> width (boundingBoxList' [origin] :: Rectangle () Int)
--   0
--   
width :: Num r => Rectangle p r -> r -- |
--   >>> height (boundingBoxList' [origin, Point2 1 2] :: Rectangle () Int)
--   2
--   
--   >>> height (boundingBoxList' [origin] :: Rectangle () Int)
--   0
--   
height :: Num r => Rectangle p r -> r class IsBoxable g boundingBox :: (IsBoxable g, Ord (NumType g)) => g -> Box (Dimension g) () (NumType g) -- | Create a bounding box that encapsulates a list of objects. boundingBoxList :: (IsBoxable g, Foldable1 c, Ord (NumType g), Arity (Dimension g)) => c g -> Box (Dimension g) () (NumType g) -- | Unsafe version of boundingBoxList, that does not check if the list is -- non-empty boundingBoxList' :: (IsBoxable g, Foldable c, Ord (NumType g), Arity (Dimension g)) => c g -> Box (Dimension g) () (NumType g) instance (GHC.Show.Show r, GHC.Show.Show p, Data.Geometry.Vector.VectorFamily.Arity d) => GHC.Show.Show (Data.Geometry.Box.Internal.Box d p r) instance (GHC.Classes.Eq r, GHC.Classes.Eq p, Data.Geometry.Vector.VectorFamily.Arity d) => GHC.Classes.Eq (Data.Geometry.Box.Internal.Box d p r) instance (GHC.Classes.Ord r, GHC.Classes.Ord p, Data.Geometry.Vector.VectorFamily.Arity d) => GHC.Classes.Ord (Data.Geometry.Box.Internal.Box d p r) instance Data.Geometry.Box.Internal.IsBoxable (Data.Geometry.Point.Internal.Point d r) instance Data.Geometry.Box.Internal.IsBoxable (Data.Geometry.Box.Internal.Box d p r) instance Data.Geometry.Box.Internal.IsBoxable c => Data.Geometry.Box.Internal.IsBoxable (c Data.Ext.:+ e) instance (Data.Geometry.Vector.VectorFamily.Arity d, GHC.Classes.Ord r, GHC.Base.Semigroup p) => GHC.Base.Semigroup (Data.Geometry.Box.Internal.Box d p r) instance (GHC.Classes.Ord r, Data.Geometry.Vector.VectorFamily.Arity d) => Data.Intersection.HasIntersectionWith (Data.Geometry.Box.Internal.Box d p r) (Data.Geometry.Box.Internal.Box d q r) instance (GHC.Classes.Ord r, Data.Geometry.Vector.VectorFamily.Arity d) => Data.Intersection.IsIntersectableWith (Data.Geometry.Box.Internal.Box d p r) (Data.Geometry.Box.Internal.Box d q r) instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Bifunctor.Bifunctor (Data.Geometry.Box.Internal.Box d) instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Bifoldable.Bifoldable (Data.Geometry.Box.Internal.Box d) instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Bitraversable.Bitraversable (Data.Geometry.Box.Internal.Box d) instance (Data.Geometry.Vector.VectorFamily.Arity d, GHC.Classes.Ord r) => Data.Intersection.HasIntersectionWith (Data.Geometry.Point.Internal.Point d r) (Data.Geometry.Box.Internal.Box d p r) instance (Data.Geometry.Vector.VectorFamily.Arity d, GHC.Classes.Ord r) => Data.Intersection.IsIntersectableWith (Data.Geometry.Point.Internal.Point d r) (Data.Geometry.Box.Internal.Box d p r) instance Data.Geometry.Point.Internal.PointFunctor (Data.Geometry.Box.Internal.Box d p) instance (GHC.Real.Fractional r, Data.Geometry.Vector.VectorFamily.Arity d, Data.Geometry.Vector.VectorFamily.Arity (d GHC.TypeNats.+ 1)) => Data.Geometry.Transformation.Internal.IsTransformable (Data.Geometry.Box.Internal.Box d p r) instance (Test.QuickCheck.Arbitrary.Arbitrary r, Data.Geometry.Vector.VectorFamily.Arity d, GHC.Classes.Ord r) => Test.QuickCheck.Arbitrary.Arbitrary (Data.Geometry.Box.Internal.Box d () r) instance GHC.Generics.Generic (Data.Geometry.Box.Internal.Box d p r) instance (Data.Geometry.Vector.VectorFamily.Arity d, GHC.Classes.Ord r) => GHC.Base.Semigroup (Data.Geometry.Box.Internal.CWMax (Data.Geometry.Point.Internal.Point d r)) instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Data.Geometry.Box.Internal.CWMax a) instance GHC.Generics.Generic (Data.Geometry.Box.Internal.CWMax a) instance Data.Traversable.Traversable Data.Geometry.Box.Internal.CWMax instance Data.Foldable.Foldable Data.Geometry.Box.Internal.CWMax instance GHC.Base.Functor Data.Geometry.Box.Internal.CWMax instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.Geometry.Box.Internal.CWMax a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Geometry.Box.Internal.CWMax a) instance GHC.Show.Show a => GHC.Show.Show (Data.Geometry.Box.Internal.CWMax a) instance (Data.Geometry.Vector.VectorFamily.Arity d, GHC.Classes.Ord r) => GHC.Base.Semigroup (Data.Geometry.Box.Internal.CWMin (Data.Geometry.Point.Internal.Point d r)) instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Data.Geometry.Box.Internal.CWMin a) instance GHC.Generics.Generic (Data.Geometry.Box.Internal.CWMin a) instance Data.Traversable.Traversable Data.Geometry.Box.Internal.CWMin instance Data.Foldable.Foldable Data.Geometry.Box.Internal.CWMin instance GHC.Base.Functor Data.Geometry.Box.Internal.CWMin instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.Geometry.Box.Internal.CWMin a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Geometry.Box.Internal.CWMin a) instance GHC.Show.Show a => GHC.Show.Show (Data.Geometry.Box.Internal.CWMin a) -- | Line segment data type and some basic functions on line segments module Data.Geometry.LineSegment.Internal -- | Line segments. LineSegments have a start and end point, both of which -- may contain additional data of type p. We can think of a Line-Segment -- being defined as -- --
--   >>> data LineSegment d p r = LineSegment (EndPoint (Point d r :+ p)) (EndPoint (Point d r :+ p))
--   
-- -- it is assumed that the two endpoints of the line segment are disjoint. -- This is not checked. data LineSegment d p r pattern LineSegment :: EndPoint (Point d r :+ p) -> EndPoint (Point d r :+ p) -> LineSegment d p r -- | Gets the start and end point, but forgetting if they are open or -- closed. pattern LineSegment' :: (Point d r :+ p) -> (Point d r :+ p) -> LineSegment d p r pattern ClosedLineSegment :: (Point d r :+ p) -> (Point d r :+ p) -> LineSegment d p r pattern OpenLineSegment :: (Point d r :+ p) -> (Point d r :+ p) -> LineSegment d p r -- | Traversal to access the endpoints. Note that this traversal allows you -- to change more or less everything, even the dimension and the numeric -- type used, but it preservers if the segment is open or closed. endPoints :: Traversal (LineSegment d p r) (LineSegment d' q s) (Point d r :+ p) (Point d' s :+ q) _SubLine :: (Num r, Arity d) => Iso' (LineSegment d p r) (SubLine d p r r) -- | Shifts the range to the right -- --
--   >>> prettyShow $ shiftRight 10 (ClosedRange 10 20)
--   "[20,30]"
--   
--   >>> prettyShow $ shiftRight 10 (OpenRange 15 25)
--   "(25,35)"
--   
shiftRight :: Num r => r -> Range r -> Range r -- | Shift a range x units to the left -- --
--   >>> prettyShow $ shiftLeft 10 (ClosedRange 10 20)
--   "[0,10]"
--   
--   >>> prettyShow $ shiftLeft 10 (OpenRange 15 25)
--   "(5,15)"
--   
shiftLeft :: Num r => r -> Range r -> Range r -- | Check if the range is valid and nonEmpty, i.e. if the lower endpoint -- is indeed smaller than the right endpoint. Note that we treat empty -- open-ranges as invalid as well. isValidRange :: Ord a => Range a -> Bool -- | Wether or not the first range completely covers the second one covers :: Ord a => Range a -> Range a -> Bool -- | Clip the interval from above. I.e. intersect with (-infty, u}, where } -- is either open, ), or closed, ], clipUpper :: Ord a => EndPoint a -> Range a -> Maybe (Range a) -- | Clip the interval from below. I.e. intersect with the interval -- {l,infty), where { is either open, (, orr closed, [. clipLower :: Ord a => EndPoint a -> Range a -> Maybe (Range a) -- | Clamps a value to a range. I.e. if the value lies outside the range we -- report the closest value "in the range". Note that if an endpoint of -- the range is open we report that value anyway, so we return a value -- that is truely inside the range only if that side of the range is -- closed. -- --
--   >>> clampTo (ClosedRange 0 10) 20
--   10
--   
--   >>> clampTo (ClosedRange 0 10) (-20)
--   0
--   
--   >>> clampTo (ClosedRange 0 10) 5
--   5
--   
--   >>> clampTo (OpenRange 0 10) 20
--   10
--   
--   >>> clampTo (OpenRange 0 10) (-20)
--   0
--   
--   >>> clampTo (OpenRange 0 10) 5
--   5
--   
clampTo :: Ord r => Range r -> r -> r -- | Test if a value lies in a range. -- --
--   >>> 1 `inRange` (OpenRange 0 2)
--   True
--   
--   >>> 1 `inRange` (OpenRange 0 1)
--   False
--   
--   >>> 1 `inRange` (ClosedRange 0 1)
--   True
--   
--   >>> 1 `inRange` (ClosedRange 1 1)
--   True
--   
--   >>> 10 `inRange` (OpenRange 1 10)
--   False
--   
--   >>> 10 `inRange` (ClosedRange 0 1)
--   False
--   
-- -- This one is kind of weird -- --
--   >>> 0 `inRange` Range (Closed 0) (Open 0)
--   False
--   
inRange :: Ord a => a -> Range a -> Bool -- | Helper function to show a range in mathematical notation. -- --
--   >>> prettyShow $ OpenRange 0 2
--   "(0,2)"
--   
--   >>> prettyShow $ ClosedRange 0 2
--   "[0,2]"
--   
--   >>> prettyShow $ Range (Open 0) (Closed 5)
--   "(0,5]"
--   
prettyShow :: Show a => Range a -> String -- | Lens access for the upper part of a range. upper :: Lens' (Range a) (EndPoint a) -- | Lens access for the lower part of a range. lower :: Lens' (Range a) (EndPoint a) -- | True iff EndPoint is closed. isClosed :: EndPoint a -> Bool -- | True iff EndPoint is open. isOpen :: EndPoint a -> Bool -- | Access lens for EndPoint value regardless of whether it is open or -- closed. -- --
--   >>> Open 5 ^. unEndPoint
--   5
--   
--   >>> Closed 10 ^. unEndPoint
--   10
--   
--   >>> Open 4 & unEndPoint .~ 0
--   Open 0
--   
unEndPoint :: Lens (EndPoint a) (EndPoint b) a b -- | Endpoints of a range may either be open or closed. data EndPoint a Open :: !a -> EndPoint a Closed :: !a -> EndPoint a -- | Data type for representing ranges. data Range a Range :: !EndPoint a -> !EndPoint a -> Range a [_lower] :: Range a -> !EndPoint a [_upper] :: Range a -> !EndPoint a pattern OpenRange :: a -> a -> Range a pattern ClosedRange :: a -> a -> Range a -- | A range from l to u, ignoring/forgetting the type of the endpoints pattern Range' :: a -> a -> Range a class HasEnd t where { type family EndCore t; type family EndExtra t; } end :: HasEnd t => Lens' t (EndCore t :+ EndExtra t) class HasStart t where { type family StartCore t; type family StartExtra t; } start :: HasStart t => Lens' t (StartCore t :+ StartExtra t) -- | An Interval is essentially a Range but with possible payload -- -- We can think of an interval being defined as: -- --
--   >>> data Interval a r = Interval (EndPoint (r :+ a)) (EndPoint (r :+ a))
--   
data Interval a r pattern ClosedInterval :: (r :+ a) -> (r :+ a) -> Interval a r pattern Interval :: EndPoint (r :+ a) -> EndPoint (r :+ a) -> Interval a r pattern OpenInterval :: (r :+ a) -> (r :+ a) -> Interval a r -- | Cast an interval to a range. toRange :: Interval a r -> Range (r :+ a) -- | Intervals and ranges are isomorphic. _Range :: Iso' (Interval a r) (Range (r :+ a)) -- | Constrct an interval from a Range fromRange :: Range (r :+ a) -> Interval a r -- | Test if a value lies in an interval. Note that the difference between -- inInterval and inRange is that the extra value is *not* used in the -- comparison with inInterval, whereas it is in inRange. inInterval :: Ord r => r -> Interval a r -> Bool -- | Shifts the interval to the left by delta shiftLeft' :: Num r => r -> Interval a r -> Interval a r -- | Makes sure the start and endpoint are oriented such that the starting -- value is smaller than the ending value. asProperInterval :: Ord r => Interval p r -> Interval p r -- | Flips the start and endpoint of the interval. flipInterval :: Interval a r -> Interval a r -- | Directly convert a line into a line segment. toLineSegment :: (Monoid p, Num r, Arity d) => Line d r -> LineSegment d p r -- | Test if a point lies on a line segment. -- -- As a user, you should typically just use intersects instead. onSegment :: (Ord r, Fractional r, Arity d) => Point d r -> LineSegment d p r -> Bool -- | Test if a point lies on a line segment. -- --
--   >>> (Point2 1 0) `onSegment2` (ClosedLineSegment (origin :+ ()) (Point2 2 0 :+ ()))
--   True
--   
--   >>> (Point2 1 1) `onSegment2` (ClosedLineSegment (origin :+ ()) (Point2 2 0 :+ ()))
--   False
--   
--   >>> (Point2 5 0) `onSegment2` (ClosedLineSegment (origin :+ ()) (Point2 2 0 :+ ()))
--   False
--   
--   >>> (Point2 (-1) 0) `onSegment2` (ClosedLineSegment (origin :+ ()) (Point2 2 0 :+ ()))
--   False
--   
--   >>> (Point2 1 1) `onSegment2` (ClosedLineSegment (origin :+ ()) (Point2 3 3 :+ ()))
--   True
--   
--   >>> (Point2 2 0) `onSegment2` (ClosedLineSegment (origin :+ ()) (Point2 2 0 :+ ()))
--   True
--   
--   >>> origin `onSegment2` (ClosedLineSegment (origin :+ ()) (Point2 2 0 :+ ()))
--   True
--   
onSegment2 :: (Ord r, Num r) => Point 2 r -> LineSegment 2 p r -> Bool -- | The left and right end point (or left below right if they have equal -- x-coords) orderedEndPoints :: Ord r => LineSegment 2 p r -> (Point 2 r :+ p, Point 2 r :+ p) -- | Length of the line segment segmentLength :: (Arity d, Floating r) => LineSegment d p r -> r sqSegmentLength :: (Arity d, Num r) => LineSegment d p r -> r -- | Squared distance from the point to the Segment s. The same remark as -- for the sqDistanceToSegArg applies here. sqDistanceToSeg :: (Arity d, Fractional r, Ord r) => Point d r -> LineSegment d p r -> r -- | Squared distance from the point to the Segment s, and the point on s -- realizing it. Note that if the segment is *open*, the closest point -- returned may be one of the (open) end points, even though technically -- the end point does not lie on the segment. (The true closest point -- then lies arbitrarily close to the end point). sqDistanceToSegArg :: (Arity d, Fractional r, Ord r) => Point d r -> LineSegment d p r -> (r, Point d r) -- | flips the start and end point of the segment flipSegment :: LineSegment d p r -> LineSegment d p r -- | Linearly interpolate the two endpoints with a value in the range [0,1] -- --
--   >>> interpolate 0.5 $ ClosedLineSegment (ext $ origin) (ext $ Point2 10.0 10.0)
--   Point2 5.0 5.0
--   
--   >>> interpolate 0.1 $ ClosedLineSegment (ext $ origin) (ext $ Point2 10.0 10.0)
--   Point2 1.0 1.0
--   
--   >>> interpolate 0 $ ClosedLineSegment (ext $ origin) (ext $ Point2 10.0 10.0)
--   Point2 0.0 0.0
--   
--   >>> interpolate 1 $ ClosedLineSegment (ext $ origin) (ext $ Point2 10.0 10.0)
--   Point2 10.0 10.0
--   
interpolate :: (Fractional r, Arity d) => r -> LineSegment d p r -> Point d r -- | smart constructor that creates a valid segment, i.e. it validates that -- the endpoints are disjoint. validSegment :: (Eq r, Arity d) => EndPoint (Point d r :+ p) -> EndPoint (Point d r :+ p) -> Maybe (LineSegment d p r) sampleLineSegment :: (Arity d, RandomGen g, Random r) => Rand g (LineSegment d () r) instance (Data.Geometry.Vector.VectorFamily.Arity d, Control.DeepSeq.NFData r, Control.DeepSeq.NFData p) => Control.DeepSeq.NFData (Data.Geometry.LineSegment.Internal.LineSegment d p r) instance (GHC.Classes.Eq r, GHC.Classes.Eq p, Data.Geometry.Vector.VectorFamily.Arity d) => GHC.Classes.Eq (Data.Geometry.LineSegment.Internal.LineSegment d p r) instance Data.Geometry.Vector.VectorFamily.Arity d => GHC.Base.Functor (Data.Geometry.LineSegment.Internal.LineSegment d p) instance Data.Geometry.Interval.HasStart (Data.Geometry.LineSegment.Internal.LineSegment d p r) instance Data.Geometry.Interval.HasEnd (Data.Geometry.LineSegment.Internal.LineSegment d p r) instance (Test.QuickCheck.Arbitrary.Arbitrary r, Test.QuickCheck.Arbitrary.Arbitrary p, GHC.Classes.Eq r, Data.Geometry.Vector.VectorFamily.Arity d) => Test.QuickCheck.Arbitrary.Arbitrary (Data.Geometry.LineSegment.Internal.LineSegment d p r) instance (GHC.Num.Num r, Data.Geometry.Vector.VectorFamily.Arity d) => Data.Geometry.Line.Internal.HasSupportingLine (Data.Geometry.LineSegment.Internal.LineSegment d p r) instance (GHC.Show.Show r, GHC.Show.Show p, Data.Geometry.Vector.VectorFamily.Arity d) => GHC.Show.Show (Data.Geometry.LineSegment.Internal.LineSegment d p r) instance (GHC.Read.Read r, GHC.Read.Read p, Data.Geometry.Vector.VectorFamily.Arity d) => GHC.Read.Read (Data.Geometry.LineSegment.Internal.LineSegment d p r) instance Data.Geometry.Point.Internal.PointFunctor (Data.Geometry.LineSegment.Internal.LineSegment d p) instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Geometry.Box.Internal.IsBoxable (Data.Geometry.LineSegment.Internal.LineSegment d p r) instance (GHC.Real.Fractional r, Data.Geometry.Vector.VectorFamily.Arity d, Data.Geometry.Vector.VectorFamily.Arity (d GHC.TypeNats.+ 1)) => Data.Geometry.Transformation.Internal.IsTransformable (Data.Geometry.LineSegment.Internal.LineSegment d p r) instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Bifunctor.Bifunctor (Data.Geometry.LineSegment.Internal.LineSegment d) instance (GHC.Classes.Ord r, GHC.Num.Num r) => Data.Intersection.HasIntersectionWith (Data.Geometry.Point.Internal.Point 2 r) (Data.Geometry.LineSegment.Internal.LineSegment 2 p r) instance (GHC.Classes.Ord r, GHC.Num.Num r) => Data.Intersection.IsIntersectableWith (Data.Geometry.Point.Internal.Point 2 r) (Data.Geometry.LineSegment.Internal.LineSegment 2 p r) instance (GHC.Classes.Ord r, GHC.Real.Fractional r, Data.Geometry.Vector.VectorFamily.Arity d) => Data.Intersection.HasIntersectionWith (Data.Geometry.Point.Internal.Point d r) (Data.Geometry.LineSegment.Internal.LineSegment d p r) instance (GHC.Classes.Ord r, GHC.Real.Fractional r, Data.Geometry.Vector.VectorFamily.Arity d) => Data.Intersection.IsIntersectableWith (Data.Geometry.Point.Internal.Point d r) (Data.Geometry.LineSegment.Internal.LineSegment d p r) instance (GHC.Classes.Ord r, GHC.Real.Fractional r) => Data.Intersection.HasIntersectionWith (Data.Geometry.LineSegment.Internal.LineSegment 2 p r) (Data.Geometry.LineSegment.Internal.LineSegment 2 p r) instance (GHC.Classes.Ord r, GHC.Real.Fractional r) => Data.Intersection.IsIntersectableWith (Data.Geometry.LineSegment.Internal.LineSegment 2 p r) (Data.Geometry.LineSegment.Internal.LineSegment 2 p r) instance (GHC.Classes.Ord r, GHC.Real.Fractional r) => Data.Intersection.HasIntersectionWith (Data.Geometry.LineSegment.Internal.LineSegment 2 p r) (Data.Geometry.Line.Internal.Line 2 r) instance (GHC.Classes.Ord r, GHC.Real.Fractional r) => Data.Intersection.IsIntersectableWith (Data.Geometry.LineSegment.Internal.LineSegment 2 p r) (Data.Geometry.Line.Internal.Line 2 r) -- | Line segment data type and some basic functions on line segments module Data.Geometry.LineSegment -- | Line segments. LineSegments have a start and end point, both of which -- may contain additional data of type p. We can think of a Line-Segment -- being defined as -- --
--   >>> data LineSegment d p r = LineSegment (EndPoint (Point d r :+ p)) (EndPoint (Point d r :+ p))
--   
-- -- it is assumed that the two endpoints of the line segment are disjoint. -- This is not checked. data LineSegment d p r pattern LineSegment :: EndPoint (Point d r :+ p) -> EndPoint (Point d r :+ p) -> LineSegment d p r -- | Gets the start and end point, but forgetting if they are open or -- closed. pattern LineSegment' :: (Point d r :+ p) -> (Point d r :+ p) -> LineSegment d p r pattern ClosedLineSegment :: (Point d r :+ p) -> (Point d r :+ p) -> LineSegment d p r pattern OpenLineSegment :: (Point d r :+ p) -> (Point d r :+ p) -> LineSegment d p r -- | Traversal to access the endpoints. Note that this traversal allows you -- to change more or less everything, even the dimension and the numeric -- type used, but it preservers if the segment is open or closed. endPoints :: Traversal (LineSegment d p r) (LineSegment d' q s) (Point d r :+ p) (Point d' s :+ q) _SubLine :: (Num r, Arity d) => Iso' (LineSegment d p r) (SubLine d p r r) -- | Shifts the range to the right -- --
--   >>> prettyShow $ shiftRight 10 (ClosedRange 10 20)
--   "[20,30]"
--   
--   >>> prettyShow $ shiftRight 10 (OpenRange 15 25)
--   "(25,35)"
--   
shiftRight :: Num r => r -> Range r -> Range r -- | Shift a range x units to the left -- --
--   >>> prettyShow $ shiftLeft 10 (ClosedRange 10 20)
--   "[0,10]"
--   
--   >>> prettyShow $ shiftLeft 10 (OpenRange 15 25)
--   "(5,15)"
--   
shiftLeft :: Num r => r -> Range r -> Range r -- | Check if the range is valid and nonEmpty, i.e. if the lower endpoint -- is indeed smaller than the right endpoint. Note that we treat empty -- open-ranges as invalid as well. isValidRange :: Ord a => Range a -> Bool -- | Wether or not the first range completely covers the second one covers :: Ord a => Range a -> Range a -> Bool -- | Clip the interval from above. I.e. intersect with (-infty, u}, where } -- is either open, ), or closed, ], clipUpper :: Ord a => EndPoint a -> Range a -> Maybe (Range a) -- | Clip the interval from below. I.e. intersect with the interval -- {l,infty), where { is either open, (, orr closed, [. clipLower :: Ord a => EndPoint a -> Range a -> Maybe (Range a) -- | Clamps a value to a range. I.e. if the value lies outside the range we -- report the closest value "in the range". Note that if an endpoint of -- the range is open we report that value anyway, so we return a value -- that is truely inside the range only if that side of the range is -- closed. -- --
--   >>> clampTo (ClosedRange 0 10) 20
--   10
--   
--   >>> clampTo (ClosedRange 0 10) (-20)
--   0
--   
--   >>> clampTo (ClosedRange 0 10) 5
--   5
--   
--   >>> clampTo (OpenRange 0 10) 20
--   10
--   
--   >>> clampTo (OpenRange 0 10) (-20)
--   0
--   
--   >>> clampTo (OpenRange 0 10) 5
--   5
--   
clampTo :: Ord r => Range r -> r -> r -- | Test if a value lies in a range. -- --
--   >>> 1 `inRange` (OpenRange 0 2)
--   True
--   
--   >>> 1 `inRange` (OpenRange 0 1)
--   False
--   
--   >>> 1 `inRange` (ClosedRange 0 1)
--   True
--   
--   >>> 1 `inRange` (ClosedRange 1 1)
--   True
--   
--   >>> 10 `inRange` (OpenRange 1 10)
--   False
--   
--   >>> 10 `inRange` (ClosedRange 0 1)
--   False
--   
-- -- This one is kind of weird -- --
--   >>> 0 `inRange` Range (Closed 0) (Open 0)
--   False
--   
inRange :: Ord a => a -> Range a -> Bool -- | Helper function to show a range in mathematical notation. -- --
--   >>> prettyShow $ OpenRange 0 2
--   "(0,2)"
--   
--   >>> prettyShow $ ClosedRange 0 2
--   "[0,2]"
--   
--   >>> prettyShow $ Range (Open 0) (Closed 5)
--   "(0,5]"
--   
prettyShow :: Show a => Range a -> String -- | Lens access for the upper part of a range. upper :: Lens' (Range a) (EndPoint a) -- | Lens access for the lower part of a range. lower :: Lens' (Range a) (EndPoint a) -- | True iff EndPoint is closed. isClosed :: EndPoint a -> Bool -- | True iff EndPoint is open. isOpen :: EndPoint a -> Bool -- | Access lens for EndPoint value regardless of whether it is open or -- closed. -- --
--   >>> Open 5 ^. unEndPoint
--   5
--   
--   >>> Closed 10 ^. unEndPoint
--   10
--   
--   >>> Open 4 & unEndPoint .~ 0
--   Open 0
--   
unEndPoint :: Lens (EndPoint a) (EndPoint b) a b -- | Endpoints of a range may either be open or closed. data EndPoint a Open :: !a -> EndPoint a Closed :: !a -> EndPoint a -- | Data type for representing ranges. data Range a Range :: !EndPoint a -> !EndPoint a -> Range a [_lower] :: Range a -> !EndPoint a [_upper] :: Range a -> !EndPoint a pattern OpenRange :: a -> a -> Range a pattern ClosedRange :: a -> a -> Range a -- | A range from l to u, ignoring/forgetting the type of the endpoints pattern Range' :: a -> a -> Range a class HasEnd t where { type family EndCore t; type family EndExtra t; } end :: HasEnd t => Lens' t (EndCore t :+ EndExtra t) class HasStart t where { type family StartCore t; type family StartExtra t; } start :: HasStart t => Lens' t (StartCore t :+ StartExtra t) -- | An Interval is essentially a Range but with possible payload -- -- We can think of an interval being defined as: -- --
--   >>> data Interval a r = Interval (EndPoint (r :+ a)) (EndPoint (r :+ a))
--   
data Interval a r pattern ClosedInterval :: (r :+ a) -> (r :+ a) -> Interval a r pattern Interval :: EndPoint (r :+ a) -> EndPoint (r :+ a) -> Interval a r pattern OpenInterval :: (r :+ a) -> (r :+ a) -> Interval a r -- | Cast an interval to a range. toRange :: Interval a r -> Range (r :+ a) -- | Intervals and ranges are isomorphic. _Range :: Iso' (Interval a r) (Range (r :+ a)) -- | Constrct an interval from a Range fromRange :: Range (r :+ a) -> Interval a r -- | Test if a value lies in an interval. Note that the difference between -- inInterval and inRange is that the extra value is *not* used in the -- comparison with inInterval, whereas it is in inRange. inInterval :: Ord r => r -> Interval a r -> Bool -- | Shifts the interval to the left by delta shiftLeft' :: Num r => r -> Interval a r -> Interval a r -- | Makes sure the start and endpoint are oriented such that the starting -- value is smaller than the ending value. asProperInterval :: Ord r => Interval p r -> Interval p r -- | Flips the start and endpoint of the interval. flipInterval :: Interval a r -> Interval a r -- | Directly convert a line into a line segment. toLineSegment :: (Monoid p, Num r, Arity d) => Line d r -> LineSegment d p r -- | The left and right end point (or left below right if they have equal -- x-coords) orderedEndPoints :: Ord r => LineSegment 2 p r -> (Point 2 r :+ p, Point 2 r :+ p) -- | Length of the line segment segmentLength :: (Arity d, Floating r) => LineSegment d p r -> r sqSegmentLength :: (Arity d, Num r) => LineSegment d p r -> r -- | Squared distance from the point to the Segment s. The same remark as -- for the sqDistanceToSegArg applies here. sqDistanceToSeg :: (Arity d, Fractional r, Ord r) => Point d r -> LineSegment d p r -> r -- | Squared distance from the point to the Segment s, and the point on s -- realizing it. Note that if the segment is *open*, the closest point -- returned may be one of the (open) end points, even though technically -- the end point does not lie on the segment. (The true closest point -- then lies arbitrarily close to the end point). sqDistanceToSegArg :: (Arity d, Fractional r, Ord r) => Point d r -> LineSegment d p r -> (r, Point d r) -- | flips the start and end point of the segment flipSegment :: LineSegment d p r -> LineSegment d p r -- | Linearly interpolate the two endpoints with a value in the range [0,1] -- --
--   >>> interpolate 0.5 $ ClosedLineSegment (ext $ origin) (ext $ Point2 10.0 10.0)
--   Point2 5.0 5.0
--   
--   >>> interpolate 0.1 $ ClosedLineSegment (ext $ origin) (ext $ Point2 10.0 10.0)
--   Point2 1.0 1.0
--   
--   >>> interpolate 0 $ ClosedLineSegment (ext $ origin) (ext $ Point2 10.0 10.0)
--   Point2 0.0 0.0
--   
--   >>> interpolate 1 $ ClosedLineSegment (ext $ origin) (ext $ Point2 10.0 10.0)
--   Point2 10.0 10.0
--   
interpolate :: (Fractional r, Arity d) => r -> LineSegment d p r -> Point d r sampleLineSegment :: (Arity d, RandomGen g, Random r) => Rand g (LineSegment d () r) -- | Line segment intersections in <math> by checking all pairs. module Algorithms.Geometry.LineSegmentIntersection.Naive -- | Compute all intersections (naively) -- -- <math> intersections :: forall r p. (Ord r, Fractional r) => [LineSegment 2 p r] -> Intersections p r -- | The <math> time line segment intersection algorithm by Bentley -- and Ottmann. module Algorithms.Geometry.LineSegmentIntersection.BentleyOttmann -- | Compute all intersections -- -- <math>, where <math> is the number of intersections. intersections :: (Ord r, Fractional r) => [LineSegment 2 p r] -> Intersections p r -- | Computes all intersection points p s.t. p lies in the interior of at -- least one of the segments. -- -- <math>, where <math> is the number of intersections. interiorIntersections :: (Ord r, Fractional r) => [LineSegment 2 p r] -> Intersections p r -- | Compare based on the x-coordinate of the intersection with the -- horizontal line through y ordAt :: (Fractional r, Ord r) => r -> Compare (LineSegment 2 p r) -- | Given a y coord and a line segment that intersects the horizontal line -- through y, compute the x-coordinate of this intersection point. -- -- note that we will pretend that the line segment is closed, even if it -- is not xCoordAt :: (Fractional r, Ord r) => r -> LineSegment 2 p r -> r instance GHC.Show.Show s => GHC.Show.Show (Algorithms.Geometry.LineSegmentIntersection.BentleyOttmann.EventType s) instance GHC.Classes.Eq r => GHC.Classes.Eq (Algorithms.Geometry.LineSegmentIntersection.BentleyOttmann.Event p r) instance (GHC.Show.Show r, GHC.Show.Show p) => GHC.Show.Show (Algorithms.Geometry.LineSegmentIntersection.BentleyOttmann.Event p r) instance GHC.Classes.Ord r => GHC.Classes.Ord (Algorithms.Geometry.LineSegmentIntersection.BentleyOttmann.Event p r) instance GHC.Classes.Eq (Algorithms.Geometry.LineSegmentIntersection.BentleyOttmann.EventType s) instance GHC.Classes.Ord (Algorithms.Geometry.LineSegmentIntersection.BentleyOttmann.EventType s) module Data.Geometry.Box.Corners -- | A data type rperesenting the corners of a box. the order of the -- Corners is 'northWest, northEast, southEast, southWest', i.e. in -- clockwise order starting from the topleft. data Corners a Corners :: !a -> !a -> !a -> !a -> Corners a northWest :: forall a_a1CYH. Lens' (Corners a_a1CYH) a_a1CYH northEast :: forall a_a1CYH. Lens' (Corners a_a1CYH) a_a1CYH southEast :: forall a_a1CYH. Lens' (Corners a_a1CYH) a_a1CYH southWest :: forall a_a1CYH. Lens' (Corners a_a1CYH) a_a1CYH -- | Get the corners of a rectangle, the order is: (TopLeft, TopRight, -- BottomRight, BottomLeft). The extra values in the Top points are taken -- from the Top point, the extra values in the Bottom points are taken -- from the Bottom point corners :: Num r => Rectangle p r -> Corners (Point 2 r :+ p) -- | Gets the corners in a particular direction cornersInDirection :: CardinalDirection -> Corners p -> Two p instance Control.Lens.At.Ixed (Data.Geometry.Box.Corners.Corners a) instance Data.Semigroup.Foldable.Class.Foldable1 Data.Geometry.Box.Corners.Corners instance Data.Semigroup.Traversable.Class.Traversable1 Data.Geometry.Box.Corners.Corners instance GHC.Base.Applicative Data.Geometry.Box.Corners.Corners instance GHC.Base.Semigroup a => GHC.Base.Semigroup (Data.Geometry.Box.Corners.Corners a) instance GHC.Base.Monoid a => GHC.Base.Monoid (Data.Geometry.Box.Corners.Corners a) instance Data.Traversable.Traversable Data.Geometry.Box.Corners.Corners instance Data.Foldable.Foldable Data.Geometry.Box.Corners.Corners instance GHC.Base.Functor Data.Geometry.Box.Corners.Corners instance GHC.Generics.Generic (Data.Geometry.Box.Corners.Corners a) instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.Geometry.Box.Corners.Corners a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Geometry.Box.Corners.Corners a) instance GHC.Show.Show a => GHC.Show.Show (Data.Geometry.Box.Corners.Corners a) module Data.Geometry.QuadTree.Quadrants pattern Quadrants :: a -> a -> a -> a -> Corners a type Quadrants = Corners module Data.Geometry.Box.Sides -- | The four sides of a rectangle data Sides a Sides :: !a -> !a -> !a -> !a -> Sides a north :: forall a_a1FoW. Lens' (Sides a_a1FoW) a_a1FoW east :: forall a_a1FoW. Lens' (Sides a_a1FoW) a_a1FoW south :: forall a_a1FoW. Lens' (Sides a_a1FoW) a_a1FoW west :: forall a_a1FoW. Lens' (Sides a_a1FoW) a_a1FoW topSide :: Num r => Rectangle p r -> LineSegment 2 p r -- | Oriented from *left to right* bottomSide :: Num r => Rectangle p r -> LineSegment 2 p r leftSide :: Num r => Rectangle p r -> LineSegment 2 p r -- | The right side, oriented from *bottom* to top rightSide :: Num r => Rectangle p r -> LineSegment 2 p r -- | The sides of the rectangle, in order (Top, Right, Bottom, Left). The -- sides themselves are also oriented in clockwise order. If, you want -- them in the same order as the functions topSide, -- bottomSide, leftSide, and rightSide, use -- sides` instead. sides :: Num r => Rectangle p r -> Sides (LineSegment 2 p r) -- | The sides of the rectangle. The order of the segments is (Top, Right, -- Bottom, Left). Note that the segments themselves, are oriented as -- described by the functions topSide, bottomSide, leftSide, rightSide -- (basically: from left to right, and from bottom to top). If you want -- the segments oriented along the boundary of the rectangle, use the -- sides function instead. sides' :: Num r => Rectangle p r -> Sides (LineSegment 2 p r) -- | Constructs a Sides value that indicates the appropriate direction. sideDirections :: Sides CardinalDirection instance GHC.Base.Applicative Data.Geometry.Box.Sides.Sides instance Data.Semigroup.Foldable.Class.Foldable1 Data.Geometry.Box.Sides.Sides instance Data.Semigroup.Traversable.Class.Traversable1 Data.Geometry.Box.Sides.Sides instance GHC.Base.Semigroup a => GHC.Base.Semigroup (Data.Geometry.Box.Sides.Sides a) instance GHC.Base.Monoid a => GHC.Base.Monoid (Data.Geometry.Box.Sides.Sides a) instance Control.Lens.At.Ixed (Data.Geometry.Box.Sides.Sides a) instance Data.Traversable.Traversable Data.Geometry.Box.Sides.Sides instance GHC.Base.Functor Data.Geometry.Box.Sides.Sides instance Data.Foldable.Foldable Data.Geometry.Box.Sides.Sides instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.Geometry.Box.Sides.Sides a) instance GHC.Generics.Generic (Data.Geometry.Box.Sides.Sides a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Geometry.Box.Sides.Sides a) instance GHC.Read.Read a => GHC.Read.Read (Data.Geometry.Box.Sides.Sides a) instance GHC.Show.Show a => GHC.Show.Show (Data.Geometry.Box.Sides.Sides a) -- | Orthogonal <math>-dimensiontal boxes (e.g. rectangles) module Data.Geometry.Box instance (Control.DeepSeq.NFData p, Control.DeepSeq.NFData r, Data.Geometry.Vector.VectorFamily.Arity d) => Control.DeepSeq.NFData (Data.Geometry.Box.Internal.Box d p r) module Data.Geometry.Transformation -- | A type representing a Transformation for d dimensional objects newtype Transformation d r Transformation :: Matrix (d + 1) (d + 1) r -> Transformation d r -- | Transformations and Matrices are isomorphic. transformationMatrix :: Iso (Transformation d r) (Transformation d s) (Matrix (d + 1) (d + 1) r) (Matrix (d + 1) (d + 1) s) -- | Compose transformations (right to left) (|.|) :: (Num r, Arity (d + 1)) => Transformation d r -> Transformation d r -> Transformation d r -- | Identity transformation; i.e. the transformation which does not change -- anything. identity :: (Num r, Arity (d + 1)) => Transformation d r -- | Compute the inverse transformation -- --
--   >>> inverseOf $ translation (Vector2 (10.0) (5.0))
--   Transformation {_transformationMatrix = Matrix (Vector3 (Vector3 1.0 0.0 (-10.0)) (Vector3 0.0 1.0 (-5.0)) (Vector3 0.0 0.0 1.0))}
--   
inverseOf :: (Fractional r, Invertible (d + 1) r) => Transformation d r -> Transformation d r -- | A class representing types that can be transformed using a -- transformation class IsTransformable g transformBy :: IsTransformable g => Transformation (Dimension g) (NumType g) -> g -> g -- | Apply a transformation to a collection of objects. -- --
--   >>> transformAllBy (uniformScaling 2) [Point1 1, Point1 2, Point1 3]
--   [Point1 2.0,Point1 4.0,Point1 6.0]
--   
transformAllBy :: (Functor c, IsTransformable g) => Transformation (Dimension g) (NumType g) -> c g -> c g -- | Apply transformation to a PointFunctor, ie something that contains -- points. Polygons, triangles, line segments, etc, are all -- PointFunctors. -- --
--   >>> transformPointFunctor (uniformScaling 2) $ OpenLineSegment (Point1 1 :+ ()) (Point1 2 :+ ())
--   OpenLineSegment (Point1 2.0 :+ ()) (Point1 4.0 :+ ())
--   
transformPointFunctor :: (PointFunctor g, Fractional r, d ~ Dimension (g r), Arity d, Arity (d + 1)) => Transformation d r -> g r -> g r -- | Create translation transformation from a vector. -- --
--   >>> transformBy (translation $ Vector2 1 2) $ Point2 2 3
--   Point2 3.0 5.0
--   
translation :: (Num r, Arity d, Arity (d + 1)) => Vector d r -> Transformation d r -- | Create scaling transformation from a vector. -- --
--   >>> transformBy (scaling $ Vector2 2 (-1)) $ Point2 2 3
--   Point2 4.0 (-3.0)
--   
scaling :: (Num r, Arity d, Arity (d + 1)) => Vector d r -> Transformation d r -- | Create scaling transformation from a scalar that is applied to all -- dimensions. -- --
--   >>> transformBy (uniformScaling 5) $ Point2 2 3
--   Point2 10.0 15.0
--   
--   >>> uniformScaling 5 == scaling (Vector2 5 5)
--   True
--   
--   >>> uniformScaling 5 == scaling (Vector3 5 5 5)
--   True
--   
uniformScaling :: (Num r, Arity d, Arity (d + 1)) => r -> Transformation d r -- | Translate a given point. -- --
--   >>> translateBy (Vector2 1 2) $ Point2 2 3
--   Point2 3.0 5.0
--   
translateBy :: (IsTransformable g, Num (NumType g), Arity (Dimension g), Arity (Dimension g + 1)) => Vector (Dimension g) (NumType g) -> g -> g -- | Scale a given point. -- --
--   >>> scaleBy (Vector2 2 (-1)) $ Point2 2 3
--   Point2 4.0 (-3.0)
--   
scaleBy :: (IsTransformable g, Num (NumType g), Arity (Dimension g), Arity (Dimension g + 1)) => Vector (Dimension g) (NumType g) -> g -> g -- | Scale a given point uniformly in all dimensions. -- --
--   >>> scaleUniformlyBy 5 $ Point2 2 3
--   Point2 10.0 15.0
--   
scaleUniformlyBy :: (IsTransformable g, Num (NumType g), Arity (Dimension g), Arity (Dimension g + 1)) => NumType g -> g -> g -- | Given three new unit-length basis vectors (u,v,w) that map to (x,y,z), -- construct the appropriate rotation that does this. rotateTo :: Num r => Vector 3 (Vector 3 r) -> Transformation 3 r -- | Skew transformation that keeps the y-coordinates fixed and shifts the -- x coordinates. skewX :: Num r => r -> Transformation 2 r -- | Create a matrix that corresponds to a rotation by a radians -- counter-clockwise around the origin. rotation :: Floating r => r -> Transformation 2 r -- | Create a matrix that corresponds to a reflection in a line through the -- origin which makes an angle of a radians with the positive -- x-asis, in counter-clockwise orientation. reflection :: Floating r => r -> Transformation 2 r -- | Vertical reflection reflectionV :: Num r => Transformation 2 r -- | Horizontal reflection reflectionH :: Num r => Transformation 2 r -- | Given a rectangle r and a geometry g with its boundingbox, transform -- the g to fit r. fitToBox :: forall g r q. (IsTransformable g, IsBoxable g, NumType g ~ r, Dimension g ~ 2, Ord r, Fractional r) => Rectangle q r -> g -> g -- | Given a rectangle r and a geometry g with its boundingbox, compute a -- transformation can fit g to r. fitToBoxTransform :: forall g r q. (IsTransformable g, IsBoxable g, NumType g ~ r, Dimension g ~ 2, Ord r, Fractional r) => Rectangle q r -> g -> Transformation 2 r module Data.Geometry.Boundary -- | The boundary of a geometric object. newtype Boundary g Boundary :: g -> Boundary g -- | Iso for converting between things with a boundary and without its -- boundary _Boundary :: Iso g h (Boundary g) (Boundary h) -- | Result of a query that asks if something is Inside a g, *on* the -- boundary of the g, or outside. data PointLocationResult Inside :: PointLocationResult OnBoundary :: PointLocationResult Outside :: PointLocationResult instance Data.Traversable.Traversable Data.Geometry.Boundary.Boundary instance Data.Foldable.Foldable Data.Geometry.Boundary.Boundary instance GHC.Base.Functor Data.Geometry.Boundary.Boundary instance Data.Geometry.Transformation.Internal.IsTransformable g => Data.Geometry.Transformation.Internal.IsTransformable (Data.Geometry.Boundary.Boundary g) instance GHC.Read.Read g => GHC.Read.Read (Data.Geometry.Boundary.Boundary g) instance GHC.Classes.Ord g => GHC.Classes.Ord (Data.Geometry.Boundary.Boundary g) instance GHC.Classes.Eq g => GHC.Classes.Eq (Data.Geometry.Boundary.Boundary g) instance GHC.Show.Show g => GHC.Show.Show (Data.Geometry.Boundary.Boundary g) instance GHC.Classes.Eq Data.Geometry.Boundary.PointLocationResult instance GHC.Read.Read Data.Geometry.Boundary.PointLocationResult instance GHC.Show.Show Data.Geometry.Boundary.PointLocationResult module Data.Geometry.QuadTree.Cell -- | side lengths will be 2^i for some integer i type WidthIndex = Int -- | A Cell corresponding to a node in the QuadTree data Cell r Cell :: {-# UNPACK #-} !WidthIndex -> !Point 2 r -> Cell r [_cellWidthIndex] :: Cell r -> {-# UNPACK #-} !WidthIndex [_lowerLeft] :: Cell r -> !Point 2 r lowerLeft :: forall r_a1JQa r_a1K19. Lens (Cell r_a1JQa) (Cell r_a1K19) (Point 2 r_a1JQa) (Point 2 r_a1K19) cellWidthIndex :: forall r_a1JQa. Lens' (Cell r_a1JQa) WidthIndex -- | Computes a cell that contains the given rectangle fitsRectangle :: (RealFrac r, Ord r) => Rectangle p r -> Cell r pow :: Fractional r => WidthIndex -> r cellWidth :: Fractional r => Cell r -> r toBox :: Fractional r => Cell r -> Box 2 () r inCell :: (Fractional r, Ord r) => (Point 2 r :+ p) -> Cell r -> Bool cellCorners :: Fractional r => Cell r -> Quadrants (Point 2 r) -- | Sides are open cellSides :: Fractional r => Cell r -> Sides (LineSegment 2 () r) splitCell :: (Num r, Fractional r) => Cell r -> Quadrants (Cell r) midPoint :: Fractional r => Cell r -> Point 2 r -- | Partitions the points into quadrants. See quadrantOf for the -- precise rules. partitionPoints :: (Fractional r, Ord r) => Cell r -> [Point 2 r :+ p] -> Quadrants [Point 2 r :+ p] -- | Computes the quadrant of the cell corresponding to the current point. -- Note that we decide the quadrant solely based on the midpoint. If the -- query point lies outside the cell, it is still assigned a quadrant. -- -- -- --
--   >>> quadrantOf (Point2 9 9) (Cell 4 origin)
--   NorthEast
--   
--   >>> quadrantOf (Point2 8 9) (Cell 4 origin)
--   NorthEast
--   
--   >>> quadrantOf (Point2 8 8) (Cell 4 origin)
--   NorthEast
--   
--   >>> quadrantOf (Point2 8 7) (Cell 4 origin)
--   SouthEast
--   
--   >>> quadrantOf (Point2 4 7) (Cell 4 origin)
--   SouthWest
--   
--   >>> quadrantOf (Point2 4 10) (Cell 4 origin)
--   NorthWest
--   
--   >>> quadrantOf (Point2 4 40) (Cell 4 origin)
--   NorthEast
--   
--   >>> quadrantOf (Point2 4 40) (Cell 4 origin)
--   NorthWest
--   
quadrantOf :: forall r. (Fractional r, Ord r) => Point 2 r -> Cell r -> InterCardinalDirection -- | Given two cells c and me, compute on which side of me the -- cell c is. -- -- pre: c and me are non-overlapping relationTo :: (Fractional r, Ord r) => (p :+ Cell r) -> Cell r -> Sides (Maybe (p :+ Cell r)) instance (GHC.Classes.Ord r, GHC.Real.Fractional r) => Data.Intersection.HasIntersectionWith (Data.Geometry.Point.Internal.Point 2 r) (Data.Geometry.QuadTree.Cell.Cell r) instance (GHC.Classes.Ord r, GHC.Real.Fractional r) => Data.Intersection.IsIntersectableWith (Data.Geometry.Point.Internal.Point 2 r) (Data.Geometry.QuadTree.Cell.Cell r) instance Data.Traversable.Traversable Data.Geometry.QuadTree.Cell.Cell instance Data.Foldable.Foldable Data.Geometry.QuadTree.Cell.Cell instance GHC.Base.Functor Data.Geometry.QuadTree.Cell.Cell instance GHC.Classes.Eq r => GHC.Classes.Eq (Data.Geometry.QuadTree.Cell.Cell r) instance GHC.Show.Show r => GHC.Show.Show (Data.Geometry.QuadTree.Cell.Cell r) module Data.Geometry.QuadTree.Split -- | Data Type to Decide if we should continue splitting the current cell data Split i v p No :: !p -> Split i v p Yes :: !v -> Quadrants i -> Split i v p _Yes :: forall i_a1Nob v_a1Noc p_a1NhQ i_a1NhO v_a1NhP. Prism (Split i_a1Nob v_a1Noc p_a1NhQ) (Split i_a1NhO v_a1NhP p_a1NhQ) (v_a1Noc, Quadrants i_a1Nob) (v_a1NhP, Quadrants i_a1NhO) _No :: forall i_a1NhO v_a1NhP p_a1No5 p_a1NhQ. Prism (Split i_a1NhO v_a1NhP p_a1No5) (Split i_a1NhO v_a1NhP p_a1NhQ) p_a1No5 p_a1NhQ -- | A splitter is a function that determines weather or not we should the -- given cell corresponding to the given input (i). type Splitter r i v p = Cell r -> i -> Split i v p -- | Transformer that limits the depth of a splitter type Limiter r i v p = Splitter r i v p -> Splitter r i v (Either i p) -- | Split only when the Cell-width is at least wMin limitWidthTo :: WidthIndex -> Limiter r i v p instance (GHC.Classes.Ord p, GHC.Classes.Ord v, GHC.Classes.Ord i) => GHC.Classes.Ord (Data.Geometry.QuadTree.Split.Split i v p) instance (GHC.Classes.Eq p, GHC.Classes.Eq v, GHC.Classes.Eq i) => GHC.Classes.Eq (Data.Geometry.QuadTree.Split.Split i v p) instance (GHC.Show.Show p, GHC.Show.Show v, GHC.Show.Show i) => GHC.Show.Show (Data.Geometry.QuadTree.Split.Split i v p) module Data.Geometry.QuadTree.Tree -- | Our cells use Rational numbers as their numeric type type CellR = Cell -- (RealNumber 10) -- -- The Actual Tree type representing a quadTree data Tree v p Leaf :: !p -> Tree v p Node :: !v -> Quadrants (Tree v p) -> Tree v p _Node :: forall v_a1Ol3 p_a1OhF v_a1OhE. Prism (Tree v_a1Ol3 p_a1OhF) (Tree v_a1OhE p_a1OhF) (v_a1Ol3, Quadrants (Tree v_a1Ol3 p_a1OhF)) (v_a1OhE, Quadrants (Tree v_a1OhE p_a1OhF)) _Leaf :: forall v_a1OhE p_a1OhF. Prism' (Tree v_a1OhE p_a1OhF) p_a1OhF -- | Fold on the Tree type. foldTree :: (p -> b) -> (v -> Quadrants b -> b) -> Tree v p -> b -- | Produce a list of all leaves of a quad tree leaves :: Tree v p -> NonEmpty p -- | Converts into a RoseTree toRoseTree :: Tree v p -> Tree (TreeNode v p) -- | Computes the height of the quadtree height :: Tree v p -> Integer -- | Builds a QuadTree build :: Fractional r => Splitter r pts v p -> Cell r -> pts -> Tree v p -- | Annotate the tree with its corresponing cells withCells :: Fractional r => Cell r -> Tree v p -> Tree (v :+ Cell r) (p :+ Cell r) -- | Build a QuadtTree from a set of points. -- -- pre: the points lie inside the initial given cell. -- -- running time: <math>, where <math> is the number of points -- and <math> is the height of the resulting quadTree. fromPoints :: (Fractional r, Ord r) => Cell r -> [Point 2 r :+ p] -> Tree () (Maybe (Point 2 r :+ p)) -- | The function that can be used to build a quadTree fromPoints fromPointsF :: (Fractional r, Ord r) => Splitter r [Point 2 r :+ p] () (Maybe (Point 2 r :+ p)) instance Data.Bifunctor.Bifunctor Data.Geometry.QuadTree.Tree.Tree instance Data.Bifoldable.Bifoldable Data.Geometry.QuadTree.Tree.Tree instance Data.Bitraversable.Bitraversable Data.Geometry.QuadTree.Tree.Tree instance Data.Semigroup.Foldable.Class.Bifoldable1 Data.Geometry.QuadTree.Tree.Tree instance Data.Semigroup.Traversable.Class.Bitraversable1 Data.Geometry.QuadTree.Tree.Tree instance (GHC.Classes.Eq p, GHC.Classes.Eq v) => GHC.Classes.Eq (Data.Geometry.QuadTree.Tree.Tree v p) instance (GHC.Show.Show p, GHC.Show.Show v) => GHC.Show.Show (Data.Geometry.QuadTree.Tree.Tree v p) module Data.Geometry.QuadTree -- | QuadTree on the starting cell data QuadTree v p r QuadTree :: !Cell r -> !Tree v p -> QuadTree v p r [_startingCell] :: QuadTree v p r -> !Cell r [_tree] :: QuadTree v p r -> !Tree v p tree :: forall v_a1Pz6 p_a1Pz7 r_a1Pz8 v_a1PLe p_a1PLf. Lens (QuadTree v_a1Pz6 p_a1Pz7 r_a1Pz8) (QuadTree v_a1PLe p_a1PLf r_a1Pz8) (Tree v_a1Pz6 p_a1Pz7) (Tree v_a1PLe p_a1PLf) startingCell :: forall v_a1Pz6 p_a1Pz7 r_a1Pz8 r_a1PLd. Lens (QuadTree v_a1Pz6 p_a1Pz7 r_a1Pz8) (QuadTree v_a1Pz6 p_a1Pz7 r_a1PLd) (Cell r_a1Pz8) (Cell r_a1PLd) withCells :: (Fractional r, Ord r) => QuadTree v p r -> QuadTree (v :+ Cell r) (p :+ Cell r) r withCellsTree :: (Fractional r, Ord r) => QuadTree v p r -> Tree (v :+ Cell r) (p :+ Cell r) leaves :: QuadTree v p r -> NonEmpty p perLevel :: QuadTree v p r -> NonEmpty (NonEmpty (TreeNode v p)) -- | Given a starting cell, a Tree builder, and some input required by the -- builder, constructs a quadTree. buildOn :: Cell r -> (Cell r -> i -> Tree v p) -> i -> QuadTree v p r -- | The Equivalent of Tree.build for constructing a QuadTree build :: (Fractional r, Ord r) => (Cell r -> i -> Split i v p) -> Cell r -> i -> QuadTree v p r -- | Build a QuadtTree from a set of points. -- -- pre: the points lie inside the initial given cell. -- -- running time: <math>, where <math> is the number of points -- and <math> is the height of the resulting quadTree. fromPointsBox :: (Fractional r, Ord r) => Cell r -> [Point 2 r :+ p] -> QuadTree () (Maybe (Point 2 r :+ p)) r fromPoints :: (RealFrac r, Ord r) => NonEmpty (Point 2 r :+ p) -> QuadTree () (Maybe (Point 2 r :+ p)) r -- | Locates the cell containing the given point, if it exists. -- -- running time: <math>, where <math> is the height of the -- quadTree findLeaf :: (Fractional r, Ord r) => Point 2 r -> QuadTree v p r -> Maybe (p :+ Cell r) fromZeros :: (Fractional r, Ord r, Num a, Eq a, v ~ Quadrants Sign) => Cell r -> (Point 2 r -> a) -> QuadTree v (Either v Sign) r fromZerosWith :: (Fractional r, Ord r, Eq a, Num a) => Limiter r (Corners Sign) (Corners Sign) Sign -> Cell r -> (Point 2 r -> a) -> QuadTree (Quadrants Sign) (Signs Sign) r type Signs sign = Either (Corners sign) sign fromZerosWith' :: (Eq sign, Fractional r, Ord r) => Limiter r (Corners sign) (Corners sign) sign -> Cell r -> (Point 2 r -> sign) -> QuadTree (Quadrants sign) (Signs sign) r data Sign Negative :: Sign Zero :: Sign Positive :: Sign -- | Interpret an ordering result as a Sign fromOrdering :: Ordering -> Sign fromSignum :: (Num a, Eq a) => (b -> a) -> b -> Sign -- | Splitter that determines if we should split a cell based on the sign -- of the corners. shouldSplitZeros :: forall r sign. (Fractional r, Eq sign) => (Point 2 r -> sign) -> Splitter r (Quadrants sign) (Quadrants sign) sign isZeroCell :: Eq sign => sign -> Either v sign -> Bool -- | Constructs an empty/complete tree from the starting width completeTree :: (Fractional r, Ord r) => Cell r -> QuadTree () () r instance GHC.Classes.Ord Data.Geometry.QuadTree.Sign instance GHC.Classes.Eq Data.Geometry.QuadTree.Sign instance GHC.Show.Show Data.Geometry.QuadTree.Sign instance Data.Traversable.Traversable (Data.Geometry.QuadTree.QuadTree v p) instance Data.Foldable.Foldable (Data.Geometry.QuadTree.QuadTree v p) instance GHC.Base.Functor (Data.Geometry.QuadTree.QuadTree v p) instance GHC.Generics.Generic (Data.Geometry.QuadTree.QuadTree v p r) instance (GHC.Classes.Eq r, GHC.Classes.Eq p, GHC.Classes.Eq v) => GHC.Classes.Eq (Data.Geometry.QuadTree.QuadTree v p r) instance (GHC.Show.Show r, GHC.Show.Show p, GHC.Show.Show v) => GHC.Show.Show (Data.Geometry.QuadTree.QuadTree v p r) module Data.Geometry.PolyLine -- | A Poly line in R^d has at least 2 vertices newtype PolyLine d p r PolyLine :: LSeq 2 (Point d r :+ p) -> PolyLine d p r [_points] :: PolyLine d p r -> LSeq 2 (Point d r :+ p) -- | PolyLines are isomorphic to a sequence of points with at least 2 -- members. points :: Iso (PolyLine d1 p1 r1) (PolyLine d2 p2 r2) (LSeq 2 (Point d1 r1 :+ p1)) (LSeq 2 (Point d2 r2 :+ p2)) -- | Builds a Polyline from a list of points, if there are sufficiently -- many points fromPoints :: [Point d r :+ p] -> Maybe (PolyLine d p r) -- | pre: The input list contains at least two points fromPointsUnsafe :: [Point d r :+ p] -> PolyLine d p r -- | pre: The input list contains at least two points. All extra vields are -- initialized with mempty. fromPointsUnsafe' :: Monoid p => [Point d r] -> PolyLine d p r -- | We consider the line-segment as closed. fromLineSegment :: LineSegment d p r -> PolyLine d p r -- | Convert to a closed line segment by taking the first two points. asLineSegment :: PolyLine d p r -> LineSegment d p r -- | Stricter version of asLineSegment that fails if the Polyline contains -- more than two points. asLineSegment' :: PolyLine d p r -> Maybe (LineSegment d p r) -- | Computes the edges, as linesegments, of an LSeq edgeSegments :: Arity d => PolyLine d p r -> LSeq 1 (LineSegment d p r) -- | Linearly interpolate the polyline with a value in the range -- <math>, where <math> is the number of vertices of the -- polyline. -- -- running time: <math> -- --
--   >>> interpolatePoly 0.5 myPolyLine
--   Point2 5.0 5.0
--   
--   >>> interpolatePoly 1.5 myPolyLine
--   Point2 10.0 15.0
--   
interpolatePoly :: (RealFrac r, Arity d) => r -> PolyLine d p r -> Point d r instance GHC.Generics.Generic (Data.Geometry.PolyLine.PolyLine d p r) instance (GHC.Show.Show r, GHC.Show.Show p, Data.Geometry.Vector.VectorFamily.Arity d) => GHC.Show.Show (Data.Geometry.PolyLine.PolyLine d p r) instance (GHC.Classes.Eq r, GHC.Classes.Eq p, Data.Geometry.Vector.VectorFamily.Arity d) => GHC.Classes.Eq (Data.Geometry.PolyLine.PolyLine d p r) instance (GHC.Classes.Ord r, GHC.Classes.Ord p, Data.Geometry.Vector.VectorFamily.Arity d) => GHC.Classes.Ord (Data.Geometry.PolyLine.PolyLine d p r) instance Data.Geometry.Vector.VectorFamily.Arity d => GHC.Base.Functor (Data.Geometry.PolyLine.PolyLine d p) instance GHC.Base.Semigroup (Data.Geometry.PolyLine.PolyLine d p r) instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Geometry.Box.Internal.IsBoxable (Data.Geometry.PolyLine.PolyLine d p r) instance (GHC.Real.Fractional r, Data.Geometry.Vector.VectorFamily.Arity d, Data.Geometry.Vector.VectorFamily.Arity (d GHC.TypeNats.+ 1)) => Data.Geometry.Transformation.Internal.IsTransformable (Data.Geometry.PolyLine.PolyLine d p r) instance Data.Geometry.Point.Internal.PointFunctor (Data.Geometry.PolyLine.PolyLine d p) instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Bifunctor.Bifunctor (Data.Geometry.PolyLine.PolyLine d) instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Bifoldable.Bifoldable (Data.Geometry.PolyLine.PolyLine d) instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Bitraversable.Bitraversable (Data.Geometry.PolyLine.PolyLine d) instance (Data.Aeson.Types.ToJSON.ToJSON p, Data.Aeson.Types.ToJSON.ToJSON r, Data.Geometry.Vector.VectorFamily.Arity d) => Data.Aeson.Types.ToJSON.ToJSON (Data.Geometry.PolyLine.PolyLine d p r) instance (Data.Aeson.Types.FromJSON.FromJSON p, Data.Aeson.Types.FromJSON.FromJSON r, Data.Geometry.Vector.VectorFamily.Arity d, GHC.TypeNats.KnownNat d) => Data.Aeson.Types.FromJSON.FromJSON (Data.Geometry.PolyLine.PolyLine d p r) instance Data.Geometry.Interval.HasStart (Data.Geometry.PolyLine.PolyLine d p r) instance Data.Geometry.Interval.HasEnd (Data.Geometry.PolyLine.PolyLine d p r) -- | <math>-dimensional lines. module Data.Geometry.Line instance (GHC.Real.Fractional r, Data.Geometry.Vector.VectorFamily.Arity d, Data.Geometry.Vector.VectorFamily.Arity (d GHC.TypeNats.+ 1)) => Data.Geometry.Transformation.Internal.IsTransformable (Data.Geometry.Line.Internal.Line d r) instance (GHC.Classes.Eq r, GHC.Real.Fractional r, Data.Geometry.Vector.VectorFamily.Arity d) => Data.Intersection.HasIntersectionWith (Data.Geometry.Point.Internal.Point d r) (Data.Geometry.Line.Internal.Line d r) instance (GHC.Classes.Ord r, GHC.Num.Num r) => Data.Intersection.HasIntersectionWith (Data.Geometry.Point.Internal.Point 2 r) (Data.Geometry.Line.Internal.Line 2 r) instance (GHC.Classes.Eq r, GHC.Real.Fractional r, Data.Geometry.Vector.VectorFamily.Arity d) => Data.Intersection.IsIntersectableWith (Data.Geometry.Point.Internal.Point d r) (Data.Geometry.Line.Internal.Line d r) instance (GHC.Classes.Ord r, GHC.Num.Num r) => Data.Intersection.IsIntersectableWith (Data.Geometry.Point.Internal.Point 2 r) (Data.Geometry.Line.Internal.Line 2 r) instance (GHC.Classes.Ord r, GHC.Real.Fractional r) => Data.Intersection.HasIntersectionWith (Data.Geometry.Line.Internal.Line 2 r) (Data.Geometry.Boundary.Boundary (Data.Geometry.Box.Internal.Rectangle p r)) instance (GHC.Classes.Ord r, GHC.Real.Fractional r) => Data.Intersection.IsIntersectableWith (Data.Geometry.Line.Internal.Line 2 r) (Data.Geometry.Boundary.Boundary (Data.Geometry.Box.Internal.Rectangle p r)) instance (GHC.Classes.Ord r, GHC.Real.Fractional r) => Data.Intersection.HasIntersectionWith (Data.Geometry.Line.Internal.Line 2 r) (Data.Geometry.Box.Internal.Rectangle p r) instance (GHC.Classes.Ord r, GHC.Real.Fractional r) => Data.Intersection.IsIntersectableWith (Data.Geometry.Line.Internal.Line 2 r) (Data.Geometry.Box.Internal.Rectangle p r) module Data.Geometry.Slab data Orthogonal Horizontal :: Orthogonal Vertical :: Orthogonal newtype Slab (o :: Orthogonal) a r Slab :: Interval a r -> Slab (o :: Orthogonal) a r [_unSlab] :: Slab (o :: Orthogonal) a r -> Interval a r unSlab :: forall o_a1Xkv a_a1Xkw r_a1Xkx o_a1Xqd a_a1Xqe r_a1Xqf. Iso (Slab o_a1Xkv a_a1Xkw r_a1Xkx) (Slab o_a1Xqd a_a1Xqe r_a1Xqf) (Interval a_a1Xkw r_a1Xkx) (Interval a_a1Xqe r_a1Xqf) -- | Smart consturctor for creating a horizontal slab horizontalSlab :: (r :+ a) -> (r :+ a) -> Slab Horizontal a r -- | Smart consturctor for creating a vertical slab verticalSlab :: (r :+ a) -> (r :+ a) -> Slab Vertical a r class HasBoundingLines (o :: Orthogonal) -- | The two bounding lines of the slab, first the lower one, then the -- higher one: boundingLines :: (HasBoundingLines o, Num r) => Slab o a r -> (Line 2 r :+ a, Line 2 r :+ a) inSlab :: (HasBoundingLines o, Ord r) => Point 2 r -> Slab o a r -> Bool instance Data.Geometry.Slab.HasBoundingLines 'Data.Geometry.Slab.Horizontal instance Data.Geometry.Slab.HasBoundingLines 'Data.Geometry.Slab.Vertical instance (GHC.Real.Fractional r, GHC.Classes.Ord r, Data.Geometry.Slab.HasBoundingLines o) => Data.Intersection.HasIntersectionWith (Data.Geometry.Line.Internal.Line 2 r) (Data.Geometry.Slab.Slab o a r) instance (GHC.Real.Fractional r, GHC.Classes.Ord r, Data.Geometry.Slab.HasBoundingLines o) => Data.Intersection.IsIntersectableWith (Data.Geometry.Line.Internal.Line 2 r) (Data.Geometry.Slab.Slab o a r) instance (GHC.Real.Fractional r, GHC.Classes.Ord r, Data.Geometry.Slab.HasBoundingLines o) => Data.Intersection.HasIntersectionWith (Data.Geometry.SubLine.SubLine 2 a r r) (Data.Geometry.Slab.Slab o a r) instance (GHC.Real.Fractional r, GHC.Classes.Ord r, Data.Geometry.Slab.HasBoundingLines o) => Data.Intersection.IsIntersectableWith (Data.Geometry.SubLine.SubLine 2 a r r) (Data.Geometry.Slab.Slab o a r) instance (GHC.Real.Fractional r, GHC.Classes.Ord r, Data.Geometry.Slab.HasBoundingLines o) => Data.Intersection.HasIntersectionWith (Data.Geometry.LineSegment.Internal.LineSegment 2 a r) (Data.Geometry.Slab.Slab o a r) instance (GHC.Real.Fractional r, GHC.Classes.Ord r, Data.Geometry.Slab.HasBoundingLines o) => Data.Intersection.IsIntersectableWith (Data.Geometry.LineSegment.Internal.LineSegment 2 a r) (Data.Geometry.Slab.Slab o a r) instance GHC.Base.Functor (Data.Geometry.Slab.Slab o a) instance Data.Foldable.Foldable (Data.Geometry.Slab.Slab o a) instance Data.Traversable.Traversable (Data.Geometry.Slab.Slab o a) instance Data.Bifunctor.Bifunctor (Data.Geometry.Slab.Slab o) instance GHC.Classes.Ord r => Data.Intersection.HasIntersectionWith (Data.Geometry.Slab.Slab o a r) (Data.Geometry.Slab.Slab o a r) instance GHC.Classes.Ord r => Data.Intersection.IsIntersectableWith (Data.Geometry.Slab.Slab o a r) (Data.Geometry.Slab.Slab o a r) instance Data.Intersection.HasIntersectionWith (Data.Geometry.Slab.Slab 'Data.Geometry.Slab.Horizontal a r) (Data.Geometry.Slab.Slab 'Data.Geometry.Slab.Vertical a r) instance Data.Intersection.IsIntersectableWith (Data.Geometry.Slab.Slab 'Data.Geometry.Slab.Horizontal a r) (Data.Geometry.Slab.Slab 'Data.Geometry.Slab.Vertical a r) instance GHC.Read.Read Data.Geometry.Slab.Orthogonal instance GHC.Classes.Eq Data.Geometry.Slab.Orthogonal instance GHC.Show.Show Data.Geometry.Slab.Orthogonal instance (GHC.Classes.Eq r, GHC.Classes.Eq a) => GHC.Classes.Eq (Data.Geometry.Slab.Slab o a r) instance (GHC.Show.Show a, GHC.Show.Show r) => GHC.Show.Show (Data.Geometry.Slab.Slab o a r) module Data.Geometry.HyperPlane -- | Hyperplanes embedded in a <math> dimensional space. data HyperPlane (d :: Nat) (r :: *) HyperPlane :: !Point d r -> !Vector d r -> HyperPlane (d :: Nat) (r :: *) [_inPlane] :: HyperPlane (d :: Nat) (r :: *) -> !Point d r [_normalVec] :: HyperPlane (d :: Nat) (r :: *) -> !Vector d r normalVec :: forall d_a20vn r_a20vo. Lens' (HyperPlane d_a20vn r_a20vo) (Vector d_a20vn r_a20vo) inPlane :: forall d_a20vn r_a20vo. Lens' (HyperPlane d_a20vn r_a20vo) (Point d_a20vn r_a20vo) type Plane = HyperPlane 3 pattern Plane :: Point 3 r -> Vector 3 r -> Plane r -- | Produces a plane. If r lies counter clockwise of q w.r.t. p then the -- normal vector of the resulting plane is pointing "upwards". -- --
--   >>> from3Points origin (Point3 1 0 0) (Point3 0 1 0)
--   HyperPlane {_inPlane = Point3 0 0 0, _normalVec = Vector3 0 0 1}
--   
from3Points :: Num r => Point 3 r -> Point 3 r -> Point 3 r -> HyperPlane 3 r -- | Convert between lines and hyperplanes _asLine :: Num r => Iso' (HyperPlane 2 r) (Line 2 r) -- | Types for which we can compute a supporting hyperplane, i.e. a -- hyperplane that contains the thing of type t. class HasSupportingPlane t supportingPlane :: HasSupportingPlane t => t -> HyperPlane (Dimension t) (NumType t) -- | Given * a plane, * a unit vector in the plane that will represent the -- y-axis (i.e. the "view up" vector), and * a point in the plane, -- -- computes the plane coordinates of the given point, using the inPlane -- point as the origin, the normal vector of the plane as the unit vector -- in the "z-direction" and the view up vector as the y-axis. -- --
--   >>> planeCoordinatesWith (Plane origin (Vector3 0 0 1)) (Vector3 0 1 0) (Point3 10 10 0)
--   Point2 10.0 10.0
--   
planeCoordinatesWith :: Fractional r => Plane r -> Vector 3 r -> Point 3 r -> Point 2 r planeCoordinatesTransform :: Num r => Plane r -> Vector 3 r -> Transformation 3 r instance (Data.Geometry.Vector.VectorFamily.Arity d, GHC.Show.Show r) => GHC.Show.Show (Data.Geometry.HyperPlane.HyperPlane d r) instance (Control.DeepSeq.NFData r, Data.Geometry.Vector.VectorFamily.Arity d) => Control.DeepSeq.NFData (Data.Geometry.HyperPlane.HyperPlane d r) instance Data.Geometry.Vector.VectorFamily.Arity d => GHC.Base.Functor (Data.Geometry.HyperPlane.HyperPlane d) instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Foldable.Foldable (Data.Geometry.HyperPlane.HyperPlane d) instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Traversable.Traversable (Data.Geometry.HyperPlane.HyperPlane d) instance Data.Geometry.HyperPlane.HasSupportingPlane (Data.Geometry.HyperPlane.HyperPlane d r) instance Data.Geometry.Line.Internal.OnSideUpDownTest (Data.Geometry.HyperPlane.Plane r) instance (GHC.Classes.Eq r, GHC.Real.Fractional r) => Data.Intersection.HasIntersectionWith (Data.Geometry.Line.Internal.Line 3 r) (Data.Geometry.HyperPlane.Plane r) instance (GHC.Classes.Eq r, GHC.Real.Fractional r) => Data.Intersection.IsIntersectableWith (Data.Geometry.Line.Internal.Line 3 r) (Data.Geometry.HyperPlane.Plane r) instance (Data.Geometry.Vector.VectorFamily.Arity d, GHC.Classes.Eq r, GHC.Real.Fractional r) => GHC.Classes.Eq (Data.Geometry.HyperPlane.HyperPlane d r) instance (Data.Geometry.Vector.VectorFamily.Arity d, Data.Geometry.Vector.VectorFamily.Arity (d GHC.TypeNats.+ 1), GHC.Real.Fractional r) => Data.Geometry.Transformation.Internal.IsTransformable (Data.Geometry.HyperPlane.HyperPlane d r) instance (GHC.Num.Num r, GHC.Classes.Eq r, Data.Geometry.Vector.VectorFamily.Arity d) => Data.Intersection.HasIntersectionWith (Data.Geometry.Point.Internal.Point d r) (Data.Geometry.HyperPlane.HyperPlane d r) instance (GHC.Num.Num r, GHC.Classes.Eq r, Data.Geometry.Vector.VectorFamily.Arity d) => Data.Intersection.IsIntersectableWith (Data.Geometry.Point.Internal.Point d r) (Data.Geometry.HyperPlane.HyperPlane d r) instance GHC.Generics.Generic (Data.Geometry.HyperPlane.HyperPlane d r) module Data.Geometry.Duality -- | Maps a line point (px,py) to a line (y=px*x - py) dualLine :: Num r => Point 2 r -> Line 2 r -- | Returns Nothing if the input line is vertical Maps a line l: y = ax + -- b to a point (a,-b) dualPoint :: (Fractional r, Eq r) => Line 2 r -> Maybe (Point 2 r) -- | Pre: the input line is not vertical dualPoint' :: (Fractional r, Eq r) => Line 2 r -> Point 2 r module Data.Geometry.KDTree newtype Coord (d :: Nat) Coord :: Int -> Coord (d :: Nat) [unCoord] :: Coord (d :: Nat) -> Int data Split d r Split :: !Coord d -> !r -> !Box d () r -> Split d r type Split' d r = SP (Coord d) r newtype KDTree' d p r KDT :: BinLeafTree (Split d r) (Point d r :+ p) -> KDTree' d p r [unKDT] :: KDTree' d p r -> BinLeafTree (Split d r) (Point d r :+ p) data KDTree d p r Empty :: KDTree d p r Tree :: KDTree' d p r -> KDTree d p r toMaybe :: KDTree d p r -> Maybe (KDTree' d p r) -- | Expects the input to be a set, i.e. no duplicates -- -- running time: <math> buildKDTree :: (Arity d, 1 <= d, Ord r) => [Point d r :+ p] -> KDTree d p r buildKDTree' :: (Arity d, 1 <= d, Ord r) => NonEmpty (Point d r :+ p) -> KDTree' d p r -- | Nub by sorting first ordNub :: Ord a => NonEmpty a -> NonEmpty a toPointSet :: (Arity d, Ord r) => LSeq n (Point d r :+ p) -> PointSet (LSeq n) d p r compareOn :: (Ord r, Arity d) => Int -> (Point d r :+ e) -> (Point d r :+ e) -> Ordering build :: (1 <= d, Arity d, Ord r) => Coord d -> PointSet (LSeq 1) d p r -> BinLeafTree (Split' d r) (Point d r :+ p) reportSubTree :: KDTree' d p r -> NonEmpty (Point d r :+ p) -- | Searches in a KDTree -- -- running time: <math> searchKDTree :: (Arity d, Ord r) => Box d q r -> KDTree d p r -> [Point d r :+ p] searchKDTree' :: (Arity d, Ord r) => Box d q r -> KDTree' d p r -> [Point d r :+ p] boxOf :: (Arity d, Ord r) => BinLeafTree (Split d r) (Point d r :+ p) -> Box d () r containedIn :: (Arity d, Ord r) => Box d q r -> Box d p r -> Bool type PointSet seq d p r = Vector d (seq (Point d r :+ p)) -- | running time: <math> splitOn :: (Arity d, KnownNat d, Ord r) => Coord d -> PointSet (LSeq 2) d p r -> (PointSet (LSeq 1) d p r, Split' d r, PointSet (LSeq 1) d p r) asSingleton :: (1 <= d, Arity d) => PointSet (LSeq 1) d p r -> Either (Point d r :+ p) (PointSet (LSeq 2) d p r) instance (GHC.Show.Show r, Data.Geometry.Vector.VectorFamily.Arity d, GHC.TypeNats.KnownNat d) => GHC.Show.Show (Data.Geometry.KDTree.Split d r) instance (GHC.Classes.Eq r, Data.Geometry.Vector.VectorFamily.Arity d, GHC.TypeNats.KnownNat d) => GHC.Classes.Eq (Data.Geometry.KDTree.Split d r) instance (GHC.Show.Show p, GHC.Show.Show r, Data.Geometry.Vector.VectorFamily.Arity d, GHC.TypeNats.KnownNat d) => GHC.Show.Show (Data.Geometry.KDTree.KDTree' d p r) instance (GHC.Classes.Eq p, GHC.Classes.Eq r, Data.Geometry.Vector.VectorFamily.Arity d, GHC.TypeNats.KnownNat d) => GHC.Classes.Eq (Data.Geometry.KDTree.KDTree' d p r) instance (GHC.Show.Show p, GHC.Show.Show r, Data.Geometry.Vector.VectorFamily.Arity d, GHC.TypeNats.KnownNat d) => GHC.Show.Show (Data.Geometry.KDTree.KDTree d p r) instance (GHC.Classes.Eq p, GHC.Classes.Eq r, Data.Geometry.Vector.VectorFamily.Arity d, GHC.TypeNats.KnownNat d) => GHC.Classes.Eq (Data.Geometry.KDTree.KDTree d p r) instance GHC.TypeNats.KnownNat d => GHC.Classes.Eq (Data.Geometry.KDTree.Coord d) instance GHC.TypeNats.KnownNat d => GHC.Show.Show (Data.Geometry.KDTree.Coord d) instance GHC.TypeNats.KnownNat d => GHC.Enum.Enum (Data.Geometry.KDTree.Coord d) module Data.Geometry.HalfLine -- | <math>-dimensional Half-Lines data HalfLine d r HalfLine :: Point d r -> Vector d r -> HalfLine d r startPoint :: forall d_a24sZ r_a24t0. Lens' (HalfLine d_a24sZ r_a24t0) (Point d_a24sZ r_a24t0) halfLineDirection :: forall d_a24sZ r_a24t0. Lens' (HalfLine d_a24sZ r_a24t0) (Vector d_a24sZ r_a24t0) -- | Transform a LineSegment into a half-line, by forgetting the second -- endpoint. Note that this also forgets about if the starting point was -- open or closed. toHalfLine :: (Num r, Arity d) => LineSegment d p r -> HalfLine d r halfLineToSubLine :: (Arity d, Num r) => HalfLine d r -> SubLine d () (UnBounded r) r fromSubLine :: (Num r, Arity d) => SubLine d p (UnBounded r) r -> Maybe (HalfLine d r) instance (GHC.Show.Show r, Data.Geometry.Vector.VectorFamily.Arity d) => GHC.Show.Show (Data.Geometry.HalfLine.HalfLine d r) instance (Control.DeepSeq.NFData r, Data.Geometry.Vector.VectorFamily.Arity d) => Control.DeepSeq.NFData (Data.Geometry.HalfLine.HalfLine d r) instance Data.Geometry.Vector.VectorFamily.Arity d => GHC.Base.Functor (Data.Geometry.HalfLine.HalfLine d) instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Foldable.Foldable (Data.Geometry.HalfLine.HalfLine d) instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Traversable.Traversable (Data.Geometry.HalfLine.HalfLine d) instance (GHC.Classes.Eq r, GHC.Real.Fractional r) => GHC.Classes.Eq (Data.Geometry.HalfLine.HalfLine 2 r) instance (GHC.Classes.Eq r, GHC.Real.Fractional r, Data.Geometry.Vector.VectorFamily.Arity d) => GHC.Classes.Eq (Data.Geometry.HalfLine.HalfLine d r) instance Data.Geometry.Interval.HasStart (Data.Geometry.HalfLine.HalfLine d r) instance Data.Geometry.Line.Internal.HasSupportingLine (Data.Geometry.HalfLine.HalfLine d r) instance (GHC.Real.Fractional r, Data.Geometry.Vector.VectorFamily.Arity d, Data.Geometry.Vector.VectorFamily.Arity (d GHC.TypeNats.+ 1)) => Data.Geometry.Transformation.Internal.IsTransformable (Data.Geometry.HalfLine.HalfLine d r) instance (GHC.Classes.Ord r, GHC.Real.Fractional r) => Data.Intersection.HasIntersectionWith (Data.Geometry.HalfLine.HalfLine 2 r) (Data.Geometry.Line.Internal.Line 2 r) instance (GHC.Classes.Ord r, GHC.Real.Fractional r) => Data.Intersection.IsIntersectableWith (Data.Geometry.HalfLine.HalfLine 2 r) (Data.Geometry.Line.Internal.Line 2 r) instance (GHC.Classes.Ord r, GHC.Real.Fractional r) => Data.Intersection.HasIntersectionWith (Data.Geometry.HalfLine.HalfLine 2 r) (Data.Geometry.HalfLine.HalfLine 2 r) instance (GHC.Classes.Ord r, GHC.Real.Fractional r) => Data.Intersection.IsIntersectableWith (Data.Geometry.HalfLine.HalfLine 2 r) (Data.Geometry.HalfLine.HalfLine 2 r) instance (GHC.Classes.Ord r, GHC.Real.Fractional r) => Data.Intersection.HasIntersectionWith (Data.Geometry.LineSegment.Internal.LineSegment 2 () r) (Data.Geometry.HalfLine.HalfLine 2 r) instance (GHC.Classes.Ord r, GHC.Real.Fractional r) => Data.Intersection.IsIntersectableWith (Data.Geometry.LineSegment.Internal.LineSegment 2 () r) (Data.Geometry.HalfLine.HalfLine 2 r) instance (GHC.Classes.Ord r, GHC.Real.Fractional r, Data.Geometry.Vector.VectorFamily.Arity d) => Data.Intersection.HasIntersectionWith (Data.Geometry.Point.Internal.Point d r) (Data.Geometry.HalfLine.HalfLine d r) instance (GHC.Classes.Ord r, GHC.Real.Fractional r, Data.Geometry.Vector.VectorFamily.Arity d) => Data.Intersection.IsIntersectableWith (Data.Geometry.Point.Internal.Point d r) (Data.Geometry.HalfLine.HalfLine d r) instance (GHC.Classes.Ord r, GHC.Real.Fractional r) => Data.Intersection.HasIntersectionWith (Data.Geometry.HalfLine.HalfLine 2 r) (Data.Geometry.Boundary.Boundary (Data.Geometry.Box.Internal.Rectangle p r)) instance (GHC.Classes.Ord r, GHC.Real.Fractional r) => Data.Intersection.IsIntersectableWith (Data.Geometry.HalfLine.HalfLine 2 r) (Data.Geometry.Boundary.Boundary (Data.Geometry.Box.Internal.Rectangle p r)) instance (GHC.Classes.Ord r, GHC.Real.Fractional r) => Data.Intersection.HasIntersectionWith (Data.Geometry.HalfLine.HalfLine 2 r) (Data.Geometry.Box.Internal.Rectangle p r) instance (GHC.Classes.Ord r, GHC.Real.Fractional r) => Data.Intersection.IsIntersectableWith (Data.Geometry.HalfLine.HalfLine 2 r) (Data.Geometry.Box.Internal.Rectangle p r) instance GHC.Generics.Generic (Data.Geometry.HalfLine.HalfLine d r) -- | <math>-dimensional HalfSpaces module Data.Geometry.HalfSpace -- | A Halfspace in <math> dimensions. Note that the intended side of -- the halfspace is already indicated by the normal vector of the -- bounding plane. newtype HalfSpace d r HalfSpace :: HyperPlane d r -> HalfSpace d r [_boundingPlane] :: HalfSpace d r -> HyperPlane d r boundingPlane :: forall d_a29A8 r_a29A9 d_a29C1 r_a29C2. Iso (HalfSpace d_a29A8 r_a29A9) (HalfSpace d_a29C1 r_a29C2) (HyperPlane d_a29A8 r_a29A9) (HyperPlane d_a29C1 r_a29C2) type HalfPlane = HalfSpace 2 -- | Get the halfplane left of a line (i.e. "above") a line -- --
--   >>> leftOf $ horizontalLine 4
--   HalfSpace {_boundingPlane = HyperPlane {_inPlane = Point2 0 4, _normalVec = Vector2 0 1}}
--   
leftOf :: Num r => Line 2 r -> HalfPlane r -- | Get the halfplane right of a line (i.e. "below") a line -- --
--   >>> rightOf $ horizontalLine 4
--   HalfSpace {_boundingPlane = HyperPlane {_inPlane = Point2 0 4, _normalVec = Vector2 0 (-1)}}
--   
rightOf :: Num r => Line 2 r -> HalfPlane r above :: Num r => Line 2 r -> HalfPlane r below :: Num r => Line 2 r -> HalfPlane r -- | Test if a point lies in a halfspace inHalfSpace :: (Num r, Ord r, Arity d) => Point d r -> HalfSpace d r -> PointLocationResult instance (Data.Geometry.Vector.VectorFamily.Arity d, GHC.Show.Show r) => GHC.Show.Show (Data.Geometry.HalfSpace.HalfSpace d r) instance Data.Geometry.Vector.VectorFamily.Arity d => GHC.Base.Functor (Data.Geometry.HalfSpace.HalfSpace d) instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Foldable.Foldable (Data.Geometry.HalfSpace.HalfSpace d) instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Traversable.Traversable (Data.Geometry.HalfSpace.HalfSpace d) instance (Data.Geometry.Vector.VectorFamily.Arity d, Data.Geometry.Vector.VectorFamily.Arity (d GHC.TypeNats.+ 1), GHC.Real.Fractional r) => Data.Geometry.Transformation.Internal.IsTransformable (Data.Geometry.HalfSpace.HalfSpace d r) instance (Data.Geometry.Vector.VectorFamily.Arity d, GHC.Classes.Eq r, GHC.Real.Fractional r) => GHC.Classes.Eq (Data.Geometry.HalfSpace.HalfSpace d r) instance (GHC.Num.Num r, GHC.Classes.Ord r, Data.Geometry.Vector.VectorFamily.Arity d) => Data.Intersection.HasIntersectionWith (Data.Geometry.Point.Internal.Point d r) (Data.Geometry.HalfSpace.HalfSpace d r) instance (GHC.Num.Num r, GHC.Classes.Ord r, Data.Geometry.Vector.VectorFamily.Arity d) => Data.Intersection.IsIntersectableWith (Data.Geometry.Point.Internal.Point d r) (Data.Geometry.HalfSpace.HalfSpace d r) instance (GHC.Real.Fractional r, GHC.Classes.Ord r) => Data.Intersection.HasIntersectionWith (Data.Geometry.Line.Internal.Line 2 r) (Data.Geometry.HalfSpace.HalfSpace 2 r) instance (GHC.Real.Fractional r, GHC.Classes.Ord r) => Data.Intersection.IsIntersectableWith (Data.Geometry.Line.Internal.Line 2 r) (Data.Geometry.HalfSpace.HalfSpace 2 r) instance GHC.Generics.Generic (Data.Geometry.HalfSpace.HalfSpace d r) -- | <math>-dimensional Balls and Spheres module Data.Geometry.Ball -- | A d-dimensional ball. data Ball d p r Ball :: !Point d r :+ p -> !r -> Ball d p r [_center] :: Ball d p r -> !Point d r :+ p [_squaredRadius] :: Ball d p r -> !r squaredRadius :: forall d_a2bTL p_a2bTM r_a2bTN. Lens' (Ball d_a2bTL p_a2bTM r_a2bTN) r_a2bTN center :: forall d_a2bTL p_a2bTM r_a2bTN d_a2bWp p_a2bWq. Lens (Ball d_a2bTL p_a2bTM r_a2bTN) (Ball d_a2bWp p_a2bWq r_a2bTN) ((:+) (Point d_a2bTL r_a2bTN) p_a2bTM) ((:+) (Point d_a2bWp r_a2bTN) p_a2bWq) -- | A lens to get/set the radius of a Ball radius :: Floating r => Lens' (Ball d p r) r -- | Given two points on the diameter of the ball, construct a ball. fromDiameter :: (Arity d, Fractional r) => Point d r -> Point d r -> Ball d () r -- | Construct a ball given the center point and a point p on the boundary. fromCenterAndPoint :: (Arity d, Num r) => (Point d r :+ p) -> (Point d r :+ p) -> Ball d p r -- | A d dimensional unit ball centered at the origin. unitBall :: (Arity d, Num r) => Ball d () r -- | Query location of a point relative to a d-dimensional ball. inBall :: (Arity d, Ord r, Num r) => Point d r -> Ball d p r -> PointLocationResult -- | Test if a point lies strictly inside a ball -- --
--   >>> (Point2 0.5 0.0) `insideBall` unitBall
--   True
--   
--   >>> (Point2 1 0) `insideBall` unitBall
--   False
--   
--   >>> (Point2 2 0) `insideBall` unitBall
--   False
--   
insideBall :: (Arity d, Ord r, Num r) => Point d r -> Ball d p r -> Bool -- | Test if a point lies in or on the ball inClosedBall :: (Arity d, Ord r, Num r) => Point d r -> Ball d p r -> Bool -- | Test if a point lies on the boundary of a ball. -- --
--   >>> (Point2 1 0) `onBall` unitBall
--   True
--   
--   >>> (Point3 1 1 0) `onBall` unitBall
--   False
--   
onBall :: (Arity d, Ord r, Num r) => Point d r -> Ball d p r -> Bool -- | Spheres, i.e. the boundary of a ball. type Sphere d p r = Boundary (Ball d p r) pattern Sphere :: (Point d r :+ p) -> r -> Sphere d p r _BallSphere :: Iso (Disk p r) (Disk p s) (Circle p r) (Circle p s) type Disk p r = Ball 2 p r -- | Given the center and the squared radius, constructs a disk pattern Disk :: (Point 2 r :+ p) -> r -> Disk p r type Circle p r = Sphere 2 p r -- | Iso for converting between Disks and Circles, i.e. forgetting the -- boundary _DiskCircle :: Iso (Disk p r) (Disk p s) (Circle p r) (Circle p s) -- | Given the center and the squared radius, constructs a circle pattern Circle :: (Point 2 r :+ p) -> r -> Circle p r -- | Given three points, get the disk through the three points. If the -- three input points are colinear we return Nothing -- --
--   >>> disk (Point2 0 10) (Point2 10 0) (Point2 (-10) 0)
--   Just (Ball {_center = Point2 0.0 0.0 :+ (), _squaredRadius = 100.0})
--   
disk :: (Eq r, Fractional r) => Point 2 r -> Point 2 r -> Point 2 r -> Maybe (Disk () r) -- | Creates a circle from three points on the boundary from3Points :: Fractional r => (Point 2 r :+ p) -> (Point 2 r :+ q) -> (Point 2 r :+ s) -> Circle () r newtype Touching p Touching :: p -> Touching p instance Data.Traversable.Traversable Data.Geometry.Ball.Touching instance Data.Foldable.Foldable Data.Geometry.Ball.Touching instance GHC.Base.Functor Data.Geometry.Ball.Touching instance GHC.Classes.Ord p => GHC.Classes.Ord (Data.Geometry.Ball.Touching p) instance GHC.Classes.Eq p => GHC.Classes.Eq (Data.Geometry.Ball.Touching p) instance GHC.Show.Show p => GHC.Show.Show (Data.Geometry.Ball.Touching p) instance (GHC.Show.Show r, GHC.Show.Show p, Data.Geometry.Vector.VectorFamily.Arity d) => GHC.Show.Show (Data.Geometry.Ball.Ball d p r) instance (GHC.Classes.Eq r, GHC.Classes.Eq p, Data.Geometry.Vector.VectorFamily.Arity d) => GHC.Classes.Eq (Data.Geometry.Ball.Ball d p r) instance (GHC.Classes.Ord r, GHC.Float.Floating r) => Data.Intersection.IsIntersectableWith (Data.Geometry.Line.Internal.Line 2 r) (Data.Geometry.Ball.Circle p r) instance (GHC.Classes.Ord r, GHC.Float.Floating r) => Data.Intersection.IsIntersectableWith (Data.Geometry.LineSegment.Internal.LineSegment 2 p r) (Data.Geometry.Ball.Circle q r) instance (GHC.Classes.Ord r, GHC.Num.Num r) => Data.Intersection.HasIntersectionWith (Data.Geometry.Line.Internal.Line 2 r) (Data.Geometry.Ball.Circle p r) instance (GHC.Classes.Ord r, GHC.Real.Fractional r, Data.Geometry.Vector.VectorFamily.Arity d) => Data.Intersection.HasIntersectionWith (Data.Geometry.Line.Internal.Line d r) (Data.Geometry.Ball.Sphere d q r) instance (GHC.Classes.Ord r, GHC.Real.Fractional r, Data.Geometry.Vector.VectorFamily.Arity d) => Data.Intersection.HasIntersectionWith (Data.Geometry.LineSegment.Internal.LineSegment d p r) (Data.Geometry.Ball.Sphere d q r) instance (Control.DeepSeq.NFData p, Control.DeepSeq.NFData r, Data.Geometry.Vector.VectorFamily.Arity d) => Control.DeepSeq.NFData (Data.Geometry.Ball.Ball d p r) instance Data.Geometry.Vector.VectorFamily.Arity d => GHC.Base.Functor (Data.Geometry.Ball.Ball d p) instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Bifunctor.Bifunctor (Data.Geometry.Ball.Ball d) instance GHC.Generics.Generic (Data.Geometry.Ball.Ball d p r) -- | Triangles in <math>-dimensional space. module Data.Geometry.Triangle -- | A triangle in <math>-dimensional space. data Triangle d p r Triangle :: !Point d r :+ p -> !Point d r :+ p -> !Point d r :+ p -> Triangle d p r -- | A <math>-dimensional triangle is isomorphic to a triple of -- <math>-dimensional points. _TriangleThreePoints :: Iso' (Triangle d p r) (Three (Point d r :+ p)) -- | convenience function to construct a triangle without associated data. pattern Triangle' :: Point d r -> Point d r -> Point d r -> Triangle d () r -- | Get the three line-segments that make up the sides of a triangle. sideSegments :: Triangle d p r -> [LineSegment d p r] -- | Compute the area of a triangle area :: Fractional r => Triangle 2 p r -> r -- | 2*the area of a triangle. doubleArea :: Num r => Triangle 2 p r -> r -- | Checks if the triangle is degenerate, i.e. has zero area. isDegenerateTriangle :: (Num r, Eq r) => Triangle 2 p r -> Bool -- | Get the inscribed disk. Returns Nothing if the triangle is degenerate, -- i.e. if the points are colinear. inscribedDisk :: (Eq r, Fractional r) => Triangle 2 p r -> Maybe (Disk () r) -- | Given a point q and a triangle, q inside the triangle, get the -- baricentric cordinates of q toBarricentric :: Fractional r => Point 2 r -> Triangle 2 p r -> Vector 3 r -- | Given a vector of barricentric coordinates and a triangle, get the -- corresponding point in the same coordinate sytsem as the vertices of -- the triangle. fromBarricentric :: (Arity d, Num r) => Vector 3 r -> Triangle d p r -> Point d r -- | Tests if a point lies inside a triangle, on its boundary, or outside -- the triangle inTriangle :: (Ord r, Fractional r) => Point 2 r -> Triangle 2 p r -> PointLocationResult inTriangleRelaxed :: (Ord r, Num r) => Point 2 r -> Triangle 2 p r -> PointLocationResult -- | Test if a point lies inside or on the boundary of a triangle onTriangle :: (Ord r, Fractional r) => Point 2 r -> Triangle 2 p r -> Bool onTriangleRelaxed :: (Ord r, Num r) => Point 2 r -> Triangle 2 p r -> Bool instance GHC.Generics.Generic (Data.Geometry.Triangle.Triangle d p r) instance (Data.Geometry.Vector.VectorFamily.Arity d, GHC.Show.Show r, GHC.Show.Show p) => GHC.Show.Show (Data.Geometry.Triangle.Triangle d p r) instance (Data.Geometry.Vector.VectorFamily.Arity d, GHC.Read.Read r, GHC.Read.Read p) => GHC.Read.Read (Data.Geometry.Triangle.Triangle d p r) instance (Data.Geometry.Vector.VectorFamily.Arity d, GHC.Classes.Eq r, GHC.Classes.Eq p) => GHC.Classes.Eq (Data.Geometry.Triangle.Triangle d p r) instance (Data.Geometry.Vector.VectorFamily.Arity d, Control.DeepSeq.NFData r, Control.DeepSeq.NFData p) => Control.DeepSeq.NFData (Data.Geometry.Triangle.Triangle d p r) instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Bifunctor.Bifunctor (Data.Geometry.Triangle.Triangle d) instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Bifoldable.Bifoldable (Data.Geometry.Triangle.Triangle d) instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Bitraversable.Bitraversable (Data.Geometry.Triangle.Triangle d) instance Control.Lens.Tuple.Field1 (Data.Geometry.Triangle.Triangle d p r) (Data.Geometry.Triangle.Triangle d p r) (Data.Geometry.Point.Internal.Point d r Data.Ext.:+ p) (Data.Geometry.Point.Internal.Point d r Data.Ext.:+ p) instance Control.Lens.Tuple.Field2 (Data.Geometry.Triangle.Triangle d p r) (Data.Geometry.Triangle.Triangle d p r) (Data.Geometry.Point.Internal.Point d r Data.Ext.:+ p) (Data.Geometry.Point.Internal.Point d r Data.Ext.:+ p) instance Control.Lens.Tuple.Field3 (Data.Geometry.Triangle.Triangle d p r) (Data.Geometry.Triangle.Triangle d p r) (Data.Geometry.Point.Internal.Point d r Data.Ext.:+ p) (Data.Geometry.Point.Internal.Point d r Data.Ext.:+ p) instance Data.Geometry.Point.Internal.PointFunctor (Data.Geometry.Triangle.Triangle d p) instance (GHC.Real.Fractional r, Data.Geometry.Vector.VectorFamily.Arity d, Data.Geometry.Vector.VectorFamily.Arity (d GHC.TypeNats.+ 1)) => Data.Geometry.Transformation.Internal.IsTransformable (Data.Geometry.Triangle.Triangle d p r) instance GHC.Num.Num r => Data.Geometry.HyperPlane.HasSupportingPlane (Data.Geometry.Triangle.Triangle 3 p r) instance (GHC.Real.Fractional r, GHC.Classes.Ord r) => Data.Intersection.HasIntersectionWith (Data.Geometry.Line.Internal.Line 2 r) (Data.Geometry.Triangle.Triangle 2 p r) instance (GHC.Real.Fractional r, GHC.Classes.Ord r) => Data.Intersection.IsIntersectableWith (Data.Geometry.Line.Internal.Line 2 r) (Data.Geometry.Triangle.Triangle 2 p r) instance (GHC.Real.Fractional r, GHC.Classes.Ord r) => Data.Intersection.HasIntersectionWith (Data.Geometry.Line.Internal.Line 3 r) (Data.Geometry.Triangle.Triangle 3 p r) instance (GHC.Real.Fractional r, GHC.Classes.Ord r) => Data.Intersection.IsIntersectableWith (Data.Geometry.Line.Internal.Line 3 r) (Data.Geometry.Triangle.Triangle 3 p r) instance (Data.Geometry.Vector.VectorFamily.Arity d, GHC.Classes.Ord r) => Data.Geometry.Box.Internal.IsBoxable (Data.Geometry.Triangle.Triangle d p r) -- | A polygon is monotone in a certain direction if rays orthogonal to -- that direction intersects the polygon at most twice. See -- https://en.wikipedia.org/wiki/Monotone_polygon module Data.Geometry.Polygon.Monotone -- | <math> A polygon is monotone if a straight line in a given -- direction cannot have more than two intersections. isMonotone :: (Fractional r, Ord r) => Vector 2 r -> SimplePolygon p r -> Bool -- | <math> Generate a random N-sided polygon that is monotone in a -- random direction. randomMonotone :: (RandomGen g, Random r, Ord r, Num r) => Int -> Rand g (SimplePolygon () r) -- | <math> Generate a random N-sided polygon that is monotone in the -- given direction. randomMonotoneDirected :: (RandomGen g, Random r, Ord r, Num r) => Int -> Vector 2 r -> Rand g (SimplePolygon () r) -- | <math> Assemble a given set of points in a polygon that is -- monotone in the given direction. monotoneFrom :: (Ord r, Num r) => Vector 2 r -> [Point 2 r] -> SimplePolygon () r -- | <math> Create a random 2D vector which has a non-zero magnitude. randomNonZeroVector :: (RandomGen g, Random r, Eq r, Num r) => Rand g (Vector 2 r) -- | Convex Polygons module Data.Geometry.Polygon.Convex -- | Data Type representing a convex polygon newtype ConvexPolygon p r ConvexPolygon :: SimplePolygon p r -> ConvexPolygon p r [_simplePolygon] :: ConvexPolygon p r -> SimplePolygon p r -- | ConvexPolygons are isomorphic to SimplePolygons with the added -- constraint that they have no reflex vertices. simplePolygon :: Iso (ConvexPolygon p1 r1) (ConvexPolygon p2 r2) (SimplePolygon p1 r1) (SimplePolygon p2 r2) -- | <math> Convex hull of a simple polygon. -- -- For algorithmic details see: -- https://en.wikipedia.org/wiki/Convex_hull_of_a_simple_polygon convexPolygon :: forall t p r. (Ord r, Num r, Show r, Show p) => Polygon t p r -> ConvexPolygon p r -- | <math> Check if a polygon is strictly convex. isConvex :: (Ord r, Num r) => SimplePolygon p r -> Bool -- | <math> Verify that a convex polygon is strictly convex. verifyConvex :: (Ord r, Num r) => ConvexPolygon p r -> Bool -- | Rotating Right - rotate clockwise -- -- Merging two convex hulls, based on the paper: -- -- Two Algorithms for Constructing a Delaunay Triangulation Lee and -- Schachter International Journal of Computer and Information Sciences, -- Vol 9, No. 3, 1980 -- -- : (combined hull, lower tangent that was added, upper tangent thtat -- was added) merge :: (Num r, Ord r) => ConvexPolygon p r -> ConvexPolygon p r -> (ConvexPolygon p r, LineSegment 2 p r, LineSegment 2 p r) -- | Compute the lower tangent of the two polgyons -- -- pre: - polygons lp and rp have at least 1 vertex - lp and rp are -- disjoint, and there is a vertical line separating the two polygons. - -- The vertices of the polygons are given in clockwise order -- -- Running time: O(n+m), where n and m are the sizes of the two polygons -- respectively lowerTangent :: (Num r, Ord r) => ConvexPolygon p r -> ConvexPolygon p r -> LineSegment 2 p r -- | Compute the lower tangent of the two convex chains lp and rp -- -- pre: - the chains lp and rp have at least 1 vertex - lp and rp are -- disjoint, and there is a vertical line having lp on the left and rp on -- the right. - The vertices in the left-chain are given in clockwise -- order, (right to left) - The vertices in the right chain are given in -- counterclockwise order (left-to-right) -- -- The result returned is the two endpoints l and r of the tangents, and -- the remainders lc and rc of the chains (i.e.) such that the lower hull -- of both chains is: (reverse lc) ++ [l,h] ++ rc -- -- Running time: <math>, where n and m are the sizes of the two -- chains respectively lowerTangent' :: (Ord r, Num r, Foldable1 f) => f (Point 2 r :+ p) -> f (Point 2 r :+ p) -> Two ((Point 2 r :+ p) :+ [Point 2 r :+ p]) -- | Compute the upper tangent of the two polgyons -- -- pre: - polygons lp and rp have at least 1 vertex - lp and rp are -- disjoint, and there is a vertical line separating the two polygons. - -- The vertices of the polygons are given in clockwise order -- -- Running time: <math>, where n and m are the sizes of the two -- polygons respectively upperTangent :: (Num r, Ord r) => ConvexPolygon p r -> ConvexPolygon p r -> LineSegment 2 p r -- | Compute the upper tangent of the two convex chains lp and rp -- -- pre: - the chains lp and rp have at least 1 vertex - lp and rp are -- disjoint, and there is a vertical line having lp on the left and rp on -- the right. - The vertices in the left-chain are given in clockwise -- order, (right to left) - The vertices in the right chain are given in -- counterclockwise order (left-to-right) -- -- The result returned is the two endpoints l and r of the tangents, and -- the remainders lc and rc of the chains (i.e.) such that the upper hull -- of both chains is: (reverse lc) ++ [l,h] ++ rc -- -- Running time: <math>, where n and m are the sizes of the two -- chains respectively upperTangent' :: (Ord r, Num r, Foldable1 f) => f (Point 2 r :+ p) -> f (Point 2 r :+ p) -> Two ((Point 2 r :+ p) :+ [Point 2 r :+ p]) -- | Finds the extreme points, minimum and maximum, in a given direction -- -- pre: The input polygon is strictly convex. -- -- running time: <math> extremes :: (Num r, Ord r) => Vector 2 r -> ConvexPolygon p r -> (Point 2 r :+ p, Point 2 r :+ p) -- | Finds the extreme maximum point in the given direction. Based on -- http://geomalgorithms.com/a14-_extreme_pts.html -- -- pre: The input polygon is strictly convex. -- -- running time: <math> maxInDirection :: (Num r, Ord r) => Vector 2 r -> ConvexPolygon p r -> Point 2 r :+ p -- | Given a convex polygon poly, and a point outside the polygon, find the -- left tangent of q and the polygon, i.e. the vertex v of the convex -- polygon s.t. the polygon lies completely to the right of the line from -- q to v. -- -- running time: <math>. leftTangent :: (Ord r, Num r) => ConvexPolygon p r -> Point 2 r -> Point 2 r :+ p -- | Given a convex polygon poly, and a point outside the polygon, find the -- right tangent of q and the polygon, i.e. the vertex v of the convex -- polygon s.t. the polygon lies completely to the left of the line from -- q to v. -- -- running time: <math>. rightTangent :: (Ord r, Num r) => ConvexPolygon p r -> Point 2 r -> Point 2 r :+ p -- | Computes the Minkowski sum of the two input polygons with $n$ and $m$ -- vertices respectively. -- -- pre: input polygons are in CCW order. -- -- running time: <math>. minkowskiSum :: (Ord r, Num r) => ConvexPolygon p r -> ConvexPolygon q r -> ConvexPolygon (p, q) r -- | Rotate to the bottommost point (and leftmost in case of ties) bottomMost :: Ord r => CircularVector (Point 2 r :+ p) -> CircularVector (Point 2 r :+ p) -- | <math> Check if a point lies inside a convex polygon, on the -- boundary, or outside of the convex polygon. inConvex :: forall p r. (Fractional r, Ord r) => Point 2 r -> ConvexPolygon p r -> PointLocationResult -- | <math> Generate a uniformly random ConvexPolygon with N -- vertices and a granularity of vMax. randomConvex :: RandomGen g => Int -> Int -> Rand g (ConvexPolygon () Rational) -- | <math> Computes the Euclidean diameter by scanning antipodal -- pairs. diameter :: (Ord r, Floating r) => ConvexPolygon p r -> r -- | <math> Computes the Euclidean diametral pair by scanning -- antipodal pairs. diametralPair :: (Ord r, Num r) => ConvexPolygon p r -> (Point 2 r :+ p, Point 2 r :+ p) -- | <math> Computes the Euclidean diametral pair by scanning -- antipodal pairs. diametralIndexPair :: (Ord r, Num r) => ConvexPolygon p r -> (Int, Int) instance (Control.DeepSeq.NFData p, Control.DeepSeq.NFData r) => Control.DeepSeq.NFData (Data.Geometry.Polygon.Convex.ConvexPolygon p r) instance (GHC.Classes.Eq p, GHC.Classes.Eq r) => GHC.Classes.Eq (Data.Geometry.Polygon.Convex.ConvexPolygon p r) instance (GHC.Show.Show p, GHC.Show.Show r) => GHC.Show.Show (Data.Geometry.Polygon.Convex.ConvexPolygon p r) instance Data.Geometry.Point.Internal.PointFunctor (Data.Geometry.Polygon.Convex.ConvexPolygon p) instance GHC.Real.Fractional r => Data.Geometry.Transformation.Internal.IsTransformable (Data.Geometry.Polygon.Convex.ConvexPolygon p r) instance Data.Geometry.Box.Internal.IsBoxable (Data.Geometry.Polygon.Convex.ConvexPolygon p r) -- | <math> algorithm for determining if any two line segments -- overlap. -- -- Shamos and Hoey. module Algorithms.Geometry.LineSegmentIntersection.BooleanSweep -- | Tests if there are any intersections. -- -- <math> hasIntersections :: (Ord r, Num r) => [LineSegment 2 p r] -> Bool segmentsOverlap :: (Num r, Ord r) => LineSegment 2 p r -> LineSegment 2 p r -> Bool module Data.Geometry.Ellipse -- | A type representing planar ellipses newtype Ellipse r Ellipse :: Transformation 2 r -> Ellipse r affineTransformation :: forall r_a2yro r_a2yU4. Iso (Ellipse r_a2yro) (Ellipse r_a2yU4) (Transformation 2 r_a2yro) (Transformation 2 r_a2yU4) ellipseMatrix :: Iso (Ellipse r) (Ellipse s) (Matrix 3 3 r) (Matrix 3 3 s) -- | Ellipse representing the unit circle unitEllipse :: Num r => Ellipse r circleToEllipse :: Floating r => Circle p r -> Ellipse r ellipseToCircle :: (Num r, Eq r) => Ellipse r -> Maybe (Circle () r) -- | Converting between ellipses and circles _EllipseCircle :: (Floating r, Eq r) => Prism' (Ellipse r) (Circle () r) instance GHC.Num.Num r => Data.Geometry.Transformation.Internal.IsTransformable (Data.Geometry.Ellipse.Ellipse r) instance Data.Traversable.Traversable Data.Geometry.Ellipse.Ellipse instance Data.Foldable.Foldable Data.Geometry.Ellipse.Ellipse instance GHC.Base.Functor Data.Geometry.Ellipse.Ellipse instance GHC.Classes.Eq r => GHC.Classes.Eq (Data.Geometry.Ellipse.Ellipse r) instance GHC.Show.Show r => GHC.Show.Show (Data.Geometry.Ellipse.Ellipse r) -- | Data types that can represent a well separated pair decomposition -- (wspd). -- | Deprecated: This module will be deleted after 2021-06-01. Use -- Algorithms.Geometry.WSPD instead. module Algorithms.Geometry.WellSeparatedPairDecomposition.Types type SplitTree d p r a = BinLeafTree (NodeData d r a) (Point d r :+ p) type PointSet d p r a = SplitTree d p r a type WSP d p r a = (PointSet d p r a, PointSet d p r a) -- | Data that we store in the split tree data NodeData d r a NodeData :: !Int -> !Box d () r -> !a -> NodeData d r a [_splitDim] :: NodeData d r a -> !Int [_bBox] :: NodeData d r a -> !Box d () r [_nodeData] :: NodeData d r a -> !a splitDim :: forall d_a2BTx r_a2BTy a_a2BTz. Lens' (NodeData d_a2BTx r_a2BTy a_a2BTz) Int nodeData :: forall d_a2BTx r_a2BTy a_a2BTz a_a2BYg. Lens (NodeData d_a2BTx r_a2BTy a_a2BTz) (NodeData d_a2BTx r_a2BTy a_a2BYg) a_a2BTz a_a2BYg bBox :: forall d_a2BTx r_a2BTy a_a2BTz d_a2BYe r_a2BYf. Lens (NodeData d_a2BTx r_a2BTy a_a2BTz) (NodeData d_a2BYe r_a2BYf a_a2BTz) (Box d_a2BTx () r_a2BTy) (Box d_a2BYe () r_a2BYf) -- | Non-empty sequence of points. type PointSeq d p r = LSeq 1 (Point d r :+ p) data Level Level :: Int -> Maybe Int -> Level [_unLevel] :: Level -> Int [_widestDim] :: Level -> Maybe Int widestDim :: Lens' Level (Maybe Int) unLevel :: Lens' Level Int nextLevel :: Level -> Level type Idx = Int data ShortSide L :: ShortSide R :: ShortSide data FindAndCompact d r p FAC :: !Seq (Point d r :+ p) -> !Seq (Point d r :+ p) -> !ShortSide -> FindAndCompact d r p [_leftPart] :: FindAndCompact d r p -> !Seq (Point d r :+ p) [_rightPart] :: FindAndCompact d r p -> !Seq (Point d r :+ p) [_shortSide] :: FindAndCompact d r p -> !ShortSide shortSide :: forall d_a2Car r_a2Cas p_a2Cat. Lens' (FindAndCompact d_a2Car r_a2Cas p_a2Cat) ShortSide rightPart :: forall d_a2Car r_a2Cas p_a2Cat. Lens' (FindAndCompact d_a2Car r_a2Cas p_a2Cat) (Seq ((:+) (Point d_a2Car r_a2Cas) p_a2Cat)) leftPart :: forall d_a2Car r_a2Cas p_a2Cat. Lens' (FindAndCompact d_a2Car r_a2Cas p_a2Cat) (Seq ((:+) (Point d_a2Car r_a2Cas) p_a2Cat)) -- | Algorithm to construct a well separated pair decomposition (wspd). module Algorithms.Geometry.WSPD -- | Construct a split tree -- -- running time: <math> fairSplitTree :: (Fractional r, Ord r, Arity d, 1 <= d, Show r, Show p) => NonEmpty (Point d r :+ p) -> SplitTree d p r () -- | Given a split tree, generate the Well separated pairs -- -- running time: <math> wellSeparatedPairs :: (Floating r, Ord r, Arity d, Arity (d + 1)) => r -> SplitTree d p r a -> [WSP d p r a] -- | Data that we store in the split tree data NodeData d r a NodeData :: !Int -> !Box d () r -> !a -> NodeData d r a type WSP d p r a = (PointSet d p r a, PointSet d p r a) type SplitTree d p r a = BinLeafTree (NodeData d r a) (Point d r :+ p) nodeData :: forall d_a2BTx r_a2BTy a_a2BTz a_a2BYg. Lens (NodeData d_a2BTx r_a2BTy a_a2BTz) (NodeData d_a2BTx r_a2BTy a_a2BYg) a_a2BTz a_a2BYg data Level Level :: Int -> Maybe Int -> Level [_unLevel] :: Level -> Int [_widestDim] :: Level -> Maybe Int -- | Given a sequence of points, whose index is increasing in the first -- dimension, i.e. if idx p < idx q, then p[0] < q[0]. Reindex the -- points so that they again have an index in the range [0,..,n'], where -- n' is the new number of points. -- -- running time: O(n' * d) (more or less; we are actually using an intmap -- for the lookups) -- -- alternatively: I can unsafe freeze and thaw an existing vector to pass -- it along to use as mapping. Except then I would have to force the -- evaluation order, i.e. we cannot be in reIndexPoints for two of -- the nodes at the same time. -- -- so, basically, run reIndex points in ST as well. reIndexPoints :: (Arity d, 1 <= d) => Vector d (PointSeq d (Idx :+ p) r) -> Vector d (PointSeq d (Idx :+ p) r) -- | Assign the points to their the correct class. The Nothing class -- is considered the last class distributePoints :: (Arity d, Show r, Show p) => Int -> Vector (Maybe Level) -> Vector d (PointSeq d (Idx :+ p) r) -> Vector (Vector d (PointSeq d (Idx :+ p) r)) -- | Assign the points to their the correct class. The Nothing class -- is considered the last class distributePoints' :: Int -> Vector (Maybe Level) -> PointSeq d (Idx :+ p) r -> Vector (PointSeq d (Idx :+ p) r) -- | Algorithm to construct a well separated pair decomposition (wspd). -- | Deprecated: This module will be deleted after 2021-06-01. Use -- Algorithms.Geometry.WSPD instead. module Algorithms.Geometry.WellSeparatedPairDecomposition.WSPD -- | Implementation of Simulation of Simplicity: A Technique to Cope with -- Degenerate Cases in Geometric Algorithms -- -- By Herbert Edelsbrunner and Ernst Peter Mucke module Algorithms.Geometry.SoS -- | The sign of an expression data Sign Negative :: Sign Positive :: Sign -- | Flip Positive = Negative. flipSign :: Sign -> Sign -- | Given the terms, in decreasing order of significance, computes the -- sign -- -- i.e. expects a list of terms, we base the sign on the sign of the -- first non-zero term. -- -- pre: the list contains at least one such a term. signFromTerms :: (Num r, Eq r) => [r] -> Sign -- | A dimension d has support for SoS when we can: compute a dterminant of -- a d+1 by d+1 dimensional matrix. type SoS d = (Arity d, HasDeterminant (d + 1)) -- | Given a query point q, and a vector of d points defining a hyperplane -- test if q lies above or below the hyperplane. Each point is assumed to -- have an unique index of type i that can be used to disambiguate it in -- case of degeneracies. -- -- some 1D examples: -- --
--   >>> sideTest (Point1 0 :+ 0) (Vector1 $ Point1 2 :+ 1)
--   Negative
--   
--   >>> sideTest (Point1 10 :+ 0) (Vector1 $ Point1 2 :+ 1)
--   Positive
--   
--   >>> sideTest (Point1 2 :+ 0) (Vector1 $ Point1 2 :+ 1)
--   Positive
--   
--   >>> sideTest (Point1 2 :+ 3) (Vector1 $ Point1 2 :+ 1)
--   Negative
--   
-- -- some 2D examples: -- --
--   >>> sideTest (Point2 1 2 :+ 0) $ Vector2 (Point2 0 0 :+ 1) (Point2 2 2 :+ 3)
--   Positive
--   
--   >>> sideTest (Point2 1 (-2) :+ 0) $ Vector2 (Point2 0 0 :+ 1) (Point2 2 2 :+ 3)
--   Negative
--   
--   >>> sideTest (Point2 1 1 :+ 0) $ Vector2 (Point2 0 0 :+ 1) (Point2 2 2 :+ 3)
--   Positive
--   
--   >>> sideTest (Point2 1 1 :+ 10) $ Vector2 (Point2 0 0 :+ 1) (Point2 2 2 :+ 3)
--   Negative
--   
--   >>> sideTest (Point2 1 1 :+ 10) $ Vector2 (Point2 0 0 :+ 3) (Point2 2 2 :+ 1)
--   Negative
--   
sideTest :: (SoS d, Num r, Ord r, Ord i) => (Point d r :+ i) -> Vector d (Point d r :+ i) -> Sign -- | Given a point q and a vector of d points defining a hyperplane, test -- on which side of the hyperplane q lies. -- -- TODO: Specify what the sign means sideTest' :: (Num r, Ord r, Ord i, HasDeterminant (d + 1), Arity d, Arity (d + 1)) => Point d (Symbolic i r) -> Vector d (Point d (Symbolic i r)) -> Sign -- | Given an input point, transform its number type to include symbolic -- $varepsilon$ expressions so that we can use SoS. toSymbolic :: (Ord i, Arity d) => (Point d r :+ i) -> Point d (Symbolic (i, Int) r) -- | pre: computes the sign of the determinant signDet :: (HasDeterminant d, Ord i, Num r, Ord r) => Matrix d d (Symbolic i r) -> Sign module Algorithms.Geometry.PolyLineSimplification.ImaiIri -- | Line simplification with the Imai-Iri alogrithm. Given a distance -- value eps and a polyline pl, constructs a simplification of pl (i.e. -- with vertices from pl) s.t. all other vertices are within dist eps to -- the original polyline. -- -- Running time: <math> time. simplify :: (Ord r, Fractional r, Arity d) => r -> PolyLine d p r -> PolyLine d p r -- | Given a function that tests if the shortcut is valid, compute a -- simplification using the Imai-Iri algorithm. -- -- Running time: <math> time, where <math> is the time to -- evaluate the predicate. simplifyWith :: (LineSegment d p r -> PolyLine d p r -> Bool) -> PolyLine d p r -> PolyLine d p r module Algorithms.Geometry.PolyLineSimplification.DouglasPeucker -- | Line simplification with the well-known Douglas Peucker alogrithm. -- Given a distance value eps and a polyline pl, constructs a -- simplification of pl (i.e. with vertices from pl) s.t. all other -- vertices are within dist eps to the original polyline. -- -- Running time: <math> worst case, <math> on average. douglasPeucker :: (Ord r, Fractional r, Arity d) => r -> PolyLine d p r -> PolyLine d p r -- | Concatenate the two polylines, dropping their shared vertex merge :: PolyLine d p r -> PolyLine d p r -> PolyLine d p r -- | Split the polyline at the given vertex. Both polylines contain this -- vertex split :: Int -> PolyLine d p r -> (PolyLine d p r, PolyLine d p r) -- | Given a sequence of points, find the index of the point that has the -- Furthest distance to the LineSegment. The result is the index of the -- point and this distance. maxDist :: (Ord r, Fractional r, Arity d) => LSeq n (Point d r :+ p) -> LineSegment d p r -> (Int, r) -- | 2D Linear programming in expected linear time. module Algorithms.Geometry.LinearProgramming.Types -- | Data type representing the solution to a linear program data LPSolution d r NoSolution :: LPSolution d r Single :: !Point d r -> LPSolution d r UnBounded :: HalfLine d r -> LPSolution d r _UnBounded :: forall d_a2Gzg r_a2Gzh. Prism' (LPSolution d_a2Gzg r_a2Gzh) (HalfLine d_a2Gzg r_a2Gzh) _Single :: forall d_a2Gzg r_a2Gzh. Prism' (LPSolution d_a2Gzg r_a2Gzh) (Point d_a2Gzg r_a2Gzh) _NoSolution :: forall d_a2Gzg r_a2Gzh. Prism' (LPSolution d_a2Gzg r_a2Gzh) () data LinearProgram d r LinearProgram :: !Vector d r -> [HalfSpace d r] -> LinearProgram d r [_objective] :: LinearProgram d r -> !Vector d r [_constraints] :: LinearProgram d r -> [HalfSpace d r] objective :: forall d_a2GAs r_a2GAt. Lens' (LinearProgram d_a2GAs r_a2GAt) (Vector d_a2GAs r_a2GAt) constraints :: forall d_a2GAs r_a2GAt. Lens' (LinearProgram d_a2GAs r_a2GAt) [HalfSpace d_a2GAs r_a2GAt] instance Data.Geometry.Vector.VectorFamily.Arity d => GHC.Base.Functor (Algorithms.Geometry.LinearProgramming.Types.LinearProgram d) instance (Data.Geometry.Vector.VectorFamily.Arity d, GHC.Show.Show r) => GHC.Show.Show (Algorithms.Geometry.LinearProgramming.Types.LinearProgram d r) instance (Data.Geometry.Vector.VectorFamily.Arity d, GHC.Real.Fractional r, GHC.Classes.Eq r) => GHC.Classes.Eq (Algorithms.Geometry.LinearProgramming.Types.LinearProgram d r) instance (Data.Geometry.Vector.VectorFamily.Arity d, GHC.Show.Show r) => GHC.Show.Show (Algorithms.Geometry.LinearProgramming.Types.LPSolution d r) instance (Data.Geometry.Vector.VectorFamily.Arity d, GHC.Classes.Eq r, GHC.Real.Fractional r) => GHC.Classes.Eq (Algorithms.Geometry.LinearProgramming.Types.LPSolution d r) -- | 2D Linear programming in expected linear time. module Algorithms.Geometry.LinearProgramming.LP2DRIC -- | Solves a bounded linear program in 2d. Returns Nothing if there is no -- solution. -- -- pre: The linear program is bounded, meaning that *the first two -- constraints* m1,m2 make sure th the there is no arbitrarily large/good -- solution. I..e. these halfspaces bound the solution in the c -- direction. -- -- (note that if there is only one constraint, m1, the assumption that -- the LP is bounded means that the contraint must be perpendicular to -- the objective direction. Hence, any point on the bounding plane is a -- solution, and they are all equally good.) -- -- <math> expected time solveBoundedLinearProgram :: (MonadRandom m, Ord r, Fractional r) => LinearProgram 2 r -> m (Maybe (Point 2 r)) -- | Solves a bounded linear program (like -- solveBoundedLinearProgram) assuming that the first two -- constraints [m1,m2] make sure the solutions is bounded, and the other -- constraints already have been shuffled. solveBoundedLinearProgram' :: (Ord r, Fractional r) => LinearProgram 2 r -> Maybe (Point 2 r) -- | Let l be the boundary of h, and assume that we know that the new point -- in the common intersection must lie on h, try to find this point. In -- partiuclar, we find the maximum point in the s^.direction -- vector. The funtion returns Nothing if no such point exists, i.e. if -- there is no point on l that is contained in all halfspaces. -- -- Note that this is essentially one dinsional LP maximumOn :: (Ord r, Fractional r) => LPState 2 r -> Line 2 r -> Maybe (Point 2 r) -- | One dimensional linear programming on lines embedded in <math>. -- -- Given an objective vector c, a line l, and a collection of half-lines -- hls that are all sublines of l (i.e. halfspaces *on* l), compute if -- there is a point inside all these halflines. If so, we actually return -- the one that maximizes c. -- -- running time: <math> oneDLinearProgramming :: (Ord r, Num r, Arity d) => Vector d r -> Line d r -> [HalfLine d r] -> Maybe (Point d r) -- | Computes the common intersection of a nonempty list of halfines that -- are all colinear with the given line l. -- -- We return either the two halflines that prove that there is no counter -- example or we return one or two points that form form the boundary -- points of the range in which all halflines intersect. commonIntersection :: (Ord r, Num r, Arity d) => Line d r -> NonEmpty (HalfLine d r :+ a) -> Either (Two (HalfLine d r :+ a)) (OneOrTwo (Point d r :+ a)) -- | Given a vector v and two points a and b, determine which is smaller in -- direction v. cmpHalfPlane :: (Ord r, Num r, Arity d) => Vector d r -> Point d r -> Point d r -> Ordering instance (Data.Geometry.Vector.VectorFamily.Arity d, GHC.Show.Show r) => GHC.Show.Show (Algorithms.Geometry.LinearProgramming.LP2DRIC.LPState d r) instance (Data.Geometry.Vector.VectorFamily.Arity d, GHC.Classes.Eq r, GHC.Real.Fractional r) => GHC.Classes.Eq (Algorithms.Geometry.LinearProgramming.LP2DRIC.LPState d r) -- | A Polygon data type and some basic functions to interact with them. module Data.Geometry.Polygon -- | We distinguish between simple polygons (without holes) and polygons -- with holes. data PolygonType Simple :: PolygonType Multi :: PolygonType -- | Polygons are sequences of points and may or may not contain holes. -- -- Degenerate polygons (polygons with self-intersections or fewer than 3 -- points) are only possible if you use functions marked as unsafe. data Polygon (t :: PolygonType) p r [SimplePolygon] :: Vertices (Point 2 r :+ p) -> SimplePolygon p r [MultiPolygon] :: SimplePolygon p r -> [SimplePolygon p r] -> MultiPolygon p r -- | Prism to test if we are a simple polygon -- --
--   >>> is _SimplePolygon simplePoly
--   True
--   
_SimplePolygon :: Prism' (Polygon Simple p r) (Vertices (Point 2 r :+ p)) -- | Prism to test if we are a Multi polygon -- --
--   >>> is _MultiPolygon multiPoly
--   True
--   
_MultiPolygon :: Prism' (Polygon Multi p r) (Polygon Simple p r, [Polygon Simple p r]) -- | Polygon without holes. type SimplePolygon = Polygon Simple -- | Polygon with zero or more holes. type MultiPolygon = Polygon Multi -- | Either a simple or multipolygon type SomePolygon p r = Either (Polygon Simple p r) (Polygon Multi p r) -- | <math> Creates a polygon from the given list of vertices. -- -- The points are placed in CCW order if they are not already. -- Overlapping edges and repeated vertices are allowed. fromPoints :: forall p r. (Eq r, Num r) => [Point 2 r :+ p] -> SimplePolygon p r -- | <math> Creates a polygon from the given vector of vertices. -- -- The points are placed in CCW order if they are not already. -- Overlapping edges and repeated vertices are allowed. fromCircularVector :: forall p r. (Eq r, Num r) => CircularVector (Point 2 r :+ p) -> SimplePolygon p r -- | <math> Creates a simple polygon from the given list of vertices. -- -- The points are placed in CCW order if they are not already. -- Overlapping edges and repeated vertices are not allowed and -- will trigger an exception. simpleFromPoints :: forall p r. (Ord r, Fractional r) => [Point 2 r :+ p] -> SimplePolygon p r -- | <math> Creates a simple polygon from the given vector of -- vertices. -- -- The points are placed in CCW order if they are not already. -- Overlapping edges and repeated vertices are not allowed and -- will trigger an exception. simpleFromCircularVector :: forall p r. (Ord r, Fractional r) => CircularVector (Point 2 r :+ p) -> SimplePolygon p r -- | <math> Creates a simple polygon from the given list of vertices. -- -- pre: the input list constains no repeated vertices. unsafeFromPoints :: [Point 2 r :+ p] -> SimplePolygon p r -- | <math> Creates a simple polygon from the given vector of -- vertices. -- -- pre: the input list constains no repeated vertices. unsafeFromCircularVector :: CircularVector (Point 2 r :+ p) -> SimplePolygon p r -- | <math> Creates a simple polygon from the given vector of -- vertices. -- -- pre: the input list constains no repeated vertices. unsafeFromVector :: Vector (Point 2 r :+ p) -> SimplePolygon p r -- | <math> Polygon points, from left to right. toVector :: Polygon t p r -> Vector (Point 2 r :+ p) -- | <math> Polygon points, from left to right. toPoints :: Polygon t p r -> [Point 2 r :+ p] -- | <math> Check if a polygon has any holes, duplicate points, or -- self-intersections. isSimple :: (Ord r, Fractional r) => Polygon p t r -> Bool -- | <math> Vertex count. Includes the vertices of holes. size :: Polygon t p r -> Int -- | <math> The vertices in the polygon. No guarantees are given on -- the order in which they appear! polygonVertices :: Polygon t p r -> NonEmpty (Point 2 r :+ p) -- | <math> Lists all edges. The edges on the outer boundary are -- given before the ones on the holes. However, no other guarantees are -- given on the order. listEdges :: Polygon t p r -> [LineSegment 2 p r] -- | <math> Lens access to the outer boundary of a polygon. outerBoundary :: forall t p r. Lens' (Polygon t p r) (SimplePolygon p r) -- | Getter access to the outer boundary vector of a polygon. -- --
--   >>> toList (simpleTriangle ^. outerBoundaryVector)
--   [Point2 0 0 :+ (),Point2 2 0 :+ (),Point2 1 1 :+ ()]
--   
outerBoundaryVector :: forall t p r. Getter (Polygon t p r) (CircularVector (Point 2 r :+ p)) -- | Unsafe lens access to the outer boundary vector of a polygon. -- --
--   >>> toList (simpleTriangle ^. unsafeOuterBoundaryVector)
--   [Point2 0 0 :+ (),Point2 2 0 :+ (),Point2 1 1 :+ ()]
--   
-- --
--   >>> simpleTriangle & unsafeOuterBoundaryVector .~ CV.singleton (Point2 0 0 :+ ())
--   SimplePolygon [Point2 0 0 :+ ()]
--   
unsafeOuterBoundaryVector :: forall t p r. Lens' (Polygon t p r) (CircularVector (Point 2 r :+ p)) -- | <math> The edges along the outer boundary of the polygon. The -- edges are half open. outerBoundaryEdges :: Polygon t p r -> CircularVector (LineSegment 2 p r) -- | O(1) Access the i^th vertex on the outer boundary. Indices are -- modulo <math>. -- --
--   >>> simplePoly ^. outerVertex 0
--   Point2 0 0 :+ ()
--   
outerVertex :: Int -> Getter (Polygon t p r) (Point 2 r :+ p) -- | <math> Get the n^th edge along the outer boundary of the -- polygon. The edge is half open. outerBoundaryEdge :: Int -> Polygon t p r -> LineSegment 2 p r -- | Lens access for polygon holes. -- --
--   >>> multiPoly ^. polygonHoles
--   [SimplePolygon [Point2 0 0 :+ (),Point2 2 0 :+ (),Point2 1 1 :+ ()]]
--   
polygonHoles :: forall p r. Lens' (Polygon Multi p r) [Polygon Simple p r] -- | <math>. Traversal lens for polygon holes. Does nothing for -- simple polygons. polygonHoles' :: Traversal' (Polygon t p r) [Polygon Simple p r] -- | Get all holes in a polygon holeList :: Polygon t p r -> [Polygon Simple p r] -- | Compute the area of a polygon area :: Fractional r => Polygon t p r -> r -- | Compute the signed area of a simple polygon. The the vertices are in -- clockwise order, the signed area will be negative, if the verices are -- given in counter clockwise order, the area will be positive. signedArea :: Fractional r => SimplePolygon p r -> r -- | Compute the centroid of a simple polygon. centroid :: Fractional r => SimplePolygon p r -> Point 2 r -- | Check if a point lies inside a polygon, on the boundary, or outside of -- the polygon. Running time: O(n). -- --
--   >>> Point2 1 1 `inPolygon` simplePoly
--   Inside
--   
--   >>> Point2 0 0 `inPolygon` simplePoly
--   OnBoundary
--   
--   >>> Point2 10 0 `inPolygon` simplePoly
--   OnBoundary
--   
--   >>> Point2 5 13 `inPolygon` simplePoly
--   Inside
--   
--   >>> Point2 5 10 `inPolygon` simplePoly
--   Inside
--   
--   >>> Point2 10 5 `inPolygon` simplePoly
--   OnBoundary
--   
--   >>> Point2 20 5 `inPolygon` simplePoly
--   Outside
--   
-- -- TODO: Add some testcases with multiPolygons TODO: Add some more -- onBoundary testcases inPolygon :: forall t p r. (Fractional r, Ord r) => Point 2 r -> Polygon t p r -> PointLocationResult -- | Test if a point lies strictly inside the polgyon. insidePolygon :: (Fractional r, Ord r) => Point 2 r -> Polygon t p r -> Bool -- | <math> Test if q lies on the boundary of the polygon. -- --
--   >>> Point2 1 1 `onBoundary` simplePoly
--   False
--   
--   >>> Point2 0 0 `onBoundary` simplePoly
--   True
--   
--   >>> Point2 10 0 `onBoundary` simplePoly
--   True
--   
--   >>> Point2 5 13 `onBoundary` simplePoly
--   False
--   
--   >>> Point2 5 10 `onBoundary` simplePoly
--   False
--   
--   >>> Point2 10 5 `onBoundary` simplePoly
--   True
--   
--   >>> Point2 20 5 `onBoundary` simplePoly
--   False
--   
-- -- TODO: testcases multipolygon onBoundary :: (Num r, Ord r) => Point 2 r -> Polygon t p r -> Bool -- | <math> Test if the polygon is a triangle isTriangle :: Polygon p t r -> Bool -- | Test if a Simple polygon is star-shaped. Returns a point in the kernel -- (i.e. from which the entire polygon is visible), if it exists. -- -- <math> expected time isStarShaped :: (MonadRandom m, Ord r, Fractional r) => SimplePolygon p r -> m (Maybe (Point 2 r)) -- | <math> Test if the outer boundary of the polygon is in clockwise -- or counter clockwise order. isCounterClockwise :: (Eq r, Num r) => Polygon t p r -> Bool -- | <math> Make sure that every edge has the polygon's interior on -- its left, by orienting the outer boundary into counter-clockwise -- order, and the inner borders (i.e. any holes, if they exist) into -- clockwise order. toCounterClockWiseOrder :: (Eq r, Num r) => Polygon t p r -> Polygon t p r -- | <math> Orient the outer boundary into counter-clockwise order. -- Leaves any holes as they are. toCounterClockWiseOrder' :: (Eq r, Num r) => Polygon t p r -> Polygon t p r -- | <math> Make sure that every edge has the polygon's interior on -- its right, by orienting the outer boundary into clockwise order, and -- the inner borders (i.e. any holes, if they exist) into -- counter-clockwise order. toClockwiseOrder :: (Eq r, Num r) => Polygon t p r -> Polygon t p r -- | <math> Orient the outer boundary into clockwise order. Leaves -- any holes as they are. toClockwiseOrder' :: (Eq r, Num r) => Polygon t p r -> Polygon t p r -- | Reorient the outer boundary from clockwise order to counter-clockwise -- order or from counter-clockwise order to clockwise order. Leaves any -- holes as they are. reverseOuterBoundary :: Polygon t p r -> Polygon t p r -- | <math> Rotate the polygon to the left by n number of points. rotateLeft :: Int -> SimplePolygon p r -> SimplePolygon p r -- | <math> Rotate the polygon to the right by n number of points. rotateRight :: Int -> SimplePolygon p r -> SimplePolygon p r -- | <math> Yield the maximum point of a polygon according to the -- given comparison function. maximumVertexBy :: ((Point 2 r :+ p) -> (Point 2 r :+ p) -> Ordering) -> Polygon t p r -> Point 2 r :+ p -- | <math> Yield the maximum point of a polygon according to the -- given comparison function. minimumVertexBy :: ((Point 2 r :+ p) -> (Point 2 r :+ p) -> Ordering) -> Polygon t p r -> Point 2 r :+ p -- | <math> Pick a point that is inside the polygon. -- -- (note: if the polygon is degenerate; i.e. has <3 vertices, we -- report a vertex of the polygon instead.) -- -- pre: the polygon is given in CCW order pickPoint :: (Ord r, Fractional r) => Polygon p t r -> Point 2 r -- | <math> Find a diagonal of the polygon. -- -- pre: the polygon is given in CCW order findDiagonal :: (Ord r, Fractional r) => Polygon t p r -> LineSegment 2 p r -- | Pairs every vertex with its incident edges. The first one is its -- predecessor edge, the second one its successor edge (in terms of the -- ordering along the boundary). -- --
--   >>> mapM_ print . polygonVertices $ withIncidentEdges simplePoly
--   Point2 0 0 :+ V2 (ClosedLineSegment (Point2 1 11 :+ ()) (Point2 0 0 :+ ())) (ClosedLineSegment (Point2 0 0 :+ ()) (Point2 10 0 :+ ()))
--   Point2 10 0 :+ V2 (ClosedLineSegment (Point2 0 0 :+ ()) (Point2 10 0 :+ ())) (ClosedLineSegment (Point2 10 0 :+ ()) (Point2 10 10 :+ ()))
--   Point2 10 10 :+ V2 (ClosedLineSegment (Point2 10 0 :+ ()) (Point2 10 10 :+ ())) (ClosedLineSegment (Point2 10 10 :+ ()) (Point2 5 15 :+ ()))
--   Point2 5 15 :+ V2 (ClosedLineSegment (Point2 10 10 :+ ()) (Point2 5 15 :+ ())) (ClosedLineSegment (Point2 5 15 :+ ()) (Point2 1 11 :+ ()))
--   Point2 1 11 :+ V2 (ClosedLineSegment (Point2 5 15 :+ ()) (Point2 1 11 :+ ())) (ClosedLineSegment (Point2 1 11 :+ ()) (Point2 0 0 :+ ()))
--   
withIncidentEdges :: Polygon t p r -> Polygon t (Two (LineSegment 2 p r)) r -- | assigns unique integer numbers to all vertices. Numbers start from 0, -- and are increasing along the outer boundary. The vertices of holes -- will be numbered last, in the same order. -- --
--   >>> numberVertices simplePoly
--   SimplePolygon [Point2 0 0 :+ SP 0 (),Point2 10 0 :+ SP 1 (),Point2 10 10 :+ SP 2 (),Point2 5 15 :+ SP 3 (),Point2 1 11 :+ SP 4 ()]
--   
numberVertices :: Polygon t p r -> Polygon t (SP Int p) r -- | Finds the extreme points, minimum and maximum, in a given direction -- -- running time: <math> extremesLinear :: (Ord r, Num r) => Vector 2 r -> Polygon t p r -> (Point 2 r :+ p, Point 2 r :+ p) -- | Comparison that compares which point is larger in the -- direction given by the vector u. cmpExtreme :: (Num r, Ord r) => Vector 2 r -> (Point 2 r :+ p) -> (Point 2 r :+ q) -> Ordering -- | Rotate to the first point that matches the given condition. -- --
--   >>> toVector <$> findRotateTo (== (Point2 1 0 :+ ())) (unsafeFromPoints [Point2 0 0 :+ (), Point2 1 0 :+ (), Point2 1 1 :+ ()])
--   Just [Point2 1 0 :+ (),Point2 1 1 :+ (),Point2 0 0 :+ ()]
--   
--   >>> findRotateTo (== (Point2 7 0 :+ ())) $ unsafeFromPoints [Point2 0 0 :+ (), Point2 1 0 :+ (), Point2 1 1 :+ ()]
--   Nothing
--   
findRotateTo :: ((Point 2 r :+ p) -> Bool) -> SimplePolygon p r -> Maybe (SimplePolygon p r) instance (GHC.Real.Fractional r, GHC.Classes.Ord r) => Data.Intersection.HasIntersectionWith (Data.Geometry.Point.Internal.Point 2 r) (Data.Geometry.Polygon.Core.Polygon t p r) instance (GHC.Real.Fractional r, GHC.Classes.Ord r) => Data.Intersection.IsIntersectableWith (Data.Geometry.Point.Internal.Point 2 r) (Data.Geometry.Polygon.Core.Polygon t p r) -- | Basic Geometry Types module Data.Geometry -- | Replicate value n times. -- -- Examples: -- --
--   >>> import Data.Vector.Fixed.Boxed (Vec2)
--   
--   >>> replicate 1 :: Vec2 Int
--   fromList [1,1]
--   
-- --
--   >>> replicate 2 :: (Double,Double,Double)
--   (2.0,2.0,2.0)
--   
-- --
--   >>> import Data.Vector.Fixed.Boxed (Vec4)
--   
--   >>> replicate "foo" :: Vec4 String
--   fromList ["foo","foo","foo","foo"]
--   
replicate :: Vector v a => a -> v a -- | Distance between two points in an affine space distanceA :: (Floating a, Foldable (Diff p), Affine p) => p a -> p a -> a -- | Compute the quadrance of the difference (the square of the distance) qdA :: (Affine p, Foldable (Diff p), Num a) => p a -> p a -> a type family Diff (p :: Type -> Type) :: Type -> Type -- | An affine space is roughly a vector space in which we have forgotten -- or at least pretend to have forgotten the origin. -- --
--   a .+^ (b .-. a)  =  b@
--   (a .+^ u) .+^ v  =  a .+^ (u ^+^ v)@
--   (a .-. b) ^+^ v  =  (a .+^ v) .-. q@
--   
class Additive Diff p => Affine (p :: Type -> Type) where { type family Diff (p :: Type -> Type) :: Type -> Type; } -- | Get the difference between two points as a vector offset. (.-.) :: (Affine p, Num a) => p a -> p a -> Diff p a -- | Add a vector offset to a point. (.+^) :: (Affine p, Num a) => p a -> Diff p a -> p a -- | Subtract a vector offset from a point. (.-^) :: (Affine p, Num a) => p a -> Diff p a -> p a infixl 6 .-^ infixl 6 .+^ infixl 6 .-. -- | Convert a non-zero vector to unit vector. signorm :: (Metric f, Floating a) => f a -> f a -- | Compute the norm of a vector in a metric space norm :: (Metric f, Floating a) => f a -> a -- | Compute the inner product of two vectors or (equivalently) convert a -- vector f a into a covector f a -> a. -- --
--   >>> V2 1 2 `dot` V2 3 4
--   11
--   
dot :: (Metric f, Num a) => f a -> f a -> a -- | Compute the squared norm. The name quadrance arises from Norman J. -- Wildberger's rational trigonometry. quadrance :: (Metric f, Num a) => f a -> a -- | Outer (tensor) product of two vectors outer :: (Functor f, Functor g, Num a) => f a -> g a -> f (g a) -- | Create a unit vector. -- --
--   >>> unit _x :: V2 Int
--   V2 1 0
--   
unit :: (Additive t, Num a) => ASetter' (t a) a -> t a -- | Produce a diagonal (scale) matrix from a vector. -- --
--   >>> scaled (V2 2 3)
--   V2 (V2 2 0) (V2 0 3)
--   
scaled :: (Traversable t, Num a) => t a -> t (t a) -- | Produce a default basis for a vector space from which the argument is -- drawn. basisFor :: (Traversable t, Num a) => t b -> [t a] -- | Produce a default basis for a vector space. If the dimensionality of -- the vector space is not statically known, see basisFor. basis :: (Additive t, Traversable t, Num a) => [t a] -- | Compute division by a scalar on the right. (^/) :: (Functor f, Fractional a) => f a -> a -> f a infixl 7 ^/ -- | Compute the right scalar product -- --
--   >>> V2 3 4 ^* 2
--   V2 6 8
--   
(^*) :: (Functor f, Num a) => f a -> a -> f a infixl 7 ^* -- | Compute the left scalar product -- --
--   >>> 2 *^ V2 3 4
--   V2 6 8
--   
(*^) :: (Functor f, Num a) => a -> f a -> f a infixl 7 *^ -- | Sum over multiple vectors -- --
--   >>> sumV [V2 1 1, V2 3 4]
--   V2 4 5
--   
sumV :: (Foldable f, Additive v, Num a) => f (v a) -> v a -- | Compute the negation of a vector -- --
--   >>> negated (V2 2 4)
--   V2 (-2) (-4)
--   
negated :: (Functor f, Num a) => f a -> f a -- | A vector is an additive group with additional structure. class Functor f => Additive (f :: Type -> Type) -- | The zero vector zero :: (Additive f, Num a) => f a -- | Compute the sum of two vectors -- --
--   >>> V2 1 2 ^+^ V2 3 4
--   V2 4 6
--   
(^+^) :: (Additive f, Num a) => f a -> f a -> f a -- | Compute the difference between two vectors -- --
--   >>> V2 4 5 ^-^ V2 3 1
--   V2 1 4
--   
(^-^) :: (Additive f, Num a) => f a -> f a -> f a -- | Linearly interpolate between two vectors. lerp :: (Additive f, Num a) => a -> f a -> f a -> f a -- | Apply a function to merge the 'non-zero' components of two vectors, -- unioning the rest of the values. -- -- liftU2 :: Additive f => (a -> a -> a) -> f a -> f a -> f a -- | Apply a function to the components of two vectors. -- -- liftI2 :: Additive f => (a -> b -> c) -> f a -> f b -> f c infixl 6 ^-^ infixl 6 ^+^ -- | A proxy which can be used for the coordinates. data C (n :: Nat) C :: C (n :: Nat) class (ImplicitArity (Peano d), KnownNat d) => Arity d -- | Datatype representing d dimensional vectors. The default -- implementation is based n VectorFixed. However, for small vectors we -- automatically select a more efficient representation. newtype Vector (d :: Nat) (r :: *) MKVector :: VectorFamily (Peano d) r -> Vector (d :: Nat) (r :: *) [_unV] :: Vector (d :: Nat) (r :: *) -> VectorFamily (Peano d) r -- | Constant sized vector with 4 elements. pattern Vector4 :: r -> r -> r -> r -> Vector 4 r -- | Constant sized vector with 3 elements. pattern Vector3 :: r -> r -> r -> Vector 3 r -- | Constant sized vector with 2 elements. pattern Vector2 :: r -> r -> Vector 2 r -- | Constant sized vector with 1 element. pattern Vector1 :: r -> Vector 1 r -- | Constant sized vector with d elements. pattern Vector :: VectorFamilyF (Peano d) r -> Vector d r -- | Vectors are isomorphic to a definition determined by -- VectorFamily. unV :: Iso (Vector d r) (Vector d s) (VectorFamily (Peano d) r) (VectorFamily (Peano d) s) -- | <math> Convert from a list to a non-empty vector. vectorFromList :: Arity d => [r] -> Maybe (Vector d r) -- | <math> Convert from a list to a non-empty vector. vectorFromListUnsafe :: Arity d => [r] -> Vector d r -- | <math> Pop the first element off a vector. destruct :: (Arity d, Arity (d + 1)) => Vector (d + 1) r -> (r, Vector d r) -- | <math> First element. Since arity is at least 1, this function -- is total. head :: (Arity d, 1 <= d) => Vector d r -> r -- | Lens into the i th element element :: forall proxy i d r. (Arity d, KnownNat i, (i + 1) <= d) => proxy i -> Lens' (Vector d r) r -- | Similar to element above. Except that we don't have a static -- guarantee that the index is in bounds. Hence, we can only return a -- Traversal element' :: forall d r. Arity d => Int -> Traversal' (Vector d r) r -- | <math> Prepend an element. cons :: (Arity d, Arity (d + 1)) => r -> Vector d r -> Vector (d + 1) r -- | Add an element at the back of the vector snoc :: (Arity (d + 1), Arity d) => Vector d r -> r -> Vector (d + 1) r -- | Get a vector of the first d - 1 elements. init :: (Arity d, Arity (d + 1)) => Vector (d + 1) r -> Vector d r -- | Get a prefix of i elements of a vector prefix :: forall i d r. (Arity d, Arity i, i <= d) => Vector d r -> Vector i r -- | Cross product of two three-dimensional vectors cross :: Num r => Vector 3 r -> Vector 3 r -> Vector 3 r -- | 'isScalarmultipleof u v' test if v is a scalar multiple of u. -- --
--   >>> Vector2 1 1 `isScalarMultipleOf` Vector2 10 10
--   True
--   
--   >>> Vector3 1 1 2 `isScalarMultipleOf` Vector3 10 10 20
--   True
--   
--   >>> Vector2 1 1 `isScalarMultipleOf` Vector2 10 1
--   False
--   
--   >>> Vector2 1 1 `isScalarMultipleOf` Vector2 (-1) (-1)
--   True
--   
--   >>> Vector2 1 1 `isScalarMultipleOf` Vector2 11.1 11.1
--   True
--   
--   >>> Vector2 1 1 `isScalarMultipleOf` Vector2 11.1 11.2
--   False
--   
--   >>> Vector2 2 1 `isScalarMultipleOf` Vector2 11.1 11.2
--   False
--   
--   >>> Vector2 2 1 `isScalarMultipleOf` Vector2 4 2
--   True
--   
--   >>> Vector2 2 1 `isScalarMultipleOf` Vector2 4 0
--   False
--   
--   >>> Vector3 2 1 0 `isScalarMultipleOf` Vector3 4 0 5
--   False
--   
--   >>> Vector3 0 0 0 `isScalarMultipleOf` Vector3 4 0 5
--   True
--   
isScalarMultipleOf :: (Eq r, Fractional r, Arity d) => Vector d r -> Vector d r -> Bool -- | scalarMultiple u v computes the scalar labmda s.t. v = lambda * u (if -- it exists) scalarMultiple :: (Eq r, Fractional r, Arity d) => Vector d r -> Vector d r -> Maybe r -- | Given two colinar vectors, u and v, test if they point in the same -- direction, i.e. iff scalarMultiple' u v == Just lambda, with lambda -- > 0 -- -- pre: u and v are colinear, u and v are non-zero sameDirection :: (Eq r, Num r, Arity d) => Vector d r -> Vector d r -> Bool -- | Shorthand to access the first component -- --
--   >>> Vector3 1 2 3 ^. xComponent
--   1
--   
--   >>> Vector2 1 2 & xComponent .~ 10
--   Vector2 10 2
--   
xComponent :: (1 <= d, Arity d) => Lens' (Vector d r) r -- | Shorthand to access the second component -- --
--   >>> Vector3 1 2 3 ^. yComponent
--   2
--   
--   >>> Vector2 1 2 & yComponent .~ 10
--   Vector2 1 10
--   
yComponent :: (2 <= d, Arity d) => Lens' (Vector d r) r -- | Shorthand to access the third component -- --
--   >>> Vector3 1 2 3 ^. zComponent
--   3
--   
--   >>> Vector3 1 2 3 & zComponent .~ 10
--   Vector3 1 2 10
--   
zComponent :: (3 <= d, Arity d) => Lens' (Vector d r) r -- | A Poly line in R^d has at least 2 vertices newtype PolyLine d p r PolyLine :: LSeq 2 (Point d r :+ p) -> PolyLine d p r [_points] :: PolyLine d p r -> LSeq 2 (Point d r :+ p) -- | PolyLines are isomorphic to a sequence of points with at least 2 -- members. points :: Iso (PolyLine d1 p1 r1) (PolyLine d2 p2 r2) (LSeq 2 (Point d1 r1 :+ p1)) (LSeq 2 (Point d2 r2 :+ p2)) -- | pre: The input list contains at least two points fromPointsUnsafe :: [Point d r :+ p] -> PolyLine d p r -- | pre: The input list contains at least two points. All extra vields are -- initialized with mempty. fromPointsUnsafe' :: Monoid p => [Point d r] -> PolyLine d p r -- | We consider the line-segment as closed. fromLineSegment :: LineSegment d p r -> PolyLine d p r -- | Convert to a closed line segment by taking the first two points. asLineSegment :: PolyLine d p r -> LineSegment d p r -- | Stricter version of asLineSegment that fails if the Polyline contains -- more than two points. asLineSegment' :: PolyLine d p r -> Maybe (LineSegment d p r) -- | Computes the edges, as linesegments, of an LSeq edgeSegments :: Arity d => PolyLine d p r -> LSeq 1 (LineSegment d p r) -- | Linearly interpolate the polyline with a value in the range -- <math>, where <math> is the number of vertices of the -- polyline. -- -- running time: <math> -- --
--   >>> interpolatePoly 0.5 myPolyLine
--   Point2 5.0 5.0
--   
--   >>> interpolatePoly 1.5 myPolyLine
--   Point2 10.0 15.0
--   
interpolatePoly :: (RealFrac r, Arity d) => r -> PolyLine d p r -> Point d r -- | Either a simple or multipolygon type SomePolygon p r = Either (Polygon Simple p r) (Polygon Multi p r) -- | Polygon with zero or more holes. type MultiPolygon = Polygon Multi -- | Polygon without holes. type SimplePolygon = Polygon Simple -- | Polygons are sequences of points and may or may not contain holes. -- -- Degenerate polygons (polygons with self-intersections or fewer than 3 -- points) are only possible if you use functions marked as unsafe. data Polygon (t :: PolygonType) p r [SimplePolygon] :: Vertices (Point 2 r :+ p) -> SimplePolygon p r [MultiPolygon] :: SimplePolygon p r -> [SimplePolygon p r] -> MultiPolygon p r -- | We distinguish between simple polygons (without holes) and polygons -- with holes. data PolygonType Simple :: PolygonType Multi :: PolygonType -- | Prism to test if we are a simple polygon -- --
--   >>> is _SimplePolygon simplePoly
--   True
--   
_SimplePolygon :: Prism' (Polygon Simple p r) (Vertices (Point 2 r :+ p)) -- | Prism to test if we are a Multi polygon -- --
--   >>> is _MultiPolygon multiPoly
--   True
--   
_MultiPolygon :: Prism' (Polygon Multi p r) (Polygon Simple p r, [Polygon Simple p r]) -- | Getter access to the outer boundary vector of a polygon. -- --
--   >>> toList (simpleTriangle ^. outerBoundaryVector)
--   [Point2 0 0 :+ (),Point2 2 0 :+ (),Point2 1 1 :+ ()]
--   
outerBoundaryVector :: forall t p r. Getter (Polygon t p r) (CircularVector (Point 2 r :+ p)) -- | Unsafe lens access to the outer boundary vector of a polygon. -- --
--   >>> toList (simpleTriangle ^. unsafeOuterBoundaryVector)
--   [Point2 0 0 :+ (),Point2 2 0 :+ (),Point2 1 1 :+ ()]
--   
-- --
--   >>> simpleTriangle & unsafeOuterBoundaryVector .~ CV.singleton (Point2 0 0 :+ ())
--   SimplePolygon [Point2 0 0 :+ ()]
--   
unsafeOuterBoundaryVector :: forall t p r. Lens' (Polygon t p r) (CircularVector (Point 2 r :+ p)) -- | <math> Lens access to the outer boundary of a polygon. outerBoundary :: forall t p r. Lens' (Polygon t p r) (SimplePolygon p r) -- | Lens access for polygon holes. -- --
--   >>> multiPoly ^. polygonHoles
--   [SimplePolygon [Point2 0 0 :+ (),Point2 2 0 :+ (),Point2 1 1 :+ ()]]
--   
polygonHoles :: forall p r. Lens' (Polygon Multi p r) [Polygon Simple p r] -- | <math>. Traversal lens for polygon holes. Does nothing for -- simple polygons. polygonHoles' :: Traversal' (Polygon t p r) [Polygon Simple p r] -- | O(1) Access the i^th vertex on the outer boundary. Indices are -- modulo <math>. -- --
--   >>> simplePoly ^. outerVertex 0
--   Point2 0 0 :+ ()
--   
outerVertex :: Int -> Getter (Polygon t p r) (Point 2 r :+ p) -- | <math> Get the n^th edge along the outer boundary of the -- polygon. The edge is half open. outerBoundaryEdge :: Int -> Polygon t p r -> LineSegment 2 p r -- | Get all holes in a polygon holeList :: Polygon t p r -> [Polygon Simple p r] -- | <math> Vertex count. Includes the vertices of holes. size :: Polygon t p r -> Int -- | <math> The vertices in the polygon. No guarantees are given on -- the order in which they appear! polygonVertices :: Polygon t p r -> NonEmpty (Point 2 r :+ p) -- | <math> Check if a polygon has any holes, duplicate points, or -- self-intersections. isSimple :: (Ord r, Fractional r) => Polygon p t r -> Bool -- | <math> Creates a polygon from the given vector of vertices. -- -- The points are placed in CCW order if they are not already. -- Overlapping edges and repeated vertices are allowed. fromCircularVector :: forall p r. (Eq r, Num r) => CircularVector (Point 2 r :+ p) -> SimplePolygon p r -- | <math> Creates a simple polygon from the given list of vertices. -- -- The points are placed in CCW order if they are not already. -- Overlapping edges and repeated vertices are not allowed and -- will trigger an exception. simpleFromPoints :: forall p r. (Ord r, Fractional r) => [Point 2 r :+ p] -> SimplePolygon p r -- | <math> Creates a simple polygon from the given vector of -- vertices. -- -- The points are placed in CCW order if they are not already. -- Overlapping edges and repeated vertices are not allowed and -- will trigger an exception. simpleFromCircularVector :: forall p r. (Ord r, Fractional r) => CircularVector (Point 2 r :+ p) -> SimplePolygon p r -- | <math> Creates a simple polygon from the given list of vertices. -- -- pre: the input list constains no repeated vertices. unsafeFromPoints :: [Point 2 r :+ p] -> SimplePolygon p r -- | <math> Creates a simple polygon from the given vector of -- vertices. -- -- pre: the input list constains no repeated vertices. unsafeFromCircularVector :: CircularVector (Point 2 r :+ p) -> SimplePolygon p r -- | <math> Creates a simple polygon from the given vector of -- vertices. -- -- pre: the input list constains no repeated vertices. unsafeFromVector :: Vector (Point 2 r :+ p) -> SimplePolygon p r -- | <math> Polygon points, from left to right. toVector :: Polygon t p r -> Vector (Point 2 r :+ p) -- | <math> Polygon points, from left to right. toPoints :: Polygon t p r -> [Point 2 r :+ p] -- | <math> The edges along the outer boundary of the polygon. The -- edges are half open. outerBoundaryEdges :: Polygon t p r -> CircularVector (LineSegment 2 p r) -- | <math> Lists all edges. The edges on the outer boundary are -- given before the ones on the holes. However, no other guarantees are -- given on the order. listEdges :: Polygon t p r -> [LineSegment 2 p r] -- | Pairs every vertex with its incident edges. The first one is its -- predecessor edge, the second one its successor edge (in terms of the -- ordering along the boundary). -- --
--   >>> mapM_ print . polygonVertices $ withIncidentEdges simplePoly
--   Point2 0 0 :+ V2 (ClosedLineSegment (Point2 1 11 :+ ()) (Point2 0 0 :+ ())) (ClosedLineSegment (Point2 0 0 :+ ()) (Point2 10 0 :+ ()))
--   Point2 10 0 :+ V2 (ClosedLineSegment (Point2 0 0 :+ ()) (Point2 10 0 :+ ())) (ClosedLineSegment (Point2 10 0 :+ ()) (Point2 10 10 :+ ()))
--   Point2 10 10 :+ V2 (ClosedLineSegment (Point2 10 0 :+ ()) (Point2 10 10 :+ ())) (ClosedLineSegment (Point2 10 10 :+ ()) (Point2 5 15 :+ ()))
--   Point2 5 15 :+ V2 (ClosedLineSegment (Point2 10 10 :+ ()) (Point2 5 15 :+ ())) (ClosedLineSegment (Point2 5 15 :+ ()) (Point2 1 11 :+ ()))
--   Point2 1 11 :+ V2 (ClosedLineSegment (Point2 5 15 :+ ()) (Point2 1 11 :+ ())) (ClosedLineSegment (Point2 1 11 :+ ()) (Point2 0 0 :+ ()))
--   
withIncidentEdges :: Polygon t p r -> Polygon t (Two (LineSegment 2 p r)) r -- | Compute the area of a polygon area :: Fractional r => Polygon t p r -> r -- | Compute the signed area of a simple polygon. The the vertices are in -- clockwise order, the signed area will be negative, if the verices are -- given in counter clockwise order, the area will be positive. signedArea :: Fractional r => SimplePolygon p r -> r -- | Compute the centroid of a simple polygon. centroid :: Fractional r => SimplePolygon p r -> Point 2 r -- | <math> Pick a point that is inside the polygon. -- -- (note: if the polygon is degenerate; i.e. has <3 vertices, we -- report a vertex of the polygon instead.) -- -- pre: the polygon is given in CCW order pickPoint :: (Ord r, Fractional r) => Polygon p t r -> Point 2 r -- | <math> Test if the polygon is a triangle isTriangle :: Polygon p t r -> Bool -- | <math> Find a diagonal of the polygon. -- -- pre: the polygon is given in CCW order findDiagonal :: (Ord r, Fractional r) => Polygon t p r -> LineSegment 2 p r -- | <math> Test if the outer boundary of the polygon is in clockwise -- or counter clockwise order. isCounterClockwise :: (Eq r, Num r) => Polygon t p r -> Bool -- | <math> Make sure that every edge has the polygon's interior on -- its right, by orienting the outer boundary into clockwise order, and -- the inner borders (i.e. any holes, if they exist) into -- counter-clockwise order. toClockwiseOrder :: (Eq r, Num r) => Polygon t p r -> Polygon t p r -- | <math> Orient the outer boundary into clockwise order. Leaves -- any holes as they are. toClockwiseOrder' :: (Eq r, Num r) => Polygon t p r -> Polygon t p r -- | <math> Make sure that every edge has the polygon's interior on -- its left, by orienting the outer boundary into counter-clockwise -- order, and the inner borders (i.e. any holes, if they exist) into -- clockwise order. toCounterClockWiseOrder :: (Eq r, Num r) => Polygon t p r -> Polygon t p r -- | <math> Orient the outer boundary into counter-clockwise order. -- Leaves any holes as they are. toCounterClockWiseOrder' :: (Eq r, Num r) => Polygon t p r -> Polygon t p r -- | Reorient the outer boundary from clockwise order to counter-clockwise -- order or from counter-clockwise order to clockwise order. Leaves any -- holes as they are. reverseOuterBoundary :: Polygon t p r -> Polygon t p r -- | assigns unique integer numbers to all vertices. Numbers start from 0, -- and are increasing along the outer boundary. The vertices of holes -- will be numbered last, in the same order. -- --
--   >>> numberVertices simplePoly
--   SimplePolygon [Point2 0 0 :+ SP 0 (),Point2 10 0 :+ SP 1 (),Point2 10 10 :+ SP 2 (),Point2 5 15 :+ SP 3 (),Point2 1 11 :+ SP 4 ()]
--   
numberVertices :: Polygon t p r -> Polygon t (SP Int p) r -- | <math> Yield the maximum point of a polygon according to the -- given comparison function. maximumVertexBy :: ((Point 2 r :+ p) -> (Point 2 r :+ p) -> Ordering) -> Polygon t p r -> Point 2 r :+ p -- | <math> Yield the maximum point of a polygon according to the -- given comparison function. minimumVertexBy :: ((Point 2 r :+ p) -> (Point 2 r :+ p) -> Ordering) -> Polygon t p r -> Point 2 r :+ p -- | Rotate to the first point that matches the given condition. -- --
--   >>> toVector <$> findRotateTo (== (Point2 1 0 :+ ())) (unsafeFromPoints [Point2 0 0 :+ (), Point2 1 0 :+ (), Point2 1 1 :+ ()])
--   Just [Point2 1 0 :+ (),Point2 1 1 :+ (),Point2 0 0 :+ ()]
--   
--   >>> findRotateTo (== (Point2 7 0 :+ ())) $ unsafeFromPoints [Point2 0 0 :+ (), Point2 1 0 :+ (), Point2 1 1 :+ ()]
--   Nothing
--   
findRotateTo :: ((Point 2 r :+ p) -> Bool) -> SimplePolygon p r -> Maybe (SimplePolygon p r) -- | <math> Rotate the polygon to the left by n number of points. rotateLeft :: Int -> SimplePolygon p r -> SimplePolygon p r -- | <math> Rotate the polygon to the right by n number of points. rotateRight :: Int -> SimplePolygon p r -> SimplePolygon p r -- | Comparison that compares which point is larger in the -- direction given by the vector u. cmpExtreme :: (Num r, Ord r) => Vector 2 r -> (Point 2 r :+ p) -> (Point 2 r :+ q) -> Ordering -- | Finds the extreme points, minimum and maximum, in a given direction -- -- running time: <math> extremesLinear :: (Ord r, Num r) => Vector 2 r -> Polygon t p r -> (Point 2 r :+ p, Point 2 r :+ p) -- | <math> Test if q lies on the boundary of the polygon. -- --
--   >>> Point2 1 1 `onBoundary` simplePoly
--   False
--   
--   >>> Point2 0 0 `onBoundary` simplePoly
--   True
--   
--   >>> Point2 10 0 `onBoundary` simplePoly
--   True
--   
--   >>> Point2 5 13 `onBoundary` simplePoly
--   False
--   
--   >>> Point2 5 10 `onBoundary` simplePoly
--   False
--   
--   >>> Point2 10 5 `onBoundary` simplePoly
--   True
--   
--   >>> Point2 20 5 `onBoundary` simplePoly
--   False
--   
-- -- TODO: testcases multipolygon onBoundary :: (Num r, Ord r) => Point 2 r -> Polygon t p r -> Bool -- | Check if a point lies inside a polygon, on the boundary, or outside of -- the polygon. Running time: O(n). -- --
--   >>> Point2 1 1 `inPolygon` simplePoly
--   Inside
--   
--   >>> Point2 0 0 `inPolygon` simplePoly
--   OnBoundary
--   
--   >>> Point2 10 0 `inPolygon` simplePoly
--   OnBoundary
--   
--   >>> Point2 5 13 `inPolygon` simplePoly
--   Inside
--   
--   >>> Point2 5 10 `inPolygon` simplePoly
--   Inside
--   
--   >>> Point2 10 5 `inPolygon` simplePoly
--   OnBoundary
--   
--   >>> Point2 20 5 `inPolygon` simplePoly
--   Outside
--   
-- -- TODO: Add some testcases with multiPolygons TODO: Add some more -- onBoundary testcases inPolygon :: forall t p r. (Fractional r, Ord r) => Point 2 r -> Polygon t p r -> PointLocationResult -- | Test if a point lies strictly inside the polgyon. insidePolygon :: (Fractional r, Ord r) => Point 2 r -> Polygon t p r -> Bool -- | Test if a Simple polygon is star-shaped. Returns a point in the kernel -- (i.e. from which the entire polygon is visible), if it exists. -- -- <math> expected time isStarShaped :: (MonadRandom m, Ord r, Fractional r) => SimplePolygon p r -> m (Maybe (Point 2 r)) -- | Naive implementation to compute the smallest enclosing disk of a set -- of points in <math> module Algorithms.Geometry.SmallestEnclosingBall.Naive -- | Horrible <math> implementation that simply tries all disks, -- checks if they enclose all points, and takes the largest one. -- Basically, this is only useful to check correctness of the other -- algorithm(s) smallestEnclosingDisk :: (Ord r, Fractional r) => [Point 2 r :+ p] -> DiskResult p r -- | check if a disk encloses all points enclosesAll :: (Num r, Ord r) => DiskResult p r -> [Point 2 r :+ q] -> Bool -- | Types to represent the smallest enclosing disk of a set of points in -- <math> module Algorithms.Geometry.SmallestEnclosingBall -- | The result of a smallest enclosing disk computation: The smallest ball -- and the points defining it data DiskResult p r DiskResult :: Disk () r -> TwoOrThree (Point 2 r :+ p) -> DiskResult p r [_enclosingDisk] :: DiskResult p r -> Disk () r [_definingPoints] :: DiskResult p r -> TwoOrThree (Point 2 r :+ p) enclosingDisk :: forall p_a2KVY r_a2KVZ. Lens' (DiskResult p_a2KVY r_a2KVZ) (Disk () r_a2KVZ) definingPoints :: forall p_a2KVY r_a2KVZ p_a2LeK. Lens (DiskResult p_a2KVY r_a2KVZ) (DiskResult p_a2LeK r_a2KVZ) (TwoOrThree ((:+) (Point 2 r_a2KVZ) p_a2KVY)) (TwoOrThree ((:+) (Point 2 r_a2KVZ) p_a2LeK)) -- | List of two or three elements data TwoOrThree a Two :: !a -> !a -> TwoOrThree a Three :: !a -> !a -> !a -> TwoOrThree a -- | Construct datatype from list with exactly two or three elements. twoOrThreeFromList :: [a] -> Either String (TwoOrThree a) -- | An randomized algorithm to compute the smallest enclosing disk of a -- set of <math> points in <math>. The expected running time -- is <math>. module Algorithms.Geometry.SmallestEnclosingBall.RIC -- | Smallest enclosing disk. smallestEnclosingDisk' :: (Ord r, Fractional r) => (Point 2 r :+ p) -> (Point 2 r :+ p) -> [Point 2 r :+ p] -> DiskResult p r -- | Compute the smallest enclosing disk of a set of points, implemented -- using randomized incremental construction. -- -- pre: the input has at least two points. -- -- running time: expected <math> time, where <math> is the -- number of input points. smallestEnclosingDisk :: (Ord r, Fractional r, MonadRandom m) => [Point 2 r :+ p] -> m (DiskResult p r) -- | Smallest enclosing disk, given that p should be on it. smallestEnclosingDiskWithPoint :: (Ord r, Fractional r) => (Point 2 r :+ p) -> NonEmpty (Point 2 r :+ p) -> Maybe (DiskResult p r) -- | Smallest enclosing disk, given that p and q should be on it -- -- running time: <math> smallestEnclosingDiskWithPoints :: (Ord r, Fractional r) => (Point 2 r :+ p) -> (Point 2 r :+ p) -> [Point 2 r :+ p] -> Maybe (DiskResult p r) module Algorithms.Geometry.Diameter.Naive -- | Computes the Euclidean diameter by naively trying all pairs. -- -- running time: <math> diameter :: (Ord r, Floating r, Arity d) => [Point d r :+ p] -> r -- | Computes the Euclidean diametral pair by naively trying all pairs. -- -- running time: <math> diametralPair :: (Ord r, Num r, Arity d) => [Point d r :+ p] -> Maybe (Point d r :+ p, Point d r :+ p) -- | Given a distance function and a list of points pts, computes the -- diametral pair by naively trying all pairs. -- -- running time: <math> diametralPairWith :: Ord r => (Point d r -> Point d r -> r) -> [Point d r :+ p] -> Maybe (Point d r :+ p, Point d r :+ p) -- | <math> time algorithm to compute the visibility polygon of a -- point inside a polygon (possibly containing holes) with <math> -- vertices, or among a set of <math> disjoint segments. The -- alogirhtm used is the the rotational sweepline algorithm by Lee, -- described in: -- -- D. T. Lee. Proximity and reachability in the plane. Report R-831, -- Dept. Elect. Engrg., Univ. Illinois, Urbana, IL, 1978. module Algorithms.Geometry.VisibilityPolygon.Lee -- | Computes the visibility polygon of a point q in a polygon with -- <math> vertices. -- -- pre: q lies strictly inside the polygon -- -- running time: <math> visibilityPolygon :: forall p t r. (Ord r, Fractional r) => Point 2 r -> Polygon t p r -> StarShapedPolygon (Definer p () r) r -- | computes a (partial) visibility polygon of a set of <math> -- disjoint segments. The input segments are allowed to share endpoints, -- but no intersections or no endpoints in the interior of other -- segments. The input vector indicates the starting direction, the Maybe -- point indicates up to which point/dicrection (CCW) of the starting -- vector we should compute the visibility polygon. -- -- pre : - all line segments are considered closed. - no singleton -- linesegments exactly pointing away from q. - for every orientattion -- the visibility is blocked somewhere, i.e. no rays starting in the -- query point q that are disjoint from all segments. - no vertices at -- staring direction sv -- -- running time: <math> visibilitySweep :: forall p r e. (Ord r, Fractional r) => Vector 2 r -> Maybe (Point 2 r) -> Point 2 r -> [LineSegment 2 p r :+ e] -> [Point 2 r :+ Definer p e r] type VisibilityPolygon p e r = StarShapedPolygon (Definer p e r) r -- | Vertices of the visibility polgyon are either original vertices or -- defined by some vertex and an edge type Definer p e r = Either p (Point 2 r :+ p, LineSegment 2 p r :+ e) type StarShapedPolygon p r = SimplePolygon p r -- | Given two segments that share an endpoint, order them by their order -- around this common endpoint. I.e. if uv and uw share endpoint u we uv -- is considered smaller iff v is smaller than w in the counterclockwise -- order around u (treating the direction from q to the common endpoint -- as zero). compareAroundEndPoint :: forall p r e. (Ord r, Fractional r) => Point 2 r -> (LineSegment 2 p r :+ e) -> (LineSegment 2 p r :+ e) -> Ordering instance GHC.Classes.Ord a => GHC.Classes.Ord (Algorithms.Geometry.VisibilityPolygon.Lee.Action a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Algorithms.Geometry.VisibilityPolygon.Lee.Action a) instance GHC.Show.Show a => GHC.Show.Show (Algorithms.Geometry.VisibilityPolygon.Lee.Action a) instance (GHC.Show.Show r, GHC.Show.Show p, GHC.Show.Show e) => GHC.Show.Show (Algorithms.Geometry.VisibilityPolygon.Lee.Event p e r) module Algorithms.Geometry.SSSP.Naive -- | <math> Single-Source Shortest Path. sssp :: (Real r, Fractional r) => SimplePolygon p r -> SSSP -- | <math> Single-Source Shortest Path from all vertices. sssp' :: (Real r, Fractional r) => SimplePolygon p r -> Vector SSSP -- | Ear clipping triangulation algorithms. The baseline algorithm runs in -- <math> but has a low constant factor overhead. The z-order -- hashed variant runs in <math>. -- -- References: -- --
    -- --
  1. https://en.wikipedia.org/wiki/Polygon_triangulation#Ear_clipping_method
  2. --
  3. https://en.wikipedia.org/wiki/Z-order_curve
  4. --
module Algorithms.Geometry.PolygonTriangulation.EarClip -- | <math> -- -- Returns triangular faces using absolute polygon point indices. earClip :: (Num r, Ord r) => SimplePolygon p r -> [(Int, Int, Int)] -- | <math> -- -- Returns triangular faces using absolute polygon point indices. earClipRandom :: (Num r, Ord r) => SimplePolygon p r -> [(Int, Int, Int)] -- | <math> expected time. -- -- Returns triangular faces using absolute polygon point indices. earClipHashed :: Real r => SimplePolygon p r -> [(Int, Int, Int)] -- | <math> expected time. -- -- Returns triangular faces using absolute polygon point indices. earClipRandomHashed :: Real r => SimplePolygon p r -> [(Int, Int, Int)] -- | O(1) Z-Order hash the first half-world of each coordinate. zHash :: V2 Word -> Word -- | O(1) Reverse z-order hash. zUnHash :: Word -> V2 Word module Algorithms.Geometry.LineSegmentIntersection -- | <math> hasInteriorIntersections :: (Ord r, Fractional r) => [LineSegment 2 p r] -> Bool -- | <math> hasSelfIntersections :: (Ord r, Fractional r) => Polygon t p r -> Bool type Intersections p r = Map (Point 2 r) (Associated p r) data Associated p r Associated :: Set' (LineSegment 2 p r) -> Set' (LineSegment 2 p r) -> Associated p r [_endPointOf] :: Associated p r -> Set' (LineSegment 2 p r) [_interiorTo] :: Associated p r -> Set' (LineSegment 2 p r) data IntersectionPoint p r IntersectionPoint :: !Point 2 r -> !Associated p r -> IntersectionPoint p r [_intersectionPoint] :: IntersectionPoint p r -> !Point 2 r [_associatedSegs] :: IntersectionPoint p r -> !Associated p r -- | reports true if there is at least one segment for which this -- intersection point is interior. -- -- <math> isEndPointIntersection :: Associated p r -> Bool associated :: Ord r => [LineSegment 2 p r] -> [LineSegment 2 p r] -> Associated p r type Compare a = a -> a -> Ordering module Algorithms.Geometry.ConvexHull.QuickHull -- | ConvexHull using Quickhull. The resulting polygon is given in -- clockwise order. -- -- running time: <math> convexHull :: (Ord r, Fractional r, Show r, Show p) => NonEmpty (Point 2 r :+ p) -> ConvexPolygon p r module Algorithms.Geometry.ConvexHull.GrahamScan -- | <math> time ConvexHull using Graham-Scan. The resulting polygon -- is given in clockwise order. convexHull :: (Ord r, Num r) => NonEmpty (Point 2 r :+ p) -> ConvexPolygon p r -- | Computes the upper hull. The upper hull is given from left to right. -- -- Specifically. A pair of points defines an edge of the upper hull iff -- all other points are strictly to the right of its supporting line. -- -- Note that this definition implies that the segment may be vertical. -- Use upperHull' if such an edge should not be reported. -- -- running time: <math> upperHull :: (Ord r, Num r) => NonEmpty (Point 2 r :+ p) -> NonEmpty (Point 2 r :+ p) -- | Computes the upper hull, making sure that there are no vertical -- segments. -- -- The upper hull is given from left to right upperHull' :: (Ord r, Num r) => NonEmpty (Point 2 r :+ p) -> NonEmpty (Point 2 r :+ p) -- | Computes the upper hull. The upper hull is given from left to right. -- -- Specifically. A pair of points defines an edge of the lower hull iff -- all other points are strictly to the left of its supporting line. -- -- Note that this definition implies that the segment may be vertical. -- Use lowerHull' if such an edge should not be reported. -- -- running time: <math> lowerHull :: (Ord r, Num r) => NonEmpty (Point 2 r :+ p) -> NonEmpty (Point 2 r :+ p) -- | Computes the lower hull, making sure there are no vertical segments. -- (Note that the only such segment could be the first segment). lowerHull' :: (Ord r, Num r) => NonEmpty (Point 2 r :+ p) -> NonEmpty (Point 2 r :+ p) -- | Given a sequence of points that is sorted on increasing x-coordinate -- and decreasing y-coordinate, computes the upper hull, in *right to -- left order*. -- -- Specifically. A pair of points defines an edge of the upper hull iff -- all other points are strictly to the right of its supporting line. -- -- Note that In constrast to the upperHull function, the result is -- returned *from right to left* !!! -- -- running time: <math>. upperHullFromSorted :: (Ord r, Num r) => NonEmpty (Point 2 r :+ p) -> NonEmpty (Point 2 r :+ p) -- | Computes the upper hull from a sorted input. Removes the last vertical -- segment. -- -- running time: <math>. upperHullFromSorted' :: (Ord r, Num r) => NonEmpty (Point 2 r :+ p) -> NonEmpty (Point 2 r :+ p) module Data.Geometry.BezierSpline -- | Datatype representing a Bezier curve of degree <math> in -- <math>-dimensional space. newtype BezierSpline n d r BezierSpline :: LSeq (1 + n) (Point d r) -> BezierSpline n d r -- | Quadratic Bezier Spline pattern Bezier2 :: Point d r -> Point d r -> Point d r -> BezierSpline 2 d r -- | Cubic Bezier Spline pattern Bezier3 :: Point d r -> Point d r -> Point d r -> Point d r -> BezierSpline 3 d r -- | Bezier control points. With n degrees, there are n+1 control points. controlPoints :: Iso (BezierSpline n1 d1 r1) (BezierSpline n2 d2 r2) (LSeq (1 + n1) (Point d1 r1)) (LSeq (1 + n2) (Point d2 r2)) -- | Constructs the Bezier Spline from a given sequence of points. fromPointSeq :: Seq (Point d r) -> BezierSpline n d r -- | Return the endpoints of the Bezier spline. endPoints :: BezierSpline n d r -> (Point d r, Point d r) -- | Reverse a BezierSpline reverse :: (Arity d, Ord r, Num r) => BezierSpline n d r -> BezierSpline n d r -- | Evaluate a BezierSpline curve at time t in [0, 1] -- -- pre: <math> evaluate :: (Arity d, Eq r, Num r) => BezierSpline n d r -> r -> Point d r -- | Split a Bezier curve at time t in [0, 1] into two pieces. split :: forall n d r. (KnownNat n, Arity d, Ord r, Num r) => r -> BezierSpline n d r -> (BezierSpline n d r, BezierSpline n d r) -- | Split a Bezier curve into many pieces. Todo: filter out duplicate -- parameter values! splitMany :: forall n d r. (KnownNat n, Arity d, Ord r, Fractional r) => [r] -> BezierSpline n d r -> [BezierSpline n d r] -- | Cut a Bezier curve into $x_i$-monotone pieces. Can only be solved -- exactly for degree 4 or smaller. Only gives rational result for degree -- 2 or smaller. Currentlly implemented for degree 3. splitMonotone :: (Arity d, Ord r, Enum r, Floating r) => Int -> BezierSpline 3 d r -> [BezierSpline 3 d r] -- | Subdivide a curve based on a sequence of points. Assumes these points -- are all supposed to lie on the curve, and snaps endpoints of pieces to -- these points. (higher dimensions would work, but depends on convex -- hull) splitByPoints :: (KnownNat n, Ord r, RealFrac r) => r -> [Point 2 r] -> BezierSpline n 2 r -> [BezierSpline n 2 r] -- | Extend a Bezier curve to a parameter value t outside the interval -- [0,1]. For t < 0, returns a Bezier representation of the section of -- the underlying curve from parameter value t until paramater value 0. -- For t > 1, the same from 1 to t. -- -- pre: t outside [0,1] extension :: forall n d r. (KnownNat n, Arity d, Ord r, Num r) => r -> BezierSpline n d r -> BezierSpline n d r -- | Extend a Bezier curve to a parameter value t outside the interval -- [0,1]. For t < 0, returns a Bezier representation of the section of -- the underlying curve from parameter value t until paramater value 1. -- For t > 1, the same from 0 to t. -- -- pre: t outside [0,1] extend :: forall n d r. (KnownNat n, Arity d, Ord r, Num r) => r -> BezierSpline n d r -> BezierSpline n d r -- | Extend a Bezier curve to a point not on the curve, but on / close to -- the extended underlying curve. growTo :: (KnownNat n, Arity d, Ord r, Fractional r) => r -> Point d r -> BezierSpline n d r -> BezierSpline n d r -- | Merge two Bezier pieces. Assumes they can be merged into a single -- piece of the same degree (as would e.g. be the case for the result of -- a split operation). Does not test whether this is the case! merge :: (KnownNat n, Arity d, Ord r, Fractional r) => r -> BezierSpline n d r -> BezierSpline n d r -> BezierSpline n d r -- | Restrict a Bezier curve to the piece between parameters t < u in -- [0, 1]. subBezier :: (KnownNat n, Arity d, Ord r, Num r) => r -> r -> BezierSpline n d r -> BezierSpline n d r -- | Extract a tangent vector from the first to the second control point. tangent :: (Arity d, Num r, 1 <= n) => BezierSpline n d r -> Vector d r -- | Approximate Bezier curve by Polyline with given resolution. That is, -- every point on the approximation will have distance at most res to the -- Bezier curve. approximate :: (KnownNat n, Arity d, Ord r, Fractional r) => r -> BezierSpline n d r -> PolyLine d () r -- | Given a point on (or within distance treshold to) a Bezier curve, -- return the parameter value of some point on the curve within distance -- treshold from p. For points farther than treshold from the curve, the -- function will attempt to return the parameter value of an approximate -- locally closest point to the input point, but no guarantees. parameterOf :: (KnownNat n, Ord r, RealFrac r) => r -> BezierSpline n 2 r -> Point 2 r -> r -- | Snap a point close to a Bezier curve to the curve. snap :: (KnownNat n, Ord r, RealFrac r) => r -> BezierSpline n 2 r -> Point 2 r -> Point 2 r -- | Given two Bezier curves, list all intersection points. Not exact, -- since for degree >= 3 there is no closed form. (In principle, this -- algorithm works in any dimension but this requires convexHull, -- area/volume, and intersect.) intersectB :: (KnownNat n, Ord r, RealFrac r) => r -> BezierSpline n 2 r -> BezierSpline n 2 r -> [Point 2 r] -- | Return True if the curve is definitely completely covered by a line of -- thickness twice the given tolerance. May return false negatives but -- not false positives. colinear :: (Ord r, Fractional r) => r -> BezierSpline 3 2 r -> Bool -- | Convert a quadratic bezier to a cubic bezier. quadToCubic :: Fractional r => BezierSpline 2 2 r -> BezierSpline 3 2 r instance (Data.Geometry.Vector.VectorFamily.Arity d, GHC.Classes.Eq r) => GHC.Classes.Eq (Data.Geometry.BezierSpline.BezierSpline n d r) instance (Data.Geometry.Vector.VectorFamily.Arity n, Data.Geometry.Vector.VectorFamily.Arity d, Test.QuickCheck.Arbitrary.Arbitrary r) => Test.QuickCheck.Arbitrary.Arbitrary (Data.Geometry.BezierSpline.BezierSpline n d r) instance (Data.Geometry.Vector.VectorFamily.Arity d, GHC.Show.Show r) => GHC.Show.Show (Data.Geometry.BezierSpline.BezierSpline n d r) instance Data.Geometry.Vector.VectorFamily.Arity d => GHC.Base.Functor (Data.Geometry.BezierSpline.BezierSpline n d) instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Foldable.Foldable (Data.Geometry.BezierSpline.BezierSpline n d) instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Traversable.Traversable (Data.Geometry.BezierSpline.BezierSpline n d) instance (GHC.Real.Fractional r, Data.Geometry.Vector.VectorFamily.Arity d, Data.Geometry.Vector.VectorFamily.Arity (d GHC.TypeNats.+ 1), Data.Geometry.Vector.VectorFamily.Arity n) => Data.Geometry.Transformation.Internal.IsTransformable (Data.Geometry.BezierSpline.BezierSpline n d r) instance Data.Geometry.Point.Internal.PointFunctor (Data.Geometry.BezierSpline.BezierSpline n d) module Data.Geometry.Polygon.Bezier data PathJoin r JoinLine :: PathJoin r JoinCurve :: Point 2 r -> Point 2 r -> PathJoin r -- | Construct a polygon from a closed set of bezier curves. Each curve -- must be connected to its neighbours. fromBeziers :: (Eq r, Num r) => [BezierSpline 3 2 r] -> SimplePolygon (PathJoin r) r approximate :: forall t r. (Ord r, Fractional r) => r -> Polygon t (PathJoin r) r -> Polygon t () r approximateSome :: (Ord r, Fractional r) => r -> SomePolygon (PathJoin r) r -> SomePolygon () r instance GHC.Classes.Ord r => GHC.Classes.Ord (Data.Geometry.Polygon.Bezier.PathJoin r) instance GHC.Classes.Eq r => GHC.Classes.Eq (Data.Geometry.Polygon.Bezier.PathJoin r) instance GHC.Show.Show r => GHC.Show.Show (Data.Geometry.Polygon.Bezier.PathJoin r) module Algorithms.Geometry.LowerEnvelope.DualCH type Envelope a r = NonEmpty (Line 2 r :+ a) -- | Given a list of non-vertical lines, computes the lower envelope using -- duality. The lines are given in left to right order. -- -- <math> lowerEnvelope :: (Ord r, Fractional r) => NonEmpty (Line 2 r :+ a) -> Envelope a r type UpperHullAlgorithm a r = NonEmpty (Point 2 r :+ a) -> NonEmpty (Point 2 r :+ a) -- | Given a list of non-vertical lines, computes the lower envelope by -- computing the upper convex hull. It uses the given algorithm to do so -- -- running time: O(time required by the given upper hull algorithm) lowerEnvelopeWith :: (Fractional r, Eq r) => UpperHullAlgorithm (Line 2 r :+ a) r -> NonEmpty (Line 2 r :+ a) -> Envelope a r -- | Computes the vertices of the envelope, in left to right order vertices :: (Ord r, Fractional r) => Envelope a r -> [Point 2 r :+ (a, a)] -- | Given two non-parallel lines, compute the intersection point and -- return the pair of a's associated with the lines intersect' :: forall r a. (Ord r, Fractional r) => (Line 2 r :+ a) -> (Line 2 r :+ a) -> Point 2 r :+ (a, a) module Algorithms.Geometry.Diameter.ConvexHull -- | Computes the Euclidean diameter by first finding the convex hull. -- -- running time: <math> diameter :: (Ord r, Floating r) => [Point 2 r :+ p] -> r -- | Computes the Euclidean diameter by first finding the convex hull. -- -- running time: <math> diametralPair :: (Ord r, Num r) => [Point 2 r :+ p] -> Maybe (Point 2 r :+ p, Point 2 r :+ p) module Algorithms.Geometry.Diameter -- | Computes the Euclidean diameter by first finding the convex hull. -- -- running time: <math> diameter :: (Ord r, Floating r) => [Point 2 r :+ p] -> r -- | Computes the Euclidean diameter by first finding the convex hull. -- -- running time: <math> diametralPair :: (Ord r, Num r) => [Point 2 r :+ p] -> Maybe (Point 2 r :+ p, Point 2 r :+ p) module Algorithms.Geometry.ConvexHull -- | <math> time ConvexHull using Graham-Scan. The resulting polygon -- is given in clockwise order. convexHull :: (Ord r, Num r) => NonEmpty (Point 2 r :+ p) -> ConvexPolygon p r -- | <math> time divide and conquer algorithm to compute the convex -- hull of a set of <math> points in <math>. module Algorithms.Geometry.ConvexHull.DivideAndConquer -- | <math> time ConvexHull using divide and conquer. The resulting -- polygon is given in clockwise order. convexHull :: (Ord r, Num r) => NonEmpty (Point 2 r :+ p) -> ConvexPolygon p r -- | <math> time UpperHull using divide and conquer. The resulting -- Hull is given from left to right, i.e. in clockwise order. upperHull :: (Ord r, Num r) => NonEmpty (Point 2 r :+ p) -> NonEmpty (Point 2 r :+ p) -- | <math> time LowerHull using divide and conquer. The resulting -- Hull is given from left to right, i.e. in counter clockwise order. lowerHull :: (Ord r, Num r) => NonEmpty (Point 2 r :+ p) -> NonEmpty (Point 2 r :+ p) instance (GHC.Show.Show r, GHC.Show.Show p) => GHC.Show.Show (Algorithms.Geometry.ConvexHull.DivideAndConquer.LH r p) instance (GHC.Classes.Eq r, GHC.Classes.Eq p) => GHC.Classes.Eq (Algorithms.Geometry.ConvexHull.DivideAndConquer.LH r p) instance (GHC.Num.Num r, GHC.Classes.Ord r) => GHC.Base.Semigroup (Algorithms.Geometry.ConvexHull.DivideAndConquer.UH r p) instance (GHC.Num.Num r, GHC.Classes.Ord r) => GHC.Base.Semigroup (Algorithms.Geometry.ConvexHull.DivideAndConquer.LH r p) -- | Given a set of red points and a set of blue points in <math> -- finds a separating line in <math> expected time, where -- <math> is the total number of points. module Algorithms.Geometry.RedBlueSeparator.RIC -- | Given a set of red points and a set of blue points in <math> -- finds a separating line (if it exists). The result is non-strict in -- the sense that there may be points *on* the line. -- -- running time: <math> expected time, where <math> is the -- total number of points. separatingLine :: (MonadRandom m, Foldable1 f, Foldable1 g, Fractional r, Ord r) => f (Point 2 r :+ redData) -> g (Point 2 r :+ blueData) -> m (Maybe (Line 2 r)) -- | Given a set of red points and a set of blue points in <math> -- finds a separating line (if it exists) that has all red points *right* -- (or on) the line, and all blue points left (or on) the line. -- -- running time: <math> expected time, where <math> is the -- total number of points. separatingLine' :: (MonadRandom m, Foldable1 f, Foldable1 g, Fractional r, Ord r) => f (Point 2 r :+ redData) -> g (Point 2 r :+ blueData) -> m (Maybe (Line 2 r)) -- | given a red and blue point that are *NOT* vertically alligned, and all -- red and all blue points, try to find a non-vertical separating line. -- -- running time: <math> expected time, where <math> is the -- total number of points. separatingLine'' :: (MonadRandom m, Foldable1 f, Foldable1 g, Fractional r, Ord r) => Point 2 r -> Point 2 r -> f (Point 2 r :+ redData) -> g (Point 2 r :+ blueData) -> m (Maybe (Line 2 r)) -- | Computes a strict vertical separating line, if one exists strictVerticalSeparatingLine :: (Foldable1 f, Foldable1 g, Fractional r, Ord r) => f (Point 2 r :+ redData) -> g (Point 2 r :+ blueData) -> Maybe (Line 2 r) -- | Test if there is a vertical separating line that has all red points to -- its right (or on it) and all blue points to its left (or on it). This -- function also returns the two extremal points; in case a line is -- returned, the line actually goes through the blue (second) point, if -- there is no line, this pair provides evidence that there is no -- vertical separating line. -- -- The line we return actually goes through one blue point. verticalSeparatingLine :: (Foldable1 f, Foldable1 g, Num r, Ord r) => f (Point 2 r :+ redData) -> g (Point 2 r :+ blueData) -> SP (Maybe (Line 2 r)) (Point 2 r :+ redData, Point 2 r :+ blueData) -- | Get the the leftmost red point and the rightmost blue point. extremalPoints :: (Foldable1 f, Foldable1 g, Ord r) => f (Point 2 r :+ redData) -> g (Point 2 r :+ blueData) -> (Point 2 r :+ redData, Point 2 r :+ blueData) module Algorithms.Geometry.ConvexHull.Naive type ConvexHull d p r = [Triangle 3 p r] -- | Computes the lower hull without its vertical triangles. -- -- pre: The points are in general position. In particular, no four points -- should be coplanar. -- -- running time: <math> lowerHull' :: forall r p. (Ord r, Fractional r, Show r) => NonEmpty (Point 3 r :+ p) -> ConvexHull 3 p r -- | Generates a set of triangles to be used to construct a complete convex -- hull. In particular, it may contain vertical triangles. -- -- pre: The points are in general position. In particular, no four points -- should be coplanar. -- -- running time: <math> lowerHullAll :: forall r p. (Ord r, Fractional r, Show r) => NonEmpty (Point 3 r :+ p) -> ConvexHull 3 p r -- | Tests if this is a valid triangle for the lower envelope. That is, if -- all point lie above the plane through these points. Returns a Maybe; -- if the result is a Nothing the triangle is valid, if not it returns a -- counter example. -- --
--   >>> let t = (Triangle (ext origin) (ext $ Point3 1 0 0) (ext $ Point3 0 1 0))
--   
--   >>> isValidTriangle t [ext $ Point3 5 5 0]
--   Nothing
--   
--   >>> let t = (Triangle (ext origin) (ext $ Point3 1 0 0) (ext $ Point3 0 1 0))
--   
--   >>> isValidTriangle t [ext $ Point3 5 5 (-10)]
--   Just (Point3 5 5 (-10) :+ ())
--   
isValidTriangle :: (Num r, Ord r) => Triangle 3 p r -> [Point 3 r :+ q] -> Maybe (Point 3 r :+ q) -- | Computes the halfspace above the triangle. -- --
--   >>> upperHalfSpaceOf (Triangle (ext $ origin) (ext $ Point3 10 0 0) (ext $ Point3 0 10 0))
--   HalfSpace {_boundingPlane = HyperPlane {_inPlane = Point3 0 0 0, _normalVec = Vector3 0 0 100}}
--   
upperHalfSpaceOf :: (Ord r, Num r) => Triangle 3 p r -> HalfSpace 3 r module Algorithms.Geometry.ConvexHull.JarvisMarch -- | Compute the convexhull using JarvisMarch. The resulting polygon is -- given in clockwise order. -- -- running time: <math>, where <math> is the number of input -- points and <math> is the complexity of the hull. convexHull :: (Ord r, Num r) => NonEmpty (Point 2 r :+ p) -> ConvexPolygon p r upperHull :: (Num r, Ord r) => NonEmpty (Point 2 r :+ p) -> NonEmpty (Point 2 r :+ p) -- | Upepr hull from left to right, without any vertical segments. upperHull' :: (Num r, Ord r) => NonEmpty (Point 2 r :+ p) -> NonEmpty (Point 2 r :+ p) -- | Computes the lower hull, from left to right. Includes vertical -- segments at the start. -- -- running time: <math>, where <math> is the complexity of -- the hull. lowerHull :: (Num r, Ord r) => NonEmpty (Point 2 r :+ p) -> NonEmpty (Point 2 r :+ p) -- | Jarvis March to compute the lower hull, without any vertical segments. -- -- running time: <math>, where <math> is the complexity of -- the hull. lowerHull' :: (Num r, Ord r) => NonEmpty (Point 2 r :+ p) -> NonEmpty (Point 2 r :+ p) -- | Find the next point in counter clockwise order, i.e. the point with -- minimum slope w.r.t. the given point. steepestCcwFrom :: (Ord r, Num r) => (Point 2 r :+ a) -> NonEmpty (Point 2 r :+ b) -> Point 2 r :+ b -- | Find the next point in clockwise order, i.e. the point with maximum -- slope w.r.t. the given point. steepestCwFrom :: (Ord r, Num r) => (Point 2 r :+ a) -> NonEmpty (Point 2 r :+ b) -> Point 2 r :+ b -- | Naive O(n^2)) time algorithm to compute the closest pair of points -- among <math> points in <math>. module Algorithms.Geometry.ClosestPair.Naive -- | Naive algorithm to compute the closest pair according to the (squared) -- Euclidean distance in <math> dimensions. Note that we need at -- least two elements for there to be a closest pair. -- -- running time: <math> time. closestPair :: (Ord r, Arity d, Num r) => LSeq 2 (Point d r :+ p) -> Two (Point d r :+ p) -- | Naive algorithm to compute the closest pair of points (and the -- distance realized by those points) given a distance function. Note -- that we need at least two elements for there to be a closest pair. -- -- running time: <math>, where <math> is the time required to -- evaluate the distance between two points in <math>. closestPairWith :: Ord r => DistanceFunction (Point d r :+ p) -> LSeq 2 (Point d r :+ p) -> SP (Two (Point d r :+ p)) r type DistanceFunction g = g -> g -> NumType g module Data.Geometry.VerticalRayShooting.PersistentSweep -- | The vertical ray shooting data structure data VerticalRayShootingStructure p e r VerticalRayShootingStructure :: r -> Vector (r :+ StatusStructure p e r) -> VerticalRayShootingStructure p e r type StatusStructure p e r = Set (LineSegment 2 p r :+ e) leftMost :: forall p_a2XeU e_a2XeV r_a2XeW. Getter (VerticalRayShootingStructure p_a2XeU e_a2XeV r_a2XeW) r_a2XeW sweepStruct :: forall p_a2XeU e_a2XeV r_a2XeW. Getter (VerticalRayShootingStructure p_a2XeU e_a2XeV r_a2XeW) (Vector ((:+) r_a2XeW (StatusStructure p_a2XeU e_a2XeV r_a2XeW))) -- | Given a set of <math> interiorly pairwise disjoint *closed* -- segments, compute a vertical ray shooting data structure. (i.e. the -- endpoints of the segments may coincide). -- -- pre: no vertical segments -- -- running time: <math>. space: <math>. verticalRayShootingStructure :: (Ord r, Fractional r, Foldable1 t) => t (LineSegment 2 p r :+ e) -> VerticalRayShootingStructure p e r -- | Find the segment vertically strictly above query point q, if it -- exists. -- -- <math> segmentAbove :: (Ord r, Num r) => Point 2 r -> VerticalRayShootingStructure p e r -> Maybe (LineSegment 2 p r :+ e) -- | Find the segment vertically query point q, if it exists. -- -- <math> segmentAboveOrOn :: (Ord r, Num r) => Point 2 r -> VerticalRayShootingStructure p e r -> Maybe (LineSegment 2 p r :+ e) -- | Given a query point, find the (data structure of the) slab containing -- the query point -- -- <math> findSlab :: Ord r => Point 2 r -> VerticalRayShootingStructure p e r -> Maybe (StatusStructure p e r) -- | Finds the first segment strictly above q -- -- <math> lookupAbove :: (Ord r, Num r) => Point 2 r -> StatusStructure p e r -> Maybe (LineSegment 2 p r :+ e) -- | Finds the segment containing or above the query point q -- -- <math> lookupAboveOrOn :: (Ord r, Num r) => Point 2 r -> StatusStructure p e r -> Maybe (LineSegment 2 p r :+ e) -- | generic searching function searchInSlab :: Num r => (Line 2 r -> Bool) -> StatusStructure p e r -> Maybe (LineSegment 2 p r :+ e) -- | Compare based on the y-coordinate of the intersection with the -- horizontal line through y ordAt :: (Fractional r, Ord r) => r -> Compare (LineSegment 2 p r :+ e) -- | Given an x-coordinate and a line segment that intersects the vertical -- line through x, compute the y-coordinate of this intersection point. -- -- note that we will pretend that the line segment is closed, even if it -- is not yCoordAt :: (Fractional r, Ord r) => r -> (LineSegment 2 p r :+ e) -> r instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Geometry.VerticalRayShooting.PersistentSweep.Action a) instance GHC.Show.Show a => GHC.Show.Show (Data.Geometry.VerticalRayShooting.PersistentSweep.Action a) instance (GHC.Classes.Eq r, GHC.Classes.Eq p, GHC.Classes.Eq e) => GHC.Classes.Eq (Data.Geometry.VerticalRayShooting.PersistentSweep.VerticalRayShootingStructure p e r) instance (GHC.Show.Show r, GHC.Show.Show p, GHC.Show.Show e) => GHC.Show.Show (Data.Geometry.VerticalRayShooting.PersistentSweep.VerticalRayShootingStructure p e r) module Data.Geometry.VerticalRayShooting -- | Data types that help encodedecode a planegraph as a JSONYAML -- file. module Data.PlaneGraph.AdjRep -- | Data type representing the graph in its JSON/Yaml format data Gr v f Gr :: [v] -> [f] -> Gr v f [adjacencies] :: Gr v f -> [v] [faces] :: Gr v f -> [f] -- | A vertex, represented by an id, location, its adjacencies, and its -- data. data Vtx v e r Vtx :: Int -> Point 2 r -> [(Int, e)] -> v -> Vtx v e r [id] :: Vtx v e r -> Int [loc] :: Vtx v e r -> Point 2 r -- | adjacent vertices + data on the edge. Adjacencies are given in -- arbitrary order [adj] :: Vtx v e r -> [(Int, e)] [vData] :: Vtx v e r -> v -- | Faces data Face f Face :: (Int, Int) -> f -> Face f -- | an edge (u,v) s.t. the face is right from (u,v) [incidentEdge] :: Face f -> (Int, Int) [fData] :: Face f -> f instance GHC.Base.Functor (Data.PlaneGraph.AdjRep.Vtx v e) instance (GHC.Classes.Eq r, GHC.Classes.Eq e, GHC.Classes.Eq v) => GHC.Classes.Eq (Data.PlaneGraph.AdjRep.Vtx v e r) instance (GHC.Show.Show r, GHC.Show.Show e, GHC.Show.Show v) => GHC.Show.Show (Data.PlaneGraph.AdjRep.Vtx v e r) instance GHC.Generics.Generic (Data.PlaneGraph.AdjRep.Vtx v e r) instance (Data.Aeson.Types.ToJSON.ToJSON r, Data.Aeson.Types.ToJSON.ToJSON v, Data.Aeson.Types.ToJSON.ToJSON e) => Data.Aeson.Types.ToJSON.ToJSON (Data.PlaneGraph.AdjRep.Vtx v e r) instance (Data.Aeson.Types.FromJSON.FromJSON r, Data.Aeson.Types.FromJSON.FromJSON v, Data.Aeson.Types.FromJSON.FromJSON e) => Data.Aeson.Types.FromJSON.FromJSON (Data.PlaneGraph.AdjRep.Vtx v e r) -- | Data types that help encodedecode a planegraph as a JSONYAML -- file. module Data.Geometry.PlanarSubdivision.TreeRep -- | Specify the planar subdivison as a tree of components data PlanarSD v e f r PlanarSD :: f -> InnerSD v e f r -> PlanarSD v e f r -- | outer face [outerFace] :: PlanarSD v e f r -> f [inner] :: PlanarSD v e f r -> InnerSD v e f r -- | A vertex, represented by an id, location, its adjacencies, and its -- data. data Vtx v e r Vtx :: Int -> Point 2 r -> [(Int, e)] -> v -> Vtx v e r [id] :: Vtx v e r -> Int [loc] :: Vtx v e r -> Point 2 r -- | adjacent vertices + data on the edge. Adjacencies are given in -- arbitrary order [adj] :: Vtx v e r -> [(Int, e)] [vData] :: Vtx v e r -> v -- | This represents the following Planar subdivision. Note that the graph -- is undirected, the arrows are just to indicate what the Positive -- direction of the darts is. -- myTreeRep :: PlanarSD Int () String (RealNumber 3) instance GHC.Generics.Generic (Data.Geometry.PlanarSubdivision.TreeRep.InnerSD v e f r) instance GHC.Base.Functor (Data.Geometry.PlanarSubdivision.TreeRep.InnerSD v e f) instance (GHC.Classes.Eq r, GHC.Classes.Eq e, GHC.Classes.Eq v, GHC.Classes.Eq f) => GHC.Classes.Eq (Data.Geometry.PlanarSubdivision.TreeRep.InnerSD v e f r) instance (GHC.Show.Show r, GHC.Show.Show e, GHC.Show.Show v, GHC.Show.Show f) => GHC.Show.Show (Data.Geometry.PlanarSubdivision.TreeRep.InnerSD v e f r) instance GHC.Generics.Generic (Data.Geometry.PlanarSubdivision.TreeRep.PlanarSD v e f r) instance GHC.Base.Functor (Data.Geometry.PlanarSubdivision.TreeRep.PlanarSD v e f) instance (GHC.Classes.Eq f, GHC.Classes.Eq r, GHC.Classes.Eq e, GHC.Classes.Eq v) => GHC.Classes.Eq (Data.Geometry.PlanarSubdivision.TreeRep.PlanarSD v e f r) instance (GHC.Show.Show f, GHC.Show.Show r, GHC.Show.Show e, GHC.Show.Show v) => GHC.Show.Show (Data.Geometry.PlanarSubdivision.TreeRep.PlanarSD v e f r) instance (Data.Aeson.Types.ToJSON.ToJSON r, Data.Aeson.Types.ToJSON.ToJSON v, Data.Aeson.Types.ToJSON.ToJSON e, Data.Aeson.Types.ToJSON.ToJSON f) => Data.Aeson.Types.ToJSON.ToJSON (Data.Geometry.PlanarSubdivision.TreeRep.PlanarSD v e f r) instance (Data.Aeson.Types.FromJSON.FromJSON r, Data.Aeson.Types.FromJSON.FromJSON v, Data.Aeson.Types.FromJSON.FromJSON e, Data.Aeson.Types.FromJSON.FromJSON f) => Data.Aeson.Types.FromJSON.FromJSON (Data.Geometry.PlanarSubdivision.TreeRep.PlanarSD v e f r) instance (Data.Aeson.Types.ToJSON.ToJSON r, Data.Aeson.Types.ToJSON.ToJSON v, Data.Aeson.Types.ToJSON.ToJSON e, Data.Aeson.Types.ToJSON.ToJSON f) => Data.Aeson.Types.ToJSON.ToJSON (Data.Geometry.PlanarSubdivision.TreeRep.InnerSD v e r f) instance (Data.Aeson.Types.FromJSON.FromJSON r, Data.Aeson.Types.FromJSON.FromJSON v, Data.Aeson.Types.FromJSON.FromJSON e, Data.Aeson.Types.FromJSON.FromJSON f) => Data.Aeson.Types.FromJSON.FromJSON (Data.Geometry.PlanarSubdivision.TreeRep.InnerSD v e r f) -- | Data type for planar graphs embedded in <math>. For functions -- that export faces and edges etc, we assume the graph has a (planar) -- straight line embedding. module Data.PlaneGraph.Core -- | Embedded, *connected*, planar graph newtype PlaneGraph s v e f r PlaneGraph :: PlanarGraph s Primal (VertexData r v) e f -> PlaneGraph s v e f r graph :: forall k_a380a (s_a37Zo :: k_a380a) v_a37Zp e_a37Zq f_a37Zr r_a37Zs k_a38as (s_a38an :: k_a38as) v_a38ao e_a38ap f_a38aq r_a38ar. Iso (PlaneGraph (s_a37Zo :: k_a380a) v_a37Zp e_a37Zq f_a37Zr r_a37Zs) (PlaneGraph (s_a38an :: k_a38as) v_a38ao e_a38ap f_a38aq r_a38ar) (PlanarGraph s_a37Zo 'Primal (VertexData r_a37Zs v_a37Zp) e_a37Zq f_a37Zr) (PlanarGraph s_a38an 'Primal (VertexData r_a38ar v_a38ao) e_a38ap f_a38aq) -- | A *connected* Planar graph with bidirected edges. I.e. the edges -- (darts) are directed, however, for every directed edge, the edge in -- the oposite direction is also in the graph. -- -- The types v, e, and f are the are the types of the data associated -- with the vertices, edges, and faces, respectively. -- -- The orbits in the embedding are assumed to be in counterclockwise -- order. Therefore, every dart directly bounds the face to its right. data PlanarGraph (s :: k) (w :: World) v e f -- | Note that the functor instance is in v data VertexData r v VertexData :: !Point 2 r -> !v -> VertexData r v vData :: forall r_a37Ku v_a37Kv v_a37Z9. Lens (VertexData r_a37Ku v_a37Kv) (VertexData r_a37Ku v_a37Z9) v_a37Kv v_a37Z9 location :: forall r_a37Ku v_a37Kv r_a37Z8. Lens (VertexData r_a37Ku v_a37Kv) (VertexData r_a37Z8 v_a37Kv) (Point 2 r_a37Ku) (Point 2 r_a37Z8) -- | Convert to an Ext vtxDataToExt :: VertexData r v -> Point 2 r :+ v -- | Construct a plane graph from a simple polygon. It is assumed that the -- polygon is given in counterclockwise order. -- -- the interior of the polygon will have faceId 0 -- -- pre: the input polygon is given in counterclockwise order running -- time: <math>. fromSimplePolygon :: proxy s -> SimplePolygon p r -> f -> f -> PlaneGraph s p () f r -- | Constructs a connected plane graph -- -- pre: The segments form a single connected component -- -- running time: <math> fromConnectedSegments :: (Foldable f, Ord r, Num r) => proxy s -> f (LineSegment 2 p r :+ e) -> PlaneGraph s (NonEmpty p) e () r -- | Construct a planar graph from a adjacency matrix. For every vertex, -- all vertices should be given in counter-clockwise order. -- -- pre: No self-loops, and no multi-edges -- -- running time: <math>. fromAdjacencyLists :: forall k (s :: k) (w :: World) h. (Foldable h, Functor h) => [(VertexId s w, h (VertexId s w))] -> PlanarGraph s w () () () -- | Get the number of vertices -- --
--   >>> numVertices smallG
--   4
--   
--   >>> numVertices myPlaneGraph
--   15
--   
numVertices :: PlaneGraph s v e f r -> Int -- | Get the number of Edges -- --
--   >>> numEdges smallG
--   5
--   
numEdges :: PlaneGraph s v e f r -> Int -- | Get the number of faces -- --
--   >>> numFaces smallG
--   3
--   
--   >>> numFaces myPlaneGraph
--   7
--   
numFaces :: PlaneGraph s v e f r -> Int -- | Get the number of Darts -- --
--   >>> numDarts smallG
--   10
--   
numDarts :: PlaneGraph s v e f r -> Int -- | Get the dual graph of this graph. dual :: forall k (s :: k) (w :: World) v e f. Getter (PlanarGraph s w v e f) (PlanarGraph s (DualOf w) f e v) -- | Enumerate all vertices -- --
--   >>> vertices' smallG
--   [VertexId 0,VertexId 1,VertexId 2,VertexId 3]
--   
vertices' :: PlaneGraph s v e f r -> Vector (VertexId' s) -- | Enumerate all vertices, together with their vertex data -- --
--   >>> mapM_ print $ vertices smallG
--   (VertexId 0,VertexData {_location = Point2 0 0, _vData = 0})
--   (VertexId 1,VertexData {_location = Point2 2 2, _vData = 1})
--   (VertexId 2,VertexData {_location = Point2 2 0, _vData = 2})
--   (VertexId 3,VertexData {_location = Point2 (-1) 4, _vData = 3})
--   
vertices :: PlaneGraph s v e f r -> Vector (VertexId' s, VertexData r v) -- | Enumerate all edges. We report only the Positive darts edges' :: PlaneGraph s v e f r -> Vector (Dart s) -- | Enumerate all edges with their edge data. We report only the Positive -- darts. -- --
--   >>> mapM_ print $ edges smallG
--   (Dart (Arc 0) +1,"0->2")
--   (Dart (Arc 1) +1,"0->1")
--   (Dart (Arc 2) +1,"0->3")
--   (Dart (Arc 4) +1,"1->2")
--   (Dart (Arc 3) +1,"1->3")
--   
edges :: PlaneGraph s v e f r -> Vector (Dart s, e) -- | Enumerate all faces in the plane graph faces' :: PlaneGraph s v e f r -> Vector (FaceId' s) -- | face Ids of all internal faces in the plane graph -- -- running time: <math> internalFaces' :: (Ord r, Fractional r) => PlaneGraph s v e f r -> Vector (FaceId' s) -- | All faces with their face data. -- --
--   >>> mapM_ print $ faces smallG
--   (FaceId 0,"OuterFace")
--   (FaceId 1,"A")
--   (FaceId 2,"B")
--   
--   >>> mapM_ print $ faces myPlaneGraph
--   (FaceId 0,"OuterFace")
--   (FaceId 1,"A")
--   (FaceId 2,"B")
--   (FaceId 3,"C")
--   (FaceId 4,"E")
--   (FaceId 5,"F")
--   (FaceId 6,"D")
--   
faces :: PlaneGraph s v e f r -> Vector (FaceId' s, f) -- | Reports all internal faces. running time: <math> internalFaces :: (Ord r, Fractional r) => PlaneGraph s v e f r -> Vector (FaceId' s, f) -- | Reports the outerface and all internal faces separately. running time: -- <math> faces'' :: (Ord r, Fractional r) => PlaneGraph s v e f r -> ((FaceId' s, f), Vector (FaceId' s, f)) -- | Enumerate all darts darts' :: PlaneGraph s v e f r -> Vector (Dart s) -- | Get all darts together with their data darts :: PlaneGraph s v e f r -> Vector (Dart s, e) -- | Traverse the vertices -- -- (^.vertexData) $ traverseVertices (i x -> Just (i,x)) smallG -- Just [(VertexId 0,0),(VertexId 1,1),(VertexId 2,2),(VertexId 3,3)] -- >>> traverseVertices (i x -> print (i,x)) smallG >> -- pure () (VertexId 0,0) (VertexId 1,1) (VertexId 2,2) (VertexId 3,3) traverseVertices :: Applicative m => (VertexId' s -> v -> m v') -> PlaneGraph s v e f r -> m (PlaneGraph s v' e f r) -- | Traverses the darts -- --
--   >>> traverseDarts (\d x -> print (d,x)) smallG >> pure ()
--   (Dart (Arc 0) +1,"0->2")
--   (Dart (Arc 0) -1,"2->0")
--   (Dart (Arc 1) +1,"0->1")
--   (Dart (Arc 1) -1,"1->0")
--   (Dart (Arc 2) +1,"0->3")
--   (Dart (Arc 2) -1,"3->0")
--   (Dart (Arc 3) +1,"1->3")
--   (Dart (Arc 3) -1,"3->1")
--   (Dart (Arc 4) +1,"1->2")
--   (Dart (Arc 4) -1,"2->1")
--   
traverseDarts :: Applicative m => (Dart s -> e -> m e') -> PlaneGraph s v e f r -> m (PlaneGraph s v e' f r) -- | Traverses the faces -- --
--   >>> traverseFaces (\i x -> print (i,x)) smallG >> pure ()
--   (FaceId 0,"OuterFace")
--   (FaceId 1,"A")
--   (FaceId 2,"B")
--   
traverseFaces :: Applicative m => (FaceId' s -> f -> m f') -> PlaneGraph s v e f r -> m (PlaneGraph s v e f' r) -- | The vertex this dart is heading in to -- -- running time: <math> -- --
--   >>> headOf (dart 0 "+1") smallG
--   VertexId 2
--   
headOf :: Dart s -> PlaneGraph s v e f r -> VertexId' s -- | The tail of a dart, i.e. the vertex this dart is leaving from -- -- running time: <math> -- --
--   >>> tailOf (dart 0 "+1") smallG
--   VertexId 0
--   
tailOf :: Dart s -> PlaneGraph s v e f r -> VertexId' s -- | Get the twin of this dart (edge) -- --
--   >>> twin (dart 0 "+1")
--   Dart (Arc 0) -1
--   
--   >>> twin (dart 0 "-1")
--   Dart (Arc 0) +1
--   
twin :: forall k (s :: k). Dart s -> Dart s -- | endPoints d g = (tailOf d g, headOf d g) -- -- running time: <math> -- --
--   >>> endPoints (dart 0 "+1") smallG
--   (VertexId 0,VertexId 2)
--   
endPoints :: Dart s -> PlaneGraph s v e f r -> (VertexId' s, VertexId' s) -- | All edges incident to vertex v, in counterclockwise order around v. -- -- running time: <math>, where <math> is the output size -- --
--   >>> incidentEdges (VertexId 1) smallG
--   [Dart (Arc 1) -1,Dart (Arc 4) +1,Dart (Arc 3) +1]
--   
--   >>> mapM_ print $ incidentEdges (VertexId 5) myPlaneGraph
--   Dart (Arc 1) -1
--   Dart (Arc 7) +1
--   Dart (Arc 10) +1
--   Dart (Arc 4) -1
--   
incidentEdges :: VertexId' s -> PlaneGraph s v e f r -> Vector (Dart s) -- | All edges incident to vertex v in incoming direction (i.e. pointing -- into v) in counterclockwise order around v. -- -- running time: <math>, where (k) is the total number of incident -- edges of v -- --
--   >>> incomingEdges (VertexId 1) smallG
--   [Dart (Arc 1) +1,Dart (Arc 4) -1,Dart (Arc 3) -1]
--   
incomingEdges :: VertexId' s -> PlaneGraph s v e f r -> Vector (Dart s) -- | All edges incident to vertex v in incoming direction (i.e. pointing -- into v) in counterclockwise order around v. -- -- running time: <math>, where (k) is the total number of incident -- edges of v -- --
--   >>> outgoingEdges (VertexId 1) smallG
--   [Dart (Arc 1) -1,Dart (Arc 4) +1,Dart (Arc 3) +1]
--   
outgoingEdges :: VertexId' s -> PlaneGraph s v e f r -> Vector (Dart s) -- | Gets the neighbours of a particular vertex, in counterclockwise order -- around the vertex. -- -- running time: <math>, where <math> is the output size -- --
--   >>> neighboursOf (VertexId 1) smallG
--   [VertexId 0,VertexId 2,VertexId 3]
--   
--   >>> neighboursOf (VertexId 5) myPlaneGraph
--   [VertexId 0,VertexId 6,VertexId 8,VertexId 1]
--   
neighboursOf :: VertexId' s -> PlaneGraph s v e f r -> Vector (VertexId' s) -- | Given a dart d that points into some vertex v, report the next dart in -- the cyclic (counterclockwise) order around v. -- -- running time: <math> -- --
--   >>> nextIncidentEdge (dart 1 "+1") smallG
--   Dart (Arc 4) +1
--   
--   >>> nextIncidentEdge (dart 1 "+1") myPlaneGraph
--   Dart (Arc 7) +1
--   
--   >>> nextIncidentEdge (dart 17 "-1") myPlaneGraph
--   Dart (Arc 15) -1
--   
nextIncidentEdge :: Dart s -> PlaneGraph s v e f r -> Dart s -- | Given a dart d that points into some vertex v, report the previous -- dart in the cyclic (counterclockwise) order around v. -- -- running time: <math> -- --
--   >>> prevIncidentEdge (dart 1 "+1") smallG
--   Dart (Arc 3) +1
--   
--   >>> prevIncidentEdge (dart 1 "+1") myPlaneGraph
--   Dart (Arc 4) -1
--   
--   >>> prevIncidentEdge (dart 7 "-1") myPlaneGraph
--   Dart (Arc 1) -1
--   
prevIncidentEdge :: Dart s -> PlaneGraph s v e f r -> Dart s -- | Given a dart d that points away from some vertex v, report the next -- dart in the cyclic (counterclockwise) order around v. -- -- running time: <math> -- --
--   >>> nextIncidentEdgeFrom (dart 1 "+1") smallG
--   Dart (Arc 2) +1
--   
--   >>> nextIncidentEdgeFrom (dart 1 "+1") myPlaneGraph
--   Dart (Arc 2) +1
--   
--   >>> nextIncidentEdgeFrom (dart 4 "+1") myPlaneGraph
--   Dart (Arc 15) +1
--   
nextIncidentEdgeFrom :: Dart s -> PlaneGraph s v e f r -> Dart s -- | Given a dart d that points into away from vertex v, report the -- previous dart in the cyclic (counterclockwise) order around v. -- -- running time: <math> -- --
--   >>> prevIncidentEdgeFrom (dart 1 "+1") smallG
--   Dart (Arc 0) +1
--   
--   >>> prevIncidentEdgeFrom (dart 4 "+1") myPlaneGraph
--   Dart (Arc 2) -1
--   
prevIncidentEdgeFrom :: Dart s -> PlaneGraph s v e f r -> Dart s -- | The face to the left of the dart -- -- running time: <math>. -- --
--   >>> leftFace (dart 1 "+1") smallG
--   FaceId 2
--   
--   >>> leftFace (dart 1 "-1") smallG
--   FaceId 1
--   
--   >>> leftFace (dart 2 "+1") smallG
--   FaceId 0
--   
--   >>> leftFace (dart 2 "-1") smallG
--   FaceId 2
--   
leftFace :: Dart s -> PlaneGraph s v e f r -> FaceId' s -- | The face to the right of the dart -- -- running time: <math>. -- --
--   >>> rightFace (dart 1 "+1") smallG
--   FaceId 1
--   
--   >>> rightFace (dart 1 "-1") smallG
--   FaceId 2
--   
--   >>> rightFace (dart 2 "+1") smallG
--   FaceId 2
--   
--   >>> rightFace (dart 2 "-1") smallG
--   FaceId 0
--   
rightFace :: Dart s -> PlaneGraph s v e f r -> FaceId' s -- | Get the next edge along the face -- -- running time: <math>. -- --
--   >>> nextEdge (dart 1 "+1") smallG
--   Dart (Arc 4) +1
--   
nextEdge :: Dart s -> PlaneGraph s v e f r -> Dart s -- | Get the previous edge along the face -- -- running time: <math>. -- --
--   >>> prevEdge (dart 1 "+1") smallG
--   Dart (Arc 0) -1
--   
prevEdge :: Dart s -> PlaneGraph s v e f r -> Dart s -- | The darts bounding this face. The darts are reported in order along -- the face. This means that for internal faces the darts are reported in -- *clockwise* order along the boundary, whereas for the outer face the -- darts are reported in counter clockwise order. -- -- running time: <math>, where <math> is the output size. -- --
--   >>> boundary (FaceId $ VertexId 2) smallG -- around face B
--   [Dart (Arc 2) +1,Dart (Arc 3) -1,Dart (Arc 1) -1]
--   
--   >>> boundary (FaceId $ VertexId 0) smallG -- around outer face
--   [Dart (Arc 0) +1,Dart (Arc 4) -1,Dart (Arc 3) +1,Dart (Arc 2) -1]
--   
boundary :: FaceId' s -> PlaneGraph s v e f r -> Vector (Dart s) -- | Given a dart d, generates the darts bounding the face that is to the -- right of the given dart. The darts are reported in order along the -- face. This means that for internal faces the darts are reported in -- *clockwise* order along the boundary, whereas for the outer face the -- darts are reported in counter clockwise order. -- -- running time: <math>, where <math> is the number of darts -- reported -- --
--   >>> boundary' (dart 2 "+1") smallG -- around face B
--   [Dart (Arc 2) +1,Dart (Arc 3) -1,Dart (Arc 1) -1]
--   
--   >>> boundary' (dart 0 "+1") smallG -- around outer face
--   [Dart (Arc 0) +1,Dart (Arc 4) -1,Dart (Arc 3) +1,Dart (Arc 2) -1]
--   
boundary' :: Dart s -> PlaneGraph s v e f r -> Vector (Dart s) -- | Gets a dart bounding this face. I.e. a dart d such that the face lies -- to the right of the dart. boundaryDart :: FaceId' s -> PlaneGraph s v e f r -> Dart s -- | The vertices bounding this face, for internal faces in clockwise -- order, for the outer face in counter clockwise order. -- -- running time: <math>, where <math> is the output size. -- --
--   >>> boundaryVertices (FaceId $ VertexId 2) smallG -- around B
--   [VertexId 0,VertexId 3,VertexId 1]
--   
--   >>> boundaryVertices (FaceId $ VertexId 0) smallG -- around outerface
--   [VertexId 0,VertexId 2,VertexId 1,VertexId 3]
--   
--   >>> mapM_ print $ boundaryVertices (FaceId $ VertexId 0) myPlaneGraph
--   VertexId 0
--   VertexId 9
--   VertexId 10
--   VertexId 11
--   VertexId 7
--   VertexId 8
--   VertexId 12
--   VertexId 13
--   VertexId 4
--   VertexId 3
--   VertexId 2
--   
boundaryVertices :: FaceId' s -> PlaneGraph s v e f r -> Vector (VertexId' s) -- | gets the id of the outer face -- -- running time: <math> outerFaceId :: (Ord r, Fractional r) => PlaneGraph s v e f r -> FaceId' s -- | gets a dart incident to the outer face (in particular, that has the -- outerface on its left) -- -- running time: <math> outerFaceDart :: (Ord r, Fractional r) => PlaneGraph s v e f r -> Dart s -- | Lens to access the vertex data -- -- Note that using the setting part of this lens may be very expensive!! -- (O(n)) vertexDataOf :: VertexId' s -> Lens' (PlaneGraph s v e f r) (VertexData r v) -- | Get the location of a vertex in the plane graph -- -- Note that the setting part of this lens may be very expensive! -- Moreover, use with care (as this may destroy planarity etc.) locationOf :: VertexId' s -> Lens' (PlaneGraph s v e f r) (Point 2 r) -- | General interface to accessing vertex data, dart data, and face data. class HasDataOf g i where { type family DataOf g i; } -- | get the data associated with the value i. -- -- running time: <math> to read the data, <math> to write it. dataOf :: HasDataOf g i => i -> Lens' g (DataOf g i) -- | Getter for the data at the endpoints of a dart -- -- running time: <math> endPointsOf :: Dart s -> Getter (PlaneGraph s v e f r) (VertexData r v, VertexData r v) -- | Data corresponding to the endpoints of the dart -- -- running time: <math> endPointData :: Dart s -> PlaneGraph s v e f r -> (VertexData r v, VertexData r v) vertexData :: Lens (PlaneGraph s v e f r) (PlaneGraph s v' e f r) (Vector v) (Vector v') -- | Lens to access face data faceData :: Lens (PlaneGraph s v e f r) (PlaneGraph s v e f' r) (Vector f) (Vector f') -- | lens to access the Dart Data dartData :: Lens (PlaneGraph s v e f r) (PlaneGraph s v e' f r) (Vector (Dart s, e)) (Vector (Dart s, e')) -- | Lens to access the raw dart data, use at your own risk rawDartData :: Lens (PlaneGraph s v e f r) (PlaneGraph s v e' f r) (Vector e) (Vector e') -- | Given a dart and the graph constructs the line segment representing -- the dart. The segment <math> is has <math> as its tail and -- <math> as its head. -- -- <math> edgeSegment :: Dart s -> PlaneGraph s v e f r -> LineSegment 2 v r :+ e -- | Reports all edges as line segments -- --
--   >>> mapM_ print $ edgeSegments smallG
--   (Dart (Arc 0) +1,ClosedLineSegment (Point2 0 0 :+ 0) (Point2 2 0 :+ 2) :+ "0->2")
--   (Dart (Arc 1) +1,ClosedLineSegment (Point2 0 0 :+ 0) (Point2 2 2 :+ 1) :+ "0->1")
--   (Dart (Arc 2) +1,ClosedLineSegment (Point2 0 0 :+ 0) (Point2 (-1) 4 :+ 3) :+ "0->3")
--   (Dart (Arc 4) +1,ClosedLineSegment (Point2 2 2 :+ 1) (Point2 2 0 :+ 2) :+ "1->2")
--   (Dart (Arc 3) +1,ClosedLineSegment (Point2 2 2 :+ 1) (Point2 (-1) 4 :+ 3) :+ "1->3")
--   
--   >>> mapM_ print $ edgeSegments myPlaneGraph
--   (Dart (Arc 0) +1,ClosedLineSegment (Point2 0 0 :+ 0) (Point2 8 (-5) :+ 9) :+ ())
--   (Dart (Arc 1) +1,ClosedLineSegment (Point2 0 0 :+ 0) (Point2 8 1 :+ 5) :+ ())
--   (Dart (Arc 2) +1,ClosedLineSegment (Point2 0 0 :+ 0) (Point2 4 4 :+ 1) :+ ())
--   (Dart (Arc 3) +1,ClosedLineSegment (Point2 0 0 :+ 0) (Point2 3 7 :+ 2) :+ ())
--   (Dart (Arc 4) +1,ClosedLineSegment (Point2 4 4 :+ 1) (Point2 8 1 :+ 5) :+ ())
--   (Dart (Arc 15) +1,ClosedLineSegment (Point2 4 4 :+ 1) (Point2 10 4 :+ 12) :+ ())
--   (Dart (Arc 5) +1,ClosedLineSegment (Point2 3 7 :+ 2) (Point2 0 5 :+ 3) :+ ())
--   (Dart (Arc 6) +1,ClosedLineSegment (Point2 0 5 :+ 3) (Point2 3 8 :+ 4) :+ ())
--   (Dart (Arc 18) +1,ClosedLineSegment (Point2 3 8 :+ 4) (Point2 9 6 :+ 13) :+ ())
--   (Dart (Arc 7) +1,ClosedLineSegment (Point2 8 1 :+ 5) (Point2 6 (-1) :+ 6) :+ ())
--   (Dart (Arc 10) +1,ClosedLineSegment (Point2 8 1 :+ 5) (Point2 12 1 :+ 8) :+ ())
--   (Dart (Arc 12) +1,ClosedLineSegment (Point2 6 (-1) :+ 6) (Point2 8 (-5) :+ 9) :+ ())
--   (Dart (Arc 8) +1,ClosedLineSegment (Point2 9 (-1) :+ 7) (Point2 12 1 :+ 8) :+ ())
--   (Dart (Arc 14) +1,ClosedLineSegment (Point2 9 (-1) :+ 7) (Point2 14 (-1) :+ 11) :+ ())
--   (Dart (Arc 9) +1,ClosedLineSegment (Point2 12 1 :+ 8) (Point2 10 4 :+ 12) :+ ())
--   (Dart (Arc 11) +1,ClosedLineSegment (Point2 8 (-5) :+ 9) (Point2 12 (-3) :+ 10) :+ ())
--   (Dart (Arc 13) +1,ClosedLineSegment (Point2 12 (-3) :+ 10) (Point2 14 (-1) :+ 11) :+ ())
--   (Dart (Arc 16) +1,ClosedLineSegment (Point2 10 4 :+ 12) (Point2 9 6 :+ 13) :+ ())
--   (Dart (Arc 17) +1,ClosedLineSegment (Point2 10 4 :+ 12) (Point2 8 5 :+ 14) :+ ())
--   (Dart (Arc 19) +1,ClosedLineSegment (Point2 9 6 :+ 13) (Point2 8 5 :+ 14) :+ ())
--   
edgeSegments :: PlaneGraph s v e f r -> Vector (Dart s, LineSegment 2 v r :+ e) -- | The boundary of the face as a simple polygon. For internal faces the -- polygon that is reported has its vertices stored in CCW order (as -- expected). -- -- pre: FaceId refers to an internal face. -- -- For the other face this prodcuces a polygon in CW order (this may lead -- to unexpected results.) -- -- runningtime: <math>, where <math> is the size of the face. faceBoundary :: FaceId' s -> PlaneGraph s v e f r -> SimplePolygon v r :+ f -- | The boundary of the face as a simple polygon. For internal faces the -- polygon that is reported has its vertices stored in CCW order (as -- expected). -- -- pre: FaceId refers to an internal face. -- -- For the other face this prodcuces a polygon in CW order (this may lead -- to unexpected results.) -- -- runningtime: <math>, where <math> is the size of the face. internalFacePolygon :: FaceId' s -> PlaneGraph s v e f r -> SimplePolygon v r :+ f -- | Given the outerFaceId and the graph, construct a sufficiently large -- rectangular multipolygon ith a hole containing the boundary of the -- outer face. outerFacePolygon :: (Num r, Ord r) => FaceId' s -> PlaneGraph s v e f r -> MultiPolygon (Maybe v) r :+ f -- | Given the outerface id, and a sufficiently large outer boundary, draw -- the outerface as a polygon with a hole. outerFacePolygon' :: FaceId' s -> SimplePolygon v' r -> PlaneGraph s v e f r -> MultiPolygon (Either v' v) r :+ f -- | Given the outerFace Id, construct polygons for all faces. We construct -- a polygon with a hole for the outer face. facePolygons :: (Num r, Ord r) => FaceId' s -> PlaneGraph s v e f r -> ((FaceId' s, MultiPolygon (Maybe v) r :+ f), Vector (FaceId' s, SimplePolygon v r :+ f)) -- | Given the outerFace Id, lists all internal faces of the plane graph -- with their boundaries. facePolygons' :: FaceId' s -> PlaneGraph s v e f r -> Vector (FaceId' s, SimplePolygon v r :+ f) -- | lists all internal faces of the plane graph with their boundaries. internalFacePolygons :: (Ord r, Fractional r) => PlaneGraph s v e f r -> Vector (FaceId' s, SimplePolygon v r :+ f) -- | A vertex in a planar graph. A vertex is tied to a particular planar -- graph by the phantom type s, and to a particular world w. newtype VertexId (s :: k) (w :: World) VertexId :: Int -> VertexId (s :: k) (w :: World) [_unVertexId] :: VertexId (s :: k) (w :: World) -> Int -- | The type to represent FaceId's newtype FaceId (s :: k) (w :: World) FaceId :: VertexId s (DualOf w) -> FaceId (s :: k) (w :: World) [_unFaceId] :: FaceId (s :: k) (w :: World) -> VertexId s (DualOf w) -- | A dart represents a bi-directed edge. I.e. a dart has a direction, -- however the dart of the oposite direction is always present in the -- planar graph as well. data Dart (s :: k) -- | The world in which the graph lives data World Primal :: World Dual :: World -- | Shorthand for vertices in the primal. type VertexId' (s :: k) = VertexId s 'Primal -- | Shorthand for FaceId's in the primal. type FaceId' (s :: k) = FaceId s 'Primal -- | Labels the edges of a plane graph with their distances, as specified -- by the distance function. withEdgeDistances :: (Point 2 r -> Point 2 r -> a) -> PlaneGraph s p e f r -> PlaneGraph s p (a :+ e) f r instance forall k (s :: k) v e f. GHC.Base.Functor (Data.PlaneGraph.Core.PlaneGraph s v e f) instance forall k (s :: k) v e f r. Data.Geometry.Box.Internal.IsBoxable (Data.PlaneGraph.Core.PlaneGraph s v e f r) instance forall k (s :: k) v e f r. Data.PlanarGraph.Core.HasDataOf (Data.PlaneGraph.Core.PlaneGraph s v e f r) (Data.PlanarGraph.Core.VertexId' s) instance forall k (s :: k) v e f r. Data.PlanarGraph.Core.HasDataOf (Data.PlaneGraph.Core.PlaneGraph s v e f r) (Data.PlanarGraph.Dart.Dart s) instance forall k (s :: k) v e f r. Data.PlanarGraph.Core.HasDataOf (Data.PlaneGraph.Core.PlaneGraph s v e f r) (Data.PlanarGraph.Core.FaceId' s) instance forall k (s :: k) v e f r. GHC.Generics.Generic (Data.PlaneGraph.Core.PlaneGraph s v e f r) instance forall k (s :: k) v e f r. (GHC.Classes.Eq r, GHC.Classes.Eq v, GHC.Classes.Eq e, GHC.Classes.Eq f) => GHC.Classes.Eq (Data.PlaneGraph.Core.PlaneGraph s v e f r) instance forall k (s :: k) v e f r. (GHC.Show.Show r, GHC.Show.Show v, GHC.Show.Show e, GHC.Show.Show f) => GHC.Show.Show (Data.PlaneGraph.Core.PlaneGraph s v e f r) instance Data.Bifunctor.Bifunctor Data.PlaneGraph.Core.VertexData instance (Data.Aeson.Types.FromJSON.FromJSON r, Data.Aeson.Types.FromJSON.FromJSON v) => Data.Aeson.Types.FromJSON.FromJSON (Data.PlaneGraph.Core.VertexData r v) instance (Data.Aeson.Types.ToJSON.ToJSON r, Data.Aeson.Types.ToJSON.ToJSON v) => Data.Aeson.Types.ToJSON.ToJSON (Data.PlaneGraph.Core.VertexData r v) instance Data.Traversable.Traversable (Data.PlaneGraph.Core.VertexData r) instance Data.Foldable.Foldable (Data.PlaneGraph.Core.VertexData r) instance GHC.Base.Functor (Data.PlaneGraph.Core.VertexData r) instance GHC.Generics.Generic (Data.PlaneGraph.Core.VertexData r v) instance (GHC.Classes.Ord r, GHC.Classes.Ord v) => GHC.Classes.Ord (Data.PlaneGraph.Core.VertexData r v) instance (GHC.Classes.Eq r, GHC.Classes.Eq v) => GHC.Classes.Eq (Data.PlaneGraph.Core.VertexData r v) instance (GHC.Show.Show r, GHC.Show.Show v) => GHC.Show.Show (Data.PlaneGraph.Core.VertexData r v) -- | Converting from/to Adjacency Representation of the plane graph module Data.PlaneGraph.IO -- | Reads a plane graph from a bytestring readPlaneGraph :: forall s v e f r. (FromJSON v, FromJSON e, FromJSON f, FromJSON r) => ByteString -> Either ParseException (PlaneGraph s v e f r) -- | Writes a plane graph to a bytestring writePlaneGraph :: (ToJSON v, ToJSON e, ToJSON f, ToJSON r) => PlaneGraph s v e f r -> ByteString -- | Transforms the plane graph into adjacency lists. For every vertex, the -- adjacent vertices are given in counter clockwise order. -- -- See toAdjacencyLists for notes on how we handle self-loops. -- -- running time: <math> toAdjRep :: PlaneGraph s v e f r -> Gr (Vtx v e r) (Face f) -- | Given the AdjacencyList representation of a plane graph, construct the -- plane graph representing it. All the adjacencylists should be in -- counter clockwise order. -- -- running time: <math> fromAdjRep :: proxy s -> Gr (Vtx v e r) (Face f) -> PlaneGraph s v e f r -- | Orders the adjacencylists of a plane graph (with <math> -- vertices) (in Adj repr) so that they are all counter-clockwise around -- the vertices. -- -- running time: <math> makeCCW :: (Num r, Ord r) => Gr (Vtx v e r) f -> Gr (Vtx v e r) f data MyWorld myPlaneGraph :: PlaneGraph MyWorld Int () String (RealNumber 5) myPlaneGraphAdjrep :: Gr (Vtx Int () (RealNumber 5)) (Face String) instance forall k v e f r (s :: k). (Data.Aeson.Types.ToJSON.ToJSON v, Data.Aeson.Types.ToJSON.ToJSON e, Data.Aeson.Types.ToJSON.ToJSON f, Data.Aeson.Types.ToJSON.ToJSON r) => Data.Aeson.Types.ToJSON.ToJSON (Data.PlaneGraph.Core.PlaneGraph s v e f r) instance forall k v e f r (s :: k). (Data.Aeson.Types.FromJSON.FromJSON v, Data.Aeson.Types.FromJSON.FromJSON e, Data.Aeson.Types.FromJSON.FromJSON f, Data.Aeson.Types.FromJSON.FromJSON r) => Data.Aeson.Types.FromJSON.FromJSON (Data.PlaneGraph.Core.PlaneGraph s v e f r) -- | Data type for planar graphs embedded in <math>. For functions -- that export faces and edges etc, we assume the graph has a (planar) -- straight line embedding. module Data.PlaneGraph -- | Embedded, *connected*, planar graph newtype PlaneGraph s v e f r PlaneGraph :: PlanarGraph s Primal (VertexData r v) e f -> PlaneGraph s v e f r graph :: forall k_a380a (s_a37Zo :: k_a380a) v_a37Zp e_a37Zq f_a37Zr r_a37Zs k_a38as (s_a38an :: k_a38as) v_a38ao e_a38ap f_a38aq r_a38ar. Iso (PlaneGraph (s_a37Zo :: k_a380a) v_a37Zp e_a37Zq f_a37Zr r_a37Zs) (PlaneGraph (s_a38an :: k_a38as) v_a38ao e_a38ap f_a38aq r_a38ar) (PlanarGraph s_a37Zo 'Primal (VertexData r_a37Zs v_a37Zp) e_a37Zq f_a37Zr) (PlanarGraph s_a38an 'Primal (VertexData r_a38ar v_a38ao) e_a38ap f_a38aq) -- | A *connected* Planar graph with bidirected edges. I.e. the edges -- (darts) are directed, however, for every directed edge, the edge in -- the oposite direction is also in the graph. -- -- The types v, e, and f are the are the types of the data associated -- with the vertices, edges, and faces, respectively. -- -- The orbits in the embedding are assumed to be in counterclockwise -- order. Therefore, every dart directly bounds the face to its right. data PlanarGraph (s :: k) (w :: World) v e f -- | Note that the functor instance is in v data VertexData r v VertexData :: !Point 2 r -> !v -> VertexData r v vData :: forall r_a37Ku v_a37Kv v_a37Z9. Lens (VertexData r_a37Ku v_a37Kv) (VertexData r_a37Ku v_a37Z9) v_a37Kv v_a37Z9 location :: forall r_a37Ku v_a37Kv r_a37Z8. Lens (VertexData r_a37Ku v_a37Kv) (VertexData r_a37Z8 v_a37Kv) (Point 2 r_a37Ku) (Point 2 r_a37Z8) -- | Convert to an Ext vtxDataToExt :: VertexData r v -> Point 2 r :+ v -- | Construct a plane graph from a simple polygon. It is assumed that the -- polygon is given in counterclockwise order. -- -- the interior of the polygon will have faceId 0 -- -- pre: the input polygon is given in counterclockwise order running -- time: <math>. fromSimplePolygon :: proxy s -> SimplePolygon p r -> f -> f -> PlaneGraph s p () f r -- | Constructs a connected plane graph -- -- pre: The segments form a single connected component -- -- running time: <math> fromConnectedSegments :: (Foldable f, Ord r, Num r) => proxy s -> f (LineSegment 2 p r :+ e) -> PlaneGraph s (NonEmpty p) e () r -- | Transforms the plane graph into adjacency lists. For every vertex, the -- adjacent vertices are given in counter clockwise order. -- -- See toAdjacencyLists for notes on how we handle self-loops. -- -- running time: <math> toAdjRep :: PlaneGraph s v e f r -> Gr (Vtx v e r) (Face f) -- | Given the AdjacencyList representation of a plane graph, construct the -- plane graph representing it. All the adjacencylists should be in -- counter clockwise order. -- -- running time: <math> fromAdjRep :: proxy s -> Gr (Vtx v e r) (Face f) -> PlaneGraph s v e f r -- | Get the number of vertices -- --
--   >>> numVertices smallG
--   4
--   
--   >>> numVertices myPlaneGraph
--   15
--   
numVertices :: PlaneGraph s v e f r -> Int -- | Get the number of Edges -- --
--   >>> numEdges smallG
--   5
--   
numEdges :: PlaneGraph s v e f r -> Int -- | Get the number of faces -- --
--   >>> numFaces smallG
--   3
--   
--   >>> numFaces myPlaneGraph
--   7
--   
numFaces :: PlaneGraph s v e f r -> Int -- | Get the number of Darts -- --
--   >>> numDarts smallG
--   10
--   
numDarts :: PlaneGraph s v e f r -> Int -- | Get the dual graph of this graph. dual :: forall k (s :: k) (w :: World) v e f. Getter (PlanarGraph s w v e f) (PlanarGraph s (DualOf w) f e v) -- | Enumerate all vertices -- --
--   >>> vertices' smallG
--   [VertexId 0,VertexId 1,VertexId 2,VertexId 3]
--   
vertices' :: PlaneGraph s v e f r -> Vector (VertexId' s) -- | Enumerate all vertices, together with their vertex data -- --
--   >>> mapM_ print $ vertices smallG
--   (VertexId 0,VertexData {_location = Point2 0 0, _vData = 0})
--   (VertexId 1,VertexData {_location = Point2 2 2, _vData = 1})
--   (VertexId 2,VertexData {_location = Point2 2 0, _vData = 2})
--   (VertexId 3,VertexData {_location = Point2 (-1) 4, _vData = 3})
--   
vertices :: PlaneGraph s v e f r -> Vector (VertexId' s, VertexData r v) -- | Enumerate all edges. We report only the Positive darts edges' :: PlaneGraph s v e f r -> Vector (Dart s) -- | Enumerate all edges with their edge data. We report only the Positive -- darts. -- --
--   >>> mapM_ print $ edges smallG
--   (Dart (Arc 0) +1,"0->2")
--   (Dart (Arc 1) +1,"0->1")
--   (Dart (Arc 2) +1,"0->3")
--   (Dart (Arc 4) +1,"1->2")
--   (Dart (Arc 3) +1,"1->3")
--   
edges :: PlaneGraph s v e f r -> Vector (Dart s, e) -- | Enumerate all faces in the plane graph faces' :: PlaneGraph s v e f r -> Vector (FaceId' s) -- | All faces with their face data. -- --
--   >>> mapM_ print $ faces smallG
--   (FaceId 0,"OuterFace")
--   (FaceId 1,"A")
--   (FaceId 2,"B")
--   
--   >>> mapM_ print $ faces myPlaneGraph
--   (FaceId 0,"OuterFace")
--   (FaceId 1,"A")
--   (FaceId 2,"B")
--   (FaceId 3,"C")
--   (FaceId 4,"E")
--   (FaceId 5,"F")
--   (FaceId 6,"D")
--   
faces :: PlaneGraph s v e f r -> Vector (FaceId' s, f) -- | Reports all internal faces. running time: <math> internalFaces :: (Ord r, Fractional r) => PlaneGraph s v e f r -> Vector (FaceId' s, f) -- | Reports the outerface and all internal faces separately. running time: -- <math> faces'' :: (Ord r, Fractional r) => PlaneGraph s v e f r -> ((FaceId' s, f), Vector (FaceId' s, f)) -- | Enumerate all darts darts' :: PlaneGraph s v e f r -> Vector (Dart s) -- | Get all darts together with their data darts :: PlaneGraph s v e f r -> Vector (Dart s, e) -- | Traverse the vertices -- -- (^.vertexData) $ traverseVertices (i x -> Just (i,x)) smallG -- Just [(VertexId 0,0),(VertexId 1,1),(VertexId 2,2),(VertexId 3,3)] -- >>> traverseVertices (i x -> print (i,x)) smallG >> -- pure () (VertexId 0,0) (VertexId 1,1) (VertexId 2,2) (VertexId 3,3) traverseVertices :: Applicative m => (VertexId' s -> v -> m v') -> PlaneGraph s v e f r -> m (PlaneGraph s v' e f r) -- | Traverses the darts -- --
--   >>> traverseDarts (\d x -> print (d,x)) smallG >> pure ()
--   (Dart (Arc 0) +1,"0->2")
--   (Dart (Arc 0) -1,"2->0")
--   (Dart (Arc 1) +1,"0->1")
--   (Dart (Arc 1) -1,"1->0")
--   (Dart (Arc 2) +1,"0->3")
--   (Dart (Arc 2) -1,"3->0")
--   (Dart (Arc 3) +1,"1->3")
--   (Dart (Arc 3) -1,"3->1")
--   (Dart (Arc 4) +1,"1->2")
--   (Dart (Arc 4) -1,"2->1")
--   
traverseDarts :: Applicative m => (Dart s -> e -> m e') -> PlaneGraph s v e f r -> m (PlaneGraph s v e' f r) -- | Traverses the faces -- --
--   >>> traverseFaces (\i x -> print (i,x)) smallG >> pure ()
--   (FaceId 0,"OuterFace")
--   (FaceId 1,"A")
--   (FaceId 2,"B")
--   
traverseFaces :: Applicative m => (FaceId' s -> f -> m f') -> PlaneGraph s v e f r -> m (PlaneGraph s v e f' r) -- | The vertex this dart is heading in to -- -- running time: <math> -- --
--   >>> headOf (dart 0 "+1") smallG
--   VertexId 2
--   
headOf :: Dart s -> PlaneGraph s v e f r -> VertexId' s -- | The tail of a dart, i.e. the vertex this dart is leaving from -- -- running time: <math> -- --
--   >>> tailOf (dart 0 "+1") smallG
--   VertexId 0
--   
tailOf :: Dart s -> PlaneGraph s v e f r -> VertexId' s -- | Get the twin of this dart (edge) -- --
--   >>> twin (dart 0 "+1")
--   Dart (Arc 0) -1
--   
--   >>> twin (dart 0 "-1")
--   Dart (Arc 0) +1
--   
twin :: forall k (s :: k). Dart s -> Dart s -- | endPoints d g = (tailOf d g, headOf d g) -- -- running time: <math> -- --
--   >>> endPoints (dart 0 "+1") smallG
--   (VertexId 0,VertexId 2)
--   
endPoints :: Dart s -> PlaneGraph s v e f r -> (VertexId' s, VertexId' s) -- | All edges incident to vertex v, in counterclockwise order around v. -- -- running time: <math>, where <math> is the output size -- --
--   >>> incidentEdges (VertexId 1) smallG
--   [Dart (Arc 1) -1,Dart (Arc 4) +1,Dart (Arc 3) +1]
--   
--   >>> mapM_ print $ incidentEdges (VertexId 5) myPlaneGraph
--   Dart (Arc 1) -1
--   Dart (Arc 7) +1
--   Dart (Arc 10) +1
--   Dart (Arc 4) -1
--   
incidentEdges :: VertexId' s -> PlaneGraph s v e f r -> Vector (Dart s) -- | All edges incident to vertex v in incoming direction (i.e. pointing -- into v) in counterclockwise order around v. -- -- running time: <math>, where (k) is the total number of incident -- edges of v -- --
--   >>> incomingEdges (VertexId 1) smallG
--   [Dart (Arc 1) +1,Dart (Arc 4) -1,Dart (Arc 3) -1]
--   
incomingEdges :: VertexId' s -> PlaneGraph s v e f r -> Vector (Dart s) -- | All edges incident to vertex v in incoming direction (i.e. pointing -- into v) in counterclockwise order around v. -- -- running time: <math>, where (k) is the total number of incident -- edges of v -- --
--   >>> outgoingEdges (VertexId 1) smallG
--   [Dart (Arc 1) -1,Dart (Arc 4) +1,Dart (Arc 3) +1]
--   
outgoingEdges :: VertexId' s -> PlaneGraph s v e f r -> Vector (Dart s) -- | Gets the neighbours of a particular vertex, in counterclockwise order -- around the vertex. -- -- running time: <math>, where <math> is the output size -- --
--   >>> neighboursOf (VertexId 1) smallG
--   [VertexId 0,VertexId 2,VertexId 3]
--   
--   >>> neighboursOf (VertexId 5) myPlaneGraph
--   [VertexId 0,VertexId 6,VertexId 8,VertexId 1]
--   
neighboursOf :: VertexId' s -> PlaneGraph s v e f r -> Vector (VertexId' s) -- | Given a dart d that points into some vertex v, report the next dart in -- the cyclic (counterclockwise) order around v. -- -- running time: <math> -- --
--   >>> nextIncidentEdge (dart 1 "+1") smallG
--   Dart (Arc 4) +1
--   
--   >>> nextIncidentEdge (dart 1 "+1") myPlaneGraph
--   Dart (Arc 7) +1
--   
--   >>> nextIncidentEdge (dart 17 "-1") myPlaneGraph
--   Dart (Arc 15) -1
--   
nextIncidentEdge :: Dart s -> PlaneGraph s v e f r -> Dart s -- | Given a dart d that points into some vertex v, report the previous -- dart in the cyclic (counterclockwise) order around v. -- -- running time: <math> -- --
--   >>> prevIncidentEdge (dart 1 "+1") smallG
--   Dart (Arc 3) +1
--   
--   >>> prevIncidentEdge (dart 1 "+1") myPlaneGraph
--   Dart (Arc 4) -1
--   
--   >>> prevIncidentEdge (dart 7 "-1") myPlaneGraph
--   Dart (Arc 1) -1
--   
prevIncidentEdge :: Dart s -> PlaneGraph s v e f r -> Dart s -- | Given a dart d that points away from some vertex v, report the next -- dart in the cyclic (counterclockwise) order around v. -- -- running time: <math> -- --
--   >>> nextIncidentEdgeFrom (dart 1 "+1") smallG
--   Dart (Arc 2) +1
--   
--   >>> nextIncidentEdgeFrom (dart 1 "+1") myPlaneGraph
--   Dart (Arc 2) +1
--   
--   >>> nextIncidentEdgeFrom (dart 4 "+1") myPlaneGraph
--   Dart (Arc 15) +1
--   
nextIncidentEdgeFrom :: Dart s -> PlaneGraph s v e f r -> Dart s -- | Given a dart d that points into away from vertex v, report the -- previous dart in the cyclic (counterclockwise) order around v. -- -- running time: <math> -- --
--   >>> prevIncidentEdgeFrom (dart 1 "+1") smallG
--   Dart (Arc 0) +1
--   
--   >>> prevIncidentEdgeFrom (dart 4 "+1") myPlaneGraph
--   Dart (Arc 2) -1
--   
prevIncidentEdgeFrom :: Dart s -> PlaneGraph s v e f r -> Dart s -- | The face to the left of the dart -- -- running time: <math>. -- --
--   >>> leftFace (dart 1 "+1") smallG
--   FaceId 2
--   
--   >>> leftFace (dart 1 "-1") smallG
--   FaceId 1
--   
--   >>> leftFace (dart 2 "+1") smallG
--   FaceId 0
--   
--   >>> leftFace (dart 2 "-1") smallG
--   FaceId 2
--   
leftFace :: Dart s -> PlaneGraph s v e f r -> FaceId' s -- | The face to the right of the dart -- -- running time: <math>. -- --
--   >>> rightFace (dart 1 "+1") smallG
--   FaceId 1
--   
--   >>> rightFace (dart 1 "-1") smallG
--   FaceId 2
--   
--   >>> rightFace (dart 2 "+1") smallG
--   FaceId 2
--   
--   >>> rightFace (dart 2 "-1") smallG
--   FaceId 0
--   
rightFace :: Dart s -> PlaneGraph s v e f r -> FaceId' s -- | Get the next edge along the face -- -- running time: <math>. -- --
--   >>> nextEdge (dart 1 "+1") smallG
--   Dart (Arc 4) +1
--   
nextEdge :: Dart s -> PlaneGraph s v e f r -> Dart s -- | Get the previous edge along the face -- -- running time: <math>. -- --
--   >>> prevEdge (dart 1 "+1") smallG
--   Dart (Arc 0) -1
--   
prevEdge :: Dart s -> PlaneGraph s v e f r -> Dart s -- | The darts bounding this face. The darts are reported in order along -- the face. This means that for internal faces the darts are reported in -- *clockwise* order along the boundary, whereas for the outer face the -- darts are reported in counter clockwise order. -- -- running time: <math>, where <math> is the output size. -- --
--   >>> boundary (FaceId $ VertexId 2) smallG -- around face B
--   [Dart (Arc 2) +1,Dart (Arc 3) -1,Dart (Arc 1) -1]
--   
--   >>> boundary (FaceId $ VertexId 0) smallG -- around outer face
--   [Dart (Arc 0) +1,Dart (Arc 4) -1,Dart (Arc 3) +1,Dart (Arc 2) -1]
--   
boundary :: FaceId' s -> PlaneGraph s v e f r -> Vector (Dart s) -- | Given a dart d, generates the darts bounding the face that is to the -- right of the given dart. The darts are reported in order along the -- face. This means that for internal faces the darts are reported in -- *clockwise* order along the boundary, whereas for the outer face the -- darts are reported in counter clockwise order. -- -- running time: <math>, where <math> is the number of darts -- reported -- --
--   >>> boundary' (dart 2 "+1") smallG -- around face B
--   [Dart (Arc 2) +1,Dart (Arc 3) -1,Dart (Arc 1) -1]
--   
--   >>> boundary' (dart 0 "+1") smallG -- around outer face
--   [Dart (Arc 0) +1,Dart (Arc 4) -1,Dart (Arc 3) +1,Dart (Arc 2) -1]
--   
boundary' :: Dart s -> PlaneGraph s v e f r -> Vector (Dart s) -- | Gets a dart bounding this face. I.e. a dart d such that the face lies -- to the right of the dart. boundaryDart :: FaceId' s -> PlaneGraph s v e f r -> Dart s -- | The vertices bounding this face, for internal faces in clockwise -- order, for the outer face in counter clockwise order. -- -- running time: <math>, where <math> is the output size. -- --
--   >>> boundaryVertices (FaceId $ VertexId 2) smallG -- around B
--   [VertexId 0,VertexId 3,VertexId 1]
--   
--   >>> boundaryVertices (FaceId $ VertexId 0) smallG -- around outerface
--   [VertexId 0,VertexId 2,VertexId 1,VertexId 3]
--   
--   >>> mapM_ print $ boundaryVertices (FaceId $ VertexId 0) myPlaneGraph
--   VertexId 0
--   VertexId 9
--   VertexId 10
--   VertexId 11
--   VertexId 7
--   VertexId 8
--   VertexId 12
--   VertexId 13
--   VertexId 4
--   VertexId 3
--   VertexId 2
--   
boundaryVertices :: FaceId' s -> PlaneGraph s v e f r -> Vector (VertexId' s) -- | gets the id of the outer face -- -- running time: <math> outerFaceId :: (Ord r, Fractional r) => PlaneGraph s v e f r -> FaceId' s -- | gets a dart incident to the outer face (in particular, that has the -- outerface on its left) -- -- running time: <math> outerFaceDart :: (Ord r, Fractional r) => PlaneGraph s v e f r -> Dart s -- | Lens to access the vertex data -- -- Note that using the setting part of this lens may be very expensive!! -- (O(n)) vertexDataOf :: VertexId' s -> Lens' (PlaneGraph s v e f r) (VertexData r v) -- | Get the location of a vertex in the plane graph -- -- Note that the setting part of this lens may be very expensive! -- Moreover, use with care (as this may destroy planarity etc.) locationOf :: VertexId' s -> Lens' (PlaneGraph s v e f r) (Point 2 r) -- | General interface to accessing vertex data, dart data, and face data. class HasDataOf g i where { type family DataOf g i; } -- | get the data associated with the value i. -- -- running time: <math> to read the data, <math> to write it. dataOf :: HasDataOf g i => i -> Lens' g (DataOf g i) -- | Getter for the data at the endpoints of a dart -- -- running time: <math> endPointsOf :: Dart s -> Getter (PlaneGraph s v e f r) (VertexData r v, VertexData r v) -- | Data corresponding to the endpoints of the dart -- -- running time: <math> endPointData :: Dart s -> PlaneGraph s v e f r -> (VertexData r v, VertexData r v) vertexData :: Lens (PlaneGraph s v e f r) (PlaneGraph s v' e f r) (Vector v) (Vector v') -- | Lens to access face data faceData :: Lens (PlaneGraph s v e f r) (PlaneGraph s v e f' r) (Vector f) (Vector f') -- | lens to access the Dart Data dartData :: Lens (PlaneGraph s v e f r) (PlaneGraph s v e' f r) (Vector (Dart s, e)) (Vector (Dart s, e')) -- | Lens to access the raw dart data, use at your own risk rawDartData :: Lens (PlaneGraph s v e f r) (PlaneGraph s v e' f r) (Vector e) (Vector e') -- | Given a dart and the graph constructs the line segment representing -- the dart. The segment <math> is has <math> as its tail and -- <math> as its head. -- -- <math> edgeSegment :: Dart s -> PlaneGraph s v e f r -> LineSegment 2 v r :+ e -- | Reports all edges as line segments -- --
--   >>> mapM_ print $ edgeSegments smallG
--   (Dart (Arc 0) +1,ClosedLineSegment (Point2 0 0 :+ 0) (Point2 2 0 :+ 2) :+ "0->2")
--   (Dart (Arc 1) +1,ClosedLineSegment (Point2 0 0 :+ 0) (Point2 2 2 :+ 1) :+ "0->1")
--   (Dart (Arc 2) +1,ClosedLineSegment (Point2 0 0 :+ 0) (Point2 (-1) 4 :+ 3) :+ "0->3")
--   (Dart (Arc 4) +1,ClosedLineSegment (Point2 2 2 :+ 1) (Point2 2 0 :+ 2) :+ "1->2")
--   (Dart (Arc 3) +1,ClosedLineSegment (Point2 2 2 :+ 1) (Point2 (-1) 4 :+ 3) :+ "1->3")
--   
--   >>> mapM_ print $ edgeSegments myPlaneGraph
--   (Dart (Arc 0) +1,ClosedLineSegment (Point2 0 0 :+ 0) (Point2 8 (-5) :+ 9) :+ ())
--   (Dart (Arc 1) +1,ClosedLineSegment (Point2 0 0 :+ 0) (Point2 8 1 :+ 5) :+ ())
--   (Dart (Arc 2) +1,ClosedLineSegment (Point2 0 0 :+ 0) (Point2 4 4 :+ 1) :+ ())
--   (Dart (Arc 3) +1,ClosedLineSegment (Point2 0 0 :+ 0) (Point2 3 7 :+ 2) :+ ())
--   (Dart (Arc 4) +1,ClosedLineSegment (Point2 4 4 :+ 1) (Point2 8 1 :+ 5) :+ ())
--   (Dart (Arc 15) +1,ClosedLineSegment (Point2 4 4 :+ 1) (Point2 10 4 :+ 12) :+ ())
--   (Dart (Arc 5) +1,ClosedLineSegment (Point2 3 7 :+ 2) (Point2 0 5 :+ 3) :+ ())
--   (Dart (Arc 6) +1,ClosedLineSegment (Point2 0 5 :+ 3) (Point2 3 8 :+ 4) :+ ())
--   (Dart (Arc 18) +1,ClosedLineSegment (Point2 3 8 :+ 4) (Point2 9 6 :+ 13) :+ ())
--   (Dart (Arc 7) +1,ClosedLineSegment (Point2 8 1 :+ 5) (Point2 6 (-1) :+ 6) :+ ())
--   (Dart (Arc 10) +1,ClosedLineSegment (Point2 8 1 :+ 5) (Point2 12 1 :+ 8) :+ ())
--   (Dart (Arc 12) +1,ClosedLineSegment (Point2 6 (-1) :+ 6) (Point2 8 (-5) :+ 9) :+ ())
--   (Dart (Arc 8) +1,ClosedLineSegment (Point2 9 (-1) :+ 7) (Point2 12 1 :+ 8) :+ ())
--   (Dart (Arc 14) +1,ClosedLineSegment (Point2 9 (-1) :+ 7) (Point2 14 (-1) :+ 11) :+ ())
--   (Dart (Arc 9) +1,ClosedLineSegment (Point2 12 1 :+ 8) (Point2 10 4 :+ 12) :+ ())
--   (Dart (Arc 11) +1,ClosedLineSegment (Point2 8 (-5) :+ 9) (Point2 12 (-3) :+ 10) :+ ())
--   (Dart (Arc 13) +1,ClosedLineSegment (Point2 12 (-3) :+ 10) (Point2 14 (-1) :+ 11) :+ ())
--   (Dart (Arc 16) +1,ClosedLineSegment (Point2 10 4 :+ 12) (Point2 9 6 :+ 13) :+ ())
--   (Dart (Arc 17) +1,ClosedLineSegment (Point2 10 4 :+ 12) (Point2 8 5 :+ 14) :+ ())
--   (Dart (Arc 19) +1,ClosedLineSegment (Point2 9 6 :+ 13) (Point2 8 5 :+ 14) :+ ())
--   
edgeSegments :: PlaneGraph s v e f r -> Vector (Dart s, LineSegment 2 v r :+ e) -- | The boundary of the face as a simple polygon. For internal faces the -- polygon that is reported has its vertices stored in CCW order (as -- expected). -- -- pre: FaceId refers to an internal face. -- -- For the other face this prodcuces a polygon in CW order (this may lead -- to unexpected results.) -- -- runningtime: <math>, where <math> is the size of the face. faceBoundary :: FaceId' s -> PlaneGraph s v e f r -> SimplePolygon v r :+ f -- | The boundary of the face as a simple polygon. For internal faces the -- polygon that is reported has its vertices stored in CCW order (as -- expected). -- -- pre: FaceId refers to an internal face. -- -- For the other face this prodcuces a polygon in CW order (this may lead -- to unexpected results.) -- -- runningtime: <math>, where <math> is the size of the face. internalFacePolygon :: FaceId' s -> PlaneGraph s v e f r -> SimplePolygon v r :+ f -- | Given the outerFaceId and the graph, construct a sufficiently large -- rectangular multipolygon ith a hole containing the boundary of the -- outer face. outerFacePolygon :: (Num r, Ord r) => FaceId' s -> PlaneGraph s v e f r -> MultiPolygon (Maybe v) r :+ f -- | Given the outerface id, and a sufficiently large outer boundary, draw -- the outerface as a polygon with a hole. outerFacePolygon' :: FaceId' s -> SimplePolygon v' r -> PlaneGraph s v e f r -> MultiPolygon (Either v' v) r :+ f -- | Given the outerFace Id, construct polygons for all faces. We construct -- a polygon with a hole for the outer face. facePolygons :: (Num r, Ord r) => FaceId' s -> PlaneGraph s v e f r -> ((FaceId' s, MultiPolygon (Maybe v) r :+ f), Vector (FaceId' s, SimplePolygon v r :+ f)) -- | Given the outerFace Id, lists all internal faces of the plane graph -- with their boundaries. facePolygons' :: FaceId' s -> PlaneGraph s v e f r -> Vector (FaceId' s, SimplePolygon v r :+ f) -- | A vertex in a planar graph. A vertex is tied to a particular planar -- graph by the phantom type s, and to a particular world w. newtype VertexId (s :: k) (w :: World) VertexId :: Int -> VertexId (s :: k) (w :: World) [_unVertexId] :: VertexId (s :: k) (w :: World) -> Int -- | The type to represent FaceId's newtype FaceId (s :: k) (w :: World) FaceId :: VertexId s (DualOf w) -> FaceId (s :: k) (w :: World) [_unFaceId] :: FaceId (s :: k) (w :: World) -> VertexId s (DualOf w) -- | A dart represents a bi-directed edge. I.e. a dart has a direction, -- however the dart of the oposite direction is always present in the -- planar graph as well. data Dart (s :: k) -- | The world in which the graph lives data World Primal :: World Dual :: World -- | Shorthand for vertices in the primal. type VertexId' (s :: k) = VertexId s 'Primal -- | Shorthand for FaceId's in the primal. type FaceId' (s :: k) = FaceId s 'Primal -- | Labels the edges of a plane graph with their distances, as specified -- by the distance function. withEdgeDistances :: (Point 2 r -> Point 2 r -> a) -> PlaneGraph s p e f r -> PlaneGraph s p (a :+ e) f r -- | Writes a plane graph to a bytestring writePlaneGraph :: (ToJSON v, ToJSON e, ToJSON f, ToJSON r) => PlaneGraph s v e f r -> ByteString -- | Reads a plane graph from a bytestring readPlaneGraph :: forall s v e f r. (FromJSON v, FromJSON e, FromJSON f, FromJSON r) => ByteString -> Either ParseException (PlaneGraph s v e f r) module Data.Geometry.PlanarSubdivision.Raw -- | Helper data type and type family to Wrap a proxy type. data Wrap' s type family Wrap (s :: k) :: k -- | ComponentId type newtype ComponentId s ComponentId :: Int -> ComponentId s [unCI] :: ComponentId s -> Int -- | Helper type for the data that we store in a planar subdivision data Raw s ia a Raw :: !ComponentId s -> !ia -> !a -> Raw s ia a [_compId] :: Raw s ia a -> !ComponentId s [_idxVal] :: Raw s ia a -> !ia [_dataVal] :: Raw s ia a -> !a -- | get the dataVal of a Raw dataVal :: Lens (Raw s ia a) (Raw s ia b) a b -- | The Face data consists of the data itself and a list of holes data FaceData h f FaceData :: Seq h -> !f -> FaceData h f [_holes] :: FaceData h f -> Seq h [_fData] :: FaceData h f -> !f holes :: forall h_a3gRp f_a3gRq h_a3hGp. Lens (FaceData h_a3gRp f_a3gRq) (FaceData h_a3hGp f_a3gRq) (Seq h_a3gRp) (Seq h_a3hGp) fData :: forall h_a3gRp f_a3gRq f_a3hGo. Lens (FaceData h_a3gRp f_a3gRq) (FaceData h_a3gRp f_a3hGo) f_a3gRq f_a3hGo -- | Face data, if the face is an inner face, store the component and -- faceId of it. If not, this face must be the outer face (and thus we -- can find all the face id's it correponds to through the FaceData). data RawFace s f RawFace :: !Maybe (ComponentId s, FaceId' (Wrap s)) -> !FaceData (Dart s) f -> RawFace s f [_faceIdx] :: RawFace s f -> !Maybe (ComponentId s, FaceId' (Wrap s)) [_faceDataVal] :: RawFace s f -> !FaceData (Dart s) f faceIdx :: forall k_a3hHi (s_a3hGE :: k_a3hHi) f_a3hGF. Lens' (RawFace (s_a3hGE :: k_a3hHi) f_a3hGF) (Maybe (ComponentId s_a3hGE, FaceId' (Wrap s_a3hGE))) faceDataVal :: forall k_a3hHi (s_a3hGE :: k_a3hHi) f_a3hGF f_a3hWm. Lens (RawFace (s_a3hGE :: k_a3hHi) f_a3hGF) (RawFace (s_a3hGE :: k_a3hHi) f_a3hWm) (FaceData (Dart s_a3hGE) f_a3hGF) (FaceData (Dart s_a3hGE) f_a3hWm) instance forall k (s :: k) f. GHC.Generics.Generic (Data.Geometry.PlanarSubdivision.Raw.RawFace s f) instance forall k (s :: k). Data.Traversable.Traversable (Data.Geometry.PlanarSubdivision.Raw.RawFace s) instance forall k (s :: k). Data.Foldable.Foldable (Data.Geometry.PlanarSubdivision.Raw.RawFace s) instance forall k (s :: k). GHC.Base.Functor (Data.Geometry.PlanarSubdivision.Raw.RawFace s) instance forall k (s :: k) f. GHC.Show.Show f => GHC.Show.Show (Data.Geometry.PlanarSubdivision.Raw.RawFace s f) instance forall k (s :: k) f. GHC.Classes.Eq f => GHC.Classes.Eq (Data.Geometry.PlanarSubdivision.Raw.RawFace s f) instance Data.Bifunctor.Bifunctor Data.Geometry.PlanarSubdivision.Raw.FaceData instance (Data.Aeson.Types.FromJSON.FromJSON h, Data.Aeson.Types.FromJSON.FromJSON f) => Data.Aeson.Types.FromJSON.FromJSON (Data.Geometry.PlanarSubdivision.Raw.FaceData h f) instance (Data.Aeson.Types.ToJSON.ToJSON h, Data.Aeson.Types.ToJSON.ToJSON f) => Data.Aeson.Types.ToJSON.ToJSON (Data.Geometry.PlanarSubdivision.Raw.FaceData h f) instance forall k (s :: k). Data.Aeson.Types.FromJSON.FromJSON (Data.Geometry.PlanarSubdivision.Raw.ComponentId s) instance forall k (s :: k). Data.Aeson.Types.ToJSON.ToJSON (Data.Geometry.PlanarSubdivision.Raw.ComponentId s) instance forall k (s :: k). GHC.Enum.Enum (Data.Geometry.PlanarSubdivision.Raw.ComponentId s) instance forall k (s :: k). GHC.Enum.Bounded (Data.Geometry.PlanarSubdivision.Raw.ComponentId s) instance forall k (s :: k). GHC.Generics.Generic (Data.Geometry.PlanarSubdivision.Raw.ComponentId s) instance forall k (s :: k). GHC.Classes.Ord (Data.Geometry.PlanarSubdivision.Raw.ComponentId s) instance forall k (s :: k). GHC.Classes.Eq (Data.Geometry.PlanarSubdivision.Raw.ComponentId s) instance forall k (s :: k). GHC.Show.Show (Data.Geometry.PlanarSubdivision.Raw.ComponentId s) instance forall k (s :: k) ia a. GHC.Generics.Generic (Data.Geometry.PlanarSubdivision.Raw.Raw s ia a) instance forall k (s :: k) ia. Data.Traversable.Traversable (Data.Geometry.PlanarSubdivision.Raw.Raw s ia) instance forall k (s :: k) ia. Data.Foldable.Foldable (Data.Geometry.PlanarSubdivision.Raw.Raw s ia) instance forall k (s :: k) ia. GHC.Base.Functor (Data.Geometry.PlanarSubdivision.Raw.Raw s ia) instance forall k (s :: k) ia a. (GHC.Show.Show ia, GHC.Show.Show a) => GHC.Show.Show (Data.Geometry.PlanarSubdivision.Raw.Raw s ia a) instance forall k (s :: k) ia a. (GHC.Classes.Eq ia, GHC.Classes.Eq a) => GHC.Classes.Eq (Data.Geometry.PlanarSubdivision.Raw.Raw s ia a) instance GHC.Generics.Generic (Data.Geometry.PlanarSubdivision.Raw.FaceData h f) instance Data.Traversable.Traversable (Data.Geometry.PlanarSubdivision.Raw.FaceData h) instance Data.Foldable.Foldable (Data.Geometry.PlanarSubdivision.Raw.FaceData h) instance GHC.Base.Functor (Data.Geometry.PlanarSubdivision.Raw.FaceData h) instance (GHC.Classes.Ord h, GHC.Classes.Ord f) => GHC.Classes.Ord (Data.Geometry.PlanarSubdivision.Raw.FaceData h f) instance (GHC.Classes.Eq h, GHC.Classes.Eq f) => GHC.Classes.Eq (Data.Geometry.PlanarSubdivision.Raw.FaceData h f) instance (GHC.Show.Show h, GHC.Show.Show f) => GHC.Show.Show (Data.Geometry.PlanarSubdivision.Raw.FaceData h f) instance forall k ia a (s :: k). (Data.Aeson.Types.FromJSON.FromJSON ia, Data.Aeson.Types.FromJSON.FromJSON a) => Data.Aeson.Types.FromJSON.FromJSON (Data.Geometry.PlanarSubdivision.Raw.Raw s ia a) instance forall k ia a (s :: k). (Data.Aeson.Types.ToJSON.ToJSON ia, Data.Aeson.Types.ToJSON.ToJSON a) => Data.Aeson.Types.ToJSON.ToJSON (Data.Geometry.PlanarSubdivision.Raw.Raw s ia a) instance forall k i (ci :: k). WithIndex.FunctorWithIndex i (Data.Geometry.PlanarSubdivision.Raw.Raw ci i) instance forall k i (ci :: k). WithIndex.FoldableWithIndex i (Data.Geometry.PlanarSubdivision.Raw.Raw ci i) instance forall k i (ci :: k). WithIndex.TraversableWithIndex i (Data.Geometry.PlanarSubdivision.Raw.Raw ci i) module Data.Geometry.PlanarSubdivision.Basic -- | Shorthand for vertices in the primal. type VertexId' (s :: k) = VertexId s 'Primal -- | Shorthand for FaceId's in the primal. type FaceId' (s :: k) = FaceId s 'Primal -- | Note that the functor instance is in v data VertexData r v VertexData :: !Point 2 r -> !v -> VertexData r v vData :: forall r_a37Ku v_a37Kv v_a37Z9. Lens (VertexData r_a37Ku v_a37Kv) (VertexData r_a37Ku v_a37Z9) v_a37Kv v_a37Z9 location :: forall r_a37Ku v_a37Kv r_a37Z8. Lens (VertexData r_a37Ku v_a37Kv) (VertexData r_a37Z8 v_a37Kv) (Point 2 r_a37Ku) (Point 2 r_a37Z8) -- | The Face data consists of the data itself and a list of holes data FaceData h f FaceData :: Seq h -> !f -> FaceData h f holes :: forall h_a3gRp f_a3gRq h_a3hGp. Lens (FaceData h_a3gRp f_a3gRq) (FaceData h_a3hGp f_a3gRq) (Seq h_a3gRp) (Seq h_a3hGp) fData :: forall h_a3gRp f_a3gRq f_a3hGo. Lens (FaceData h_a3gRp f_a3gRq) (FaceData h_a3gRp f_a3hGo) f_a3gRq f_a3hGo -- | A planarsubdivision is essentially a bunch of plane-graphs; one for -- every connected component. These graphs store the global ID's (darts, -- vertexId's, faceId's) in their data values. This essentially gives us -- a mapping between the two. -- -- note that a face may actually occur in multiple graphs, hence when we -- store the edges to the the holes, we store the global edgeId's rather -- than the local edgeId (dart)'s. -- -- invariant: the outerface has faceId 0 data PlanarSubdivision s v e f r PlanarSubdivision :: Vector (Component s r) -> Vector (Raw s (VertexId' (Wrap s)) v) -> Vector (Raw s (Dart (Wrap s)) e) -> Vector (RawFace s f) -> PlanarSubdivision s v e f r type family Wrap (s :: k) :: k -- | A connected component. -- -- For every face f, and every hole in this face, the facedata points to -- a dart d on the hole s.t. this dart has the face f on its left. i.e. -- leftFace d = f type Component s r = PlaneGraph (Wrap s) (VertexId' s) (Dart s) (FaceId' s) r -- | ComponentId type data ComponentId s -- | Data type that expresses whether or not we are inside or outside the -- polygon. data PolygonFaceData Inside :: PolygonFaceData Outside :: PolygonFaceData -- | A *connected* Planar graph with bidirected edges. I.e. the edges -- (darts) are directed, however, for every directed edge, the edge in -- the oposite direction is also in the graph. -- -- The types v, e, and f are the are the types of the data associated -- with the vertices, edges, and faces, respectively. -- -- The orbits in the embedding are assumed to be in counterclockwise -- order. Therefore, every dart directly bounds the face to its right. data PlanarGraph (s :: k) (w :: World) v e f -- | Embedded, *connected*, planar graph data PlaneGraph s v e f r -- | Construct a plane graph from a simple polygon. It is assumed that the -- polygon is given in counterclockwise order. -- -- the interior of the polygon will have faceId 0 -- -- pre: the input polygon is given in counterclockwise order running -- time: <math>. fromSimplePolygon :: (Ord r, Fractional r) => proxy s -> SimplePolygon p r -> f -> f -> PlanarSubdivision s p () f r -- | Constructs a connected planar subdivision. -- -- pre: the segments form a single connected component running time: -- <math> fromConnectedSegments :: (Foldable f, Ord r, Fractional r) => proxy s -> f (LineSegment 2 p r :+ e) -> PlanarSubdivision s (NonEmpty p) e () r -- | Constructs a planarsubdivision from a PlaneGraph -- -- runningTime: <math> fromPlaneGraph :: forall s v e f r. (Ord r, Fractional r) => PlaneGraph s v e f r -> PlanarSubdivision s v e f r -- | Given a (connected) PlaneGraph and a dart that has the outerface on -- its left | Constructs a planarsubdivision -- -- runningTime: <math> fromPlaneGraph' :: forall s v e f r. PlaneGraph s v e f r -> Dart s -> PlanarSubdivision s v e f r -- | Get the number of vertices -- --
--   >>> numVertices myGraph
--   1
--   
numComponents :: PlanarSubdivision s v e f r -> Int -- | Get the number of vertices -- --
--   >>> numVertices myGraph
--   4
--   
numVertices :: PlanarSubdivision s v e f r -> Int -- | Get the number of Edges -- --
--   >>> numEdges myGraph
--   6
--   
numEdges :: PlanarSubdivision s v e f r -> Int -- | <math>. Get the number of faces -- --
--   >>> numFaces myGraph
--   4
--   
numFaces :: PlanarSubdivision s v e f r -> Int -- | Get the number of Darts -- --
--   >>> numDarts myGraph
--   12
--   
numDarts :: PlanarSubdivision s v e f r -> Int -- | Get the dual graph of this graph. dual :: forall k (s :: k) (w :: World) v e f. Getter (PlanarGraph s w v e f) (PlanarGraph s (DualOf w) f e v) components :: forall k_a3nak (s_a3n9G :: k_a3nak) v_a3n9H e_a3n9I f_a3n9J r_a3n9K r_a3nmP. Lens (PlanarSubdivision (s_a3n9G :: k_a3nak) v_a3n9H e_a3n9I f_a3n9J r_a3n9K) (PlanarSubdivision (s_a3n9G :: k_a3nak) v_a3n9H e_a3n9I f_a3n9J r_a3nmP) (Vector (Component s_a3n9G r_a3n9K)) (Vector (Component s_a3n9G r_a3nmP)) -- | Lens to access a particular component of the planar subdivision. component :: ComponentId s -> Lens' (PlanarSubdivision s v e f r) (Component s r) -- | Enumerate all vertices -- --
--   >>> vertices' myGraph
--   [VertexId 0,VertexId 1,VertexId 2,VertexId 3]
--   
vertices' :: PlanarSubdivision s v e f r -> Vector (VertexId' s) -- | Enumerate all vertices, together with their vertex data vertices :: PlanarSubdivision s v e f r -> Vector (VertexId' s, VertexData r v) -- | Enumerate all edges. We report only the Positive darts edges' :: PlanarSubdivision s v e f r -> Vector (Dart s) -- | Enumerate all edges with their edge data. We report only the Positive -- darts. -- --
--   >>> mapM_ print $ edges myGraph
--   (Dart (Arc 2) +1,"c+")
--   (Dart (Arc 1) +1,"b+")
--   (Dart (Arc 0) +1,"a+")
--   (Dart (Arc 5) +1,"g+")
--   (Dart (Arc 4) +1,"e+")
--   (Dart (Arc 3) +1,"d+")
--   
edges :: PlanarSubdivision s v e f r -> Vector (Dart s, e) -- | <math>. Vector of all primal faces. faces' :: PlanarSubdivision s v e f r -> Vector (FaceId' s) -- | <math>. Vector of all primal faces. internalFaces' :: PlanarSubdivision s v e f r -> Vector (FaceId' s) -- | <math>. Vector of all primal faces with associated data. faces :: PlanarSubdivision s v e f r -> Vector (FaceId' s, FaceData (Dart s) f) -- | Enumerates all faces with their face data exlcluding the outer face internalFaces :: PlanarSubdivision s v e f r -> Vector (FaceId' s, FaceData (Dart s) f) -- | Enumerate all darts darts' :: PlanarSubdivision s v e f r -> Vector (Dart s) -- | Traverse the vertices of the planar subdivision traverseVertices :: Applicative g => (VertexId' s -> v -> g v') -> PlanarSubdivision s v e f r -> g (PlanarSubdivision s v' e f r) -- | Traverse the darts of the Planar subdivision traverseDarts :: Applicative g => (Dart s -> e -> g e') -> PlanarSubdivision s v e f r -> g (PlanarSubdivision s v e' f r) -- | Traverse the faces of the planar subdivision. traverseFaces :: Applicative g => (FaceId' s -> f -> g f') -> PlanarSubdivision s v e f r -> g (PlanarSubdivision s v e f' r) -- | Map with index over all vertices mapVertices :: (VertexId' s -> t -> v') -> PlanarSubdivision s t e f r -> PlanarSubdivision s v' e f r -- | Map with index over all darts mapDarts :: (Dart s -> t -> e') -> PlanarSubdivision s v t f r -> PlanarSubdivision s v e' f r -- | Map with index over all faces mapFaces :: (FaceId' s -> t -> f') -> PlanarSubdivision s v e t r -> PlanarSubdivision s v e f' r -- | The vertex this dart is heading in to -- -- running time: <math> headOf :: Dart s -> PlanarSubdivision s v e f r -> VertexId' s -- | The tail of a dart, i.e. the vertex this dart is leaving from -- -- running time: <math> tailOf :: Dart s -> PlanarSubdivision s v e f r -> VertexId' s -- | Get the twin of this dart (edge) -- --
--   >>> twin (dart 0 "+1")
--   Dart (Arc 0) -1
--   
--   >>> twin (dart 0 "-1")
--   Dart (Arc 0) +1
--   
twin :: forall k (s :: k). Dart s -> Dart s -- | endPoints d g = (tailOf d g, headOf d g) -- -- running time: <math> endPoints :: Dart s -> PlanarSubdivision s v e f r -> (VertexId' s, VertexId' s) -- | All edges incident to vertex v, in counterclockwise order around v. -- -- running time: <math>, where <math> is the number of edges -- reported. incidentEdges :: VertexId' s -> PlanarSubdivision s v e f r -> Vector (Dart s) -- | All edges incident to vertex v in incoming direction (i.e. pointing -- into v) in counterclockwise order around v. -- -- running time: <math>, where (k) is the total number of incident -- edges of v incomingEdges :: VertexId' s -> PlanarSubdivision s v e f r -> Vector (Dart s) -- | All edges incident to vertex v in outgoing direction (i.e. pointing -- away from v) in counterclockwise order around v. -- -- running time: <math>, where (k) is the total number of incident -- edges of v outgoingEdges :: VertexId' s -> PlanarSubdivision s v e f r -> Vector (Dart s) -- | Given a dart d that points into some vertex v, report the next dart in -- the cyclic (counterclockwise) order around v. -- -- running time: <math> nextIncidentEdge :: Dart s -> PlanarSubdivision s v e f r -> Dart s -- | Given a dart d that points into some vertex v, report the previous -- dart in the cyclic (counterclockwise) order around v. -- -- running time: <math> -- --
--   >>> prevIncidentEdge (dart 1 "+1") smallG
--   Dart (Arc 3) +1
--   
prevIncidentEdge :: Dart s -> PlanarSubdivision s v e f r -> Dart s -- | Given a dart d that points away from some vertex v, report the next -- dart in the cyclic (counterclockwise) order around v. -- -- running time: <math> nextIncidentEdgeFrom :: Dart s -> PlanarSubdivision s v e f r -> Dart s -- | Given a dart d that points into away from vertex v, report the -- previous dart in the cyclic (counterclockwise) order around v. -- -- running time: <math> prevIncidentEdgeFrom :: Dart s -> PlanarSubdivision s v e f r -> Dart s -- | Gets the neighbours of a particular vertex, in counterclockwise order -- around the vertex. -- -- running time: <math>, where <math> is the output size neighboursOf :: VertexId' s -> PlanarSubdivision s v e f r -> Vector (VertexId' s) -- | The face to the left of the dart -- -- running time: <math>. leftFace :: Dart s -> PlanarSubdivision s v e f r -> FaceId' s -- | The face to the right of the dart -- -- running time: <math>. rightFace :: Dart s -> PlanarSubdivision s v e f r -> FaceId' s -- | The darts on the outer boundary of this face. The darts are reported -- in order along the face. This means that for internal faces the darts -- are reported in *clockwise* order along the boundary, whereas for the -- outer face the darts are reported in counter clockwise order. -- -- running time: <math>, where <math> is the output size. outerBoundaryDarts :: FaceId' s -> PlanarSubdivision s v e f r -> Vector (Dart s) -- | The vertices of the outer boundary of the face, for internal faces in -- clockwise order, for the outer face in counter clockwise order. -- -- running time: <math>, where <math> is the output size. boundaryVertices :: FaceId' s -> PlanarSubdivision s v e f r -> Vector (VertexId' s) -- | Lists the holes in this face, given as a list of darts to arbitrary -- darts on those faces. The returned darts are on the outside of the -- hole, i.e. they are incident to the given input face: -- --
--   all (\d -> leftFace d ps == fi) $ holesOf fi ps
--   
-- -- running time: <math>, where <math> is the number of darts -- returned. holesOf :: FaceId' s -> PlanarSubdivision s v e f r -> Seq (Dart s) -- | gets the id of the outer face -- -- running time: <math> outerFaceId :: PlanarSubdivision s v e f r -> FaceId' s -- | Given a dart d, generates the darts on (the current component of) the -- boundary of the the face that is to the right of the given dart. The -- darts are reported in order along the face. This means that for -- -- -- -- Note that this latter case means that in the darts of a a component of -- the outer face are reported in counter clockwise order. -- -- <math>, where <math> is the number of darts reported boundary' :: Dart s -> PlanarSubdivision s v e f r -> Vector (Dart s) -- | Get the location of a vertex in the planar subdivision. -- -- Note that the setting part of this lens may be very expensive! -- Moreover, use with care (as this may destroy planarity etc.) locationOf :: VertexId' s -> Lens' (PlanarSubdivision s v e f r) (Point 2 r) -- | General interface to accessing vertex data, dart data, and face data. class HasDataOf g i where { type family DataOf g i; } -- | get the data associated with the value i. -- -- running time: <math> to read the data, <math> to write it. dataOf :: HasDataOf g i => i -> Lens' g (DataOf g i) -- | Getter for the data at the endpoints of a dart -- -- running time: <math> endPointsOf :: Dart s -> Getter (PlanarSubdivision s v e f r) (VertexData r v, VertexData r v) -- | data corresponding to the endpoints of the dart -- -- running time: <math> endPointData :: Dart s -> PlanarSubdivision s v e f r -> (VertexData r v, VertexData r v) -- | Lens to get the face data of a particular face. Note that the setting -- part of this lens may be very expensive! (O(n)) faceDataOf :: FaceId' s -> Lens' (PlanarSubdivision s v e f r) (FaceData (Dart s) f) -- | Given a dart and the subdivision constructs the line segment -- representing it. The segment <math> is has <math> as its -- tail and <math> as its head. -- -- <math> edgeSegment :: Dart s -> PlanarSubdivision s v e f r -> LineSegment 2 v r :+ e -- | Reports all edges as line segments edgeSegments :: PlanarSubdivision s v e f r -> Vector (Dart s, LineSegment 2 v r :+ e) -- | The outerboundary of the face as a simple polygon. For internal faces -- the polygon that is reported has its vertices stored in CCW order (as -- expected). -- -- pre: FaceId refers to an internal face. -- -- <math>, where <math> is the complexity of the outer -- boundary of the face faceBoundary :: FaceId' s -> PlanarSubdivision s v e f r -> SimplePolygon v r :+ f -- | Constructs the boundary of the given face. -- -- <math>, where <math> is the complexity of the face internalFacePolygon :: FaceId' s -> PlanarSubdivision s v e f r -> SomePolygon v r :+ f -- | Procuces a polygon for each *internal* face of the planar subdivision. internalFacePolygons :: PlanarSubdivision s v e f r -> Vector (FaceId' s, SomePolygon v r :+ f) -- | Returns a sufficiently large, rectangular, polygon that contains the -- entire planar subdivision. Each component corresponds to a hole in -- this polygon. outerFacePolygon :: (Num r, Ord r) => PlanarSubdivision s v e f r -> MultiPolygon (Maybe v) r :+ f -- | Given a sufficiently large outer boundary, draw the outerface as a -- polygon with a hole. outerFacePolygon' :: SimplePolygon v' r -> PlanarSubdivision s v e f r -> MultiPolygon (Either v' v) r :+ f -- | Procuces a polygon for each face of the planar subdivision. facePolygons :: (Num r, Ord r) => PlanarSubdivision s v e f r -> Vector (FaceId' s, SomePolygon (Maybe v) r :+ f) -- | A vertex in a planar graph. A vertex is tied to a particular planar -- graph by the phantom type s, and to a particular world w. newtype VertexId (s :: k) (w :: World) VertexId :: Int -> VertexId (s :: k) (w :: World) [_unVertexId] :: VertexId (s :: k) (w :: World) -> Int -- | The type to represent FaceId's newtype FaceId (s :: k) (w :: World) FaceId :: VertexId s (DualOf w) -> FaceId (s :: k) (w :: World) [_unFaceId] :: FaceId (s :: k) (w :: World) -> VertexId s (DualOf w) -- | A dart represents a bi-directed edge. I.e. a dart has a direction, -- however the dart of the oposite direction is always present in the -- planar graph as well. data Dart (s :: k) -- | The world in which the graph lives data World Primal :: World Dual :: World rawVertexData :: forall k_a3nak (s_a3n9G :: k_a3nak) v_a3n9H e_a3n9I f_a3n9J r_a3n9K v_a3nmS. Lens (PlanarSubdivision (s_a3n9G :: k_a3nak) v_a3n9H e_a3n9I f_a3n9J r_a3n9K) (PlanarSubdivision (s_a3n9G :: k_a3nak) v_a3nmS e_a3n9I f_a3n9J r_a3n9K) (Vector (Raw s_a3n9G (VertexId' (Wrap s_a3n9G)) v_a3n9H)) (Vector (Raw s_a3n9G (VertexId' (Wrap s_a3n9G)) v_a3nmS)) rawDartData :: forall k_a3nak (s_a3n9G :: k_a3nak) v_a3n9H e_a3n9I f_a3n9J r_a3n9K e_a3nmQ. Lens (PlanarSubdivision (s_a3n9G :: k_a3nak) v_a3n9H e_a3n9I f_a3n9J r_a3n9K) (PlanarSubdivision (s_a3n9G :: k_a3nak) v_a3n9H e_a3nmQ f_a3n9J r_a3n9K) (Vector (Raw s_a3n9G (Dart (Wrap s_a3n9G)) e_a3n9I)) (Vector (Raw s_a3n9G (Dart (Wrap s_a3n9G)) e_a3nmQ)) rawFaceData :: forall k_a3nak (s_a3n9G :: k_a3nak) v_a3n9H e_a3n9I f_a3n9J r_a3n9K f_a3nmR. Lens (PlanarSubdivision (s_a3n9G :: k_a3nak) v_a3n9H e_a3n9I f_a3n9J r_a3n9K) (PlanarSubdivision (s_a3n9G :: k_a3nak) v_a3n9H e_a3n9I f_a3nmR r_a3n9K) (Vector (RawFace s_a3n9G f_a3n9J)) (Vector (RawFace s_a3n9G f_a3nmR)) -- | Lens to the facedata of the vertexdata themselves. The indices -- correspond to the vertexId's vertexData :: Lens (PlanarSubdivision s v e f r) (PlanarSubdivision s v' e f r) (Vector v) (Vector v') -- | lens to access the Dart Data dartData :: Lens (PlanarSubdivision s v e f r) (PlanarSubdivision s v e' f r) (Vector (Dart s, e)) (Vector (Dart s, e')) -- | Lens to the facedata of the faces themselves. The indices correspond -- to the faceIds faceData :: Lens (PlanarSubdivision s v e f r) (PlanarSubdivision s v e f' r) (Vector f) (Vector f') -- | get the dataVal of a Raw dataVal :: Lens (Raw s ia a) (Raw s ia b) a b -- | Mapping between the internal and extenral darts dartMapping :: PlanarSubdivision s v e f r -> Vector (Dart (Wrap s), Dart s) -- | Helper type for the data that we store in a planar subdivision data Raw s ia a Raw :: !ComponentId s -> !ia -> !a -> Raw s ia a [_compId] :: Raw s ia a -> !ComponentId s [_idxVal] :: Raw s ia a -> !ia [_dataVal] :: Raw s ia a -> !a asLocalD :: Dart s -> PlanarSubdivision s v e f r -> (ComponentId s, Dart (Wrap s), Component s r) asLocalV :: VertexId' s -> PlanarSubdivision s v e f r -> (ComponentId s, VertexId' (Wrap s), Component s r) -- | Get the local face and component from a given face. asLocalF :: FaceId' s -> PlanarSubdivision s v e f r -> NonEmpty (ComponentId s, FaceId' (Wrap s), Component s r) -- | A class for describing which features (vertex, edge, face) of a planar -- subdivision can be incident to each other. class Incident s a b incidences :: Incident s a b => PlanarSubdivision s v e f r -> a -> [b] -- | Given two features (vertex, edge, or face) of a subdivision, report -- all features of a given type that are incident to both. common :: (Incident s a c, Incident s b c, Ord c) => PlanarSubdivision s v e f r -> a -> b -> [c] -- | Given two features (edge or face) of a subdivision, report all -- vertices that are incident to both. commonVertices :: (Incident s a (VertexId' s), Incident s b (VertexId' s)) => PlanarSubdivision s v e f r -> a -> b -> [VertexId' s] -- | Given two features (vertex or face) of a subdivision, report all edges -- that are incident to both. Returns both darts of each qualifying edge. commonDarts :: (Incident s a (Dart s), Incident s b (Dart s)) => PlanarSubdivision s v e f r -> a -> b -> [Dart s] -- | Given two features (vertex or edge) of a subdivision, report all faces -- that are incident to both. commonFaces :: (Incident s a (FaceId' s), Incident s b (FaceId' s)) => PlanarSubdivision s v e f r -> a -> b -> [FaceId' s] instance GHC.Classes.Eq Data.Geometry.PlanarSubdivision.Basic.PolygonFaceData instance GHC.Read.Read Data.Geometry.PlanarSubdivision.Basic.PolygonFaceData instance GHC.Show.Show Data.Geometry.PlanarSubdivision.Basic.PolygonFaceData instance forall k (s :: k). Data.Geometry.PlanarSubdivision.Basic.Incident s (Data.PlanarGraph.Core.VertexId' s) (Data.PlanarGraph.Dart.Dart s) instance forall k (s :: k). Data.Geometry.PlanarSubdivision.Basic.Incident s (Data.PlanarGraph.Core.VertexId' s) (Data.PlanarGraph.Core.FaceId' s) instance forall k (s :: k). Data.Geometry.PlanarSubdivision.Basic.Incident s (Data.PlanarGraph.Dart.Dart s) (Data.PlanarGraph.Core.VertexId' s) instance forall k (s :: k). Data.Geometry.PlanarSubdivision.Basic.Incident s (Data.PlanarGraph.Dart.Dart s) (Data.PlanarGraph.Core.FaceId' s) instance forall k (s :: k). Data.Geometry.PlanarSubdivision.Basic.Incident s (Data.PlanarGraph.Core.FaceId' s) (Data.PlanarGraph.Core.VertexId' s) instance forall k (s :: k). Data.Geometry.PlanarSubdivision.Basic.Incident s (Data.PlanarGraph.Core.FaceId' s) (Data.PlanarGraph.Dart.Dart s) instance forall k (s :: k) v e f r. Data.Geometry.Box.Internal.IsBoxable (Data.Geometry.PlanarSubdivision.Basic.PlanarSubdivision s v e f r) instance forall k (s :: k) v e f r. Data.PlanarGraph.Core.HasDataOf (Data.Geometry.PlanarSubdivision.Basic.PlanarSubdivision s v e f r) (Data.PlanarGraph.Core.VertexId' s) instance forall k (s :: k) v e f r. Data.PlanarGraph.Core.HasDataOf (Data.Geometry.PlanarSubdivision.Basic.PlanarSubdivision s v e f r) (Data.PlanarGraph.Dart.Dart s) instance forall k (s :: k) v e f r. Data.PlanarGraph.Core.HasDataOf (Data.Geometry.PlanarSubdivision.Basic.PlanarSubdivision s v e f r) (Data.PlanarGraph.Core.FaceId' s) instance forall k (s :: k) v e f r. GHC.Generics.Generic (Data.Geometry.PlanarSubdivision.Basic.PlanarSubdivision s v e f r) instance forall k (s :: k) v e f. GHC.Base.Functor (Data.Geometry.PlanarSubdivision.Basic.PlanarSubdivision s v e f) instance forall k (s :: k) v e f r. (GHC.Classes.Eq r, GHC.Classes.Eq v, GHC.Classes.Eq e, GHC.Classes.Eq f) => GHC.Classes.Eq (Data.Geometry.PlanarSubdivision.Basic.PlanarSubdivision s v e f r) instance forall k (s :: k) v e f r. (GHC.Show.Show r, GHC.Show.Show v, GHC.Show.Show e, GHC.Show.Show f) => GHC.Show.Show (Data.Geometry.PlanarSubdivision.Basic.PlanarSubdivision s v e f r) module Data.Geometry.PlanarSubdivision.Merge -- | Merge a pair of *disjoint* planar subdivisions, unifying their outer -- face. For the outerface data it simply takes the data of the first -- subdivision. -- -- runningtime: <math> merge :: PlanarSubdivision s v e f r -> PlanarSubdivision s v e f r -> PlanarSubdivision s v e f r -- | Merge a pair of *disjoint* planar subdivisions. In particular, this -- function unifies the structure assuming that the two subdivisions -- share the outer face. -- -- runningtime: <math> mergeWith :: (f -> f -> f) -> PlanarSubdivision s v e f r -> PlanarSubdivision s v e f r -> PlanarSubdivision s v e f r -- | Merge a pair of *disjoint* planar subdivisions, unifying their outer -- face. The given function is used to merge the data corresponding to -- the outer face. The subdivisions are merged pairwise, no guarantees -- are given about the order in which they are merged. Hence, it is -- expected that f is commutative. -- -- running time: <math>, where <math> is the total size of -- the subdivisions. mergeAllWith :: Foldable1 t => (f -> f -> f) -> t (PlanarSubdivision s v e f r) -> PlanarSubdivision s v e f r embedAsHoleIn :: forall s h v e f r. PlanarSubdivision h v e f r -> (f -> f -> f) -> FaceId' s -> PlanarSubdivision s v e f r -> PlanarSubdivision s v e f r embedAsHolesIn :: forall t s h v e f r. (Foldable1 t, Functor t) => t (PlanarSubdivision h v e f r) -> (t f -> f -> f) -> FaceId' s -> PlanarSubdivision s v e f r -> PlanarSubdivision s v e f r -- | Data type to represent a PlanarSubdivision module Data.Geometry.PlanarSubdivision -- | Constructs a planar subdivision from a collection of <math> -- disjoint polygons of total complexity <math>. -- -- pre: The boundary of the polygons is given in counterclockwise -- orientation -- -- runningtime: <math> in case of polygons with holes, and -- <math> in case of simple polygons. fromPolygons :: (Foldable1 c, Ord r, Fractional r) => proxy s -> f -> c (Polygon t p r :+ f) -> PlanarSubdivision s p () f r -- | Version of fromPolygons that accepts SomePolygons as -- input. fromPolygons' :: forall proxy c s p r f. (Foldable1 c, Ord r, Fractional r) => proxy s -> f -> c (SomePolygon p r :+ f) -> PlanarSubdivision s p () f r -- | Construct a planar subdivision from a polygon. Since our -- PlanarSubdivision models only connected planar subdivisions, this may -- add dummy/invisible edges. -- -- pre: The outer boundary of the polygons is given in counterclockwise -- orientation -- -- running time: <math> for a simple polygon, <math> for a -- polygon with holes. fromPolygon :: forall proxy t p f r s. (Ord r, Fractional r) => proxy s -> Polygon t p r -> f -> f -> PlanarSubdivision s p () f r instance (GHC.Classes.Eq f, GHC.Classes.Eq p) => GHC.Classes.Eq (Data.Geometry.PlanarSubdivision.HoleData f p) instance (GHC.Show.Show f, GHC.Show.Show p) => GHC.Show.Show (Data.Geometry.PlanarSubdivision.HoleData f p) module Data.Geometry.PointLocation.PersistentSweep -- | Planar Point Location Data structure data PointLocationDS s v e f r PointLocationDS :: VerticalRayShootingStructure v (Dart s) r -> PlanarSubdivision s v e f r -> FaceId' s -> PointLocationDS s v e f r verticalRayShootingStructure :: forall k_a3xHR (s_a3xHC :: k_a3xHR) v_a3xHD e_a3xHE f_a3xHF r_a3xHG. Getter (PointLocationDS (s_a3xHC :: k_a3xHR) v_a3xHD e_a3xHE f_a3xHF r_a3xHG) (VerticalRayShootingStructure v_a3xHD (Dart s_a3xHC) r_a3xHG) subdivision :: forall k_a3xHR (s_a3xHC :: k_a3xHR) v_a3xHD e_a3xHE f_a3xHF r_a3xHG. Getter (PointLocationDS (s_a3xHC :: k_a3xHR) v_a3xHD e_a3xHE f_a3xHF r_a3xHG) (PlanarSubdivision s_a3xHC v_a3xHD e_a3xHE f_a3xHF r_a3xHG) outerFace :: forall k_a3xHR (s_a3xHC :: k_a3xHR) v_a3xHD e_a3xHE f_a3xHF r_a3xHG. Getter (PointLocationDS (s_a3xHC :: k_a3xHR) v_a3xHD e_a3xHE f_a3xHF r_a3xHG) (FaceId' s_a3xHC) -- | Builds a pointlocation data structure on the planar subdivision with -- <math> vertices. -- -- running time: <math>. space: <math>. pointLocationDS :: (Ord r, Fractional r) => PlanarSubdivision s v e f r -> PointLocationDS s v e f r -- | Locates the first edge (dart) strictly above the query point. returns -- Nothing if the query point lies in the outer face and there is no dart -- above it. -- -- running time: <math> dartAbove :: (Ord r, Fractional r) => Point 2 r -> PointLocationDS s v e f r -> Maybe (Dart s) dartAboveOrOn :: (Ord r, Fractional r) => Point 2 r -> PointLocationDS s v e f r -> Maybe (Dart s) -- | Locates the face containing the query point. -- -- running time: <math> faceContaining :: (Ord r, Fractional r) => Point 2 r -> PointLocationDS s v e f r -> f -- | Locates the faceId of the face containing the query point. -- -- If the query point lies *on* an edge, an arbitrary face incident to -- the edge is returned. -- -- running time: <math> faceIdContaining :: (Ord r, Fractional r) => Point 2 r -> PointLocationDS s v e f r -> FaceId' s type InPolygonDS v r = PointLocationDS Dummy (SP Int v) () InOut r inPolygonDS :: (Fractional r, Ord r) => SimplePolygon v r -> InPolygonDS v r -- | Data structure for fast InPolygon Queries newtype InPolygonDS v r = -- InPolygonDS (VRS.VerticalRayShootingStructure (Vertex v r) () r) -- deriving (Show,Eq) data InOut In :: InOut Out :: InOut -- | Returns if a query point lies in (or on the boundary of) the polygon. -- -- <math> pointInPolygon :: (Ord r, Fractional r) => Point 2 r -> InPolygonDS v r -> InOut -- | Finds the edge on or above the query point, if it exists edgeOnOrAbove :: (Ord r, Fractional r) => Point 2 r -> InPolygonDS v r -> Maybe (LineSegment 2 (SP Int v) r) instance Data.Traversable.Traversable Data.Geometry.PointLocation.PersistentSweep.OneOrTwo instance Data.Foldable.Foldable Data.Geometry.PointLocation.PersistentSweep.OneOrTwo instance GHC.Base.Functor Data.Geometry.PointLocation.PersistentSweep.OneOrTwo instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.Geometry.PointLocation.PersistentSweep.OneOrTwo a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Geometry.PointLocation.PersistentSweep.OneOrTwo a) instance GHC.Read.Read a => GHC.Read.Read (Data.Geometry.PointLocation.PersistentSweep.OneOrTwo a) instance GHC.Show.Show a => GHC.Show.Show (Data.Geometry.PointLocation.PersistentSweep.OneOrTwo a) instance GHC.Classes.Eq Data.Geometry.PointLocation.PersistentSweep.InOut instance GHC.Show.Show Data.Geometry.PointLocation.PersistentSweep.InOut instance forall k (s :: k) v e f r. (GHC.Classes.Eq r, GHC.Classes.Eq v, GHC.Classes.Eq e, GHC.Classes.Eq f) => GHC.Classes.Eq (Data.Geometry.PointLocation.PersistentSweep.PointLocationDS s v e f r) instance forall k (s :: k) v e f r. (GHC.Show.Show r, GHC.Show.Show v, GHC.Show.Show e, GHC.Show.Show f) => GHC.Show.Show (Data.Geometry.PointLocation.PersistentSweep.PointLocationDS s v e f r) module Data.Geometry.PointLocation module Data.Geometry.PlanarSubdivision.Dynamic -- | Splits a given edge of a planar subdivision by inserting a new vertex -- on the edges. Increases edges by 1. splitEdge :: (Show v, Show e, Show f, Show r) => VertexId' s -> VertexId' s -> Point 2 r -> v -> (e -> (e, e)) -> PlanarSubdivision s v e f r -> PlanarSubdivision s v e f r -- | Splits a given edge of a planar subdivision by inserting a new vertex -- on the edges. Increases edges by 1. unSplitEdge :: (Show v, Show e, Show f, Show r) => VertexId' s -> ((e, e) -> e) -> PlanarSubdivision s v e f r -> PlanarSubdivision s v e f r -- | Sprouts a new edge from a given vertex into the interior of a given -- (incident) face. Increases edges by 1. sproutIntoFace :: (Show v, Show e, Show f, Show r) => VertexId' s -> FaceId' s -> Point 2 r -> v -> (e, e) -> PlanarSubdivision s v e f r -> PlanarSubdivision s v e f r -- | Inserts a new edge between two given vertices, adjacent to a common -- face. Increases faces by 1. splitFace :: (Show v, Show e, Show f, Show r) => VertexId' s -> VertexId' s -> (e, e) -> (f -> (f, f)) -> PlanarSubdivision s v e f r -> PlanarSubdivision s v e f r -- | Data type for representing an Arrangement of lines in <math>. module Data.Geometry.Arrangement.Internal type ArrangementBoundary s e r = Vector (Point 2 r, VertexId' s, Maybe (Line 2 r :+ e)) -- | Data type representing a two dimensional planar arrangement data Arrangement s l v e f r Arrangement :: Vector (Line 2 r :+ l) -> PlanarSubdivision s v e f r -> Rectangle () r -> ArrangementBoundary s l r -> Arrangement s l v e f r [_inputLines] :: Arrangement s l v e f r -> Vector (Line 2 r :+ l) [_subdivision] :: Arrangement s l v e f r -> PlanarSubdivision s v e f r [_boundedArea] :: Arrangement s l v e f r -> Rectangle () r [_unboundedIntersections] :: Arrangement s l v e f r -> ArrangementBoundary s l r unboundedIntersections :: forall k_a3CsL (s_a3Csh :: k_a3CsL) l_a3Csi v_a3Csj e_a3Csk f_a3Csl r_a3Csm. Lens' (Arrangement (s_a3Csh :: k_a3CsL) l_a3Csi v_a3Csj e_a3Csk f_a3Csl r_a3Csm) (ArrangementBoundary s_a3Csh l_a3Csi r_a3Csm) subdivision :: forall k_a3CsL (s_a3Csh :: k_a3CsL) l_a3Csi v_a3Csj e_a3Csk f_a3Csl r_a3Csm v_a3CzY e_a3CzZ f_a3CA0. Lens (Arrangement (s_a3Csh :: k_a3CsL) l_a3Csi v_a3Csj e_a3Csk f_a3Csl r_a3Csm) (Arrangement (s_a3Csh :: k_a3CsL) l_a3Csi v_a3CzY e_a3CzZ f_a3CA0 r_a3Csm) (PlanarSubdivision s_a3Csh v_a3Csj e_a3Csk f_a3Csl r_a3Csm) (PlanarSubdivision s_a3Csh v_a3CzY e_a3CzZ f_a3CA0 r_a3Csm) inputLines :: forall k_a3CsL (s_a3Csh :: k_a3CsL) l_a3Csi v_a3Csj e_a3Csk f_a3Csl r_a3Csm. Lens' (Arrangement (s_a3Csh :: k_a3CsL) l_a3Csi v_a3Csj e_a3Csk f_a3Csl r_a3Csm) (Vector ((:+) (Line 2 r_a3Csm) l_a3Csi)) boundedArea :: forall k_a3CsL (s_a3Csh :: k_a3CsL) l_a3Csi v_a3Csj e_a3Csk f_a3Csl r_a3Csm. Lens' (Arrangement (s_a3Csh :: k_a3CsL) l_a3Csi v_a3Csj e_a3Csk f_a3Csl r_a3Csm) (Rectangle () r_a3Csm) -- | Builds an arrangement of <math> lines -- -- running time: <math> constructArrangement :: (Ord r, Fractional r) => proxy s -> [Line 2 r :+ l] -> Arrangement s l () (Maybe l) () r -- | Constructs the arrangemnet inside the box. note that the resulting box -- may be larger than the given box to make sure that all vertices of the -- arrangement actually fit. -- -- running time: <math> constructArrangementInBox :: (Ord r, Fractional r) => proxy s -> Rectangle () r -> [Line 2 r :+ l] -> Arrangement s l () (Maybe l) () r -- | Constructs the arrangemnet inside the box. (for parts to be useful, it -- is assumed this boxfits at least the boundingbox of the intersections -- in the Arrangement) constructArrangementInBox' :: (Ord r, Fractional r) => proxy s -> Rectangle () r -> [Line 2 r :+ l] -> Arrangement s l () (Maybe l) () r computeSegsAndParts :: forall r l. (Ord r, Fractional r) => Rectangle () r -> [Line 2 r :+ l] -> ([LineSegment 2 () r :+ Maybe l], [(Point 2 r, Maybe (Line 2 r :+ l))]) perLine :: forall r l. (Ord r, Fractional r) => Rectangle () r -> (Line 2 r :+ l) -> [Line 2 r :+ l] -> [LineSegment 2 () r :+ l] intersectionPoint :: forall r l. (Ord r, Fractional r) => (Line 2 r :+ l) -> (Line 2 r :+ l) -> Maybe (Point 2 r) toSegments :: Ord r => [Point 2 r] -> [LineSegment 2 () r] -- | Constructs a boundingbox containing all intersections -- -- running time: <math>, where <math> is the number of input -- lines makeBoundingBox :: (Ord r, Fractional r) => [Line 2 r :+ l] -> Rectangle () r -- | Computes all intersections intersections :: (Ord r, Fractional r) => [Line 2 r :+ l] -> [Point 2 r] -- | Computes the intersections with a particular side sideIntersections :: (Ord r, Fractional r) => [Line 2 r :+ l] -> LineSegment 2 q r -> [(Point 2 r, Line 2 r :+ l)] -- | Constructs the unbounded intersections. Reported in clockwise -- direction. unBoundedParts :: (Ord r, Fractional r) => Rectangle () r -> [Line 2 r :+ l] -> [(Point 2 r, Maybe (Line 2 r :+ l))] -- | Links the vertices of the outer boundary with those in the subdivision link :: Eq r => [(Point 2 r, a)] -> PlanarSubdivision s v (Maybe e) f r -> Vector (Point 2 r, VertexId' s, a) makePairs :: [a] -> [(a, [a])] allPairs :: [a] -> [(a, a)] -- | Given a predicate that tests if two elements of a CSeq match, find a -- rotation of the seqs such at they match. -- -- Running time: <math> alignWith :: (a -> b -> Bool) -> CSeq a -> CSeq b -> Maybe (CSeq (a, b)) -- | Given an Arrangement and a line in the arrangement, follow the line -- through he arrangement. traverseLine :: (Ord r, Fractional r) => Line 2 r -> Arrangement s l v (Maybe e) f r -> [Dart s] -- | Find the starting point of the line the arrangement findStart :: forall s l v e f r. (Ord r, Fractional r) => Line 2 r -> Arrangement s l v (Maybe e) f r -> Maybe (Dart s) -- | Given a point on the boundary of the boundedArea box; find the vertex -- this point corresponds to. -- -- running time: <math> -- -- basically; maps every point to a tuple of the point and the side the -- point occurs on. We then binary search to find the point we are -- looking for. findStartVertex :: (Ord r, Fractional r) => Point 2 r -> Arrangement s l v e f r -> Maybe (Point 2 r, VertexId' s, Maybe (Line 2 r :+ l)) -- | Find the starting dart of the given vertex v. Reports a dart s.t. -- tailOf d = v -- -- running me: <math> where <math> is the degree of the -- vertex findStartDart :: PlanarSubdivision s v (Maybe e) f r -> VertexId' s -> Maybe (Dart s) -- | Given a dart d that incoming to v (headOf d == v), find the outgoing -- dart colinear with the incoming one. Again reports dart d' s.t. tailOf -- d' = v -- -- running time: <math>, where k is the degree of the vertex d -- points to follow :: (Ord r, Num r) => Arrangement s l v e f r -> Dart s -> Maybe (Dart s) instance forall k (s :: k) l v e f r. (GHC.Real.Fractional r, GHC.Classes.Eq r, GHC.Classes.Eq l, GHC.Classes.Eq v, GHC.Classes.Eq e, GHC.Classes.Eq f) => GHC.Classes.Eq (Data.Geometry.Arrangement.Internal.Arrangement s l v e f r) instance forall k (s :: k) l v e f r. (GHC.Show.Show r, GHC.Show.Show l, GHC.Show.Show v, GHC.Show.Show e, GHC.Show.Show f) => GHC.Show.Show (Data.Geometry.Arrangement.Internal.Arrangement s l v e f r) -- | Data type for representing an Arrangement of lines in <math>. module Data.Geometry.Arrangement -- | Data type representing a two dimensional planar arrangement data Arrangement s l v e f r Arrangement :: Vector (Line 2 r :+ l) -> PlanarSubdivision s v e f r -> Rectangle () r -> ArrangementBoundary s l r -> Arrangement s l v e f r [_inputLines] :: Arrangement s l v e f r -> Vector (Line 2 r :+ l) [_subdivision] :: Arrangement s l v e f r -> PlanarSubdivision s v e f r [_boundedArea] :: Arrangement s l v e f r -> Rectangle () r [_unboundedIntersections] :: Arrangement s l v e f r -> ArrangementBoundary s l r inputLines :: forall k_a3CsL (s_a3Csh :: k_a3CsL) l_a3Csi v_a3Csj e_a3Csk f_a3Csl r_a3Csm. Lens' (Arrangement (s_a3Csh :: k_a3CsL) l_a3Csi v_a3Csj e_a3Csk f_a3Csl r_a3Csm) (Vector ((:+) (Line 2 r_a3Csm) l_a3Csi)) subdivision :: forall k_a3CsL (s_a3Csh :: k_a3CsL) l_a3Csi v_a3Csj e_a3Csk f_a3Csl r_a3Csm v_a3CzY e_a3CzZ f_a3CA0. Lens (Arrangement (s_a3Csh :: k_a3CsL) l_a3Csi v_a3Csj e_a3Csk f_a3Csl r_a3Csm) (Arrangement (s_a3Csh :: k_a3CsL) l_a3Csi v_a3CzY e_a3CzZ f_a3CA0 r_a3Csm) (PlanarSubdivision s_a3Csh v_a3Csj e_a3Csk f_a3Csl r_a3Csm) (PlanarSubdivision s_a3Csh v_a3CzY e_a3CzZ f_a3CA0 r_a3Csm) boundedArea :: forall k_a3CsL (s_a3Csh :: k_a3CsL) l_a3Csi v_a3Csj e_a3Csk f_a3Csl r_a3Csm. Lens' (Arrangement (s_a3Csh :: k_a3CsL) l_a3Csi v_a3Csj e_a3Csk f_a3Csl r_a3Csm) (Rectangle () r_a3Csm) unboundedIntersections :: forall k_a3CsL (s_a3Csh :: k_a3CsL) l_a3Csi v_a3Csj e_a3Csk f_a3Csl r_a3Csm. Lens' (Arrangement (s_a3Csh :: k_a3CsL) l_a3Csi v_a3Csj e_a3Csk f_a3Csl r_a3Csm) (ArrangementBoundary s_a3Csh l_a3Csi r_a3Csm) type ArrangementBoundary s e r = Vector (Point 2 r, VertexId' s, Maybe (Line 2 r :+ e)) -- | Builds an arrangement of <math> lines -- -- running time: <math> constructArrangement :: (Ord r, Fractional r) => proxy s -> [Line 2 r :+ l] -> Arrangement s l () (Maybe l) () r -- | Constructs the arrangemnet inside the box. note that the resulting box -- may be larger than the given box to make sure that all vertices of the -- arrangement actually fit. -- -- running time: <math> constructArrangementInBox :: (Ord r, Fractional r) => proxy s -> Rectangle () r -> [Line 2 r :+ l] -> Arrangement s l () (Maybe l) () r -- | Constructs the arrangemnet inside the box. (for parts to be useful, it -- is assumed this boxfits at least the boundingbox of the intersections -- in the Arrangement) constructArrangementInBox' :: (Ord r, Fractional r) => proxy s -> Rectangle () r -> [Line 2 r :+ l] -> Arrangement s l () (Maybe l) () r -- | Given an Arrangement and a line in the arrangement, follow the line -- through he arrangement. traverseLine :: (Ord r, Fractional r) => Line 2 r -> Arrangement s l v (Maybe e) f r -> [Dart s] -- | Find the starting point of the line the arrangement findStart :: forall s l v e f r. (Ord r, Fractional r) => Line 2 r -> Arrangement s l v (Maybe e) f r -> Maybe (Dart s) -- | Given a point on the boundary of the boundedArea box; find the vertex -- this point corresponds to. -- -- running time: <math> -- -- basically; maps every point to a tuple of the point and the side the -- point occurs on. We then binary search to find the point we are -- looking for. findStartVertex :: (Ord r, Fractional r) => Point 2 r -> Arrangement s l v e f r -> Maybe (Point 2 r, VertexId' s, Maybe (Line 2 r :+ l)) -- | Find the starting dart of the given vertex v. Reports a dart s.t. -- tailOf d = v -- -- running me: <math> where <math> is the degree of the -- vertex findStartDart :: PlanarSubdivision s v (Maybe e) f r -> VertexId' s -> Maybe (Dart s) -- | Given a dart d that incoming to v (headOf d == v), find the outgoing -- dart colinear with the incoming one. Again reports dart d' s.t. tailOf -- d' = v -- -- running time: <math>, where k is the degree of the vertex d -- points to follow :: (Ord r, Num r) => Arrangement s l v e f r -> Dart s -> Maybe (Dart s) module Algorithms.Geometry.PolygonTriangulation.Types -- | After triangulation, edges are either from the original polygon or a -- new diagonal. data PolygonEdgeType Original :: PolygonEdgeType Diagonal :: PolygonEdgeType -- | Given a list of original edges and a list of diagonals, creates a -- planar-subdivision -- -- running time: <math> constructSubdivision :: forall proxy r s p. (Fractional r, Ord r) => proxy s -> LineSegment 2 p r -> [LineSegment 2 p r] -> [LineSegment 2 p r] -> PlanarSubdivision s p PolygonEdgeType PolygonFaceData r -- | Given a list of original edges and a list of diagonals, creates a -- planar-subdivision -- -- running time: <math> constructGraph :: forall proxy r s p. (Fractional r, Ord r) => proxy s -> LineSegment 2 p r -> [LineSegment 2 p r] -> [LineSegment 2 p r] -> PlaneGraph s p PolygonEdgeType PolygonFaceData r instance GHC.Classes.Eq Algorithms.Geometry.PolygonTriangulation.Types.PolygonEdgeType instance GHC.Read.Read Algorithms.Geometry.PolygonTriangulation.Types.PolygonEdgeType instance GHC.Show.Show Algorithms.Geometry.PolygonTriangulation.Types.PolygonEdgeType module Algorithms.Geometry.PolygonTriangulation.MakeMonotone -- | Computes a set of diagionals that decompose the polygon into -- y-monotone pieces. -- -- pre: the polygon boundary is given in counterClockwise order. -- -- running time: <math> makeMonotone :: (Fractional r, Ord r) => proxy s -> Polygon t p r -> PlanarSubdivision s p PolygonEdgeType PolygonFaceData r -- | Given a polygon, find a set of non-intersecting diagonals that -- partition the polygon into y-monotone pieces. -- -- running time: <math> computeDiagonals :: forall t r p. (Fractional r, Ord r) => Polygon t p r -> [LineSegment 2 p r] data VertexType Start :: VertexType Merge :: VertexType Split :: VertexType End :: VertexType Regular :: VertexType -- | assigns a vertex type to each vertex -- -- pre: Both the outer boundary and the inner boundary of the polygon are -- given in CCW order. -- -- running time: <math>. classifyVertices :: (Num r, Ord r) => Polygon t p r -> Polygon t (p :+ VertexType) r instance GHC.Classes.Eq Algorithms.Geometry.PolygonTriangulation.MakeMonotone.VertexType instance GHC.Read.Read Algorithms.Geometry.PolygonTriangulation.MakeMonotone.VertexType instance GHC.Show.Show Algorithms.Geometry.PolygonTriangulation.MakeMonotone.VertexType instance GHC.Show.Show r => GHC.Show.Show (Algorithms.Geometry.PolygonTriangulation.MakeMonotone.StatusStruct r) module Algorithms.Geometry.PolygonTriangulation.TriangulateMonotone -- | Y-monotone polygon. All straight horizontal lines intersects the -- polygon no more than twice. type MonotonePolygon p r = SimplePolygon p r -- | Triangulates a polygon of <math> vertices -- -- running time: <math> triangulate :: (Ord r, Fractional r) => proxy s -> MonotonePolygon p r -> PlanarSubdivision s p PolygonEdgeType PolygonFaceData r -- | Triangulates a polygon of <math> vertices -- -- running time: <math> triangulate' :: (Ord r, Fractional r) => proxy s -> MonotonePolygon p r -> PlaneGraph s p PolygonEdgeType PolygonFaceData r -- | Given a y-monotone polygon in counter clockwise order computes the -- diagonals to add to triangulate the polygon -- -- pre: the input polygon is y-monotone and has <math> vertices -- -- running time: <math> computeDiagonals :: (Ord r, Num r) => MonotonePolygon p r -> [LineSegment 2 p r] instance GHC.Classes.Eq Algorithms.Geometry.PolygonTriangulation.TriangulateMonotone.LR instance GHC.Show.Show Algorithms.Geometry.PolygonTriangulation.TriangulateMonotone.LR module Algorithms.Geometry.PolygonTriangulation.Triangulate -- | Triangulates a polygon of <math> vertices -- -- running time: <math> triangulate :: (Ord r, Fractional r) => proxy s -> Polygon t p r -> PlanarSubdivision s p PolygonEdgeType PolygonFaceData r -- | Triangulates a polygon of <math> vertices -- -- running time: <math> triangulate' :: (Ord r, Fractional r) => proxy s -> Polygon t p r -> PlaneGraph s p PolygonEdgeType PolygonFaceData r -- | Computes a set of diagaonals that together triangulate the input -- polygon of <math> vertices. -- -- running time: <math> computeDiagonals :: (Ord r, Fractional r) => Polygon t p r -> [LineSegment 2 p r] -- | Computes a set of diagaonals that together triangulate the input -- polygon of <math> vertices. Returns a copy of the input polygon, -- whose boundaries are oriented in counter clockwise order, as well. -- -- running time: <math> computeDiagonals' :: (Ord r, Fractional r) => Polygon t p r -> (Polygon t p r, [LineSegment 2 p r]) module Algorithms.Geometry.SSSP -- | Single-source shortest paths tree. Both keys and values are vertex -- offset ints. -- --
--   parentOf(i) = sssp[i]
--   
type SSSP = Vector Int -- | <math> triangulate :: (Ord r, Fractional r) => SimplePolygon p r -> PlaneGraph s Int PolygonEdgeType PolygonFaceData r -- | <math> Single-Source shortest path. sssp :: (Ord r, Fractional r) => PlaneGraph s Int PolygonEdgeType PolygonFaceData r -> SSSP visibilityDual :: forall s r. (Ord r, Fractional r) => PlaneGraph s Int PolygonEdgeType PolygonFaceData r -> Dual r visibilityFinger :: forall r. (Fractional r, Ord r, Show r) => Dual r -> [Either (Int, Int, Int) (Point 2 r)] visibilitySensitive :: forall s r. (Ord r, Fractional r, Show r) => PlaneGraph s Int PolygonEdgeType PolygonFaceData r -> SimplePolygon () r instance GHC.Show.Show (Algorithms.Geometry.SSSP.MinMax r) instance GHC.Show.Show (Algorithms.Geometry.SSSP.Funnel r) instance GHC.Show.Show Algorithms.Geometry.SSSP.SplitDirection instance GHC.Show.Show (Algorithms.Geometry.SSSP.DualTree r) instance GHC.Show.Show (Algorithms.Geometry.SSSP.Dual r) instance GHC.Base.Semigroup (Algorithms.Geometry.SSSP.MinMax r) instance GHC.Base.Monoid (Algorithms.Geometry.SSSP.MinMax r) instance Data.FingerTree.Measured (Algorithms.Geometry.SSSP.MinMax r) (Algorithms.Geometry.SSSP.Index r) instance GHC.Show.Show (Algorithms.Geometry.SSSP.Index r) instance GHC.Classes.Eq (Algorithms.Geometry.SSSP.Index r) module Data.Geometry.Polygon.Inflate -- | Points annotated with an Arc indicate that the edge from this -- point to the next should not be a straight line but instead an arc -- with a given center and a given border edge. data Arc r Arc :: Point 2 r -> (Point 2 r, Point 2 r) -> Arc r [arcCenter] :: Arc r -> Point 2 r [arcEdge] :: Arc r -> (Point 2 r, Point 2 r) -- | <math> inflate :: (Real r, Fractional r) => Double -> SimplePolygon () r -> SimplePolygon (Arc r) r instance GHC.Show.Show r => GHC.Show.Show (Data.Geometry.Polygon.Inflate.Arc r) module Algorithms.Geometry.PolygonTriangulation -- | Triangulates a polygon of <math> vertices -- -- running time: <math> triangulate :: (Ord r, Fractional r) => proxy s -> Polygon t p r -> PlanarSubdivision s p PolygonEdgeType PolygonFaceData r -- | Triangulates a polygon of <math> vertices -- -- running time: <math> triangulate' :: (Ord r, Fractional r) => proxy s -> Polygon t p r -> PlaneGraph s p PolygonEdgeType PolygonFaceData r -- | Computes a set of diagaonals that together triangulate the input -- polygon of <math> vertices. -- -- running time: <math> computeDiagonals :: (Ord r, Fractional r) => Polygon t p r -> [LineSegment 2 p r] -- | Defines some geometric types used in the delaunay triangulation module Algorithms.Geometry.DelaunayTriangulation.Types -- | Vertex identifier. type VertexID = Int -- | Rotating Right - rotate clockwise type Vertex = CList VertexID -- | Neighbours indexed by VertexID. type Adj = IntMap (CList VertexID) -- | Neighbours are stored in clockwise order: i.e. rotating right moves to -- the next clockwise neighbour. data Triangulation p r Triangulation :: Map (Point 2 r) VertexID -> Vector (Point 2 r :+ p) -> Vector (CList VertexID) -> Triangulation p r [_vertexIds] :: Triangulation p r -> Map (Point 2 r) VertexID [_positions] :: Triangulation p r -> Vector (Point 2 r :+ p) [_neighbours] :: Triangulation p r -> Vector (CList VertexID) -- | Mapping between triangulated points and their internal VertexID. vertexIds :: Lens' (Triangulation p r) (Map (Point 2 r) VertexID) -- | Point positions indexed by VertexID. positions :: Lens (Triangulation p1 r) (Triangulation p2 r) (Vector (Point 2 r :+ p1)) (Vector (Point 2 r :+ p2)) -- | Point neighbours indexed by VertexID. neighbours :: Lens' (Triangulation p r) (Vector (CList VertexID)) -- | Bidirectional mapping between points and VertexIDs. type Mapping p r = (Map (Point 2 r) VertexID, Vector (Point 2 r :+ p)) -- | List add edges as point pairs. edgesAsPoints :: Triangulation p r -> [(Point 2 r :+ p, Point 2 r :+ p)] -- | List add edges as VertexID pairs. edgesAsVertices :: Triangulation p r -> [(VertexID, VertexID)] -- | ST' is a strict triple (m,a,x) containing: -- -- -- -- convert the triangulation into a planarsubdivision -- -- running time: <math>. toPlanarSubdivision :: (Ord r, Fractional r) => proxy s -> Triangulation p r -> PlanarSubdivision s p () () r -- | convert the triangulation into a plane graph -- -- running time: <math>. toPlaneGraph :: forall proxy s p r. proxy s -> Triangulation p r -> PlaneGraph s p () () r instance (GHC.Classes.Eq r, GHC.Classes.Eq p) => GHC.Classes.Eq (Algorithms.Geometry.DelaunayTriangulation.Types.Triangulation p r) instance (GHC.Show.Show r, GHC.Show.Show p) => GHC.Show.Show (Algorithms.Geometry.DelaunayTriangulation.Types.Triangulation p r) module Algorithms.Geometry.DelaunayTriangulation.Naive -- | Naive <math> time implementation of the delaunay triangulation. -- Simply tries each triple (p,q,r) and tests if it is delaunay, i.e. if -- there are no other points in the circle defined by p, q, and r. -- -- pre: the input is a *SET*, i.e. contains no duplicate points. (If the -- input does contain duplicate points, the implementation throws them -- away) delaunayTriangulation :: (Ord r, Fractional r) => NonEmpty (Point 2 r :+ p) -> Triangulation p r -- | Given a list of edges, as vertexId pairs, construct a vector with the -- adjacency lists, each in CW sorted order. toAdjLists :: (Num r, Ord r) => Mapping p r -> [(VertexID, VertexID)] -> Vector (CList VertexID) -- | Given a particular point u and a list of points vs, sort the points vs -- in CW order around u. running time: <math>, where m=|vs| is the -- number of vertices to sort. sortAroundMapping :: (Num r, Ord r) => Mapping p r -> VertexID -> [VertexID] -> [VertexID] -- | Given a list of faces, construct a list of edges extractEdges :: [(VertexID, VertexID, VertexID)] -> [(VertexID, VertexID)] -- | <math> Test if the given three points form a triangle in the -- delaunay triangulation. isDelaunay :: (Fractional r, Ord r) => Mapping p r -> VertexID -> VertexID -> VertexID -> Bool module Algorithms.Geometry.DelaunayTriangulation.DivideAndConquer -- | Computes the delaunay triangulation of a set of points. -- -- Running time: <math> (note: We use an IntMap in the -- implementation. So maybe actually <math>) -- -- pre: the input is a *SET*, i.e. contains no duplicate points. (If the -- input does contain duplicate points, the implementation throws them -- away) delaunayTriangulation :: (Ord r, Fractional r) => NonEmpty (Point 2 r :+ p) -> Triangulation p r -- | <math> time algorithm algorithm to compute the Euclidean minimum -- spanning tree of a set of <math> points in <math>. module Algorithms.Geometry.EuclideanMST -- | Computes the Euclidean Minimum Spanning Tree. We compute the Delaunay -- Triangulation (DT), and then extract the EMST. Hence, the same -- restrictions apply as for the DT: -- -- pre: the input is a *SET*, i.e. contains no duplicate points. (If the -- input does contain duplicate points, the implementation throws them -- away) -- -- running time: <math> euclideanMST :: (Ord r, Fractional r) => NonEmpty (Point 2 r :+ p) -> Tree (Point 2 r :+ p) -- | <math> time algorithm algorithm to compute the Euclidean minimum -- spanning tree of a set of <math> points in <math>. -- | Deprecated: This module will be deleted after 2021-06-01. Use -- Algorithms.Geometry.EuclideanMST instead. module Algorithms.Geometry.EuclideanMST.EuclideanMST module Graphics.Camera -- | A basic camera data type. The fields stored are: -- -- data Camera r Camera :: !Point 3 r -> !Vector 3 r -> !Vector 3 r -> !r -> !r -> !r -> !Vector 2 r -> Camera r -- | Camera position. cameraPosition :: Lens' (Camera r) (Point 3 r) -- | Raw camera normal, i.e. a unit vector into the center of the screen. rawCameraNormal :: Lens' (Camera r) (Vector 3 r) -- | Raw view up vector indicating which side points "upwards" in the -- scene. rawViewUp :: Lens' (Camera r) (Vector 3 r) -- | Viewplane depth (i.e. the distance from the camera position to the -- plane on which we project). viewPlaneDepth :: Lens' (Camera r) r -- | Near distance (everything closer than this is clipped). nearDist :: Lens' (Camera r) r -- | Far distance (everything further away than this is clipped). farDist :: Lens' (Camera r) r -- | Screen dimensions. screenDimensions :: Lens' (Camera r) (Vector 2 r) -- | Lens to get and set the Camera normal, makes sure that the vector -- remains normalized. cameraNormal :: Floating r => Lens' (Camera r) (Vector 3 r) -- | Lens to get and set the viewUp vector. Makes sure the vector remains -- normalized. viewUp :: Floating r => Lens' (Camera r) (Vector 3 r) -- | Full transformation that renders the figure cameraTransform :: Fractional r => Camera r -> Transformation 3 r -- | Translates world coordinates into view coordinates worldToView :: Fractional r => Camera r -> Transformation 3 r -- | Transformation into viewport coordinates toViewPort :: Fractional r => Camera r -> Transformation 3 r -- | constructs a perspective projection perspectiveProjection :: Fractional r => Camera r -> Transformation 3 r -- | Rotates coordinate system around the camera, such that we look in the -- negative z direction rotateCoordSystem :: Num r => Camera r -> Transformation 3 r -- | Flips the y and z axis. flipAxes :: Num r => Transformation 3 r instance GHC.Classes.Ord r => GHC.Classes.Ord (Graphics.Camera.Camera r) instance GHC.Classes.Eq r => GHC.Classes.Eq (Graphics.Camera.Camera r) instance GHC.Show.Show r => GHC.Show.Show (Graphics.Camera.Camera r) module Graphics.Render -- | Rendering function for a triangle. renderTriangle :: Fractional r => Transformation 3 r -> Triangle 3 p r -> Triangle 2 p r -- | Render a point renderPoint :: Fractional r => Transformation 3 r -> Point 3 r -> Point 2 r -- | Renders a line segment renderLineSegment :: Fractional r => Transformation 3 r -> LineSegment 3 p r -> LineSegment 2 p r -- | Generic Rendering Function renderWithTransform :: (Fractional r, IsTransformable g, Dimension g ~ 3, NumType g ~ r) => (g -> g') -> Transformation 3 r -> g -> g'