packages feed

hgeometry 0.10.0.0 → 0.11.0.0

raw patch · 74 files changed

+3332/−677 lines, 74 filesdep +hashabledep +randomdep ~hgeometry-combinatorialPVP ok

version bump matches the API change (PVP)

Dependencies added: hashable, random

Dependency ranges changed: hgeometry-combinatorial

API changes (from Hackage documentation)

- Algorithms.Geometry.LinearProgramming.LP2DRIC: instance (Data.Geometry.Vector.VectorFamily.Arity d, GHC.Classes.Eq r) => GHC.Classes.Eq (Algorithms.Geometry.LinearProgramming.LP2DRIC.LPState d r)
- Algorithms.Geometry.LinearProgramming.Types: instance (Data.Geometry.Vector.VectorFamily.Arity d, GHC.Classes.Eq r) => GHC.Classes.Eq (Algorithms.Geometry.LinearProgramming.Types.LPSolution d r)
- Algorithms.Geometry.LinearProgramming.Types: instance (Data.Geometry.Vector.VectorFamily.Arity d, GHC.Classes.Eq r) => GHC.Classes.Eq (Algorithms.Geometry.LinearProgramming.Types.LinearProgram d r)
- Algorithms.Geometry.WellSeparatedPairDecomposition.Types: instance GHC.Base.Semigroup v => Data.BinaryTree.Measured v (Algorithms.Geometry.WellSeparatedPairDecomposition.Types.NodeData d r v)
- Data.Geometry: E :: (forall x. () => Lens' (t x) x) -> E
- Data.Geometry: [el] :: E -> forall x. () => Lens' (t x) x
- Data.Geometry: fromPoints' :: Monoid p => [Point d r] -> PolyLine d p r
- Data.Geometry: imap :: (Vector v a, Vector v b) => (Int -> a -> b) -> v a -> v b
- Data.Geometry: newtype E (t :: Type -> Type)
- Data.Geometry: type Arity d = (ImplicitArity (Peano d), KnownNat d)
- Data.Geometry.Arrangement.Internal: map4 :: (a -> b) -> (a, a, a, a) -> (b, b, b, b)
- Data.Geometry.Box: bottomSide :: Num r => Rectangle p r -> LineSegment 2 p r
- Data.Geometry.Box: leftSide :: Num r => Rectangle p r -> LineSegment 2 p r
- Data.Geometry.Box: rightSide :: Num r => Rectangle p r -> LineSegment 2 p r
- Data.Geometry.Box: sides :: Num r => Rectangle p r -> (LineSegment 2 p r, LineSegment 2 p r, LineSegment 2 p r, LineSegment 2 p r)
- Data.Geometry.Box: sides' :: Num r => Rectangle p r -> (LineSegment 2 p r, LineSegment 2 p r, LineSegment 2 p r, LineSegment 2 p r)
- Data.Geometry.Box: topSide :: Num r => Rectangle p r -> LineSegment 2 p r
- Data.Geometry.Box.Internal: corners :: Num r => Rectangle p r -> (Point 2 r :+ p, Point 2 r :+ p, Point 2 r :+ p, Point 2 r :+ p)
- Data.Geometry.Box.Internal: instance (Data.Geometry.Vector.VectorFamily.Arity d, GHC.Classes.Ord r) => Data.Intersection.IsIntersectableWith (Data.Geometry.Point.Point d r) (Data.Geometry.Box.Internal.Box d p r)
- Data.Geometry.Box.Internal: instance (Data.Geometry.Vector.VectorFamily.Arity d, GHC.Classes.Ord r) => GHC.Base.Semigroup (Data.Geometry.Box.Internal.CWMax (Data.Geometry.Point.Point d r))
- Data.Geometry.Box.Internal: instance (Data.Geometry.Vector.VectorFamily.Arity d, GHC.Classes.Ord r) => GHC.Base.Semigroup (Data.Geometry.Box.Internal.CWMin (Data.Geometry.Point.Point d r))
- Data.Geometry.Box.Internal: instance Data.Geometry.Box.Internal.IsBoxable (Data.Geometry.Point.Point d r)
- Data.Geometry.Box.Internal: instance Data.Geometry.Point.PointFunctor (Data.Geometry.Box.Internal.Box d p)
- Data.Geometry.HalfLine: instance (GHC.Classes.Eq r, Data.Geometry.Vector.VectorFamily.Arity d) => GHC.Classes.Eq (Data.Geometry.HalfLine.HalfLine d r)
- Data.Geometry.HalfSpace: instance (Data.Geometry.Vector.VectorFamily.Arity d, GHC.Classes.Eq r) => GHC.Classes.Eq (Data.Geometry.HalfSpace.HalfSpace d r)
- Data.Geometry.HalfSpace: instance (GHC.Num.Num r, GHC.Classes.Ord r, Data.Geometry.Vector.VectorFamily.Arity d) => Data.Intersection.IsIntersectableWith (Data.Geometry.Point.Point d r) (Data.Geometry.HalfSpace.HalfSpace d r)
- Data.Geometry.HyperPlane: instance (Data.Geometry.Vector.VectorFamily.Arity d, GHC.Classes.Eq r) => GHC.Classes.Eq (Data.Geometry.HyperPlane.HyperPlane d r)
- Data.Geometry.HyperPlane: instance (GHC.Num.Num r, GHC.Classes.Eq r, Data.Geometry.Vector.VectorFamily.Arity d) => Data.Intersection.IsIntersectableWith (Data.Geometry.Point.Point d r) (Data.Geometry.HyperPlane.HyperPlane d r)
- Data.Geometry.Interval: GInterval :: Range (r :+ a) -> Interval a r
- Data.Geometry.Interval: [_unInterval] :: Interval a r -> Range (r :+ a)
- Data.Geometry.Interval: newtype Interval a r
- Data.Geometry.IntervalTree: toRange :: IntervalLike i => i -> Range (NumType i)
- Data.Geometry.Line: instance (GHC.Classes.Eq r, GHC.Real.Fractional r, Data.Geometry.Vector.VectorFamily.Arity d) => Data.Intersection.IsIntersectableWith (Data.Geometry.Point.Point d r) (Data.Geometry.Line.Internal.Line d r)
- Data.Geometry.Line: instance (GHC.Classes.Ord r, GHC.Num.Num r) => Data.Intersection.IsIntersectableWith (Data.Geometry.Point.Point 2 r) (Data.Geometry.Line.Internal.Line 2 r)
- Data.Geometry.LineSegment: GInterval :: Range (r :+ a) -> Interval a r
- Data.Geometry.LineSegment: [_unInterval] :: Interval a r -> Range (r :+ a)
- Data.Geometry.LineSegment: instance Data.Geometry.Point.PointFunctor (Data.Geometry.LineSegment.LineSegment d p)
- Data.Geometry.LineSegment: newtype Interval a r
- Data.Geometry.Point: CCW :: CCW
- Data.Geometry.Point: CW :: CCW
- Data.Geometry.Point: CoLinear :: CCW
- Data.Geometry.Point: instance (Data.Aeson.Types.FromJSON.FromJSON r, Data.Geometry.Vector.VectorFamily.Arity d, GHC.TypeNats.KnownNat d) => Data.Aeson.Types.FromJSON.FromJSON (Data.Geometry.Point.Point d r)
- Data.Geometry.Point: instance (Data.Aeson.Types.ToJSON.ToJSON r, Data.Geometry.Vector.VectorFamily.Arity d) => Data.Aeson.Types.ToJSON.ToJSON (Data.Geometry.Point.Point d r)
- Data.Geometry.Point: instance (Data.Geometry.Vector.VectorFamily.Arity d, Control.DeepSeq.NFData r) => Control.DeepSeq.NFData (Data.Geometry.Point.Point d r)
- Data.Geometry.Point: instance (Data.Geometry.Vector.VectorFamily.Arity d, Test.QuickCheck.Arbitrary.Arbitrary r) => Test.QuickCheck.Arbitrary.Arbitrary (Data.Geometry.Point.Point d r)
- Data.Geometry.Point: instance (GHC.Classes.Eq r, Data.Geometry.Vector.VectorFamily.Arity d) => GHC.Classes.Eq (Data.Geometry.Point.Point d r)
- Data.Geometry.Point: instance (GHC.Classes.Ord r, Data.Geometry.Vector.VectorFamily.Arity d) => GHC.Classes.Ord (Data.Geometry.Point.Point d r)
- Data.Geometry.Point: instance (GHC.Read.Read r, Data.Geometry.Vector.VectorFamily.Arity d) => GHC.Read.Read (Data.Geometry.Point.Point d r)
- Data.Geometry.Point: instance (GHC.Show.Show r, Data.Geometry.Vector.VectorFamily.Arity d) => GHC.Show.Show (Data.Geometry.Point.Point d r)
- Data.Geometry.Point: instance Data.Geometry.Point.PointFunctor (Data.Geometry.Point.Point d)
- Data.Geometry.Point: instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Foldable.Foldable (Data.Geometry.Point.Point d)
- Data.Geometry.Point: instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Traversable.Traversable (Data.Geometry.Point.Point d)
- Data.Geometry.Point: instance Data.Geometry.Vector.VectorFamily.Arity d => GHC.Base.Functor (Data.Geometry.Point.Point d)
- Data.Geometry.Point: instance Data.Geometry.Vector.VectorFamily.Arity d => Linear.Affine.Affine (Data.Geometry.Point.Point d)
- Data.Geometry.Point: instance GHC.Classes.Eq Data.Geometry.Point.CCW
- Data.Geometry.Point: instance GHC.Classes.Eq Data.Geometry.Point.Quadrant
- Data.Geometry.Point: instance GHC.Classes.Ord Data.Geometry.Point.Quadrant
- Data.Geometry.Point: instance GHC.Enum.Bounded Data.Geometry.Point.Quadrant
- Data.Geometry.Point: instance GHC.Enum.Enum Data.Geometry.Point.Quadrant
- Data.Geometry.Point: instance GHC.Generics.Generic (Data.Geometry.Point.Point d r)
- Data.Geometry.Point: instance GHC.Read.Read Data.Geometry.Point.Quadrant
- Data.Geometry.Point: instance GHC.Show.Show Data.Geometry.Point.CCW
- Data.Geometry.Point: instance GHC.Show.Show Data.Geometry.Point.Quadrant
- Data.Geometry.PolyLine: fromPoints' :: Monoid p => [Point d r] -> PolyLine d p r
- Data.Geometry.PolyLine: instance Data.Geometry.Point.PointFunctor (Data.Geometry.PolyLine.PolyLine d p)
- Data.Geometry.Polygon.Convex: instance Data.Geometry.Point.PointFunctor (Data.Geometry.Polygon.Convex.ConvexPolygon p)
- Data.Geometry.RangeTree: instance (Data.Geometry.RangeTree.RTMeasure v d p r, GHC.Classes.Ord r, 1 GHC.TypeNats.<= d, Data.Geometry.Vector.VectorFamily.Arity d) => Data.BinaryTree.Measured (Data.Geometry.RangeTree.Assoc 2 d v p r) (Data.Geometry.RangeTree.Leaf 2 d v p r)
- Data.Geometry.RangeTree: instance Data.Geometry.RangeTree.RTMeasure v d p r => Data.BinaryTree.Measured (Data.Geometry.RangeTree.Assoc 1 d v p r) (Data.Geometry.RangeTree.Leaf 1 d v p r)
- Data.Geometry.RangeTree.Generic: instance Data.BinaryTree.Measured (Data.Geometry.RangeTree.Measure.Count p) (Data.Geometry.RangeTree.Generic.CountOf p)
- Data.Geometry.RangeTree.Measure: instance Data.BinaryTree.Measured (Data.Geometry.RangeTree.Measure.Report p) (Data.Geometry.RangeTree.Measure.Report p)
- Data.Geometry.SegmentTree.Generic: instance Data.BinaryTree.Measured Data.Geometry.SegmentTree.Generic.Count (Data.Geometry.SegmentTree.Generic.C i)
- Data.Geometry.SegmentTree.Generic: instance Data.BinaryTree.Measured [Data.Geometry.SegmentTree.Generic.I a] (Data.Geometry.SegmentTree.Generic.I a)
- Data.Geometry.Transformation: Matrix :: Vector n (Vector m r) -> Matrix n m r
- Data.Geometry.Transformation: class Invertible n r
- Data.Geometry.Transformation: instance (Data.Geometry.Vector.VectorFamily.Arity n, Data.Geometry.Vector.VectorFamily.Arity m) => GHC.Base.Functor (Data.Geometry.Transformation.Matrix n m)
- Data.Geometry.Transformation: instance (GHC.Classes.Eq r, Data.Geometry.Vector.VectorFamily.Arity n, Data.Geometry.Vector.VectorFamily.Arity m) => GHC.Classes.Eq (Data.Geometry.Transformation.Matrix n m r)
- Data.Geometry.Transformation: instance (GHC.Classes.Ord r, Data.Geometry.Vector.VectorFamily.Arity n, Data.Geometry.Vector.VectorFamily.Arity m) => GHC.Classes.Ord (Data.Geometry.Transformation.Matrix n m r)
- Data.Geometry.Transformation: instance (GHC.Real.Fractional r, Data.Geometry.Vector.VectorFamily.Arity d, Data.Geometry.Vector.VectorFamily.Arity (d GHC.TypeNats.+ 1)) => Data.Geometry.Transformation.IsTransformable (Data.Geometry.Point.Point d r)
- Data.Geometry.Transformation: instance (GHC.Show.Show r, Data.Geometry.Vector.VectorFamily.Arity n, Data.Geometry.Vector.VectorFamily.Arity m) => GHC.Show.Show (Data.Geometry.Transformation.Matrix n m r)
- Data.Geometry.Transformation: instance GHC.Real.Fractional r => Data.Geometry.Transformation.Invertible 2 r
- Data.Geometry.Transformation: instance GHC.Real.Fractional r => Data.Geometry.Transformation.Invertible 3 r
- Data.Geometry.Transformation: instance GHC.Real.Fractional r => Data.Geometry.Transformation.Invertible 4 r
- Data.Geometry.Transformation: inverse' :: Invertible n r => Matrix n n r -> Matrix n n r
- Data.Geometry.Transformation: mkRow :: forall d r. (Arity d, Num r) => Int -> r -> Vector d r
- Data.Geometry.Transformation: mult :: (Arity m, Arity n, Num r) => Matrix n m r -> Vector m r -> Vector n r
- Data.Geometry.Transformation: multM :: (Arity r, Arity c, Arity c', Num a) => Matrix r c a -> Matrix c c' a -> Matrix r c' a
- Data.Geometry.Transformation: newtype Matrix n m r
- Data.Geometry.Triangle: instance Data.Geometry.Point.PointFunctor (Data.Geometry.Triangle.Triangle d p)
- Data.Geometry.Triangle: instance Data.Geometry.Vector.VectorFamily.Arity d => GHC.Base.Functor (Data.Geometry.Triangle.Triangle d p)
- Data.Geometry.Vector: imap :: (Vector v a, Vector v b) => (Int -> a -> b) -> v a -> v b
- Data.Geometry.Vector.VectorFamily: type Arity d = (ImplicitArity (Peano d), KnownNat d)
- Data.Geometry.Vector.VectorFamilyPeano: type ImplicitArity d = (ImplicitPeano d, Arity (FromPeano d))
+ Algorithms.Geometry.ConvexHull.GrahamScan: lowerHull' :: (Ord r, Num r) => NonEmpty (Point 2 r :+ p) -> NonEmpty (Point 2 r :+ p)
+ Algorithms.Geometry.ConvexHull.GrahamScan: upperHull' :: (Ord r, Num r) => NonEmpty (Point 2 r :+ p) -> NonEmpty (Point 2 r :+ p)
+ Algorithms.Geometry.ConvexHull.GrahamScan: upperHullFromSorted :: (Ord r, Num r) => NonEmpty (Point 2 r :+ p) -> NonEmpty (Point 2 r :+ p)
+ Algorithms.Geometry.ConvexHull.GrahamScan: upperHullFromSorted' :: (Ord r, Num r) => NonEmpty (Point 2 r :+ p) -> NonEmpty (Point 2 r :+ p)
+ Algorithms.Geometry.ConvexHull.JarvisMarch: convexHull :: (Ord r, Num r) => NonEmpty (Point 2 r :+ p) -> ConvexPolygon p r
+ Algorithms.Geometry.ConvexHull.JarvisMarch: lowerHull :: (Num r, Ord r) => NonEmpty (Point 2 r :+ p) -> NonEmpty (Point 2 r :+ p)
+ Algorithms.Geometry.ConvexHull.JarvisMarch: lowerHull' :: (Num r, Ord r) => NonEmpty (Point 2 r :+ p) -> NonEmpty (Point 2 r :+ p)
+ Algorithms.Geometry.ConvexHull.JarvisMarch: steepestCcwFrom :: (Ord r, Num r) => (Point 2 r :+ a) -> NonEmpty (Point 2 r :+ b) -> Point 2 r :+ b
+ Algorithms.Geometry.ConvexHull.JarvisMarch: steepestCwFrom :: (Ord r, Num r) => (Point 2 r :+ a) -> NonEmpty (Point 2 r :+ b) -> Point 2 r :+ b
+ Algorithms.Geometry.ConvexHull.JarvisMarch: upperHull :: (Num r, Ord r) => NonEmpty (Point 2 r :+ p) -> NonEmpty (Point 2 r :+ p)
+ Algorithms.Geometry.ConvexHull.JarvisMarch: upperHull' :: (Num r, Ord r) => NonEmpty (Point 2 r :+ p) -> NonEmpty (Point 2 r :+ p)
+ Algorithms.Geometry.ConvexHull.Naive: isValidTriangle :: (Num r, Ord r) => Triangle 3 p r -> [Point 3 r :+ q] -> Maybe (Point 3 r :+ q)
+ Algorithms.Geometry.ConvexHull.Naive: lowerHull' :: forall r p. (Ord r, Fractional r, Show r) => NonEmpty (Point 3 r :+ p) -> ConvexHull 3 p r
+ Algorithms.Geometry.ConvexHull.Naive: lowerHullAll :: forall r p. (Ord r, Fractional r, Show r) => NonEmpty (Point 3 r :+ p) -> ConvexHull 3 p r
+ Algorithms.Geometry.ConvexHull.Naive: type ConvexHull d p r = [Triangle 3 p r]
+ Algorithms.Geometry.ConvexHull.Naive: upperHalfSpaceOf :: (Ord r, Num r) => Triangle 3 p r -> HalfSpace 3 r
+ Algorithms.Geometry.LineSegmentIntersection.Types: type Compare a = a -> a -> Ordering
+ Algorithms.Geometry.LinearProgramming.LP2DRIC: 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)
+ Algorithms.Geometry.LinearProgramming.Types: 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)
+ Algorithms.Geometry.LinearProgramming.Types: 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)
+ Algorithms.Geometry.SoS: Negative :: Sign
+ Algorithms.Geometry.SoS: Positive :: Sign
+ Algorithms.Geometry.SoS: data Sign
+ Algorithms.Geometry.SoS: flipSign :: Sign -> Sign
+ Algorithms.Geometry.SoS: sideTest :: (SoS d, Num r, Ord r, Ord i) => (Point d r :+ i) -> Vector d (Point d r :+ i) -> Sign
+ Algorithms.Geometry.SoS: 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
+ Algorithms.Geometry.SoS: signDet :: (HasDeterminant d, Ord i, Num r, Ord r) => Matrix d d (Symbolic i r) -> Sign
+ Algorithms.Geometry.SoS: signFromTerms :: (Num r, Eq r) => [r] -> Sign
+ Algorithms.Geometry.SoS: toSymbolic :: (Ord i, Arity d) => (Point d r :+ i) -> Point d (Symbolic (i, Int) r)
+ Algorithms.Geometry.SoS: type SoS d = (Arity d, HasDeterminant (d + 1))
+ Algorithms.Geometry.SoS.Symbolic: Term :: r -> EpsFold i -> Term i r
+ Algorithms.Geometry.SoS.Symbolic: constant :: Ord i => r -> Symbolic i r
+ Algorithms.Geometry.SoS.Symbolic: constantFactor :: Lens' (Term i r) r
+ Algorithms.Geometry.SoS.Symbolic: data EpsFold i
+ Algorithms.Geometry.SoS.Symbolic: data Symbolic i r
+ Algorithms.Geometry.SoS.Symbolic: data Term i r
+ Algorithms.Geometry.SoS.Symbolic: eps :: i -> EpsFold i
+ Algorithms.Geometry.SoS.Symbolic: factors :: EpsFold i -> Bag i
+ Algorithms.Geometry.SoS.Symbolic: hasNoPertubation :: EpsFold i -> Bool
+ Algorithms.Geometry.SoS.Symbolic: instance (GHC.Classes.Ord a, Test.QuickCheck.Arbitrary.Arbitrary a) => Test.QuickCheck.Arbitrary.Arbitrary (Algorithms.Geometry.SoS.Symbolic.Bag a)
+ Algorithms.Geometry.SoS.Symbolic: instance (GHC.Classes.Ord i, GHC.Classes.Eq r) => GHC.Classes.Eq (Algorithms.Geometry.SoS.Symbolic.Term i r)
+ Algorithms.Geometry.SoS.Symbolic: instance (GHC.Classes.Ord i, GHC.Classes.Eq r, GHC.Num.Num r) => GHC.Classes.Eq (Algorithms.Geometry.SoS.Symbolic.Symbolic i r)
+ Algorithms.Geometry.SoS.Symbolic: instance (GHC.Classes.Ord i, GHC.Classes.Ord r, GHC.Num.Num r) => GHC.Classes.Ord (Algorithms.Geometry.SoS.Symbolic.Symbolic i r)
+ Algorithms.Geometry.SoS.Symbolic: instance (GHC.Classes.Ord i, GHC.Classes.Ord r, GHC.Num.Num r) => GHC.Classes.Ord (Algorithms.Geometry.SoS.Symbolic.Term i r)
+ Algorithms.Geometry.SoS.Symbolic: instance (GHC.Classes.Ord i, GHC.Num.Num r, GHC.Classes.Eq r) => GHC.Num.Num (Algorithms.Geometry.SoS.Symbolic.Symbolic i r)
+ Algorithms.Geometry.SoS.Symbolic: instance (GHC.Show.Show i, GHC.Show.Show r) => GHC.Show.Show (Algorithms.Geometry.SoS.Symbolic.Symbolic i r)
+ Algorithms.Geometry.SoS.Symbolic: instance (GHC.Show.Show i, GHC.Show.Show r) => GHC.Show.Show (Algorithms.Geometry.SoS.Symbolic.Term i r)
+ Algorithms.Geometry.SoS.Symbolic: instance (Test.QuickCheck.Arbitrary.Arbitrary i, GHC.Classes.Ord i) => Test.QuickCheck.Arbitrary.Arbitrary (Algorithms.Geometry.SoS.Symbolic.EpsFold i)
+ Algorithms.Geometry.SoS.Symbolic: 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)
+ Algorithms.Geometry.SoS.Symbolic: 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)
+ Algorithms.Geometry.SoS.Symbolic: instance Data.Foldable.Foldable Algorithms.Geometry.SoS.Symbolic.Bag
+ Algorithms.Geometry.SoS.Symbolic: instance GHC.Base.Functor (Algorithms.Geometry.SoS.Symbolic.Symbolic i)
+ Algorithms.Geometry.SoS.Symbolic: instance GHC.Base.Functor (Algorithms.Geometry.SoS.Symbolic.Term i)
+ Algorithms.Geometry.SoS.Symbolic: instance GHC.Classes.Eq a => GHC.Classes.Eq (Algorithms.Geometry.SoS.Symbolic.Bag a)
+ Algorithms.Geometry.SoS.Symbolic: instance GHC.Classes.Ord a => GHC.Classes.Ord (Algorithms.Geometry.SoS.Symbolic.Bag a)
+ Algorithms.Geometry.SoS.Symbolic: instance GHC.Classes.Ord i => GHC.Base.Monoid (Algorithms.Geometry.SoS.Symbolic.EpsFold i)
+ Algorithms.Geometry.SoS.Symbolic: instance GHC.Classes.Ord i => GHC.Base.Semigroup (Algorithms.Geometry.SoS.Symbolic.EpsFold i)
+ Algorithms.Geometry.SoS.Symbolic: instance GHC.Classes.Ord i => GHC.Classes.Eq (Algorithms.Geometry.SoS.Symbolic.EpsFold i)
+ Algorithms.Geometry.SoS.Symbolic: instance GHC.Classes.Ord i => GHC.Classes.Ord (Algorithms.Geometry.SoS.Symbolic.EpsFold i)
+ Algorithms.Geometry.SoS.Symbolic: instance GHC.Classes.Ord k => GHC.Base.Monoid (Algorithms.Geometry.SoS.Symbolic.Bag k)
+ Algorithms.Geometry.SoS.Symbolic: instance GHC.Classes.Ord k => GHC.Base.Semigroup (Algorithms.Geometry.SoS.Symbolic.Bag k)
+ Algorithms.Geometry.SoS.Symbolic: instance GHC.Show.Show a => GHC.Show.Show (Algorithms.Geometry.SoS.Symbolic.Bag a)
+ Algorithms.Geometry.SoS.Symbolic: instance GHC.Show.Show i => GHC.Show.Show (Algorithms.Geometry.SoS.Symbolic.EpsFold i)
+ Algorithms.Geometry.SoS.Symbolic: mkEpsFold :: Ord i => [i] -> EpsFold i
+ Algorithms.Geometry.SoS.Symbolic: perturb :: (Num r, Ord i) => r -> i -> Symbolic i r
+ Algorithms.Geometry.SoS.Symbolic: signOf :: (Num r, Eq r) => Symbolic i r -> Maybe Sign
+ Algorithms.Geometry.SoS.Symbolic: suitableBase :: EpsFold i -> Int
+ Algorithms.Geometry.SoS.Symbolic: symbolic :: Ord i => r -> i -> Symbolic i r
+ Algorithms.Geometry.SoS.Symbolic: term :: r -> i -> Term i r
+ Algorithms.Geometry.SoS.Symbolic: toTerms :: Symbolic i r -> [Term i r]
+ Algorithms.Geometry.WellSeparatedPairDecomposition.Types: instance GHC.Base.Semigroup v => Data.Measured.Class.Measured v (Algorithms.Geometry.WellSeparatedPairDecomposition.Types.NodeData d r v)
+ Data.Geometry: class (ImplicitArity (Peano d), KnownNat d) => Arity d
+ Data.Geometry: cons :: (Arity d, Arity (d + 1)) => r -> Vector d r -> Vector (d + 1) r
+ Data.Geometry: edgeSegments :: Arity d => PolyLine d p r -> LSeq 1 (LineSegment d p r)
+ Data.Geometry: fromPointsUnsafe :: [Point d r :+ p] -> PolyLine d p r
+ Data.Geometry: fromPointsUnsafe' :: Monoid p => [Point d r] -> PolyLine d p r
+ Data.Geometry: interpolatePoly :: (RealFrac r, Arity d) => r -> PolyLine d p r -> Point d r
+ Data.Geometry: quadrance :: (Metric f, Num a) => f a -> a
+ Data.Geometry.Ball: _BallSphere :: Iso (Disk p r) (Disk p s) (Circle p r) (Circle p s)
+ Data.Geometry.Ball: _DiskCircle :: Iso (Disk p r) (Disk p s) (Circle p r) (Circle p s)
+ Data.Geometry.BezierSpline: BezierSpline :: LSeq (1 + n) (Point d r) -> BezierSpline n d r
+ Data.Geometry.BezierSpline: approximate :: forall n d r. (KnownNat n, Arity d, Ord r, Fractional r) => r -> BezierSpline n d r -> [Point d r]
+ Data.Geometry.BezierSpline: controlPoints :: forall n_a2jaG d_a2jaH r_a2jaI n_a2jbq d_a2jbr r_a2jbs. Iso (BezierSpline n_a2jaG d_a2jaH r_a2jaI) (BezierSpline n_a2jbq d_a2jbr r_a2jbs) (LSeq ((+) 1 n_a2jaG) (Point d_a2jaH r_a2jaI)) (LSeq ((+) 1 n_a2jbq) (Point d_a2jbr r_a2jbs))
+ Data.Geometry.BezierSpline: evaluate :: (Arity d, Ord r, Num r) => BezierSpline n d r -> r -> Point d r
+ Data.Geometry.BezierSpline: fromPointSeq :: Seq (Point d r) -> BezierSpline n d r
+ Data.Geometry.BezierSpline: instance (Data.Geometry.Vector.VectorFamily.Arity d, GHC.Classes.Eq r) => GHC.Classes.Eq (Data.Geometry.BezierSpline.BezierSpline n d r)
+ Data.Geometry.BezierSpline: instance (Data.Geometry.Vector.VectorFamily.Arity d, GHC.Show.Show r) => GHC.Show.Show (Data.Geometry.BezierSpline.BezierSpline n d r)
+ Data.Geometry.BezierSpline: 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)
+ Data.Geometry.BezierSpline: 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.IsTransformable (Data.Geometry.BezierSpline.BezierSpline n d r)
+ Data.Geometry.BezierSpline: instance Data.Geometry.Point.Internal.PointFunctor (Data.Geometry.BezierSpline.BezierSpline n d)
+ Data.Geometry.BezierSpline: instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Foldable.Foldable (Data.Geometry.BezierSpline.BezierSpline n d)
+ Data.Geometry.BezierSpline: instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Traversable.Traversable (Data.Geometry.BezierSpline.BezierSpline n d)
+ Data.Geometry.BezierSpline: instance Data.Geometry.Vector.VectorFamily.Arity d => GHC.Base.Functor (Data.Geometry.BezierSpline.BezierSpline n d)
+ Data.Geometry.BezierSpline: newtype BezierSpline n d r
+ Data.Geometry.BezierSpline: parameterOf :: (Arity d, Ord r, Fractional r) => BezierSpline n d r -> Point d r -> r
+ Data.Geometry.BezierSpline: pattern Bezier2 :: Point d r -> Point d r -> Point d r -> BezierSpline 2 d r
+ Data.Geometry.BezierSpline: pattern Bezier3 :: Point d r -> Point d r -> Point d r -> Point d r -> BezierSpline 3 d r
+ Data.Geometry.BezierSpline: snap :: (Arity d, Ord r, Fractional r) => BezierSpline n d r -> Point d r -> Point d r
+ Data.Geometry.BezierSpline: 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)
+ Data.Geometry.BezierSpline: subBezier :: (KnownNat n, Arity d, Ord r, Num r) => r -> r -> BezierSpline n d r -> BezierSpline n d r
+ Data.Geometry.BezierSpline: tangent :: (Arity d, Num r, 1 <= n) => BezierSpline n d r -> Vector d r
+ Data.Geometry.Boundary: _Boundary :: Iso g h (Boundary g) (Boundary h)
+ Data.Geometry.Box.Corners: Corners :: !a -> !a -> !a -> !a -> Corners a
+ Data.Geometry.Box.Corners: corners :: Num r => Rectangle p r -> Corners (Point 2 r :+ p)
+ Data.Geometry.Box.Corners: cornersInDirection :: CardinalDirection -> Corners p -> Two p
+ Data.Geometry.Box.Corners: data Corners a
+ Data.Geometry.Box.Corners: instance Control.Lens.At.Ixed (Data.Geometry.Box.Corners.Corners a)
+ Data.Geometry.Box.Corners: instance Data.Foldable.Foldable Data.Geometry.Box.Corners.Corners
+ Data.Geometry.Box.Corners: instance Data.Semigroup.Foldable.Class.Foldable1 Data.Geometry.Box.Corners.Corners
+ Data.Geometry.Box.Corners: instance Data.Semigroup.Traversable.Class.Traversable1 Data.Geometry.Box.Corners.Corners
+ Data.Geometry.Box.Corners: instance Data.Traversable.Traversable Data.Geometry.Box.Corners.Corners
+ Data.Geometry.Box.Corners: instance GHC.Base.Applicative Data.Geometry.Box.Corners.Corners
+ Data.Geometry.Box.Corners: instance GHC.Base.Functor Data.Geometry.Box.Corners.Corners
+ Data.Geometry.Box.Corners: instance GHC.Base.Monoid a => GHC.Base.Monoid (Data.Geometry.Box.Corners.Corners a)
+ Data.Geometry.Box.Corners: instance GHC.Base.Semigroup a => GHC.Base.Semigroup (Data.Geometry.Box.Corners.Corners a)
+ Data.Geometry.Box.Corners: instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Geometry.Box.Corners.Corners a)
+ Data.Geometry.Box.Corners: instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.Geometry.Box.Corners.Corners a)
+ Data.Geometry.Box.Corners: instance GHC.Generics.Generic (Data.Geometry.Box.Corners.Corners a)
+ Data.Geometry.Box.Corners: instance GHC.Show.Show a => GHC.Show.Show (Data.Geometry.Box.Corners.Corners a)
+ Data.Geometry.Box.Corners: northEast :: forall a_a1OzZ. Lens' (Corners a_a1OzZ) a_a1OzZ
+ Data.Geometry.Box.Corners: northWest :: forall a_a1OzZ. Lens' (Corners a_a1OzZ) a_a1OzZ
+ Data.Geometry.Box.Corners: southEast :: forall a_a1OzZ. Lens' (Corners a_a1OzZ) a_a1OzZ
+ Data.Geometry.Box.Corners: southWest :: forall a_a1OzZ. Lens' (Corners a_a1OzZ) a_a1OzZ
+ Data.Geometry.Box.Internal: 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)
+ Data.Geometry.Box.Internal: 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))
+ Data.Geometry.Box.Internal: 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))
+ Data.Geometry.Box.Internal: instance Data.Geometry.Box.Internal.IsBoxable (Data.Geometry.Point.Internal.Point d r)
+ Data.Geometry.Box.Internal: instance Data.Geometry.Box.Internal.IsBoxable c => Data.Geometry.Box.Internal.IsBoxable (c Data.Ext.:+ e)
+ Data.Geometry.Box.Internal: instance Data.Geometry.Point.Internal.PointFunctor (Data.Geometry.Box.Internal.Box d p)
+ Data.Geometry.Box.Internal: instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Bifoldable.Bifoldable (Data.Geometry.Box.Internal.Box d)
+ Data.Geometry.Box.Internal: instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Bitraversable.Bitraversable (Data.Geometry.Box.Internal.Box d)
+ Data.Geometry.Box.Sides: Sides :: !a -> !a -> !a -> !a -> Sides a
+ Data.Geometry.Box.Sides: bottomSide :: Num r => Rectangle p r -> LineSegment 2 p r
+ Data.Geometry.Box.Sides: data Sides a
+ Data.Geometry.Box.Sides: east :: forall a_a1R1A. Lens' (Sides a_a1R1A) a_a1R1A
+ Data.Geometry.Box.Sides: instance Control.Lens.At.Ixed (Data.Geometry.Box.Sides.Sides a)
+ Data.Geometry.Box.Sides: instance Data.Foldable.Foldable Data.Geometry.Box.Sides.Sides
+ Data.Geometry.Box.Sides: instance Data.Semigroup.Foldable.Class.Foldable1 Data.Geometry.Box.Sides.Sides
+ Data.Geometry.Box.Sides: instance Data.Semigroup.Traversable.Class.Traversable1 Data.Geometry.Box.Sides.Sides
+ Data.Geometry.Box.Sides: instance Data.Traversable.Traversable Data.Geometry.Box.Sides.Sides
+ Data.Geometry.Box.Sides: instance GHC.Base.Applicative Data.Geometry.Box.Sides.Sides
+ Data.Geometry.Box.Sides: instance GHC.Base.Functor Data.Geometry.Box.Sides.Sides
+ Data.Geometry.Box.Sides: instance GHC.Base.Monoid a => GHC.Base.Monoid (Data.Geometry.Box.Sides.Sides a)
+ Data.Geometry.Box.Sides: instance GHC.Base.Semigroup a => GHC.Base.Semigroup (Data.Geometry.Box.Sides.Sides a)
+ Data.Geometry.Box.Sides: instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Geometry.Box.Sides.Sides a)
+ Data.Geometry.Box.Sides: instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.Geometry.Box.Sides.Sides a)
+ Data.Geometry.Box.Sides: instance GHC.Generics.Generic (Data.Geometry.Box.Sides.Sides a)
+ Data.Geometry.Box.Sides: instance GHC.Read.Read a => GHC.Read.Read (Data.Geometry.Box.Sides.Sides a)
+ Data.Geometry.Box.Sides: instance GHC.Show.Show a => GHC.Show.Show (Data.Geometry.Box.Sides.Sides a)
+ Data.Geometry.Box.Sides: leftSide :: Num r => Rectangle p r -> LineSegment 2 p r
+ Data.Geometry.Box.Sides: north :: forall a_a1R1A. Lens' (Sides a_a1R1A) a_a1R1A
+ Data.Geometry.Box.Sides: rightSide :: Num r => Rectangle p r -> LineSegment 2 p r
+ Data.Geometry.Box.Sides: sideDirections :: Sides CardinalDirection
+ Data.Geometry.Box.Sides: sides :: Num r => Rectangle p r -> Sides (LineSegment 2 p r)
+ Data.Geometry.Box.Sides: sides' :: Num r => Rectangle p r -> Sides (LineSegment 2 p r)
+ Data.Geometry.Box.Sides: south :: forall a_a1R1A. Lens' (Sides a_a1R1A) a_a1R1A
+ Data.Geometry.Box.Sides: topSide :: Num r => Rectangle p r -> LineSegment 2 p r
+ Data.Geometry.Box.Sides: west :: forall a_a1R1A. Lens' (Sides a_a1R1A) a_a1R1A
+ Data.Geometry.Directions: East :: CardinalDirection
+ Data.Geometry.Directions: North :: CardinalDirection
+ Data.Geometry.Directions: NorthEast :: InterCardinalDirection
+ Data.Geometry.Directions: NorthWest :: InterCardinalDirection
+ Data.Geometry.Directions: South :: CardinalDirection
+ Data.Geometry.Directions: SouthEast :: InterCardinalDirection
+ Data.Geometry.Directions: SouthWest :: InterCardinalDirection
+ Data.Geometry.Directions: West :: CardinalDirection
+ Data.Geometry.Directions: _East :: Prism' CardinalDirection ()
+ Data.Geometry.Directions: _North :: Prism' CardinalDirection ()
+ Data.Geometry.Directions: _NorthEast :: Prism' InterCardinalDirection ()
+ Data.Geometry.Directions: _NorthWest :: Prism' InterCardinalDirection ()
+ Data.Geometry.Directions: _South :: Prism' CardinalDirection ()
+ Data.Geometry.Directions: _SouthEast :: Prism' InterCardinalDirection ()
+ Data.Geometry.Directions: _SouthWest :: Prism' InterCardinalDirection ()
+ Data.Geometry.Directions: _West :: Prism' CardinalDirection ()
+ Data.Geometry.Directions: data CardinalDirection
+ Data.Geometry.Directions: data InterCardinalDirection
+ Data.Geometry.Directions: instance GHC.Classes.Eq Data.Geometry.Directions.CardinalDirection
+ Data.Geometry.Directions: instance GHC.Classes.Eq Data.Geometry.Directions.InterCardinalDirection
+ Data.Geometry.Directions: instance GHC.Classes.Ord Data.Geometry.Directions.CardinalDirection
+ Data.Geometry.Directions: instance GHC.Classes.Ord Data.Geometry.Directions.InterCardinalDirection
+ Data.Geometry.Directions: instance GHC.Enum.Bounded Data.Geometry.Directions.CardinalDirection
+ Data.Geometry.Directions: instance GHC.Enum.Enum Data.Geometry.Directions.CardinalDirection
+ Data.Geometry.Directions: instance GHC.Enum.Enum Data.Geometry.Directions.InterCardinalDirection
+ Data.Geometry.Directions: instance GHC.Generics.Generic Data.Geometry.Directions.InterCardinalDirection
+ Data.Geometry.Directions: instance GHC.Read.Read Data.Geometry.Directions.CardinalDirection
+ Data.Geometry.Directions: instance GHC.Read.Read Data.Geometry.Directions.InterCardinalDirection
+ Data.Geometry.Directions: instance GHC.Show.Show Data.Geometry.Directions.CardinalDirection
+ Data.Geometry.Directions: instance GHC.Show.Show Data.Geometry.Directions.InterCardinalDirection
+ Data.Geometry.Directions: interCardinalsOf :: CardinalDirection -> Two InterCardinalDirection
+ Data.Geometry.Directions: oppositeDirection :: CardinalDirection -> CardinalDirection
+ Data.Geometry.Ellipse: Ellipse :: Transformation 2 r -> Ellipse r
+ Data.Geometry.Ellipse: _EllipseCircle :: (Floating r, Eq r) => Prism' (Ellipse r) (Circle () r)
+ Data.Geometry.Ellipse: affineTransformation :: forall r_a2FNO r_a2GfJ. Iso (Ellipse r_a2FNO) (Ellipse r_a2GfJ) (Transformation 2 r_a2FNO) (Transformation 2 r_a2GfJ)
+ Data.Geometry.Ellipse: circleToEllipse :: Floating r => Circle p r -> Ellipse r
+ Data.Geometry.Ellipse: ellipseMatrix :: Iso (Ellipse r) (Ellipse s) (Matrix 3 3 r) (Matrix 3 3 s)
+ Data.Geometry.Ellipse: ellipseToCircle :: (Num r, Eq r) => Ellipse r -> Maybe (Circle () r)
+ Data.Geometry.Ellipse: instance Data.Foldable.Foldable Data.Geometry.Ellipse.Ellipse
+ Data.Geometry.Ellipse: instance Data.Traversable.Traversable Data.Geometry.Ellipse.Ellipse
+ Data.Geometry.Ellipse: instance GHC.Base.Functor Data.Geometry.Ellipse.Ellipse
+ Data.Geometry.Ellipse: instance GHC.Classes.Eq r => GHC.Classes.Eq (Data.Geometry.Ellipse.Ellipse r)
+ Data.Geometry.Ellipse: instance GHC.Num.Num r => Data.Geometry.Transformation.IsTransformable (Data.Geometry.Ellipse.Ellipse r)
+ Data.Geometry.Ellipse: instance GHC.Show.Show r => GHC.Show.Show (Data.Geometry.Ellipse.Ellipse r)
+ Data.Geometry.Ellipse: newtype Ellipse r
+ Data.Geometry.Ellipse: unitEllipse :: Num r => Ellipse r
+ Data.Geometry.HalfLine: instance (GHC.Classes.Eq r, GHC.Real.Fractional r, Data.Geometry.Vector.VectorFamily.Arity d) => GHC.Classes.Eq (Data.Geometry.HalfLine.HalfLine d r)
+ Data.Geometry.HalfSpace: instance (Data.Geometry.Vector.VectorFamily.Arity d, GHC.Classes.Eq r, GHC.Real.Fractional r) => GHC.Classes.Eq (Data.Geometry.HalfSpace.HalfSpace d r)
+ Data.Geometry.HalfSpace: 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)
+ Data.Geometry.HyperPlane: instance (Data.Geometry.Vector.VectorFamily.Arity d, GHC.Classes.Eq r, GHC.Real.Fractional r) => GHC.Classes.Eq (Data.Geometry.HyperPlane.HyperPlane d r)
+ Data.Geometry.HyperPlane: 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)
+ Data.Geometry.HyperPlane: instance Data.Geometry.Line.Internal.OnSideUpDownTest (Data.Geometry.HyperPlane.Plane r)
+ Data.Geometry.HyperPlane: planeCoordinatesTransform :: Num r => Plane r -> Vector 3 r -> Transformation 3 r
+ Data.Geometry.HyperPlane: planeCoordinatesWith :: Fractional r => Plane r -> Vector 3 r -> Point 3 r -> Point 2 r
+ Data.Geometry.Interval: _Range :: Lens' (Interval a r) (Range (r :+ a))
+ Data.Geometry.Interval: asProperInterval :: Ord r => Interval p r -> Interval p r
+ Data.Geometry.Interval: data Interval a r
+ Data.Geometry.Interval: flipInterval :: Interval a r -> Interval a r
+ Data.Geometry.Interval: fromRange :: Range (r :+ a) -> Interval a r
+ Data.Geometry.Interval: toRange :: Interval a r -> Range (r :+ a)
+ Data.Geometry.IntervalTree: asRange :: IntervalLike i => i -> Range (NumType i)
+ Data.Geometry.Line: 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)
+ Data.Geometry.Line: 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)
+ Data.Geometry.Line.Internal: class OnSideUpDownTest t
+ Data.Geometry.Line.Internal: instance Data.Geometry.Line.Internal.OnSideUpDownTest (Data.Geometry.Line.Internal.Line 2 r)
+ Data.Geometry.LineSegment: _Range :: Lens' (Interval a r) (Range (r :+ a))
+ Data.Geometry.LineSegment: asProperInterval :: Ord r => Interval p r -> Interval p r
+ Data.Geometry.LineSegment: data Interval a r
+ Data.Geometry.LineSegment: flipInterval :: Interval a r -> Interval a r
+ Data.Geometry.LineSegment: fromRange :: Range (r :+ a) -> Interval a r
+ Data.Geometry.LineSegment: instance Data.Geometry.Point.Internal.PointFunctor (Data.Geometry.LineSegment.LineSegment d p)
+ Data.Geometry.LineSegment: interpolate :: (Fractional r, Arity d) => r -> LineSegment d p r -> Point d r
+ Data.Geometry.LineSegment: pattern OpenLineSegment :: (Point d r :+ p) -> (Point d r :+ p) -> LineSegment d p r
+ Data.Geometry.Matrix: Matrix :: Vector n (Vector m r) -> Matrix n m r
+ Data.Geometry.Matrix: class Arity d => HasDeterminant d
+ Data.Geometry.Matrix: class Invertible n r
+ Data.Geometry.Matrix: det :: (HasDeterminant d, Num r) => Matrix d d r -> r
+ Data.Geometry.Matrix: identityMatrix :: (Arity d, Num r) => Matrix d d r
+ Data.Geometry.Matrix: instance (Data.Geometry.Vector.VectorFamily.Arity n, Data.Geometry.Vector.VectorFamily.Arity m) => Data.Foldable.Foldable (Data.Geometry.Matrix.Matrix n m)
+ Data.Geometry.Matrix: instance (Data.Geometry.Vector.VectorFamily.Arity n, Data.Geometry.Vector.VectorFamily.Arity m) => Data.Traversable.Traversable (Data.Geometry.Matrix.Matrix n m)
+ Data.Geometry.Matrix: instance (Data.Geometry.Vector.VectorFamily.Arity n, Data.Geometry.Vector.VectorFamily.Arity m) => GHC.Base.Functor (Data.Geometry.Matrix.Matrix n m)
+ Data.Geometry.Matrix: 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)
+ Data.Geometry.Matrix: 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)
+ Data.Geometry.Matrix: 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)
+ Data.Geometry.Matrix: instance Data.Geometry.Matrix.HasDeterminant 1
+ Data.Geometry.Matrix: instance Data.Geometry.Matrix.HasDeterminant 2
+ Data.Geometry.Matrix: instance Data.Geometry.Matrix.HasDeterminant 3
+ Data.Geometry.Matrix: instance Data.Geometry.Matrix.HasDeterminant 4
+ Data.Geometry.Matrix: instance GHC.Real.Fractional r => Data.Geometry.Matrix.Invertible 2 r
+ Data.Geometry.Matrix: instance GHC.Real.Fractional r => Data.Geometry.Matrix.Invertible 3 r
+ Data.Geometry.Matrix: instance GHC.Real.Fractional r => Data.Geometry.Matrix.Invertible 4 r
+ Data.Geometry.Matrix: inverse' :: Invertible n r => Matrix n n r -> Matrix n n r
+ Data.Geometry.Matrix: mult :: (Arity m, Arity n, Num r) => Matrix n m r -> Vector m r -> Vector n r
+ Data.Geometry.Matrix: multM :: (Arity r, Arity c, Arity c', Num a) => Matrix r c a -> Matrix c c' a -> Matrix r c' a
+ Data.Geometry.Matrix: newtype Matrix n m r
+ Data.Geometry.Point: asAPoint :: AsAPoint p => Lens (p d r) (p d' r') (Point d r) (Point d' r')
+ Data.Geometry.Point: class AsAPoint p
+ Data.Geometry.Point: pattern CCW :: CCW
+ Data.Geometry.Point: pattern CW :: CCW
+ Data.Geometry.Point: pattern CoLinear :: CCW
+ Data.Geometry.Point: pattern Point1 :: r -> Point 1 r
+ Data.Geometry.Point: vector' :: AsAPoint p => Lens (p d r) (p d r') (Vector d r) (Vector d r')
+ Data.Geometry.PolyLine: edgeSegments :: Arity d => PolyLine d p r -> LSeq 1 (LineSegment d p r)
+ Data.Geometry.PolyLine: fromPointsUnsafe :: [Point d r :+ p] -> PolyLine d p r
+ Data.Geometry.PolyLine: fromPointsUnsafe' :: Monoid p => [Point d r] -> PolyLine d p r
+ Data.Geometry.PolyLine: instance Data.Geometry.Point.Internal.PointFunctor (Data.Geometry.PolyLine.PolyLine d p)
+ Data.Geometry.PolyLine: instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Bifoldable.Bifoldable (Data.Geometry.PolyLine.PolyLine d)
+ Data.Geometry.PolyLine: instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Bitraversable.Bitraversable (Data.Geometry.PolyLine.PolyLine d)
+ Data.Geometry.PolyLine: interpolatePoly :: (RealFrac r, Arity d) => r -> PolyLine d p r -> Point d r
+ Data.Geometry.Polygon.Convex: instance Data.Geometry.Point.Internal.PointFunctor (Data.Geometry.Polygon.Convex.ConvexPolygon p)
+ Data.Geometry.QuadTree: Negative :: Sign
+ Data.Geometry.QuadTree: Positive :: Sign
+ Data.Geometry.QuadTree: QuadTree :: !Cell r -> !Tree v p -> QuadTree v p r
+ Data.Geometry.QuadTree: Zero :: Sign
+ Data.Geometry.QuadTree: [_startingCell] :: QuadTree v p r -> !Cell r
+ Data.Geometry.QuadTree: [_tree] :: QuadTree v p r -> !Tree v p
+ Data.Geometry.QuadTree: build :: (Fractional r, Ord r) => (Cell r -> i -> Split i v p) -> Cell r -> i -> QuadTree v p r
+ Data.Geometry.QuadTree: buildOn :: Cell r -> (Cell r -> i -> Tree v p) -> i -> QuadTree v p r
+ Data.Geometry.QuadTree: completeTree :: (Fractional r, Ord r) => Cell r -> QuadTree () () r
+ Data.Geometry.QuadTree: data QuadTree v p r
+ Data.Geometry.QuadTree: data Sign
+ Data.Geometry.QuadTree: findLeaf :: (Fractional r, Ord r) => Point 2 r -> QuadTree v p r -> Maybe (p :+ Cell r)
+ Data.Geometry.QuadTree: fromOrdering :: Ordering -> Sign
+ Data.Geometry.QuadTree: fromPoints :: (RealFrac r, Ord r) => NonEmpty (Point 2 r :+ p) -> QuadTree () (Maybe (Point 2 r :+ p)) r
+ Data.Geometry.QuadTree: fromPointsBox :: (Fractional r, Ord r) => Cell r -> [Point 2 r :+ p] -> QuadTree () (Maybe (Point 2 r :+ p)) r
+ Data.Geometry.QuadTree: fromSignum :: (Num a, Eq a) => (b -> a) -> b -> Sign
+ Data.Geometry.QuadTree: fromZeros :: (Fractional r, Ord r, Num a, Eq a, v ~ Quadrants Sign) => Cell r -> (Point 2 r -> a) -> QuadTree v (Either v Sign) r
+ Data.Geometry.QuadTree: 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
+ Data.Geometry.QuadTree: 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.Geometry.QuadTree: instance (GHC.Classes.Eq r, GHC.Classes.Eq p, GHC.Classes.Eq v) => GHC.Classes.Eq (Data.Geometry.QuadTree.QuadTree v p r)
+ Data.Geometry.QuadTree: instance (GHC.Show.Show r, GHC.Show.Show p, GHC.Show.Show v) => GHC.Show.Show (Data.Geometry.QuadTree.QuadTree v p r)
+ Data.Geometry.QuadTree: instance Data.Foldable.Foldable (Data.Geometry.QuadTree.QuadTree v p)
+ Data.Geometry.QuadTree: instance Data.Traversable.Traversable (Data.Geometry.QuadTree.QuadTree v p)
+ Data.Geometry.QuadTree: instance GHC.Base.Functor (Data.Geometry.QuadTree.QuadTree v p)
+ Data.Geometry.QuadTree: instance GHC.Classes.Eq Data.Geometry.QuadTree.Sign
+ Data.Geometry.QuadTree: instance GHC.Classes.Ord Data.Geometry.QuadTree.Sign
+ Data.Geometry.QuadTree: instance GHC.Generics.Generic (Data.Geometry.QuadTree.QuadTree v p r)
+ Data.Geometry.QuadTree: instance GHC.Show.Show Data.Geometry.QuadTree.Sign
+ Data.Geometry.QuadTree: isZeroCell :: Eq sign => sign -> Either v sign -> Bool
+ Data.Geometry.QuadTree: leaves :: QuadTree v p r -> NonEmpty p
+ Data.Geometry.QuadTree: perLevel :: QuadTree v p r -> NonEmpty (NonEmpty (TreeNode v p))
+ Data.Geometry.QuadTree: shouldSplitZeros :: forall r sign. (Fractional r, Eq sign) => (Point 2 r -> sign) -> Splitter r (Quadrants sign) (Quadrants sign) sign
+ Data.Geometry.QuadTree: startingCell :: forall v_a1ZtD p_a1ZtE r_a1ZtF r_a1ZFG. Lens (QuadTree v_a1ZtD p_a1ZtE r_a1ZtF) (QuadTree v_a1ZtD p_a1ZtE r_a1ZFG) (Cell r_a1ZtF) (Cell r_a1ZFG)
+ Data.Geometry.QuadTree: tree :: forall v_a1ZtD p_a1ZtE r_a1ZtF v_a1ZFH p_a1ZFI. Lens (QuadTree v_a1ZtD p_a1ZtE r_a1ZtF) (QuadTree v_a1ZFH p_a1ZFI r_a1ZtF) (Tree v_a1ZtD p_a1ZtE) (Tree v_a1ZFH p_a1ZFI)
+ Data.Geometry.QuadTree: type Signs sign = Either (Corners sign) sign
+ Data.Geometry.QuadTree: withCells :: (Fractional r, Ord r) => QuadTree v p r -> QuadTree (v :+ Cell r) (p :+ Cell r) r
+ Data.Geometry.QuadTree: withCellsTree :: (Fractional r, Ord r) => QuadTree v p r -> Tree (v :+ Cell r) (p :+ Cell r)
+ Data.Geometry.QuadTree.Cell: Cell :: {-# UNPACK #-} !WidthIndex -> !Point 2 r -> Cell r
+ Data.Geometry.QuadTree.Cell: [_cellWidthIndex] :: Cell r -> {-# UNPACK #-} !WidthIndex
+ Data.Geometry.QuadTree.Cell: [_lowerLeft] :: Cell r -> !Point 2 r
+ Data.Geometry.QuadTree.Cell: cellCorners :: Fractional r => Cell r -> Quadrants (Point 2 r)
+ Data.Geometry.QuadTree.Cell: cellSides :: Fractional r => Cell r -> Sides (LineSegment 2 () r)
+ Data.Geometry.QuadTree.Cell: cellWidth :: Fractional r => Cell r -> r
+ Data.Geometry.QuadTree.Cell: cellWidthIndex :: forall r_a1TUJ. Lens' (Cell r_a1TUJ) WidthIndex
+ Data.Geometry.QuadTree.Cell: data Cell r
+ Data.Geometry.QuadTree.Cell: fitsRectangle :: (RealFrac r, Ord r) => Rectangle p r -> Cell r
+ Data.Geometry.QuadTree.Cell: inCell :: (Fractional r, Ord r) => (Point 2 r :+ p) -> Cell r -> Bool
+ Data.Geometry.QuadTree.Cell: 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)
+ Data.Geometry.QuadTree.Cell: instance Data.Foldable.Foldable Data.Geometry.QuadTree.Cell.Cell
+ Data.Geometry.QuadTree.Cell: instance Data.Traversable.Traversable Data.Geometry.QuadTree.Cell.Cell
+ Data.Geometry.QuadTree.Cell: instance GHC.Base.Functor Data.Geometry.QuadTree.Cell.Cell
+ Data.Geometry.QuadTree.Cell: instance GHC.Classes.Eq r => GHC.Classes.Eq (Data.Geometry.QuadTree.Cell.Cell r)
+ Data.Geometry.QuadTree.Cell: instance GHC.Show.Show r => GHC.Show.Show (Data.Geometry.QuadTree.Cell.Cell r)
+ Data.Geometry.QuadTree.Cell: lowerLeft :: forall r_a1TUJ r_a1U5N. Lens (Cell r_a1TUJ) (Cell r_a1U5N) (Point 2 r_a1TUJ) (Point 2 r_a1U5N)
+ Data.Geometry.QuadTree.Cell: midPoint :: Fractional r => Cell r -> Point 2 r
+ Data.Geometry.QuadTree.Cell: partitionPoints :: (Fractional r, Ord r) => Cell r -> [Point 2 r :+ p] -> Quadrants [Point 2 r :+ p]
+ Data.Geometry.QuadTree.Cell: pow :: Fractional r => WidthIndex -> r
+ Data.Geometry.QuadTree.Cell: quadrantOf :: forall r. (Fractional r, Ord r) => Point 2 r -> Cell r -> InterCardinalDirection
+ Data.Geometry.QuadTree.Cell: relationTo :: (Fractional r, Ord r) => (p :+ Cell r) -> Cell r -> Sides (Maybe (p :+ Cell r))
+ Data.Geometry.QuadTree.Cell: splitCell :: (Num r, Fractional r) => Cell r -> Quadrants (Cell r)
+ Data.Geometry.QuadTree.Cell: toBox :: Fractional r => Cell r -> Box 2 () r
+ Data.Geometry.QuadTree.Cell: type WidthIndex = Int
+ Data.Geometry.QuadTree.Quadrants: pattern Quadrants :: a -> a -> a -> a -> Corners a
+ Data.Geometry.QuadTree.Quadrants: type Quadrants = Corners
+ Data.Geometry.QuadTree.Split: No :: !p -> Split i v p
+ Data.Geometry.QuadTree.Split: Yes :: !v -> Quadrants i -> Split i v p
+ Data.Geometry.QuadTree.Split: _No :: forall i_a1X9q v_a1X9r p_a1X9s p_a1XfS. Prism (Split i_a1X9q v_a1X9r p_a1XfS) (Split i_a1X9q v_a1X9r p_a1X9s) p_a1XfS p_a1X9s
+ Data.Geometry.QuadTree.Split: _Yes :: forall i_a1X9q v_a1X9r p_a1X9s i_a1XfY v_a1XfZ. Prism (Split i_a1XfY v_a1XfZ p_a1X9s) (Split i_a1X9q v_a1X9r p_a1X9s) (v_a1XfZ, Quadrants i_a1XfY) (v_a1X9r, Quadrants i_a1X9q)
+ Data.Geometry.QuadTree.Split: data Split i v p
+ Data.Geometry.QuadTree.Split: instance (GHC.Classes.Eq p, GHC.Classes.Eq v, GHC.Classes.Eq i) => GHC.Classes.Eq (Data.Geometry.QuadTree.Split.Split i v p)
+ Data.Geometry.QuadTree.Split: instance (GHC.Classes.Ord p, GHC.Classes.Ord v, GHC.Classes.Ord i) => GHC.Classes.Ord (Data.Geometry.QuadTree.Split.Split i v p)
+ Data.Geometry.QuadTree.Split: instance (GHC.Show.Show p, GHC.Show.Show v, GHC.Show.Show i) => GHC.Show.Show (Data.Geometry.QuadTree.Split.Split i v p)
+ Data.Geometry.QuadTree.Split: limitWidthTo :: WidthIndex -> Limiter r i v p
+ Data.Geometry.QuadTree.Split: type Limiter r i v p = Splitter r i v p -> Splitter r i v (Either i p)
+ Data.Geometry.QuadTree.Split: type Splitter r i v p = Cell r -> i -> Split i v p
+ Data.Geometry.QuadTree.Tree: Leaf :: !p -> Tree v p
+ Data.Geometry.QuadTree.Tree: Node :: !v -> Quadrants (Tree v p) -> Tree v p
+ Data.Geometry.QuadTree.Tree: _Leaf :: forall v_a1YaG p_a1YaH. Prism' (Tree v_a1YaG p_a1YaH) p_a1YaH
+ Data.Geometry.QuadTree.Tree: _Node :: forall v_a1YaG p_a1YaH v_a1Yei. Prism (Tree v_a1Yei p_a1YaH) (Tree v_a1YaG p_a1YaH) (v_a1Yei, Quadrants (Tree v_a1Yei p_a1YaH)) (v_a1YaG, Quadrants (Tree v_a1YaG p_a1YaH))
+ Data.Geometry.QuadTree.Tree: build :: Fractional r => Splitter r pts v p -> Cell r -> pts -> Tree v p
+ Data.Geometry.QuadTree.Tree: data Tree v p
+ Data.Geometry.QuadTree.Tree: foldTree :: (p -> b) -> (v -> Quadrants b -> b) -> Tree v p -> b
+ Data.Geometry.QuadTree.Tree: fromPoints :: (Fractional r, Ord r) => Cell r -> [Point 2 r :+ p] -> Tree () (Maybe (Point 2 r :+ p))
+ Data.Geometry.QuadTree.Tree: fromPointsF :: (Fractional r, Ord r) => Splitter r [Point 2 r :+ p] () (Maybe (Point 2 r :+ p))
+ Data.Geometry.QuadTree.Tree: height :: Tree v p -> Integer
+ Data.Geometry.QuadTree.Tree: instance (GHC.Classes.Eq p, GHC.Classes.Eq v) => GHC.Classes.Eq (Data.Geometry.QuadTree.Tree.Tree v p)
+ Data.Geometry.QuadTree.Tree: instance (GHC.Show.Show p, GHC.Show.Show v) => GHC.Show.Show (Data.Geometry.QuadTree.Tree.Tree v p)
+ Data.Geometry.QuadTree.Tree: instance Data.Bifoldable.Bifoldable Data.Geometry.QuadTree.Tree.Tree
+ Data.Geometry.QuadTree.Tree: instance Data.Bifunctor.Bifunctor Data.Geometry.QuadTree.Tree.Tree
+ Data.Geometry.QuadTree.Tree: instance Data.Bitraversable.Bitraversable Data.Geometry.QuadTree.Tree.Tree
+ Data.Geometry.QuadTree.Tree: instance Data.Semigroup.Foldable.Class.Bifoldable1 Data.Geometry.QuadTree.Tree.Tree
+ Data.Geometry.QuadTree.Tree: instance Data.Semigroup.Traversable.Class.Bitraversable1 Data.Geometry.QuadTree.Tree.Tree
+ Data.Geometry.QuadTree.Tree: leaves :: Tree v p -> NonEmpty p
+ Data.Geometry.QuadTree.Tree: toRoseTree :: Tree v p -> Tree (TreeNode v p)
+ Data.Geometry.QuadTree.Tree: withCells :: Fractional r => Cell r -> Tree v p -> Tree (v :+ Cell r) (p :+ Cell r)
+ Data.Geometry.RangeTree: 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)
+ Data.Geometry.RangeTree: 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)
+ Data.Geometry.RangeTree.Generic: instance Data.Measured.Class.Measured (Data.Geometry.RangeTree.Measure.Count p) (Data.Geometry.RangeTree.Generic.CountOf p)
+ Data.Geometry.RangeTree.Measure: instance Data.Measured.Class.Measured (Data.Geometry.RangeTree.Measure.Report p) (Data.Geometry.RangeTree.Measure.Report p)
+ Data.Geometry.SegmentTree.Generic: instance Data.Measured.Class.Measured Data.Geometry.SegmentTree.Generic.Count (Data.Geometry.SegmentTree.Generic.C i)
+ Data.Geometry.SegmentTree.Generic: instance Data.Measured.Class.Measured [Data.Geometry.SegmentTree.Generic.I a] (Data.Geometry.SegmentTree.Generic.I a)
+ Data.Geometry.Transformation: instance (GHC.Real.Fractional r, Data.Geometry.Vector.VectorFamily.Arity d, Data.Geometry.Vector.VectorFamily.Arity (d GHC.TypeNats.+ 1)) => Data.Geometry.Transformation.IsTransformable (Data.Geometry.Point.Internal.Point d r)
+ Data.Geometry.Transformation: instance Data.Geometry.Vector.VectorFamily.Arity (d GHC.TypeNats.+ 1) => Data.Foldable.Foldable (Data.Geometry.Transformation.Transformation d)
+ Data.Geometry.Transformation: instance Data.Geometry.Vector.VectorFamily.Arity (d GHC.TypeNats.+ 1) => Data.Traversable.Traversable (Data.Geometry.Transformation.Transformation d)
+ Data.Geometry.Transformation: skewX :: Num r => r -> Transformation 2 r
+ Data.Geometry.Triangle: _TriangleThreePoints :: Iso' (Triangle d p r) (Three (Point d r :+ p))
+ Data.Geometry.Triangle: 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)
+ Data.Geometry.Triangle: 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)
+ Data.Geometry.Triangle: 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)
+ Data.Geometry.Triangle: 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)
+ Data.Geometry.Triangle: instance Data.Geometry.Point.Internal.PointFunctor (Data.Geometry.Triangle.Triangle d p)
+ Data.Geometry.Triangle: instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Bifoldable.Bifoldable (Data.Geometry.Triangle.Triangle d)
+ Data.Geometry.Triangle: instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Bifunctor.Bifunctor (Data.Geometry.Triangle.Triangle d)
+ Data.Geometry.Triangle: instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Bitraversable.Bitraversable (Data.Geometry.Triangle.Triangle d)
+ Data.Geometry.Triangle: instance GHC.Generics.Generic (Data.Geometry.Triangle.Triangle d p r)
+ Data.Geometry.Vector: (*^) :: (Functor f, Num a) => a -> f a -> f a
+ Data.Geometry.Vector: (^*) :: (Functor f, Num a) => f a -> a -> f a
+ Data.Geometry.Vector: (^+^) :: (Additive f, Num a) => f a -> f a -> f a
+ Data.Geometry.Vector: (^-^) :: (Additive f, Num a) => f a -> f a -> f a
+ Data.Geometry.Vector: (^/) :: (Functor f, Fractional a) => f a -> a -> f a
+ Data.Geometry.Vector: basis :: (Additive t, Traversable t, Num a) => [t a]
+ Data.Geometry.Vector: basisFor :: (Traversable t, Num a) => t b -> [t a]
+ Data.Geometry.Vector: class Functor f => Additive (f :: Type -> Type)
+ Data.Geometry.Vector: infixl 7 *^
+ Data.Geometry.Vector: instance (System.Random.Random r, Data.Geometry.Vector.VectorFamily.Arity d) => System.Random.Random (Data.Geometry.Vector.VectorFamily.Vector d r)
+ Data.Geometry.Vector: lerp :: (Additive f, Num a) => a -> f a -> f a -> f a
+ Data.Geometry.Vector: liftI2 :: Additive f => (a -> b -> c) -> f a -> f b -> f c
+ Data.Geometry.Vector: liftU2 :: Additive f => (a -> a -> a) -> f a -> f a -> f a
+ Data.Geometry.Vector: negated :: (Functor f, Num a) => f a -> f a
+ Data.Geometry.Vector: outer :: (Functor f, Functor g, Num a) => f a -> g a -> f (g a)
+ Data.Geometry.Vector: quadrance :: (Metric f, Num a) => f a -> a
+ Data.Geometry.Vector: scaled :: (Traversable t, Num a) => t a -> t (t a)
+ Data.Geometry.Vector: sumV :: (Foldable f, Additive v, Num a) => f (v a) -> v a
+ Data.Geometry.Vector: unit :: (Additive t, Num a) => ASetter' (t a) a -> t a
+ Data.Geometry.Vector: zero :: (Additive f, Num a) => f a
+ Data.Geometry.Vector.VectorFamily: class (ImplicitArity (Peano d), KnownNat d) => Arity d
+ Data.Geometry.Vector.VectorFamily: cons :: (Arity d, Arity (d + 1)) => r -> Vector d r -> Vector (d + 1) r
+ Data.Geometry.Vector.VectorFamily: instance (Data.Geometry.Vector.VectorFamily.Arity d, Data.Hashable.Class.Hashable r) => Data.Hashable.Class.Hashable (Data.Geometry.Vector.VectorFamily.Vector d r)
+ Data.Geometry.Vector.VectorFamily: instance (Data.Geometry.Vector.VectorFamilyPeano.ImplicitArity (Data.Vector.Fixed.Cont.Peano d), GHC.TypeNats.KnownNat d) => Data.Geometry.Vector.VectorFamily.Arity d
+ Data.Geometry.Vector.VectorFamily: instance Data.Geometry.Vector.VectorFamily.Arity d => Control.Lens.Indexed.FoldableWithIndex GHC.Types.Int (Data.Geometry.Vector.VectorFamily.Vector d)
+ Data.Geometry.Vector.VectorFamily: instance Data.Geometry.Vector.VectorFamily.Arity d => Control.Lens.Indexed.FunctorWithIndex GHC.Types.Int (Data.Geometry.Vector.VectorFamily.Vector d)
+ Data.Geometry.Vector.VectorFamily: instance Data.Geometry.Vector.VectorFamily.Arity d => Control.Lens.Indexed.TraversableWithIndex GHC.Types.Int (Data.Geometry.Vector.VectorFamily.Vector d)
+ Data.Geometry.Vector.VectorFamilyPeano: class (ImplicitPeano d, Arity (FromPeano d)) => ImplicitArity d
+ Data.Geometry.Vector.VectorFamilyPeano: instance (Data.Geometry.Vector.VectorFamilyPeano.ImplicitPeano d, Data.Hashable.Class.Hashable r) => Data.Hashable.Class.Hashable (Data.Geometry.Vector.VectorFamilyPeano.VectorFamily d r)
+ Data.Geometry.Vector.VectorFamilyPeano: instance (Data.Geometry.Vector.VectorFamilyPeano.ImplicitPeano d, Data.Vector.Fixed.Cont.Arity (Data.Geometry.Vector.VectorFamilyPeano.FromPeano d)) => Data.Geometry.Vector.VectorFamilyPeano.ImplicitArity d
- Algorithms.Geometry.DelaunayTriangulation.Types: neighbours :: forall p_a36ps r_a36pt. Lens' (Triangulation p_a36ps r_a36pt) (Vector (CList VertexID))
+ Algorithms.Geometry.DelaunayTriangulation.Types: neighbours :: forall p_a3yrK r_a3yrL. Lens' (Triangulation p_a3yrK r_a3yrL) (Vector (CList VertexID))
- Algorithms.Geometry.DelaunayTriangulation.Types: positions :: forall p_a36ps r_a36pt p_a36uj. Lens (Triangulation p_a36ps r_a36pt) (Triangulation p_a36uj r_a36pt) (Vector ((:+) (Point 2 r_a36pt) p_a36ps)) (Vector ((:+) (Point 2 r_a36pt) p_a36uj))
+ Algorithms.Geometry.DelaunayTriangulation.Types: positions :: forall p_a3yrK r_a3yrL p_a3ywF. Lens (Triangulation p_a3yrK r_a3yrL) (Triangulation p_a3ywF r_a3yrL) (Vector ((:+) (Point 2 r_a3yrL) p_a3yrK)) (Vector ((:+) (Point 2 r_a3yrL) p_a3ywF))
- Algorithms.Geometry.DelaunayTriangulation.Types: vertexIds :: forall p_a36ps r_a36pt. Lens' (Triangulation p_a36ps r_a36pt) (Map (Point 2 r_a36pt) VertexID)
+ Algorithms.Geometry.DelaunayTriangulation.Types: vertexIds :: forall p_a3yrK r_a3yrL. Lens' (Triangulation p_a3yrK r_a3yrL) (Map (Point 2 r_a3yrL) VertexID)
- Algorithms.Geometry.LineSegmentIntersection.Types: associatedSegs :: forall p_a1Bd1 r_a1Bd2 p_a1BzI. Lens (IntersectionPoint p_a1Bd1 r_a1Bd2) (IntersectionPoint p_a1BzI r_a1Bd2) (Associated p_a1Bd1 r_a1Bd2) (Associated p_a1BzI r_a1Bd2)
+ Algorithms.Geometry.LineSegmentIntersection.Types: associatedSegs :: forall p_a1HAK r_a1HAL p_a1HUq. Lens (IntersectionPoint p_a1HAK r_a1HAL) (IntersectionPoint p_a1HUq r_a1HAL) (Associated p_a1HAK r_a1HAL) (Associated p_a1HUq r_a1HAL)
- Algorithms.Geometry.LineSegmentIntersection.Types: intersectionPoint :: forall p_a1Bd1 r_a1Bd2. Lens' (IntersectionPoint p_a1Bd1 r_a1Bd2) (Point 2 r_a1Bd2)
+ Algorithms.Geometry.LineSegmentIntersection.Types: intersectionPoint :: forall p_a1HAK r_a1HAL. Lens' (IntersectionPoint p_a1HAK r_a1HAL) (Point 2 r_a1HAL)
- Algorithms.Geometry.LinearProgramming.Types: _NoSolution :: forall d_a2mSY r_a2mSZ. Prism' (LPSolution d_a2mSY r_a2mSZ) ()
+ Algorithms.Geometry.LinearProgramming.Types: _NoSolution :: forall d_a2O97 r_a2O98. Prism' (LPSolution d_a2O97 r_a2O98) ()
- Algorithms.Geometry.LinearProgramming.Types: _Single :: forall d_a2mSY r_a2mSZ. Prism' (LPSolution d_a2mSY r_a2mSZ) (Point d_a2mSY r_a2mSZ)
+ Algorithms.Geometry.LinearProgramming.Types: _Single :: forall d_a2O97 r_a2O98. Prism' (LPSolution d_a2O97 r_a2O98) (Point d_a2O97 r_a2O98)
- Algorithms.Geometry.LinearProgramming.Types: _UnBounded :: forall d_a2mSY r_a2mSZ. Prism' (LPSolution d_a2mSY r_a2mSZ) (HalfLine d_a2mSY r_a2mSZ)
+ Algorithms.Geometry.LinearProgramming.Types: _UnBounded :: forall d_a2O97 r_a2O98. Prism' (LPSolution d_a2O97 r_a2O98) (HalfLine d_a2O97 r_a2O98)
- Algorithms.Geometry.LinearProgramming.Types: constraints :: forall d_a2mUZ r_a2mV0. Lens' (LinearProgram d_a2mUZ r_a2mV0) [HalfSpace d_a2mUZ r_a2mV0]
+ Algorithms.Geometry.LinearProgramming.Types: constraints :: forall d_a2Oaq r_a2Oar. Lens' (LinearProgram d_a2Oaq r_a2Oar) [HalfSpace d_a2Oaq r_a2Oar]
- Algorithms.Geometry.LinearProgramming.Types: objective :: forall d_a2mUZ r_a2mV0. Lens' (LinearProgram d_a2mUZ r_a2mV0) (Vector d_a2mUZ r_a2mV0)
+ Algorithms.Geometry.LinearProgramming.Types: objective :: forall d_a2Oaq r_a2Oar. Lens' (LinearProgram d_a2Oaq r_a2Oar) (Vector d_a2Oaq r_a2Oar)
- Algorithms.Geometry.SmallestEnclosingBall.Types: definingPoints :: forall p_a2rvM r_a2rvN p_a2rOU. Lens (DiskResult p_a2rvM r_a2rvN) (DiskResult p_a2rOU r_a2rvN) (TwoOrThree ((:+) (Point 2 r_a2rvN) p_a2rvM)) (TwoOrThree ((:+) (Point 2 r_a2rvN) p_a2rOU))
+ Algorithms.Geometry.SmallestEnclosingBall.Types: definingPoints :: forall p_a2SvR r_a2SvS p_a2SOG. Lens (DiskResult p_a2SvR r_a2SvS) (DiskResult p_a2SOG r_a2SvS) (TwoOrThree ((:+) (Point 2 r_a2SvS) p_a2SvR)) (TwoOrThree ((:+) (Point 2 r_a2SvS) p_a2SOG))
- Algorithms.Geometry.SmallestEnclosingBall.Types: enclosingDisk :: forall p_a2rvM r_a2rvN. Lens' (DiskResult p_a2rvM r_a2rvN) (Disk () r_a2rvN)
+ Algorithms.Geometry.SmallestEnclosingBall.Types: enclosingDisk :: forall p_a2SvR r_a2SvS. Lens' (DiskResult p_a2SvR r_a2SvS) (Disk () r_a2SvS)
- Algorithms.Geometry.WellSeparatedPairDecomposition.Types: bBox :: forall d_a2iC8 r_a2iC9 a_a2iCa d_a2iH2 r_a2iH3. Lens (NodeData d_a2iC8 r_a2iC9 a_a2iCa) (NodeData d_a2iH2 r_a2iH3 a_a2iCa) (Box d_a2iC8 () r_a2iC9) (Box d_a2iH2 () r_a2iH3)
+ Algorithms.Geometry.WellSeparatedPairDecomposition.Types: bBox :: forall d_a2JkP r_a2JkQ a_a2JkR d_a2JpH r_a2JpI. Lens (NodeData d_a2JkP r_a2JkQ a_a2JkR) (NodeData d_a2JpH r_a2JpI a_a2JkR) (Box d_a2JkP () r_a2JkQ) (Box d_a2JpH () r_a2JpI)
- Algorithms.Geometry.WellSeparatedPairDecomposition.Types: leftPart :: forall d_a2iTd r_a2iTe p_a2iTf. Lens' (FindAndCompact d_a2iTd r_a2iTe p_a2iTf) (Seq ((:+) (Point d_a2iTd r_a2iTe) p_a2iTf))
+ Algorithms.Geometry.WellSeparatedPairDecomposition.Types: leftPart :: forall d_a2JBS r_a2JBT p_a2JBU. Lens' (FindAndCompact d_a2JBS r_a2JBT p_a2JBU) (Seq ((:+) (Point d_a2JBS r_a2JBT) p_a2JBU))
- Algorithms.Geometry.WellSeparatedPairDecomposition.Types: nodeData :: forall d_a2iC8 r_a2iC9 a_a2iCa a_a2iH4. Lens (NodeData d_a2iC8 r_a2iC9 a_a2iCa) (NodeData d_a2iC8 r_a2iC9 a_a2iH4) a_a2iCa a_a2iH4
+ Algorithms.Geometry.WellSeparatedPairDecomposition.Types: nodeData :: forall d_a2JkP r_a2JkQ a_a2JkR a_a2JpJ. Lens (NodeData d_a2JkP r_a2JkQ a_a2JkR) (NodeData d_a2JkP r_a2JkQ a_a2JpJ) a_a2JkR a_a2JpJ
- Algorithms.Geometry.WellSeparatedPairDecomposition.Types: rightPart :: forall d_a2iTd r_a2iTe p_a2iTf. Lens' (FindAndCompact d_a2iTd r_a2iTe p_a2iTf) (Seq ((:+) (Point d_a2iTd r_a2iTe) p_a2iTf))
+ Algorithms.Geometry.WellSeparatedPairDecomposition.Types: rightPart :: forall d_a2JBS r_a2JBT p_a2JBU. Lens' (FindAndCompact d_a2JBS r_a2JBT p_a2JBU) (Seq ((:+) (Point d_a2JBS r_a2JBT) p_a2JBU))
- Algorithms.Geometry.WellSeparatedPairDecomposition.Types: shortSide :: forall d_a2iTd r_a2iTe p_a2iTf. Lens' (FindAndCompact d_a2iTd r_a2iTe p_a2iTf) ShortSide
+ Algorithms.Geometry.WellSeparatedPairDecomposition.Types: shortSide :: forall d_a2JBS r_a2JBT p_a2JBU. Lens' (FindAndCompact d_a2JBS r_a2JBT p_a2JBU) ShortSide
- Algorithms.Geometry.WellSeparatedPairDecomposition.Types: splitDim :: forall d_a2iC8 r_a2iC9 a_a2iCa. Lens' (NodeData d_a2iC8 r_a2iC9 a_a2iCa) Int
+ Algorithms.Geometry.WellSeparatedPairDecomposition.Types: splitDim :: forall d_a2JkP r_a2JkQ a_a2JkR. Lens' (NodeData d_a2JkP r_a2JkQ a_a2JkR) Int
- Data.Geometry: points :: forall d_a1IC4 p_a1IC5 r_a1IC6 d_a1IEd p_a1IEe r_a1IEf. Iso (PolyLine d_a1IC4 p_a1IC5 r_a1IC6) (PolyLine d_a1IEd p_a1IEe r_a1IEf) (LSeq 2 ((:+) (Point d_a1IC4 r_a1IC6) p_a1IC5)) (LSeq 2 ((:+) (Point d_a1IEd r_a1IEf) p_a1IEe))
+ Data.Geometry: points :: forall d_a22fG p_a22fH r_a22fI d_a22hP p_a22hQ r_a22hR. Iso (PolyLine d_a22fG p_a22fH r_a22fI) (PolyLine d_a22hP p_a22hQ r_a22hR) (LSeq 2 ((:+) (Point d_a22fG r_a22fI) p_a22fH)) (LSeq 2 ((:+) (Point d_a22hP r_a22hR) p_a22hQ))
- Data.Geometry.Arrangement: boundedArea :: forall s_a2VLj l_a2VLk v_a2VLl e_a2VLm f_a2VLn r_a2VLo. Lens' (Arrangement s_a2VLj l_a2VLk v_a2VLl e_a2VLm f_a2VLn r_a2VLo) (Rectangle () r_a2VLo)
+ Data.Geometry.Arrangement: boundedArea :: forall s_a3nHW l_a3nHX v_a3nHY e_a3nHZ f_a3nI0 r_a3nI1. Lens' (Arrangement s_a3nHW l_a3nHX v_a3nHY e_a3nHZ f_a3nI0 r_a3nI1) (Rectangle () r_a3nI1)
- Data.Geometry.Arrangement: inputLines :: forall s_a2VLj l_a2VLk v_a2VLl e_a2VLm f_a2VLn r_a2VLo. Lens' (Arrangement s_a2VLj l_a2VLk v_a2VLl e_a2VLm f_a2VLn r_a2VLo) (Vector ((:+) (Line 2 r_a2VLo) l_a2VLk))
+ Data.Geometry.Arrangement: inputLines :: forall s_a3nHW l_a3nHX v_a3nHY e_a3nHZ f_a3nI0 r_a3nI1. Lens' (Arrangement s_a3nHW l_a3nHX v_a3nHY e_a3nHZ f_a3nI0 r_a3nI1) (Vector ((:+) (Line 2 r_a3nI1) l_a3nHX))
- Data.Geometry.Arrangement: subdivision :: forall s_a2VLj l_a2VLk v_a2VLl e_a2VLm f_a2VLn r_a2VLo v_a2VTb e_a2VTc f_a2VTd. Lens (Arrangement s_a2VLj l_a2VLk v_a2VLl e_a2VLm f_a2VLn r_a2VLo) (Arrangement s_a2VLj l_a2VLk v_a2VTb e_a2VTc f_a2VTd r_a2VLo) (PlanarSubdivision s_a2VLj v_a2VLl e_a2VLm f_a2VLn r_a2VLo) (PlanarSubdivision s_a2VLj v_a2VTb e_a2VTc f_a2VTd r_a2VLo)
+ Data.Geometry.Arrangement: subdivision :: forall s_a3nHW l_a3nHX v_a3nHY e_a3nHZ f_a3nI0 r_a3nI1 v_a3nPK e_a3nPL f_a3nPM. Lens (Arrangement s_a3nHW l_a3nHX v_a3nHY e_a3nHZ f_a3nI0 r_a3nI1) (Arrangement s_a3nHW l_a3nHX v_a3nPK e_a3nPL f_a3nPM r_a3nI1) (PlanarSubdivision s_a3nHW v_a3nHY e_a3nHZ f_a3nI0 r_a3nI1) (PlanarSubdivision s_a3nHW v_a3nPK e_a3nPL f_a3nPM r_a3nI1)
- Data.Geometry.Arrangement: unboundedIntersections :: forall s_a2VLj l_a2VLk v_a2VLl e_a2VLm f_a2VLn r_a2VLo. Lens' (Arrangement s_a2VLj l_a2VLk v_a2VLl e_a2VLm f_a2VLn r_a2VLo) (ArrangementBoundary s_a2VLj l_a2VLk r_a2VLo)
+ Data.Geometry.Arrangement: unboundedIntersections :: forall s_a3nHW l_a3nHX v_a3nHY e_a3nHZ f_a3nI0 r_a3nI1. Lens' (Arrangement s_a3nHW l_a3nHX v_a3nHY e_a3nHZ f_a3nI0 r_a3nI1) (ArrangementBoundary s_a3nHW l_a3nHX r_a3nI1)
- Data.Geometry.Arrangement.Internal: boundedArea :: forall s_a2VLj l_a2VLk v_a2VLl e_a2VLm f_a2VLn r_a2VLo. Lens' (Arrangement s_a2VLj l_a2VLk v_a2VLl e_a2VLm f_a2VLn r_a2VLo) (Rectangle () r_a2VLo)
+ Data.Geometry.Arrangement.Internal: boundedArea :: forall s_a3nHW l_a3nHX v_a3nHY e_a3nHZ f_a3nI0 r_a3nI1. Lens' (Arrangement s_a3nHW l_a3nHX v_a3nHY e_a3nHZ f_a3nI0 r_a3nI1) (Rectangle () r_a3nI1)
- Data.Geometry.Arrangement.Internal: inputLines :: forall s_a2VLj l_a2VLk v_a2VLl e_a2VLm f_a2VLn r_a2VLo. Lens' (Arrangement s_a2VLj l_a2VLk v_a2VLl e_a2VLm f_a2VLn r_a2VLo) (Vector ((:+) (Line 2 r_a2VLo) l_a2VLk))
+ Data.Geometry.Arrangement.Internal: inputLines :: forall s_a3nHW l_a3nHX v_a3nHY e_a3nHZ f_a3nI0 r_a3nI1. Lens' (Arrangement s_a3nHW l_a3nHX v_a3nHY e_a3nHZ f_a3nI0 r_a3nI1) (Vector ((:+) (Line 2 r_a3nI1) l_a3nHX))
- Data.Geometry.Arrangement.Internal: subdivision :: forall s_a2VLj l_a2VLk v_a2VLl e_a2VLm f_a2VLn r_a2VLo v_a2VTb e_a2VTc f_a2VTd. Lens (Arrangement s_a2VLj l_a2VLk v_a2VLl e_a2VLm f_a2VLn r_a2VLo) (Arrangement s_a2VLj l_a2VLk v_a2VTb e_a2VTc f_a2VTd r_a2VLo) (PlanarSubdivision s_a2VLj v_a2VLl e_a2VLm f_a2VLn r_a2VLo) (PlanarSubdivision s_a2VLj v_a2VTb e_a2VTc f_a2VTd r_a2VLo)
+ Data.Geometry.Arrangement.Internal: subdivision :: forall s_a3nHW l_a3nHX v_a3nHY e_a3nHZ f_a3nI0 r_a3nI1 v_a3nPK e_a3nPL f_a3nPM. Lens (Arrangement s_a3nHW l_a3nHX v_a3nHY e_a3nHZ f_a3nI0 r_a3nI1) (Arrangement s_a3nHW l_a3nHX v_a3nPK e_a3nPL f_a3nPM r_a3nI1) (PlanarSubdivision s_a3nHW v_a3nHY e_a3nHZ f_a3nI0 r_a3nI1) (PlanarSubdivision s_a3nHW v_a3nPK e_a3nPL f_a3nPM r_a3nI1)
- Data.Geometry.Arrangement.Internal: unboundedIntersections :: forall s_a2VLj l_a2VLk v_a2VLl e_a2VLm f_a2VLn r_a2VLo. Lens' (Arrangement s_a2VLj l_a2VLk v_a2VLl e_a2VLm f_a2VLn r_a2VLo) (ArrangementBoundary s_a2VLj l_a2VLk r_a2VLo)
+ Data.Geometry.Arrangement.Internal: unboundedIntersections :: forall s_a3nHW l_a3nHX v_a3nHY e_a3nHZ f_a3nI0 r_a3nI1. Lens' (Arrangement s_a3nHW l_a3nHX v_a3nHY e_a3nHZ f_a3nI0 r_a3nI1) (ArrangementBoundary s_a3nHW l_a3nHX r_a3nI1)
- Data.Geometry.Ball: center :: forall d_a2081 p_a2082 r_a2083 d_a20aJ p_a20aK. Lens (Ball d_a2081 p_a2082 r_a2083) (Ball d_a20aJ p_a20aK r_a2083) ((:+) (Point d_a2081 r_a2083) p_a2082) ((:+) (Point d_a20aJ r_a2083) p_a20aK)
+ Data.Geometry.Ball: center :: forall d_a2mAY p_a2mAZ r_a2mB0 d_a2mDG p_a2mDH. Lens (Ball d_a2mAY p_a2mAZ r_a2mB0) (Ball d_a2mDG p_a2mDH r_a2mB0) ((:+) (Point d_a2mAY r_a2mB0) p_a2mAZ) ((:+) (Point d_a2mDG r_a2mB0) p_a2mDH)
- Data.Geometry.Ball: squaredRadius :: forall d_a2081 p_a2082 r_a2083. Lens' (Ball d_a2081 p_a2082 r_a2083) r_a2083
+ Data.Geometry.Ball: squaredRadius :: forall d_a2mAY p_a2mAZ r_a2mB0. Lens' (Ball d_a2mAY p_a2mAZ r_a2mB0) r_a2mB0
- Data.Geometry.Box.Internal: cwMax :: forall a_a1qcB a_a1qtB. Iso (CWMax a_a1qcB) (CWMax a_a1qtB) a_a1qcB a_a1qtB
+ Data.Geometry.Box.Internal: cwMax :: forall a_a1xgn a_a1xxm. Iso (CWMax a_a1xgn) (CWMax a_a1xxm) a_a1xgn a_a1xxm
- Data.Geometry.Box.Internal: cwMin :: forall a_a1pXD a_a1qcv. Iso (CWMin a_a1pXD) (CWMin a_a1qcv) a_a1pXD a_a1qcv
+ Data.Geometry.Box.Internal: cwMin :: forall a_a1x1y a_a1xgh. Iso (CWMin a_a1x1y) (CWMin a_a1xgh) a_a1x1y a_a1xgh
- Data.Geometry.Box.Internal: maxP :: forall d_a1qtI p_a1qtJ r_a1qtK. Lens' (Box d_a1qtI p_a1qtJ r_a1qtK) ((:+) (CWMax (Point d_a1qtI r_a1qtK)) p_a1qtJ)
+ Data.Geometry.Box.Internal: maxP :: forall d_a1xxt p_a1xxu r_a1xxv. Lens' (Box d_a1xxt p_a1xxu r_a1xxv) ((:+) (CWMax (Point d_a1xxt r_a1xxv)) p_a1xxu)
- Data.Geometry.Box.Internal: minP :: forall d_a1qtI p_a1qtJ r_a1qtK. Lens' (Box d_a1qtI p_a1qtJ r_a1qtK) ((:+) (CWMin (Point d_a1qtI r_a1qtK)) p_a1qtJ)
+ Data.Geometry.Box.Internal: minP :: forall d_a1xxt p_a1xxu r_a1xxv. Lens' (Box d_a1xxt p_a1xxu r_a1xxv) ((:+) (CWMin (Point d_a1xxt r_a1xxv)) p_a1xxu)
- Data.Geometry.HalfLine: halfLineDirection :: forall d_a1TA4 r_a1TA5. Lens' (HalfLine d_a1TA4 r_a1TA5) (Vector d_a1TA4 r_a1TA5)
+ Data.Geometry.HalfLine: halfLineDirection :: forall d_a2dr4 r_a2dr5. Lens' (HalfLine d_a2dr4 r_a2dr5) (Vector d_a2dr4 r_a2dr5)
- Data.Geometry.HalfLine: startPoint :: forall d_a1TA4 r_a1TA5. Lens' (HalfLine d_a1TA4 r_a1TA5) (Point d_a1TA4 r_a1TA5)
+ Data.Geometry.HalfLine: startPoint :: forall d_a2dr4 r_a2dr5. Lens' (HalfLine d_a2dr4 r_a2dr5) (Point d_a2dr4 r_a2dr5)
- Data.Geometry.HalfSpace: boundingPlane :: forall d_a1Wts r_a1Wtt d_a1Wvp r_a1Wvq. Iso (HalfSpace d_a1Wts r_a1Wtt) (HalfSpace d_a1Wvp r_a1Wvq) (HyperPlane d_a1Wts r_a1Wtt) (HyperPlane d_a1Wvp r_a1Wvq)
+ Data.Geometry.HalfSpace: boundingPlane :: forall d_a2fS6 r_a2fS7 d_a2fU3 r_a2fU4. Iso (HalfSpace d_a2fS6 r_a2fS7) (HalfSpace d_a2fU3 r_a2fU4) (HyperPlane d_a2fS6 r_a2fS7) (HyperPlane d_a2fU3 r_a2fU4)
- Data.Geometry.HyperPlane: inPlane :: forall d_a1QBe r_a1QBf. Lens' (HyperPlane d_a1QBe r_a1QBf) (Point d_a1QBe r_a1QBf)
+ Data.Geometry.HyperPlane: inPlane :: forall d_a2alM r_a2alN. Lens' (HyperPlane d_a2alM r_a2alN) (Point d_a2alM r_a2alN)
- Data.Geometry.HyperPlane: normalVec :: forall d_a1QBe r_a1QBf. Lens' (HyperPlane d_a1QBe r_a1QBf) (Vector d_a1QBe r_a1QBf)
+ Data.Geometry.HyperPlane: normalVec :: forall d_a2alM r_a2alN. Lens' (HyperPlane d_a2alM r_a2alN) (Vector d_a2alM r_a2alN)
- Data.Geometry.Interval.Util: unL :: forall r_aaGJ r_anth. Iso (L r_aaGJ) (L r_anth) (EndPoint r_aaGJ) (EndPoint r_anth)
+ Data.Geometry.Interval.Util: unL :: forall r_avvf r_awrF. Iso (L r_avvf) (L r_awrF) (EndPoint r_avvf) (EndPoint r_awrF)
- Data.Geometry.Interval.Util: unR :: forall r_antn r_anOq. Iso (R r_antn) (R r_anOq) (EndPoint r_antn) (EndPoint r_anOq)
+ Data.Geometry.Interval.Util: unR :: forall r_awrL r_awGg. Iso (R r_awrL) (R r_awGg) (EndPoint r_awrL) (EndPoint r_awGg)
- Data.Geometry.IntervalTree: intervalsLeft :: forall i_arOZ r_arP0. Lens' (NodeData i_arOZ r_arP0) (Map (L r_arP0) [i_arOZ])
+ Data.Geometry.IntervalTree: intervalsLeft :: forall i_aAf8 r_aAf9. Lens' (NodeData i_aAf8 r_aAf9) (Map (L r_aAf9) [i_aAf8])
- Data.Geometry.IntervalTree: intervalsRight :: forall i_arOZ r_arP0. Lens' (NodeData i_arOZ r_arP0) (Map (R r_arP0) [i_arOZ])
+ Data.Geometry.IntervalTree: intervalsRight :: forall i_aAf8 r_aAf9. Lens' (NodeData i_aAf8 r_aAf9) (Map (R r_aAf9) [i_aAf8])
- Data.Geometry.IntervalTree: splitPoint :: forall i_arOZ r_arP0. Lens' (NodeData i_arOZ r_arP0) r_arP0
+ Data.Geometry.IntervalTree: splitPoint :: forall i_aAf8 r_aAf9. Lens' (NodeData i_aAf8 r_aAf9) r_aAf9
- Data.Geometry.IntervalTree: unIntervalTree :: forall i_as0g r_as0h i_as7p r_as7q. Iso (IntervalTree i_as0g r_as0h) (IntervalTree i_as7p r_as7q) (BinaryTree (NodeData i_as0g r_as0h)) (BinaryTree (NodeData i_as7p r_as7q))
+ Data.Geometry.IntervalTree: unIntervalTree :: forall i_aAor r_aAos i_aAvA r_aAvB. Iso (IntervalTree i_aAor r_aAos) (IntervalTree i_aAvA r_aAvB) (BinaryTree (NodeData i_aAor r_aAos)) (BinaryTree (NodeData i_aAvA r_aAvB))
- Data.Geometry.Line.Internal: anchorPoint :: forall d_a1fO7 r_a1fO8. Lens' (Line d_a1fO7 r_a1fO8) (Point d_a1fO7 r_a1fO8)
+ Data.Geometry.Line.Internal: anchorPoint :: forall d_a1nxr r_a1nxs. Lens' (Line d_a1nxr r_a1nxs) (Point d_a1nxr r_a1nxs)
- Data.Geometry.Line.Internal: direction :: forall d_a1fO7 r_a1fO8. Lens' (Line d_a1fO7 r_a1fO8) (Vector d_a1fO7 r_a1fO8)
+ Data.Geometry.Line.Internal: direction :: forall d_a1nxr r_a1nxs. Lens' (Line d_a1nxr r_a1nxs) (Vector d_a1nxr r_a1nxs)
- Data.Geometry.Line.Internal: onSideUpDown :: (Ord r, Num r) => Point 2 r -> Line 2 r -> SideTestUpDown
+ Data.Geometry.Line.Internal: onSideUpDown :: (OnSideUpDownTest t, d ~ Dimension t, r ~ NumType t, Ord r, Num r) => Point d r -> t -> SideTestUpDown
- Data.Geometry.PlanarSubdivision.Basic: components :: forall s_a2MVP v_a2MVQ e_a2MVR f_a2MVS r_a2MVT r_a2N95. Lens (PlanarSubdivision s_a2MVP v_a2MVQ e_a2MVR f_a2MVS r_a2MVT) (PlanarSubdivision s_a2MVP v_a2MVQ e_a2MVR f_a2MVS r_a2N95) (Vector (Component s_a2MVP r_a2MVT)) (Vector (Component s_a2MVP r_a2N95))
+ Data.Geometry.PlanarSubdivision.Basic: components :: forall s_a3eQC v_a3eQD e_a3eQE f_a3eQF r_a3eQG r_a3f3S. Lens (PlanarSubdivision s_a3eQC v_a3eQD e_a3eQE f_a3eQF r_a3eQG) (PlanarSubdivision s_a3eQC v_a3eQD e_a3eQE f_a3eQF r_a3f3S) (Vector (Component s_a3eQC r_a3eQG)) (Vector (Component s_a3eQC r_a3f3S))
- Data.Geometry.PlanarSubdivision.Basic: fData :: forall h_a2GIA f_a2GIB f_a2Hz0. Lens (FaceData h_a2GIA f_a2GIB) (FaceData h_a2GIA f_a2Hz0) f_a2GIB f_a2Hz0
+ Data.Geometry.PlanarSubdivision.Basic: fData :: forall h_a38zf f_a38zg f_a39pF. Lens (FaceData h_a38zf f_a38zg) (FaceData h_a38zf f_a39pF) f_a38zg f_a39pF
- Data.Geometry.PlanarSubdivision.Basic: holes :: forall h_a2GIA f_a2GIB h_a2Hz1. Lens (FaceData h_a2GIA f_a2GIB) (FaceData h_a2Hz1 f_a2GIB) (Seq h_a2GIA) (Seq h_a2Hz1)
+ Data.Geometry.PlanarSubdivision.Basic: holes :: forall h_a38zf f_a38zg h_a39pG. Lens (FaceData h_a38zf f_a38zg) (FaceData h_a39pG f_a38zg) (Seq h_a38zf) (Seq h_a39pG)
- Data.Geometry.PlanarSubdivision.Basic: location :: forall r_a2yMq v_a2yMr r_a2z17. Lens (VertexData r_a2yMq v_a2yMr) (VertexData r_a2z17 v_a2yMr) (Point 2 r_a2yMq) (Point 2 r_a2z17)
+ Data.Geometry.PlanarSubdivision.Basic: location :: forall r_a30z8 v_a30z9 r_a30NV. Lens (VertexData r_a30z8 v_a30z9) (VertexData r_a30NV v_a30z9) (Point 2 r_a30z8) (Point 2 r_a30NV)
- Data.Geometry.PlanarSubdivision.Basic: rawDartData :: forall s_a2MVP v_a2MVQ e_a2MVR f_a2MVS r_a2MVT e_a2N96. Lens (PlanarSubdivision s_a2MVP v_a2MVQ e_a2MVR f_a2MVS r_a2MVT) (PlanarSubdivision s_a2MVP v_a2MVQ e_a2N96 f_a2MVS r_a2MVT) (Vector (Raw s_a2MVP (Dart (Wrap s_a2MVP)) e_a2MVR)) (Vector (Raw s_a2MVP (Dart (Wrap s_a2MVP)) e_a2N96))
+ Data.Geometry.PlanarSubdivision.Basic: rawDartData :: forall s_a3eQC v_a3eQD e_a3eQE f_a3eQF r_a3eQG e_a3f3T. Lens (PlanarSubdivision s_a3eQC v_a3eQD e_a3eQE f_a3eQF r_a3eQG) (PlanarSubdivision s_a3eQC v_a3eQD e_a3f3T f_a3eQF r_a3eQG) (Vector (Raw s_a3eQC (Dart (Wrap s_a3eQC)) e_a3eQE)) (Vector (Raw s_a3eQC (Dart (Wrap s_a3eQC)) e_a3f3T))
- Data.Geometry.PlanarSubdivision.Basic: rawFaceData :: forall s_a2MVP v_a2MVQ e_a2MVR f_a2MVS r_a2MVT f_a2N97. Lens (PlanarSubdivision s_a2MVP v_a2MVQ e_a2MVR f_a2MVS r_a2MVT) (PlanarSubdivision s_a2MVP v_a2MVQ e_a2MVR f_a2N97 r_a2MVT) (Vector (RawFace s_a2MVP f_a2MVS)) (Vector (RawFace s_a2MVP f_a2N97))
+ Data.Geometry.PlanarSubdivision.Basic: rawFaceData :: forall s_a3eQC v_a3eQD e_a3eQE f_a3eQF r_a3eQG f_a3f3U. Lens (PlanarSubdivision s_a3eQC v_a3eQD e_a3eQE f_a3eQF r_a3eQG) (PlanarSubdivision s_a3eQC v_a3eQD e_a3eQE f_a3f3U r_a3eQG) (Vector (RawFace s_a3eQC f_a3eQF)) (Vector (RawFace s_a3eQC f_a3f3U))
- Data.Geometry.PlanarSubdivision.Basic: rawVertexData :: forall s_a2MVP v_a2MVQ e_a2MVR f_a2MVS r_a2MVT v_a2N98. Lens (PlanarSubdivision s_a2MVP v_a2MVQ e_a2MVR f_a2MVS r_a2MVT) (PlanarSubdivision s_a2MVP v_a2N98 e_a2MVR f_a2MVS r_a2MVT) (Vector (Raw s_a2MVP (VertexId' (Wrap s_a2MVP)) v_a2MVQ)) (Vector (Raw s_a2MVP (VertexId' (Wrap s_a2MVP)) v_a2N98))
+ Data.Geometry.PlanarSubdivision.Basic: rawVertexData :: forall s_a3eQC v_a3eQD e_a3eQE f_a3eQF r_a3eQG v_a3f3V. Lens (PlanarSubdivision s_a3eQC v_a3eQD e_a3eQE f_a3eQF r_a3eQG) (PlanarSubdivision s_a3eQC v_a3f3V e_a3eQE f_a3eQF r_a3eQG) (Vector (Raw s_a3eQC (VertexId' (Wrap s_a3eQC)) v_a3eQD)) (Vector (Raw s_a3eQC (VertexId' (Wrap s_a3eQC)) v_a3f3V))
- Data.Geometry.PlanarSubdivision.Basic: vData :: forall r_a2yMq v_a2yMr v_a2z18. Lens (VertexData r_a2yMq v_a2yMr) (VertexData r_a2yMq v_a2z18) v_a2yMr v_a2z18
+ Data.Geometry.PlanarSubdivision.Basic: vData :: forall r_a30z8 v_a30z9 v_a30NW. Lens (VertexData r_a30z8 v_a30z9) (VertexData r_a30z8 v_a30NW) v_a30z9 v_a30NW
- Data.Geometry.PlanarSubdivision.Raw: fData :: forall h_a2GIA f_a2GIB f_a2Hz0. Lens (FaceData h_a2GIA f_a2GIB) (FaceData h_a2GIA f_a2Hz0) f_a2GIB f_a2Hz0
+ Data.Geometry.PlanarSubdivision.Raw: fData :: forall h_a38zf f_a38zg f_a39pF. Lens (FaceData h_a38zf f_a38zg) (FaceData h_a38zf f_a39pF) f_a38zg f_a39pF
- Data.Geometry.PlanarSubdivision.Raw: faceDataVal :: forall s_a2Hzg f_a2Hzh f_a2HOX. Lens (RawFace s_a2Hzg f_a2Hzh) (RawFace s_a2Hzg f_a2HOX) (FaceData (Dart s_a2Hzg) f_a2Hzh) (FaceData (Dart s_a2Hzg) f_a2HOX)
+ Data.Geometry.PlanarSubdivision.Raw: faceDataVal :: forall s_a39pV f_a39pW f_a39FC. Lens (RawFace s_a39pV f_a39pW) (RawFace s_a39pV f_a39FC) (FaceData (Dart s_a39pV) f_a39pW) (FaceData (Dart s_a39pV) f_a39FC)
- Data.Geometry.PlanarSubdivision.Raw: faceIdx :: forall s_a2Hzg f_a2Hzh. Lens' (RawFace s_a2Hzg f_a2Hzh) (Maybe (ComponentId s_a2Hzg, FaceId' (Wrap s_a2Hzg)))
+ Data.Geometry.PlanarSubdivision.Raw: faceIdx :: forall s_a39pV f_a39pW. Lens' (RawFace s_a39pV f_a39pW) (Maybe (ComponentId s_a39pV, FaceId' (Wrap s_a39pV)))
- Data.Geometry.PlanarSubdivision.Raw: holes :: forall h_a2GIA f_a2GIB h_a2Hz1. Lens (FaceData h_a2GIA f_a2GIB) (FaceData h_a2Hz1 f_a2GIB) (Seq h_a2GIA) (Seq h_a2Hz1)
+ Data.Geometry.PlanarSubdivision.Raw: holes :: forall h_a38zf f_a38zg h_a39pG. Lens (FaceData h_a38zf f_a38zg) (FaceData h_a39pG f_a38zg) (Seq h_a38zf) (Seq h_a39pG)
- Data.Geometry.Point: coord :: forall proxy i d r. (1 <= i, i <= d, ((i - 1) + 1) ~ i, Arity (i - 1), Arity d) => proxy i -> Lens' (Point d r) r
+ Data.Geometry.Point: coord :: (1 <= i, i <= d, KnownNat i, Arity d, AsAPoint p) => proxy i -> Lens' (p d r) r
- Data.Geometry.Point: unsafeCoord :: Arity d => Int -> Lens' (Point d r) r
+ Data.Geometry.Point: unsafeCoord :: (Arity d, AsAPoint p) => Int -> Lens' (p d r) r
- Data.Geometry.Point: xCoord :: (1 <= d, Arity d) => Lens' (Point d r) r
+ Data.Geometry.Point: xCoord :: (1 <= d, Arity d, AsAPoint point) => Lens' (point d r) r
- Data.Geometry.Point: yCoord :: (2 <= d, Arity d) => Lens' (Point d r) r
+ Data.Geometry.Point: yCoord :: (2 <= d, Arity d, AsAPoint point) => Lens' (point d r) r
- Data.Geometry.Point: zCoord :: (3 <= d, Arity d) => Lens' (Point d r) r
+ Data.Geometry.Point: zCoord :: (3 <= d, Arity d, AsAPoint point) => Lens' (point d r) r
- Data.Geometry.PolyLine: fromPoints :: [Point d r :+ p] -> PolyLine d p r
+ Data.Geometry.PolyLine: fromPoints :: [Point d r :+ p] -> Maybe (PolyLine d p r)
- Data.Geometry.PolyLine: points :: forall d_a1IC4 p_a1IC5 r_a1IC6 d_a1IEd p_a1IEe r_a1IEf. Iso (PolyLine d_a1IC4 p_a1IC5 r_a1IC6) (PolyLine d_a1IEd p_a1IEe r_a1IEf) (LSeq 2 ((:+) (Point d_a1IC4 r_a1IC6) p_a1IC5)) (LSeq 2 ((:+) (Point d_a1IEd r_a1IEf) p_a1IEe))
+ Data.Geometry.PolyLine: points :: forall d_a22fG p_a22fH r_a22fI d_a22hP p_a22hQ r_a22hR. Iso (PolyLine d_a22fG p_a22fH r_a22fI) (PolyLine d_a22hP p_a22hQ r_a22hR) (LSeq 2 ((:+) (Point d_a22fG r_a22fI) p_a22fH)) (LSeq 2 ((:+) (Point d_a22hP r_a22hR) p_a22hQ))
- Data.Geometry.Polygon.Convex: simplePolygon :: forall p_a2ewa r_a2ewb p_a2eAN r_a2eAO. Iso (ConvexPolygon p_a2ewa r_a2ewb) (ConvexPolygon p_a2eAN r_a2eAO) (SimplePolygon p_a2ewa r_a2ewb) (SimplePolygon p_a2eAN r_a2eAO)
+ Data.Geometry.Polygon.Convex: simplePolygon :: forall p_a2BxI r_a2BxJ p_a2BCl r_a2BCm. Iso (ConvexPolygon p_a2BxI r_a2BxJ) (ConvexPolygon p_a2BCl r_a2BCm) (SimplePolygon p_a2BxI r_a2BxJ) (SimplePolygon p_a2BCl r_a2BCm)
- Data.Geometry.SegmentTree.Generic: assoc :: forall v_awpX r_awpY v_awx9. Lens (NodeData v_awpX r_awpY) (NodeData v_awx9 r_awpY) v_awpX v_awx9
+ Data.Geometry.SegmentTree.Generic: assoc :: forall v_aEbu r_aEbv v_aEiG. Lens (NodeData v_aEbu r_aEbv) (NodeData v_aEiG r_aEbv) v_aEbu v_aEiG
- Data.Geometry.SegmentTree.Generic: atomicRange :: forall v_awxz r_awxA r_awLu. Lens (LeafData v_awxz r_awxA) (LeafData v_awxz r_awLu) (AtomicRange r_awxA) (AtomicRange r_awLu)
+ Data.Geometry.SegmentTree.Generic: atomicRange :: forall v_aEj6 r_aEj7 r_aEwY. Lens (LeafData v_aEj6 r_aEj7) (LeafData v_aEj6 r_aEwY) (AtomicRange r_aEj7) (AtomicRange r_aEwY)
- Data.Geometry.SegmentTree.Generic: leafAssoc :: forall v_awxz r_awxA v_awLv. Lens (LeafData v_awxz r_awxA) (LeafData v_awLv r_awxA) v_awxz v_awLv
+ Data.Geometry.SegmentTree.Generic: leafAssoc :: forall v_aEj6 r_aEj7 v_aEwZ. Lens (LeafData v_aEj6 r_aEj7) (LeafData v_aEwZ r_aEj7) v_aEj6 v_aEwZ
- Data.Geometry.SegmentTree.Generic: range :: forall v_awpX r_awpY. Lens' (NodeData v_awpX r_awpY) (Range r_awpY)
+ Data.Geometry.SegmentTree.Generic: range :: forall v_aEbu r_aEbv. Lens' (NodeData v_aEbu r_aEbv) (Range r_aEbv)
- Data.Geometry.SegmentTree.Generic: splitPoint :: forall v_awpX r_awpY. Lens' (NodeData v_awpX r_awpY) (EndPoint r_awpY)
+ Data.Geometry.SegmentTree.Generic: splitPoint :: forall v_aEbu r_aEbv. Lens' (NodeData v_aEbu r_aEbv) (EndPoint r_aEbv)
- Data.Geometry.SegmentTree.Generic: unSegmentTree :: forall v_awLJ r_awLK v_awTI r_awTJ. Iso (SegmentTree v_awLJ r_awLK) (SegmentTree v_awTI r_awTJ) (BinLeafTree (NodeData v_awLJ r_awLK) (LeafData v_awLJ r_awLK)) (BinLeafTree (NodeData v_awTI r_awTJ) (LeafData v_awTI r_awTJ))
+ Data.Geometry.SegmentTree.Generic: unSegmentTree :: forall v_aExd r_aExe v_aEFc r_aEFd. Iso (SegmentTree v_aExd r_aExe) (SegmentTree v_aEFc r_aEFd) (BinLeafTree (NodeData v_aExd r_aExe) (LeafData v_aExd r_aExe)) (BinLeafTree (NodeData v_aEFc r_aEFd) (LeafData v_aEFc r_aEFd))
- Data.Geometry.Slab: unSlab :: forall o_a1NfM a_a1NfN r_a1NfO o_a1NlF a_a1NlG r_a1NlH. Iso (Slab o_a1NfM a_a1NfN r_a1NfO) (Slab o_a1NlF a_a1NlG r_a1NlH) (Interval a_a1NfN r_a1NfO) (Interval a_a1NlG r_a1NlH)
+ Data.Geometry.Slab: unSlab :: forall o_a26XO a_a26XP r_a26XQ o_a273z a_a273A r_a273B. Iso (Slab o_a26XO a_a26XP r_a26XQ) (Slab o_a273z a_a273A r_a273B) (Interval a_a26XP r_a26XQ) (Interval a_a273A r_a273B)
- Data.Geometry.SubLine: line :: forall d_a1lFq p_a1lFr s_a1lFs r_a1lFt d_a1lGk r_a1lGl. Lens (SubLine d_a1lFq p_a1lFr s_a1lFs r_a1lFt) (SubLine d_a1lGk p_a1lFr s_a1lFs r_a1lGl) (Line d_a1lFq r_a1lFt) (Line d_a1lGk r_a1lGl)
+ Data.Geometry.SubLine: line :: forall d_a1t6F p_a1t6G s_a1t6H r_a1t6I d_a1t7z r_a1t7A. Lens (SubLine d_a1t6F p_a1t6G s_a1t6H r_a1t6I) (SubLine d_a1t7z p_a1t6G s_a1t6H r_a1t7A) (Line d_a1t6F r_a1t6I) (Line d_a1t7z r_a1t7A)
- Data.Geometry.SubLine: subRange :: forall d_a1lFq p_a1lFr s_a1lFs r_a1lFt p_a1lGm s_a1lGn. Lens (SubLine d_a1lFq p_a1lFr s_a1lFs r_a1lFt) (SubLine d_a1lFq p_a1lGm s_a1lGn r_a1lFt) (Interval p_a1lFr s_a1lFs) (Interval p_a1lGm s_a1lGn)
+ Data.Geometry.SubLine: subRange :: forall d_a1t6F p_a1t6G s_a1t6H r_a1t6I p_a1t7B s_a1t7C. Lens (SubLine d_a1t6F p_a1t6G s_a1t6H r_a1t6I) (SubLine d_a1t6F p_a1t7B s_a1t7C r_a1t6I) (Interval p_a1t6G s_a1t6H) (Interval p_a1t7B s_a1t7C)
- Data.Geometry.Transformation: transformationMatrix :: Lens' (Transformation d r) (Matrix (d + 1) (d + 1) r)
+ Data.Geometry.Transformation: transformationMatrix :: Iso (Transformation d r) (Transformation d s) (Matrix (d + 1) (d + 1) r) (Matrix (d + 1) (d + 1) s)
- Data.Geometry.Triangle: Triangle :: (Point d r :+ p) -> (Point d r :+ p) -> (Point d r :+ p) -> Triangle d p r
+ Data.Geometry.Triangle: Triangle :: !Point d r :+ p -> !Point d r :+ p -> !Point d r :+ p -> Triangle d p r
- Data.PlaneGraph: graph :: forall s_a2z1n v_a2z1o e_a2z1p f_a2z1q r_a2z1r s_a2zd9 v_a2zda e_a2zdb f_a2zdc r_a2zdd. Iso (PlaneGraph s_a2z1n v_a2z1o e_a2z1p f_a2z1q r_a2z1r) (PlaneGraph s_a2zd9 v_a2zda e_a2zdb f_a2zdc r_a2zdd) (PlanarGraph s_a2z1n 'Primal (VertexData r_a2z1r v_a2z1o) e_a2z1p f_a2z1q) (PlanarGraph s_a2zd9 'Primal (VertexData r_a2zdd v_a2zda) e_a2zdb f_a2zdc)
+ Data.PlaneGraph: graph :: forall s_a30Ob v_a30Oc e_a30Od f_a30Oe r_a30Of s_a30ZX v_a30ZY e_a30ZZ f_a3100 r_a3101. Iso (PlaneGraph s_a30Ob v_a30Oc e_a30Od f_a30Oe r_a30Of) (PlaneGraph s_a30ZX v_a30ZY e_a30ZZ f_a3100 r_a3101) (PlanarGraph s_a30Ob 'Primal (VertexData r_a30Of v_a30Oc) e_a30Od f_a30Oe) (PlanarGraph s_a30ZX 'Primal (VertexData r_a3101 v_a30ZY) e_a30ZZ f_a3100)
- Data.PlaneGraph: location :: forall r_a2yMq v_a2yMr r_a2z17. Lens (VertexData r_a2yMq v_a2yMr) (VertexData r_a2z17 v_a2yMr) (Point 2 r_a2yMq) (Point 2 r_a2z17)
+ Data.PlaneGraph: location :: forall r_a30z8 v_a30z9 r_a30NV. Lens (VertexData r_a30z8 v_a30z9) (VertexData r_a30NV v_a30z9) (Point 2 r_a30z8) (Point 2 r_a30NV)
- Data.PlaneGraph: vData :: forall r_a2yMq v_a2yMr v_a2z18. Lens (VertexData r_a2yMq v_a2yMr) (VertexData r_a2yMq v_a2z18) v_a2yMr v_a2z18
+ Data.PlaneGraph: vData :: forall r_a30z8 v_a30z9 v_a30NW. Lens (VertexData r_a30z8 v_a30z9) (VertexData r_a30z8 v_a30NW) v_a30z9 v_a30NW
- Data.PlaneGraph.Core: graph :: forall s_a2z1n v_a2z1o e_a2z1p f_a2z1q r_a2z1r s_a2zd9 v_a2zda e_a2zdb f_a2zdc r_a2zdd. Iso (PlaneGraph s_a2z1n v_a2z1o e_a2z1p f_a2z1q r_a2z1r) (PlaneGraph s_a2zd9 v_a2zda e_a2zdb f_a2zdc r_a2zdd) (PlanarGraph s_a2z1n 'Primal (VertexData r_a2z1r v_a2z1o) e_a2z1p f_a2z1q) (PlanarGraph s_a2zd9 'Primal (VertexData r_a2zdd v_a2zda) e_a2zdb f_a2zdc)
+ Data.PlaneGraph.Core: graph :: forall s_a30Ob v_a30Oc e_a30Od f_a30Oe r_a30Of s_a30ZX v_a30ZY e_a30ZZ f_a3100 r_a3101. Iso (PlaneGraph s_a30Ob v_a30Oc e_a30Od f_a30Oe r_a30Of) (PlaneGraph s_a30ZX v_a30ZY e_a30ZZ f_a3100 r_a3101) (PlanarGraph s_a30Ob 'Primal (VertexData r_a30Of v_a30Oc) e_a30Od f_a30Oe) (PlanarGraph s_a30ZX 'Primal (VertexData r_a3101 v_a30ZY) e_a30ZZ f_a3100)
- Data.PlaneGraph.Core: location :: forall r_a2yMq v_a2yMr r_a2z17. Lens (VertexData r_a2yMq v_a2yMr) (VertexData r_a2z17 v_a2yMr) (Point 2 r_a2yMq) (Point 2 r_a2z17)
+ Data.PlaneGraph.Core: location :: forall r_a30z8 v_a30z9 r_a30NV. Lens (VertexData r_a30z8 v_a30z9) (VertexData r_a30NV v_a30z9) (Point 2 r_a30z8) (Point 2 r_a30NV)
- Data.PlaneGraph.Core: vData :: forall r_a2yMq v_a2yMr v_a2z18. Lens (VertexData r_a2yMq v_a2yMr) (VertexData r_a2yMq v_a2z18) v_a2yMr v_a2z18
+ Data.PlaneGraph.Core: vData :: forall r_a30z8 v_a30z9 v_a30NW. Lens (VertexData r_a30z8 v_a30z9) (VertexData r_a30z8 v_a30NW) v_a30z9 v_a30NW
- Graphics.Camera: cameraPosition :: forall r_a38P3. Lens' (Camera r_a38P3) (Point 3 r_a38P3)
+ Graphics.Camera: cameraPosition :: forall r_a3ATc. Lens' (Camera r_a3ATc) (Point 3 r_a3ATc)
- Graphics.Camera: farDist :: forall r_a38P3. Lens' (Camera r_a38P3) r_a38P3
+ Graphics.Camera: farDist :: forall r_a3ATc. Lens' (Camera r_a3ATc) r_a3ATc
- Graphics.Camera: nearDist :: forall r_a38P3. Lens' (Camera r_a38P3) r_a38P3
+ Graphics.Camera: nearDist :: forall r_a3ATc. Lens' (Camera r_a3ATc) r_a3ATc
- Graphics.Camera: rawCameraNormal :: forall r_a38P3. Lens' (Camera r_a38P3) (Vector 3 r_a38P3)
+ Graphics.Camera: rawCameraNormal :: forall r_a3ATc. Lens' (Camera r_a3ATc) (Vector 3 r_a3ATc)
- Graphics.Camera: rawViewUp :: forall r_a38P3. Lens' (Camera r_a38P3) (Vector 3 r_a38P3)
+ Graphics.Camera: rawViewUp :: forall r_a3ATc. Lens' (Camera r_a3ATc) (Vector 3 r_a3ATc)
- Graphics.Camera: screenDimensions :: forall r_a38P3. Lens' (Camera r_a38P3) (Vector 2 r_a38P3)
+ Graphics.Camera: screenDimensions :: forall r_a3ATc. Lens' (Camera r_a3ATc) (Vector 2 r_a3ATc)
- Graphics.Camera: viewPlaneDepth :: forall r_a38P3. Lens' (Camera r_a38P3) r_a38P3
+ Graphics.Camera: viewPlaneDepth :: forall r_a3ATc. Lens' (Camera r_a3ATc) r_a3ATc

Files

changelog.org view
@@ -2,6 +2,40 @@  * Changelog +** 0.11++- Removed Functor instance from Triangle and replaced it with Bifunctor/Bifoldable/Bitraversable+- Testing if a point lies above/below a line is now in a typeclass,+  moreover there now is also an instance of this typeclass for+  planes. Hence, we can test if a point in R^3 lies above or below a+  plane.+- Bugfixes in the incomingEdges and outgoingEdges functions in+  Planar/Plane graphs and Planar subdivisions+- Added separate data types for Sides and Corners of Rectangles.+- More functionality for working with Halfspaces+- Fixed a bug in computing the intersection of overlapping+  linesegments+- PolyLine.fromPoints now returns a Maybe PolyLine rather than a+  Polyine. Use fromPointsUnsafe for the old behavior.+- Interval now no longer exports its constructor. Use the provided+  patterns instead.+- Added an OpenLineSegment pattern/constructor+- The corners and sides functions in Box now return specific types+  representing those rather than four tuples.+- Added a BezierSpline module and data type (Thanks to Maarten).+- Added a QuadTree implementation. It can be built from a set of+  points, and to represent the zeroset of some function.+- Added a Naive implementation of Convex hull in R^3. Note however+  that it works only for points in general position. In particular, no+  four points should be coplanar.+- Added a Data.Geometry.Directions module that defines cardinal and+  InterCardinal directions.+- Added an Ellipse type (mostly so that hgeometry-ipe can read+  ellipses)+- Added FunctorWithIndex, FoldableWithIndex, and TraversableWithIndex+  instances for Vector, and removed specifically exporting imap; we+  can now just use those functions from the Lens package.+ ** 0.10  - renamed the smallest enclosing ball to RIC
doctests.hs view
@@ -63,6 +63,11 @@   , "Data.Geometry.Polygon"   , "Data.Geometry.Ball"   , "Data.Geometry.Box"+  , "Data.Geometry.HyperPlane"    -- , "Algorithms.Geometry.HiddenSurfaceRemoval.HiddenSurfaceRemoval"+  , "Algorithms.Geometry.ConvexHull.Naive"+  , "Algorithms.Geometry.ConvexHull.JarvisMarch"++  , "Algorithms.Geometry.SoS.Orientation"   ]
hgeometry.cabal view
@@ -1,5 +1,5 @@ name:                hgeometry-version:             0.10.0.0+version:             0.11.0.0 synopsis:            Geometric Algorithms, Data structures, and Data types. description:   HGeometry provides some basic geometry types, and geometric algorithms and@@ -56,12 +56,17 @@   ghc-options: -O2 -Wall -fno-warn-unticked-promoted-constructors -fno-warn-type-defaults    exposed-modules:+                    -- * Primitives; Simulating General Position+                    Algorithms.Geometry.SoS+                    Algorithms.Geometry.SoS.Symbolic+                     -- * Generic Geometry                     Data.Geometry                     Data.Geometry.Properties                     Data.Geometry.Transformation                     Data.Geometry.Boundary                     Data.Geometry.Duality+                    Data.Geometry.Directions                      -- * Basic Geometry Types                     Data.Geometry.Vector@@ -69,10 +74,13 @@                     Data.Geometry.Vector.VectorFamily                     Data.Geometry.Vector.VectorFamilyPeano +                    Data.Geometry.Matrix+                     -- Data.Geometry.Vector.Vinyl                     Data.Geometry.Interval                     Data.Geometry.Interval.Util                     Data.Geometry.Point+                     Data.Geometry.Line                     Data.Geometry.Line.Internal                     Data.Geometry.LineSegment@@ -86,10 +94,17 @@                     Data.Geometry.Slab                     Data.Geometry.Box                     Data.Geometry.Box.Internal+                    Data.Geometry.Box.Sides+                    Data.Geometry.Box.Corners+                     Data.Geometry.Ball+                    Data.Geometry.Ellipse+                     Data.Geometry.Polygon                     Data.Geometry.Polygon.Convex +                    Data.Geometry.BezierSpline+                     -- * Geometric Data Structures                     Data.Geometry.IntervalTree                     Data.Geometry.SegmentTree@@ -111,13 +126,21 @@                      Data.Geometry.PrioritySearchTree +                    Data.Geometry.QuadTree+                    Data.Geometry.QuadTree.Cell+                    Data.Geometry.QuadTree.Quadrants+                    Data.Geometry.QuadTree.Split+                    Data.Geometry.QuadTree.Tree++                     -- * Algorithms                      -- * Geometric Algorithms                     Algorithms.Geometry.ConvexHull.GrahamScan                     Algorithms.Geometry.ConvexHull.DivideAndConquer                     Algorithms.Geometry.ConvexHull.QuickHull-                    -- Algorithms.Geometry.ConvexHull.JarvisMarch+                    Algorithms.Geometry.ConvexHull.JarvisMarch+                    Algorithms.Geometry.ConvexHull.Naive                      Algorithms.Geometry.LowerEnvelope.DualCH @@ -174,14 +197,32 @@                     Graphics.Render    other-modules:+                    Data.Geometry.Matrix.Internal+                     -- * Implementation Internals of Polygons                     Data.Geometry.Polygon.Core                     Data.Geometry.Polygon.Extremes ++                    Data.Geometry.Point.Internal+                    Data.Geometry.Point.Orientation+                    Data.Geometry.Point.Quadrants+                    Data.Geometry.Point.Orientation.Degenerate+                    Data.Geometry.Point.Class++                    Algorithms.Geometry.SoS.Expr+                    Algorithms.Geometry.SoS.AsPoint+                    Algorithms.Geometry.SoS.Internal+                    Algorithms.Geometry.SoS.Orientation+                    Algorithms.Geometry.SoS.Determinant+                    Algorithms.Geometry.SoS.Sign+++   -- other-extensions:   build-depends:                 base                    >= 4.11      &&     < 5-              , hgeometry-combinatorial >= 0.10.0.0+              , hgeometry-combinatorial >= 0.11.0.0                , bifunctors              >= 4.1               , bytestring              >= 0.10@@ -198,10 +239,13 @@               , deepseq                 >= 1.1               , fingertree              >= 0.1               , MonadRandom             >= 0.5+              , random                  >= 1.1               , QuickCheck              >= 2.5               , quickcheck-instances    >= 0.3               , reflection              >= 2.1               , primitive               >= 0.6.3.0+              , hashable                >= 1.2+               -- , singleton-typelits      >= 0.1.0.0                -- , ghc-typelits-natnormalise >= 0.6@@ -220,7 +264,7 @@               , hspec, QuickCheck, quickcheck-instances  -  hs-source-dirs: src test+  hs-source-dirs: src    default-language:    Haskell2010 
src/Algorithms/Geometry/ConvexHull/DivideAndConquer.hs view
@@ -16,7 +16,6 @@  import           Algorithms.DivideAndConquer import           Control.Arrow ((&&&))-import           Control.Lens ((^.), to) import           Data.Ext import           Data.Geometry.Point import           Data.Geometry.Polygon
src/Algorithms/Geometry/ConvexHull/GrahamScan.hs view
@@ -1,6 +1,8 @@ module Algorithms.Geometry.ConvexHull.GrahamScan( convexHull-                                                , upperHull-                                                , lowerHull+                                                , upperHull, upperHull'+                                                , lowerHull, lowerHull'++                                                , upperHullFromSorted, upperHullFromSorted'                                                 ) where  import           Control.Lens ((^.))@@ -23,13 +25,54 @@                        in ConvexPolygon . fromPoints . reverse $ lh ++ uh  -- | 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: \(O(n\log n)\) upperHull  :: (Ord r, Num r) => NonEmpty (Point 2 r :+ p) -> NonEmpty (Point 2 r :+ p) upperHull = NonEmpty.reverse . hull id --- | Computes the upper hull. The upper hull is given from left to right+-- | 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)+upperHull' = NonEmpty.reverse . dropVertical . hull id++-- | Helper function to remove vertical segments from the hull.+--+-- Tests if the first two points are on a vertical line, if so removes+-- the first point.+dropVertical :: Eq r => NonEmpty (Point 2 r :+ p) -> NonEmpty (Point 2 r :+ p)+dropVertical = \case+  h@(_ :| [])                                            -> h+  h@(p :| (q : rest)) | p^.core.xCoord == q^.core.xCoord -> q :| rest+                      | otherwise                        -> h+++-- | 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: \(O(n\log n)\) lowerHull :: (Ord r, Num r) => NonEmpty (Point 2 r :+ p) -> NonEmpty (Point 2 r :+ p) lowerHull = hull reverse +-- | 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)+lowerHull' = dropVertical . hull reverse  -- | Helper function so that that can compute both the upper or the lower hull, depending -- on the function f@@ -43,6 +86,32 @@ incXdecY  :: Ord r => (Point 2 r) :+ p -> (Point 2 r) :+ q -> Ordering incXdecY (Point2 px py :+ _) (Point2 qx qy :+ _) =   compare px qx <> compare qy py+++-- | 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: \(O(n)\).+upperHullFromSorted :: (Ord r, Num r) => NonEmpty (Point 2 r :+ p) -> NonEmpty (Point 2 r :+ p)+upperHullFromSorted = \case+  h@(_ :| [])  -> h+  pts          -> hull' $ NonEmpty.toList pts++-- | Computes the upper hull from a sorted input. Removes the last vertical segment.+--+--+-- running time: \(O(n)\).+upperHullFromSorted' :: (Ord r, Num r) => NonEmpty (Point 2 r :+ p) -> NonEmpty (Point 2 r :+ p)+upperHullFromSorted' = dropVertical . upperHullFromSorted   -- | Precondition: The list of input points is sorted
+ src/Algorithms/Geometry/ConvexHull/JarvisMarch.hs view
@@ -0,0 +1,145 @@+module Algorithms.Geometry.ConvexHull.JarvisMarch(+    convexHull++  , upperHull, upperHull'+  , lowerHull, lowerHull'+  , steepestCcwFrom, steepestCwFrom+  ) where++import           Control.Lens ((^.))+import           Data.Bifunctor+import           Data.Either (either)+import           Data.Ext+import           Data.Foldable+import           Data.Geometry.Point+import           Data.Geometry.Polygon+import           Data.Geometry.Polygon.Convex (ConvexPolygon(..))+import           Data.Geometry.Vector+import qualified Data.List as List+import           Data.List.NonEmpty (NonEmpty(..), (<|))+import qualified Data.List.NonEmpty as NonEmpty+import           Data.Ord (comparing, Down(..))+import           Data.Semigroup.Foldable++--------------------------------------------------------------------------------++-- | Compute the convexhull using JarvisMarch. The resulting polygon+-- is given in clockwise order.+--+-- running time: \(O(nh)\), where \(n\) is the number of input points+-- and \(h\) is the complexity of the hull.+convexHull            :: (Ord r, Num r)+                      => NonEmpty (Point 2 r :+ p) -> ConvexPolygon p r+convexHull (p :| []) = ConvexPolygon . fromPoints $ [p]+convexHull pts       = ConvexPolygon . fromPoints $ uh <> reverse lh+  where+    lh = case NonEmpty.nonEmpty (NonEmpty.init $ lowerHull pts) of+           Nothing       -> []+           Just (_:|lh') -> lh'+    uh = toList $ upperHull pts++                       -- note that fromList is afe since ps contains at least two elements+  -- where+  --   SP p@(c :+ _) pts = minViewBy incXdecY ps+  --   takeWhile' pf (x :| xs) = x : takeWhile pf xs++upperHull     ::  (Num r, Ord r) =>  NonEmpty (Point 2 r :+ p) -> NonEmpty (Point 2 r :+ p)+upperHull pts = repeatedly cmp steepestCwFrom s rest+  where+    (s:_ :+ rest) = extractMinimaBy cmp (NonEmpty.toList pts)+    cmp           = comparing (\(Point2 x y :+ _) -> (x, Down y))+                    -- start from the topmost point that has minimum x-coord+                    -- also use cmp as the comparator, so that we also select the last+                    -- vertical segment.++-- | 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)+upperHull' pts = pruneVertical $ repeatedly cmp steepestCwFrom s rest+  where+    (s:_ :+ rest) = extractMinimaBy cmp0 (NonEmpty.toList pts)+    cmp0          = comparing (\(Point2 x y :+ _) -> (x, Down y))+                    -- start from the topmost point that has minimum x-coord+    cmp           = comparing (^.core)+                    -- for the rest select them in normal+                    -- lexicographic order, this causes the last+                    -- vertical segment to be ignored.++-- | Computes the lower hull, from left to right. Includes vertical+-- segments at the start.+--+-- running time: \(O(nh)\), where \(h\) is the complexity of the hull.+lowerHull     ::  (Num r, Ord r) =>  NonEmpty (Point 2 r :+ p) -> NonEmpty (Point 2 r :+ p)+lowerHull pts = pruneVertical $ repeatedly cmp steepestCcwFrom s rest+  where+    (s:_ :+ rest) = extractMinimaBy cmp0 (NonEmpty.toList pts)+    cmp0          = comparing (\(Point2 x y :+ _) -> (x, Down y))+                    -- start from the topmost point that has minimum x-coord+    cmp           = comparing (^.core)+                    -- for the rest of the comparions use the normal+                    -- lexicographic comparing order.++-- | Jarvis March to compute the lower hull, without any vertical segments.+--+--+-- running time: \(O(nh)\), where \(h\) is the complexity of the hull.+lowerHull'     :: (Num r, Ord r) => NonEmpty (Point 2 r :+ p) -> NonEmpty (Point 2 r :+ p)+lowerHull' pts = pruneVertical $ repeatedly cmp steepestCcwFrom s rest+  where+    (s:_ :+ rest) = extractMinimaBy cmp (NonEmpty.toList pts)+    cmp           = comparing (^.core)+++-- | 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+steepestCcwFrom p = List.minimumBy (ccwCmpAroundWith (Vector2 0 (-1)) p)++-- | 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+steepestCwFrom p = List.minimumBy (cwCmpAroundWith (Vector2 0 1) p)++repeatedly       :: (a -> a -> Ordering) -> (a -> NonEmpty a -> a) -> a -> [a] -> NonEmpty a+repeatedly cmp f = go+  where+    go m xs' = case NonEmpty.nonEmpty xs' of+      Nothing -> m :| []+      Just xs -> let p = f m xs+                 in m <| go p (NonEmpty.filter (\x -> p `cmp` x == LT) xs)+++-- | Removes the topmost vertical points, if they exist+pruneVertical :: Eq r => NonEmpty (Point 2 r :+ p) -> NonEmpty (Point 2 r :+ p)+pruneVertical = either id id . foldr1With f (\q -> Left $ q:|[])+  where+    f p = \case+      Left (q:|qs) | p^.core.xCoord == q^.core.xCoord -> Left  (p :| qs)+                   | otherwise                        -> Right (p :| q:qs)+      Right pts                                       -> Right (p <| pts)++-- | Foldr, but start by applying some function on the rightmost+-- element to get the starting value.+foldr1With     :: Foldable1 f => (a -> b -> b) -> (a -> b) -> f a -> b+foldr1With f b = go . toNonEmpty+  where+    go (x :| xs) = case NonEmpty.nonEmpty xs of+                     Nothing  -> b x+                     Just xs' -> x `f` (go xs')++-- | extracts all minima from the list. The result consists of the+-- list of minima, and all remaining points. Both lists are returned+-- in the order in which they occur in the input.+--+-- >>> extractMinimaBy compare [1,2,3,0,1,2,3,0,1,2,0,2]+-- [0,0,0] :+ [2,3,1,2,3,1,2,1,2]+extractMinimaBy     :: (a -> a -> Ordering) -> [a] -> [a] :+ [a]+extractMinimaBy cmp = \case+  []     -> [] :+ []+  (x:xs) -> first NonEmpty.toList $ foldr (\y (mins@(m:|_) :+ rest) ->+                                             case m `cmp` y of+                                               LT -> mins :+ y:rest+                                               EQ -> (y NonEmpty.<| mins) :+ rest+                                               GT -> (y:|[]) :+ NonEmpty.toList mins <> rest+                                          ) ((x:|[]) :+ []) xs
+ src/Algorithms/Geometry/ConvexHull/Naive.hs view
@@ -0,0 +1,93 @@+module Algorithms.Geometry.ConvexHull.Naive( ConvexHull+                                           , lowerHull', lowerHullAll++                                           , isValidTriangle, upperHalfSpaceOf+                                           ) where++import           Control.Lens+import           Data.Ext+import           Data.Foldable (toList)+import           Data.Geometry.HalfSpace+import           Data.Geometry.HyperPlane+import           Data.Geometry.Line+import           Data.Geometry.Point+import           Data.Geometry.Triangle+import           Data.Geometry.Vector+import           Data.Intersection(intersects)+import qualified Data.List as List+import           Data.List.NonEmpty (NonEmpty(..))+import qualified Data.List.NonEmpty as NonEmpty+import           Data.Maybe (listToMaybe, isNothing)+import           Data.Util+--------------------------------------------------------------------------------++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: \(O(n^4)\)+lowerHull' :: forall r p. (Ord r, Fractional r, Show r)+           => NonEmpty (Point 3 r :+ p) -> ConvexHull 3 p r+lowerHull' = filter (not . isVertical) . lowerHullAll+  where+    isVertical (Triangle p q r) =+      ccw' (p&core %~ projectPoint) (q&core %~ projectPoint) (r&core %~ projectPoint) == CoLinear++-- | 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: \(O(n^4)\)+lowerHullAll                 :: forall r p. (Ord r, Fractional r, Show r)+                             => NonEmpty (Point 3 r :+ p) -> ConvexHull 3 p r+lowerHullAll (toList -> pts) = let mkT (Three p q r) = Triangle p q r in+    [ t | t <- mkT <$> uniqueTriplets pts, isNothing (isValidTriangle t pts) ]++++killOverlapping :: (Ord r, Fractional r) => [Triangle 3 p r] -> [Triangle 3 p r]+killOverlapping = foldr keepIfNotOverlaps []+  where+    keepIfNotOverlaps t ts | any (t `overlaps`) ts = ts+                           | otherwise             = t:ts+++t1@(Triangle p q r) `overlaps` t2@(Triangle a b c) = upperHalfSpaceOf t1 == upperHalfSpaceOf t2+                                                  && False++++-- | 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)+isValidTriangle t = listToMaybe . filter (\a -> not $ (a^.core) `intersects` h)+  where+    h = upperHalfSpaceOf t+++-- | 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+upperHalfSpaceOf (Triangle p q r) = HalfSpace h+  where+    h' = from3Points (p^.core) (q^.core) (r^.core)+    c  = p&core.zCoord -~ 1+    h  = if (c^.core) `liesBelow` h' then h' else h'&normalVec %~ ((-1) *^)+    a `liesBelow` plane = (a `onSideUpDown` plane) == Below
src/Algorithms/Geometry/DelaunayTriangulation/DivideAndConquer.hs view
@@ -8,21 +8,22 @@ import           Control.Monad.State import           Data.BinaryTree import qualified Data.CircularList as CL-import qualified Data.CircularSeq as CS import qualified Data.CircularList.Util as CU+import qualified Data.CircularSeq as CS import           Data.Ext import qualified Data.Foldable as F import           Data.Function (on) import           Data.Geometry hiding (rotateTo) import           Data.Geometry.Ball (disk, insideBall) import           Data.Geometry.Polygon-import qualified Data.Geometry.Polygon.Convex as Convex import           Data.Geometry.Polygon.Convex (ConvexPolygon(..), simplePolygon)+import qualified Data.Geometry.Polygon.Convex as Convex import qualified Data.IntMap.Strict as IM import qualified Data.List as L import qualified Data.List.NonEmpty as NonEmpty import qualified Data.Map as M import           Data.Maybe (fromJust, fromMaybe)+import           Data.Measured.Size import qualified Data.Vector as V  -------------------------------------------------------------------------------
src/Algorithms/Geometry/LineSegmentIntersection/BentleyOttmann.hs view
@@ -26,7 +26,6 @@ import qualified Data.Map as M import           Data.Maybe import           Data.Ord (Down(..), comparing)-import           Data.OrdSeq (Compare) import qualified Data.Set as SS -- status struct import qualified Data.Set.Util as SS -- status struct import qualified Data.Set as EQ -- event queue
src/Algorithms/Geometry/LineSegmentIntersection/Types.hs view
@@ -16,6 +16,8 @@  -------------------------------------------------------------------------------- +type Compare a = a -> a -> Ordering+ -- get the endpoints of a line segment endPoints'   :: (HasEnd s, HasStart s) => s -> (StartCore s, EndCore s) endPoints' s = (s^.start.core,s^.end.core)
src/Algorithms/Geometry/LinearProgramming/LP2DRIC.hs view
@@ -86,8 +86,8 @@                            , _current :: !(Point d r)                            } -deriving instance (Arity d, Show r)   => Show    (LPState d r)-deriving instance (Arity d, Eq r)     => Eq      (LPState d r)+deriving instance (Arity d, Show r)             => Show    (LPState d r)+deriving instance (Arity d, Eq r, Fractional r) => Eq      (LPState d r)  obj     :: Lens' (LPState d r) (Vector d r) obj     = lens _obj     (\(LPState _ s p) o -> LPState o s p)
src/Algorithms/Geometry/LinearProgramming/Types.hs view
@@ -26,14 +26,14 @@                     | UnBounded (HalfLine d r) makePrisms ''LPSolution -deriving instance (Arity d, Show r)   => Show    (LPSolution d r)-deriving instance (Arity d, Eq r)     => Eq      (LPSolution d r)+deriving instance (Arity d, Show r)             => Show    (LPSolution d r)+deriving instance (Arity d, Eq r, Fractional r) => Eq      (LPSolution d r)  data LinearProgram d r = LinearProgram { _objective   :: !(Vector d r)                                        , _constraints :: [HalfSpace d r]                                        } makeLenses ''LinearProgram -deriving instance Arity d             => Functor (LinearProgram d)-deriving instance (Arity d, Show r)   => Show    (LinearProgram d r)-deriving instance (Arity d, Eq r)     => Eq      (LinearProgram d r)+deriving instance Arity d                       => Functor (LinearProgram d)+deriving instance (Arity d, Show r)             => Show    (LinearProgram d r)+deriving instance (Arity d, Fractional r, Eq r) => Eq      (LinearProgram d r)
src/Algorithms/Geometry/PolyLineSimplification/DouglasPeucker.hs view
@@ -22,15 +22,15 @@ douglasPeucker         :: (Ord r, Fractional r, Arity d)                        => r -> PolyLine d p r -> PolyLine d p r douglasPeucker eps pl-    | dst <= (eps*eps) = fromPoints [a,b]+    | dst <= (eps*eps) = fromPointsUnsafe [a,b] -- at least two points, so we are fine.     | otherwise        = douglasPeucker eps pref `merge` douglasPeucker eps subf   where-    pts     = pl^.points-    a       = LSeq.head pts-    b       = LSeq.last pts-    (i,dst)             = maxDist pts (ClosedLineSegment a b)+    pts         = pl^.points+    a           = LSeq.head pts+    b           = LSeq.last pts+    (i,dst)     = maxDist pts (ClosedLineSegment a b) -    (pref,subf)         = split i pl+    (pref,subf) = split i pl  -------------------------------------------------------------------------------- -- * Internal functions
src/Algorithms/Geometry/SmallestEnclosingBall/Naive.hs view
@@ -22,8 +22,8 @@ import Data.List (minimumBy) import Data.Function (on) import Data.Maybe (fromMaybe)-import Data.Util(STR(..),SP(..), uniquePairs, uniqueTriplets)-+import Data.Util(uniquePairs, uniqueTriplets)+import qualified Data.Util as Util --------------------------------------------------------------------------------  -- | Horrible O(n^4) implementation that simply tries all disks, checks if they@@ -38,11 +38,11 @@  pairs     :: Fractional r => [Point 2 r :+ p] -> [DiskResult p r] pairs pts = [ DiskResult (fromDiameter (a^.core) (b^.core)) (Two a b)-            | SP a b <- uniquePairs pts]+            | Util.Two a b <- uniquePairs pts]  triplets     :: (Ord r, Fractional r) => [Point 2 r :+ p] -> [DiskResult p r] triplets pts = [DiskResult (disk' a b c) (Three a b c)-               | STR a b c <- uniqueTriplets pts]+               | Util.Three a b c <- uniqueTriplets pts]  disk'       :: (Ord r, Fractional r)             => Point 2 r :+ p -> Point 2 r :+ p -> Point 2 r :+ p -> Disk () r
src/Algorithms/Geometry/SmallestEnclosingBall/RIC.hs view
@@ -31,6 +31,7 @@ import           Data.Ord (comparing) import           System.Random.Shuffle (shuffle) +import Data.RealNumber.Rational import Debug.Trace  --------------------------------------------------------------------------------@@ -149,16 +150,32 @@  -------------------------------------------------------------------------------- -test :: Maybe (DiskResult () Rational)-test = smallestEnclosingDiskWithPoints p q myPts-  where-    p = ext $ Point2 0 (-6)-    q = ext $ Point2 0 6+-- test :: Maybe (DiskResult () Rational)+-- test = smallestEnclosingDiskWithPoints p q myPts+--   where+--     p = ext $ Point2 0 (-6)+--     q = ext $ Point2 0 6  -myPts = map ext [Point2 5 1, Point2 3 3, Point2 (-2) 2, Point2 (-4) 5]+-- myPts = map ext [Point2 5 1, Point2 3 3, Point2 (-2) 2, Point2 (-4) 5] -disk'' r = (r:+) <$> disk (p^.core) (q^.core) (r^.core)-  where-    p = ext $ Point2 0 (-6)-    q = ext $ Point2 0 6+-- disk'' r = (r:+) <$> disk (p^.core) (q^.core) (r^.core)+--   where+--     p = ext $ Point2 0 (-6)+--     q = ext $ Point2 0 6+++-- maartenBug :: DiskResult () Double+-- maartenBug = let (p:q:rest) = maartenBug'+--              in smallestEnclosingDisk' p q rest++-- maartenBug' :: [Point 2 Double :+ ()]+-- maartenBug' = [ Point2 (7.2784424e-3) (249.23) :+ ()+--               , Point2 (-5.188493   ) (249.23) :+ ()+--               , Point2 (-10.382694  ) (249.23) :+ ()+--               , Point2 (-15.575621  ) (249.23) :+ ()+--               , Point2 (0.0         ) (249.23) :+ ()+--               , Point2 (0.0         ) (239.9031) :+ ()+--               , Point2 (0.0         ) (230.37791) :+ ()+--               , Point2 (0.0         ) (220.67882) :+ ()+--               ]
+ src/Algorithms/Geometry/SoS.hs view
@@ -0,0 +1,241 @@+--------------------------------------------------------------------------------+-- |+-- Module      :  Algorithms.Geometry.SoS+-- Copyright   :  (C) Frank Staals+-- License     :  see the LICENSE file+-- Maintainer  :  Frank Staals+--+-- 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+  ( module Algorithms.Geometry.SoS.Sign+  , module Algorithms.Geometry.SoS.Orientation+  , module Algorithms.Geometry.SoS.Determinant+  ) where++-- import Algorithms.Geometry.SoS.Internal+import Algorithms.Geometry.SoS.Orientation+import Algorithms.Geometry.SoS.Determinant+import Algorithms.Geometry.SoS.Sign+import Control.CanAquire+import Control.Lens+import Data.Ext+import Data.Geometry.Point.Internal+import Data.Geometry.Properties+import Data.Geometry.Vector++--------------------------------------------------------------------------------++--------------------------------------------------------------------------------++++-- sideTest'             :: ( SoS p, Dimension p ~ 2, r ~ NumType p+--                          , Eq r, Num r+--                          ) => [p] -> Sign+-- sideTest' (q:p1:p2:_) = sideTest q (Vector2 p1 p2)+++++++--------------------------------------------------------------------------------+++----------------------------------------+--------------------------------------------------------------------------------++--------------------------------------------------------------------------------++++++-- instance (i `CanAquire` Point d r, Arity d) => P i d r `CanAquire` Point d (R i) where+--   aquire (P i) = Point $ pure ()+++++--------------------------------------------------------------------------------++++--------------------------------------------------------------------------------+++--------------------------------------------------------------------------------+++-- -- TODO: Remove this one+-- instance HasIndex (Point d r :+ Int) where+--   indexOf = view extra+++-- test1 :: Sign+-- test1 = sideTest (Point1 1 :+ 0 :: Point 1 Int :+ Int) (Vector1 $ Point1 5 :+ 1)++-- test2 :: Sign+-- test2 = sideTest (Point1 5 :+ 0 :: Point 1 Int :+ Int) (Vector1 $ Point1 5 :+ 1)+++-- test3 :: Sign+-- test3 = sideTest (Point2 (-1) 5 :+ 0 :: Point 2 Int :+ Int) (Vector2 (Point2 0 0  :+ 1)+--                                                                      (Point2 0 10 :+ 2)+--                                                             )+++-- pattern Point1 x = Point (Vector1 x)+++-- testV :: Sign+-- testV = simulateSimplicity sideTest' [ Point2 (-1) 5+--                                      , Point2 0 0+--                                      , Point2 0 10+--                                      ]++++++--------------------------------------------------------------------------------+++++++++-- cmpSignificance                   :: Ord k => Bag k -> Bag k -> Ordering+-- cmpSignificance (Bag e1) (Bag e2) = e1e2 `compare` e2e1+--   where+--     e1e2 = fmap fst . Map.lookupMax $ e1 `Map.difference` e2+--     e2e1 = fmap fst . Map.lookupMax $ e2 `Map.difference` e1++++-- -- | Represents a Sum of terms, i.e. a value that has the form:+-- --+-- -- \[+-- --   \sum c \Pi_{(i,j)} \varepsilon(i,j)+-- -- \]+-- newtype Symbolic i j r = Symbolic [Term i j r] deriving (Show,Eq,Functor)++-- instance (Ord i, Ord j, Num r) => Num (Symbolic i j r) where+--   (Symbolic ts) + (Symbolic ts') = Symbolic (ts `addTerms` ts')+--   negate = fmap negate+--   (Symbolic ts) * (Symbolic ts') = Symbolic $ multiplyTerms ts ts'+--   fromInteger x = constant (fromInteger x)+--   -- abs x | signum x == -1 = (-1)*x+--   --       | oterwise       = x++--   -- signum = undefined+++++++++++-- -- | Adds two lists of terms+-- addTerms        :: forall i j r. (Ord i, Ord j, Num r)+--                 => [Term i j r] -> [Term i j r] -> [Term i j r]+-- addTerms ts ts' = (\(eps,c) -> Term c eps) <$> Map.toList m+--   where+--     m :: Map.Map (EpsFold i j) r+--     m = Map.fromListWith (+) [ (eps,c) | (Term c eps) <- ts <> ts' ]++-- multiplyTerms        :: forall i j r. (Ord i, Ord j, Num r)+--                      => [Term i j r] -> [Term i j r] -> [Term i j r]+-- multiplyTerms ts ts' = (\(eps,c) -> Term c eps) <$> Map.toList m+--   where+--     m :: Map.Map (EpsFold i j) r+--     m = Map.fromListWith (+) [ (es <> es',c*d) | (Term c es) <- ts, (Term d es') <- ts' ]+++++-- orderedTerms               :: (Ord i, Ord j) => Symbolic i j r -> [Term i j r]+-- orderedTerms (Symbolic ts) = List.sortBy (\(Term _ e1) (Term _ e2) -> cmpSignificance e1 e2) ts++++++++++++++++++  -- zipWith (\j x -> Term x $ singleton (i,j)) [0..] . toList+++++++-- orderTerms               :: (Ord i, Ord j) => Symbolic i j r -> Symbolic i j r+-- orderTerms (Symbolic ts) = Symbolic $ List.sortBy cmpSignificance ts++++-- fromPoint'   :: Foldable f => i -> f r -> Symbolic i Int r+-- fromPoint' i = Symbolic . zipWith (\j x -> Term x [(i,j)]) [0..] . toList++++-- testZ :: Symbolic Int Int Int+-- testZ = (5 + 6) *++++++  --   case sign i of+  --                   (-1) -> Negative $ fromInteger i+  --                   0    -> Zero+  --                   _    -> Positive $ fromInteger i+  -- negate        = \case+  --   Negative c -> Positive c+  --   Positive c -> Negative c+++-- newtype N = N String deriving (Show,Eq)+++-- instance Num N where+--   (N x) + (N y) = N $ x <> "+" <> y+--   (N x) * (N y) = N $ x <> y+--   negate  (N x) = N ("negate(" <> x <> ")")+--   fromInteger = N . show+++-- n       :: (Ord i, Ord j) => String -> i -> j -> Symbolic i j N+-- n x i j = Symbolic [Term (N x) mempty, Term 1 (singleton (i,j))]++++++-- testM3 = det33 $ V3 (fromPoint' [N "px", N "py"] <> 1)+--                     (fromPoint' [N "px", N "py"] <> 1)+--    (fromPoint' [N "px", N "py"] <> 1)+-- -- (V3 (N "qx") (N "qy") 1)+-- --                     (V3 (N "rx") (N "ry") 1)
+ src/Algorithms/Geometry/SoS/AsPoint.hs view
@@ -0,0 +1,29 @@+module Algorithms.Geometry.SoS.AsPoint where++import           Control.CanAquire+import           Control.Lens+import           Data.Ext+import           Data.Geometry.Point.Class+import           Data.Geometry.Point.Internal+import           Data.Geometry.Properties+import           Data.Geometry.Vector++--------------------------------------------------------------------------------+-- | a P is a 'read only' point in d dimensions+newtype P i d r = P i deriving (Eq, Show)++-- | Indxec type that can disambiguate points+newtype SoSIndex i = SoSIndex i deriving (Show,Eq,Ord)++instance HasIndex (P i d r) i where+  indexOf (P i) = i++instance Int `CanAquire` (Point d r) => (P Int d r) `CanAquire` (Point d r) where+  aquire (P i) = aquire i++type instance NumType   (P i d r) = r+type instance Dimension (P i d r) = d++asPointWithIndex       :: (Arity d, i `CanAquire` Point d r)+                       => P i d r -> Point d r :+ SoSIndex i+asPointWithIndex (P i) = aquire i :+ (SoSIndex i)
+ src/Algorithms/Geometry/SoS/Determinant.hs view
@@ -0,0 +1,13 @@+module Algorithms.Geometry.SoS.Determinant where++import           Algorithms.Geometry.SoS.Sign+import           Algorithms.Geometry.SoS.Symbolic+import           Data.Geometry.Matrix+++-- | pre: computes the sign of the determinant+signDet   :: (HasDeterminant d, Ord i, Num r, Ord r) => Matrix d d (Symbolic i r) -> Sign+signDet m = case det m `compare` 0 of+              LT -> Negative+              GT -> Positive+              EQ -> error "signDet: determinant is zero! this should not happen!"
+ src/Algorithms/Geometry/SoS/Expr.hs view
@@ -0,0 +1,77 @@+{-# LANGUAGE TemplateHaskell #-}+module Algorithms.Geometry.SoS.Expr where++import           Control.Lens+import qualified Data.List as List+import           Data.List.NonEmpty (NonEmpty(..),nonEmpty)++--------------------------------------------------------------------------------++data Expr v r = Constant r+              | Negate (Expr v r)+              | Sum  [Expr v r]+              | Prod [Expr v r]+              | Var v+              deriving (Show,Eq)+makePrisms ''Expr+++foldExpr :: (r -> b) -> (b -> b) -> ([b] -> b) -> ([b] -> b) -> (v -> b) -> Expr v r -> b+foldExpr con' neg' sum' prod' var' = go+  where+    go = \case+      Constant c -> con' c+      Negate e   -> neg'  $ go e+      Sum es     -> sum'  $ map go es+      Prod es    -> prod' $ map go es+      Var v      -> var' v++-- | Test if the expression has any variables.+hasVariables :: Expr v r -> Bool+hasVariables = foldExpr (const False)+                        id+                        or+                        or+                        (const True)++instance (Num r) => Num (Expr i r) where+  fromInteger = Constant . fromInteger+  negate      = \case+    Negate e -> e+    e        -> Negate e++  (Sum es) + (Sum es') = Sum $ es <> es'+  (Sum es) + e         = Sum (e:es)+  e        + (Sum es)  = Sum (e:es)+  e        + e'        = Sum [e,e']++  (Prod es) * (Prod es') = Prod $ es <> es'+  (Prod es) * e          = Prod (e:es)+  e         * (Prod es)   = Prod (e:es)+  e         * e'          = Prod [e,e']+++simplify :: (Num r, Eq r) => Expr v r -> Expr v r+simplify = \case+  Prod es  -> case filter (isn't $ _Constant.only 1) es of+                []  -> Constant 1+                es' -> Prod $ map simplify es'+  Sum  es  -> case filter (isn't $ _Constant.only 0) es of+                []  -> Constant 0+                es' -> Sum $ map simplify es'+  Negate e -> Negate $ simplify e+  e        -> e++prettyP :: (Show r, Show v) => Expr v r -> String+prettyP = \case+  Constant c  -> show c+  Negate e    -> "(-1)*(" <> prettyP e <> ")"+  Prod es     -> mconcat [ "("+                            , List.intercalate ")*(" (prettyP <$> es)+                            , ")"+                            ]+  Sum es     -> mconcat [ "("+                        , List.intercalate ") + (" (prettyP <$> es)+                        , ")"+                        ]+  Var v -> show v
+ src/Algorithms/Geometry/SoS/Internal.hs view
@@ -0,0 +1,28 @@+module Algorithms.Geometry.SoS.Internal where++import           Algorithms.Geometry.SoS.AsPoint+import           Algorithms.Geometry.SoS.Orientation+import           Control.CanAquire+import           Data.Geometry.Point.Internal++--------------------------------------------------------------------------------++-- simulateSimplicity :: forall t d r b. (Traversable t, SoSD d)+--                    => (forall p. ( AsPoint p, HasIndex p+--                                  , d ~ Dimension p, r ~ NumType p+--                                  ) => t p -> b)+--                    -> t (Point d r) -> b+-- simulateSimplicity = simulateSimplicity'+++-- | The actual implementation of SoS+simulateSimplicity'     :: forall t d r b. (Traversable t, SoS d)+                        => (forall i. ( CanAquire i (Point d r)+                                      , SoS d+                                      ) => t (P i d r) -> b)+                        -> t (Point d r) -> b+simulateSimplicity' alg = runAcquire alg'+  where+    alg' :: forall i. CanAquire i (Point d r) => t i -> b+    alg' = alg . fmap (P @i @d @r)+      -- ideally the fmap would just be a coerce, but GHC does not want to do that.
+ src/Algorithms/Geometry/SoS/Orientation.hs view
@@ -0,0 +1,83 @@+module Algorithms.Geometry.SoS.Orientation( SoS++                                          , sideTest+                                          , sideTest'++                                          , toSymbolic+                                          ) where++import Algorithms.Geometry.SoS.Determinant+import Algorithms.Geometry.SoS.Sign+import Algorithms.Geometry.SoS.Symbolic+import Control.Lens hiding (snoc,cons)+import Data.Ext+import Data.Geometry.Matrix+import Data.Geometry.Point+import Data.Geometry.Vector+import GHC.TypeNats++--------------------------------------------------------------------------------++++-- | 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+sideTest q ps = sideTest'' . fmap toSymbolic $ cons q ps++-- | 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)+toSymbolic (p :+ i) = p&vector' %~ imap (\j x -> symbolic x (i,j))++-- | 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+sideTest' q ps = sideTest'' $ cons q ps++-- | Given a vector of points, tests if the point encoded in the first+-- row is above/below the hyperplane defined by the remaining points+-- (rows).+sideTest'' :: (Num r, Ord r, Ord i, HasDeterminant (d+1), Arity d, Arity (d+1))+           => Vector (d+1) (Point d (Symbolic i r)) -> Sign+sideTest'' = signDet . Matrix . fmap mkLambdaRow++-- | Given a point produces the vector/row corresponding to this point+-- in a homogeneous matrix represetnation. I.e. we add a 1 as an+-- additonal column at the end.+mkLambdaRow :: (Num r, Arity d, Arity (d+1)) => Point d r -> Vector (d+1) r+mkLambdaRow = flip snoc 1 . view vector'
+ src/Algorithms/Geometry/SoS/Sign.hs view
@@ -0,0 +1,30 @@+module Algorithms.Geometry.SoS.Sign where++import qualified Data.List as List+import           Data.Maybe++--------------------------------------------------------------------------------++-- | The sign of an expression+data Sign = Negative | Positive deriving (Show,Eq,Ord,Enum,Bounded)++flipSign :: Sign -> Sign+flipSign = \case+  Negative -> Positive+  Positive -> Negative++--------------------------------------------------------------------------------++-- | 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+signFromTerms = List.head . mapMaybe signum'+  where+    signum' x = case signum x of+                  -1    -> Just Negative+                  0     -> Nothing+                  1     -> Just Positive+                  _     -> error "signum': absurd"
+ src/Algorithms/Geometry/SoS/Symbolic.hs view
@@ -0,0 +1,352 @@+module Algorithms.Geometry.SoS.Symbolic(+    EpsFold+  , eps, mkEpsFold+  , hasNoPertubation+  , factors+  , suitableBase++  , Term(..), term, constantFactor++  , Symbolic+  , constant, symbolic, perturb++  , toTerms+  , signOf+  ) where++import           Algorithms.Geometry.SoS.Sign (Sign(..))+import           Control.Lens+import           Data.Foldable (toList)+import qualified Data.List as List+import qualified Data.Map as Map+import qualified Data.Map.Merge.Strict as Map+import           Data.Maybe (isNothing)+import           Data.Word+import           Test.QuickCheck (Arbitrary(..), listOf, suchThat)+import           Test.QuickCheck.Instances ()++--------------------------------------------------------------------------------+-- * EpsFolds++{-+Let \(\mathcal{I}\) be a bag with indices, let \(c\) be an upper+bound on the number of times a single item may occur in+\(\mathcal{I}\), and let \(\varepsilon\) be a function mapping indices+to real numbers that satisfies:++1. \(0 < \varepsilon(j) < 1\), for all \(1 \leq j\),+2. \(\prod_{0 \leq i \leq j} \varepsilon(i)^c > \varepsilon(k)\), for all \(1 \leq j < k\)++Note that such a function exists:++\begin{lemma}+  \label{lem:condition_2}+  Let \(\delta \in (0,1)\) and \(d \geq c+1\). The function+  \(\varepsilon(i) = \delta^{d^i}\) satisfies condition 2.+\end{lemma}++\begin{proof}+  By transitivity it suffices to argue this for \(k=j+1\):++  \begin{align*}+           &\qquad \prod_{0 \leq i \leq j} \varepsilon(i)^c > \varepsilon(j+1) \\+    \equiv &\qquad \prod_{0 \leq i \leq j} (\delta^{d^i})^c > \delta^{d^{j+1}}\\+    \equiv &\qquad \prod_{0 \leq i \leq j} \delta^{cd^i}    > \delta^{d^{j+1}} \\+    \equiv &\qquad \delta^{\sum_{0 \leq i \leq j} cd^i} > \delta^{d^{j+1}} &+                                                                    \text{using+                                                                    }+                                                                    \delta \in (0,1)\\+    \equiv &\qquad \sum_{0 \leq i \leq j} cd^i < d^{j+1} \\+    \equiv &\qquad c\sum_{0 \leq i \leq j} d^i < d^{j+1} \\+  \end{align*}++  We prove this by induction.++  For the base case \(j=0\): we have \(0 < 1\), which is trivially true.++  For the step case we have the induction hypothesis+  \(c\sum_{0 \leq i \leq j} d^i < d^{j+1}\), and we have to prove that+  \(c\sum_{0 \leq i \leq j+1} d^i < d^{j+2}\):++  \begin{align*}+    c\sum_{0 \leq i \leq j+1} d^i+    &= cd^{j+1} + c\sum_{0 \leq i \leq j} d^i \\+    &< cd^{j+1} + d^{j+1}   & \text{using IH}  \\+    &= (c+1)d^{j+1}        & \text{using that } c+1 \leq d \\+    &\leq dd^{j+1}  \\+    &=d^{j+2}+  \end{align*}+  This completes the proof.+\end{proof}+++++++An EpsFold now represents the term++\[ \prod_{i \in \mathcal{I}} \varepsilon(i) \]++for some bag \(\mathcal{I}\).+++Let \(\mathcal{J}\) be some sub-bag of \(\mathcal{I}\). Note that+condition 2 implies that:++\(\prod_{i \in \mathcal{J}} \varepsilon(i) > \varepsilon(k)\), for all \(1 \leq j < k\)++This means that when comparing two EpsFolds, say \(e_1\) and \(e_2\),+representing bags \(\mathcal{I}_1\) and \(\mathcal{I}_2\),+respectively. It suffices to compare the largest index+\(j \in \mathcal{I}_1\setminus\mathcal{I}_2\) with the largest index+\(k \in \mathcal{I}_2\setminus\mathcal{I}_1\). We have that++\(e_1 > e_2\) if and only if \(j < k\).+-}+newtype EpsFold i = Pi (Bag i) deriving (Semigroup,Monoid)++-- | Gets the factors+factors         :: EpsFold i -> Bag i+factors (Pi is) = is++-- | Creates the term \(\varepsilon(i)\)+eps :: i -> EpsFold i+eps = Pi . singleton++mkEpsFold :: Ord i => [i] -> EpsFold i+mkEpsFold = Pi . foldMap singleton++++-- | computes a base 'd' that can be used as:+--+-- \( \varepsilon(i) = \varepsilon^{d^i} \)+suitableBase :: EpsFold i -> Int+suitableBase = max 2 . (1+) . maxMultiplicity . factors++instance Show i => Show (EpsFold i) where+  showsPrec d (Pi b) = showParen (d > app_prec) $+                         showString "Pi " . showsPrec d (toList b)+    where+      app_prec = 10+++instance Ord i => Eq (EpsFold i) where+  e1 == e2 = (e1 `compare` e2) == EQ++instance Ord i => Ord (EpsFold i) where+  (Pi e1) `compare` (Pi e2) = k `compare` j -- note that k and j are flipped here+    where+      j = maximum' $ e1 `difference` e2+      k = maximum' $ e2 `difference` e1+    -- note: If the terms are all the same, the difference of the bags is empty+    -- and thus both e1e2 and e2e1 are Nothing and thus equal.++    -- otherwise, let j be the largest term that is in e1 but not in e2.+    -- If e2 does not have any terms at all (Nothing) it will be bigger than e1+    --+    -- if e2 does have a term, let k be the largest one, then the+    -- biggest of those terms is the pair whose indices comes first.++instance (Arbitrary i, Ord i) => Arbitrary (EpsFold i) where+  arbitrary = (mkEpsFold . take 4) <$> listOf arbitrary+++-- | Test if the epsfold has no pertubation at all (i.e. if it is \(\Pi_{\emptyset}\)+hasNoPertubation        :: EpsFold i -> Bool+hasNoPertubation (Pi b) = null b+++--------------------------------------------------------------------------------+-- * Terms++-- | A term 'Term c es' represents a term:+--+-- \[ c \Pi_{i \in es} \varepsilon(i)+-- \]+--+-- for a constant c and an arbitrarily small value \(\varepsilon\),+-- parameterized by i.+data Term i r = Term r (EpsFold i) deriving (Eq,Functor)++-- | Lens to access the constant 'c' in the term.+constantFactor :: Lens' (Term i r) r+constantFactor = lens (\(Term c _) -> c) (\(Term _ es) c -> Term c es)+++instance (Show i, Show r) => Show (Term i r) where+  showsPrec d (Term c es) = showParen (d > up_prec) $+                               showsPrec (up_prec + 1) c+                             . showString " * "+                             . showsPrec (up_prec + 1) es+    where+      up_prec = 5+++-- | Creates a singleton term+term     :: r -> i -> Term i r+term r i = Term r $ eps i++instance (Ord i, Ord r, Num r) => Ord (Term i r) where+  (Term c e1) `compare` (Term d e2) = case (hasNoPertubation e1, hasNoPertubation e2) of+                                        (True,True) -> c    `compare` d+                                        _           -> case (signum c, signum d) of+                                                         (-1,-1) -> e2 `compare` e1+                                                         (0,0)   -> e1 `compare` e2+                                                         (1,1)   -> e1 `compare` e2+                                                         (-1,_)  -> LT+                                                         (_,-1)  -> GT+                                                         _       -> error "SoS: Term.ord absurd"+  -- If both the eps folds are zero, and thus we just have constants+  -- then we should compare the individual terms.++  -- if *one* of the two has an eps term, then we can choose eps to be+  -- arbitrarily small, i.e. small enough so that that terms is+  -- actually smaller than the other term.  this is reflected since+  -- findMax will then return a Noting, which is smaller than anything+  -- else++  -- if both terms have epsilon terms, we first look at the sign. If+  -- they have non-negative signs we compare the eps-folds as in the+  -- paper. (Lemma 3.3). If both are negative, that reverses the+  -- ordering. If the signs are different then we can base the+  -- ordering on that.++instance (Arbitrary r, Arbitrary (EpsFold i), Ord i) => Arbitrary (Term i r) where+  arbitrary = Term <$> arbitrary <*> arbitrary++--------------------------------------------------------------------------------+-- * Symbolic++-- | Represents a Sum of terms, i.e. a value that has the form:+--+-- \[+--   \sum c \Pi_i \varepsilon(i)+-- \]+--+-- The terms are represented in order of decreasing significance.+--+-- The main idea in this type is that, if symbolic values contains+-- \(\varepsilon(i)\) terms we can always order them. That is, two+-- Symbolic terms will be equal only if:+--+-- - they contain *only* a constant term (that is equal)+-- - they contain the exact same \(\varepsilon\)-fold.+--+newtype Symbolic i r = Sum (Map.Map (EpsFold i) r) deriving (Functor)++-- | Produces a list of terms, in decreasing order of significance+toTerms         :: Symbolic i r -> [Term i r]+toTerms (Sum m) = map (\(i,c) -> Term c i) . Map.toDescList $ m++-- | Computing the Sign of an expression. (Nothing represents zero)+signOf   :: (Num r, Eq r) => Symbolic i r -> Maybe Sign+signOf e = case List.dropWhile (== 0) . map (\(Term c _) -> signum c) $ toTerms e of+             []     -> Nothing+             (-1:_) -> Just Negative+             _      -> Just Positive++instance (Ord i, Eq r, Num r) => Eq (Symbolic i r) where+  e1 == e2 = isNothing $ signOf (e1 - e2)++instance (Ord i, Ord r, Num r) => Ord (Symbolic i r) where+  e1 `compare` e2 = case signOf (e1 - e2) of+                      Nothing       -> EQ+                      Just Negative -> LT+                      Just Positive -> GT++instance (Ord i, Num r, Eq r) => Num (Symbolic i r) where+  (Sum e1) + (Sum e2) = Sum $ Map.merge Map.preserveMissing -- insert things only in e1+                                        Map.preserveMissing -- insert things only in e2+                                        combine+                                        e1 e2+    where+      -- if things are in both e1 and e2, we add the constant terms. If they are non-zero+      -- we use this value in the map. Otherwise we drop it.+      combine = Map.zipWithMaybeMatched+                (\_ c d -> let x = c + d in if x /= 0 then Just x else Nothing)+    -- Symbolic $ Map.unionWith (+) ts ts'++  negate = fmap negate++  (Sum ts) * (Sum ts') = Sum $ Map.fromListWith (+) [ (es <> es',c*d)+                                                    | (es, c) <- Map.toList ts+                                                    , (es',d) <- Map.toList ts'+                                                    , c*d /= 0+                                                    ]++  fromInteger x = constant (fromInteger x)++  signum s = case signOf s of+               Nothing       -> 0+               Just Negative -> (-1)+               Just Positive -> 1++  abs x | signum x == -1 = (-1)*x+        | otherwise      = x+++instance (Show i, Show r) => Show (Symbolic i r) where+  showsPrec d s = showParen (d > app_prec) $+                    showString "Sum " . showsPrec d (toTerms s)+    where+      app_prec = 10++instance (Arbitrary r, Ord i, Arbitrary (EpsFold i)) => Arbitrary (Symbolic i r) where+  arbitrary = Sum <$> arbitrary++----------------------------------------++-- | Creates a constant symbolic value+constant   :: Ord i => r -> Symbolic i r+constant c = Sum $ Map.singleton mempty c++-- | 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+symbolic r i = Sum $ Map.singleton (eps i) r++-- | given the value c and the index i, creates the perturbed value+-- \(c + \varepsilon(i)\)+perturb      :: (Num r, Ord i) => r -> i -> Symbolic i r+perturb c i = Sum $ Map.fromAscList [ (mempty,c) , (eps i,1) ]+++--------------------------------------------------------------------------------++-- | The word specifiies how many *duplicates* there are. I.e. If the+-- Bag maps k to i, then k has multiplicity i+1.+newtype Bag a = Bag (Map.Map a Int) deriving (Show,Eq,Ord,Arbitrary)++singleton   :: k -> Bag k+singleton x = Bag $ Map.singleton x 0+++instance Foldable Bag where+  -- ^ Takes multiplicity into account.+  foldMap f (Bag m) =+    Map.foldMapWithKey (\k d -> foldMap f (List.replicate (fromIntegral d+1) k)) m+  null (Bag m) = Map.null m++instance Ord k => Semigroup (Bag k) where+  (Bag m) <> (Bag m') = Bag $ Map.unionWith (\d d' -> d + d' + 1) m m'++instance Ord k => Monoid (Bag k) where+  mempty = Bag $ Map.empty++-- | Computes the difference of the two maps+difference                   :: Ord a => Bag a -> Bag a -> Bag a+difference (Bag m1) (Bag m2) = Bag $ Map.differenceWith updateCount m1 m2+  where+    updateCount i j = let d = i - j -- note that we should actually compare (i+1) and (j+1)+                      in if d <= 0 then Nothing -- we have no copies left+                                   else Just $ d - 1+++maximum'         :: Bag b -> Maybe b+maximum' (Bag m) = fmap fst . Map.lookupMax $ m+++-- | maximum multiplicity of an element in the bag+maxMultiplicity         :: Bag a -> Int+maxMultiplicity (Bag m) = maximum . (0:) . map (1+) . Map.elems $ m
src/Algorithms/Geometry/WellSeparatedPairDecomposition/Types.hs view
@@ -19,6 +19,7 @@ import           Data.Geometry.Point import           Data.Geometry.Vector import qualified Data.LSeq as LSeq+import           Data.Measured.Class import qualified Data.Sequence as S import qualified Data.Traversable as Tr 
src/Algorithms/Geometry/WellSeparatedPairDecomposition/WSPD.hs view
@@ -50,7 +50,7 @@                   => NonEmpty.NonEmpty (Point d r :+ p) -> SplitTree d p r () fairSplitTree pts = foldUp node' Leaf $ fairSplitTree' n pts'   where-    pts' = GV.imap sortOn . pure . g $ pts+    pts' = imap sortOn . pure . g $ pts     n    = length $ pts'^.GV.element (C :: C 0)      sortOn' i = NonEmpty.sortWith (^.core.unsafeCoord i)@@ -354,7 +354,7 @@ -- -- pre: points are sorted according to their dimension extends :: Arity d => GV.Vector d (PointSeq d p r) -> GV.Vector d (Range r)-extends = GV.imap (\i pts ->+extends = imap (\i pts ->                      ClosedRange ((LSeq.head pts)^.core.unsafeCoord (i + 1))                                  ((LSeq.last pts)^.core.unsafeCoord (i + 1))) 
src/Data/Geometry/Arrangement/Internal.hs view
@@ -11,6 +11,7 @@ -------------------------------------------------------------------------------- module Data.Geometry.Arrangement.Internal where +import           Algorithms.BinarySearch import           Control.Lens import qualified Data.CircularSeq as CSeq import           Data.Ext@@ -25,7 +26,6 @@ import qualified Data.List as List import           Data.Maybe import           Data.Ord (Down(..))-import           Data.Sequence.Util import qualified Data.Vector as V import           Data.Vinyl.CoRec @@ -192,13 +192,10 @@ unBoundedParts rect ls = [tl] <> t <> [tr] <> reverse r <> [br] <> reverse b <> [bl] <> l   where     sideIntersections' = over (traverse._2) Just . sideIntersections ls-    (t,r,b,l)     = map4 sideIntersections'      $ sides   rect-    (tl,tr,br,bl) = map4 ((,Nothing) . (^.core)) $ corners rect+    Sides t r b l       = fmap sideIntersections'      $ sides   rect+    Corners tl tr br bl = fmap ((,Nothing) . (^.core)) $ corners rect  -map4              :: (a -> b) -> (a,a,a,a) -> (b,b,b,b)-map4 f (a,b',c,d) = (f a, f b', f c, f d)- -- | 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            -> V.Vector (Point 2 r, VertexId' s, a)@@ -270,8 +267,8 @@     i  <- binarySearchVec (pred' ss) (arr^.unboundedIntersections)     pure $ arr^.unboundedIntersections.singular (ix i)   where-    (t,r,b,l) = sides'' $ arr^.boundedArea-    sides'' = map4 (\(ClosedLineSegment a c) -> LineSegment (Closed a) (Open c)) . sides+    Sides t r b l = sides'' $ arr^.boundedArea+    sides''       = fmap (\(ClosedLineSegment a c) -> LineSegment (Closed a) (Open c)) . sides      findSide q = fmap fst . List.find (onSegment q . snd) $ zip [1..] [t,r,b,l] 
src/Data/Geometry/Ball.hs view
@@ -123,21 +123,27 @@ pattern Sphere c r = Boundary (Ball c r) {-# COMPLETE Sphere #-} --+-- |+_BallSphere :: Iso (Disk p r) (Disk p s) (Circle p r) (Circle p s)+_BallSphere = _Boundary  -------------------------------------------------------------------------------- -- * Disks and Circles, aka 2-dimensional Balls and Spheres  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 pattern Disk c r = Ball c r {-# COMPLETE Disk #-} - 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)+_DiskCircle = _BallSphere++-- | Given the center and the squared radius, constructs a circle pattern Circle     :: Point 2 r :+ p ->  r -> Circle p r pattern Circle c r = Sphere c r {-# COMPLETE Circle #-}
+ src/Data/Geometry/BezierSpline.hs view
@@ -0,0 +1,169 @@+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE TemplateHaskell #-}+module Data.Geometry.BezierSpline(+    BezierSpline (BezierSpline)+  , controlPoints+  , fromPointSeq++  , evaluate+  , split+  , subBezier+  , tangent+  , approximate+  , parameterOf+  , snap++  , pattern Bezier2, pattern Bezier3+  ) where++import           Control.Lens hiding (Empty)+import qualified Data.Foldable as F+import           Data.Geometry.Point+import           Data.Geometry.Properties+import           Data.Geometry.Transformation+import           Data.Geometry.Vector+import           Data.LSeq (LSeq)+import qualified Data.LSeq as LSeq+import           Data.Sequence (Seq(..))+import qualified Data.Sequence as Seq+import           Data.Traversable (fmapDefault,foldMapDefault)+import           GHC.TypeNats+import qualified Test.QuickCheck as QC++--------------------------------------------------------------------------------++-- | Datatype representing a Bezier curve of degree \(n\) in \(d\)-dimensional space.+newtype BezierSpline n d r = BezierSpline { _controlPoints :: LSeq (1+n) (Point d r) }+makeLenses ''BezierSpline++-- | Quadratic Bezier Spline+pattern Bezier2      :: Point d r -> Point d r -> Point d r -> BezierSpline 2 d r+pattern Bezier2 p q r <- ((F.toList . LSeq.take 3 . _controlPoints) -> [p,q,r])+  where+    Bezier2 p q r = fromPointSeq . Seq.fromList $ [p,q,r]+{-# COMPLETE Bezier2 #-}++-- | Cubic Bezier Spline+pattern Bezier3         :: Point d r -> Point d r -> Point d r -> Point d r -> BezierSpline 3 d r+pattern Bezier3 p q r s <- ((F.toList . LSeq.take 4 . _controlPoints) -> [p,q,r,s])+  where+    Bezier3 p q r s = fromPointSeq . Seq.fromList $ [p,q,r,s]+{-# COMPLETE Bezier3 #-}++deriving instance (Arity d, Eq r) => Eq (BezierSpline n d r)++type instance Dimension (BezierSpline n d r) = d+type instance NumType   (BezierSpline n d r) = r+++instance (Arity n, Arity d, QC.Arbitrary r) => QC.Arbitrary (BezierSpline n d r) where+  arbitrary = fromPointSeq . Seq.fromList <$> QC.vector (fromIntegral . (1+) . natVal $ C @n)++-- | Constructs the Bezier Spline from a given sequence of points.+fromPointSeq :: Seq (Point d r) -> BezierSpline n d r+fromPointSeq = BezierSpline . LSeq.promise . LSeq.fromSeq+++instance (Arity d, Show r) => Show (BezierSpline n d r) where+  show (BezierSpline ps) =+    mconcat [ "BezierSpline", show $ length ps - 1, " ", show (F.toList ps) ]++instance Arity d => Functor (BezierSpline n d) where+  fmap = fmapDefault++instance Arity d => Foldable (BezierSpline n d) where+  foldMap = foldMapDefault++instance Arity d => Traversable (BezierSpline n d) where+  traverse f (BezierSpline ps) = BezierSpline <$> traverse (traverse f) ps++instance (Fractional r, Arity d, Arity (d + 1), Arity n)+          => IsTransformable (BezierSpline n d r) where+  transformBy = transformPointFunctor++instance PointFunctor (BezierSpline n d) where+  pmap f = over controlPoints (fmap f)++-- | Evaluate a BezierSpline curve at time t in [0, 1]+--+-- pre: \(t \in [0,1]\)+evaluate    :: (Arity d, Ord r, Num r) => BezierSpline n d r -> r -> Point d r+evaluate b t = evaluate' (b^.controlPoints.to LSeq.toSeq)+  where+    evaluate' = \case+      (p :<| Empty)  -> p+      pts@(_ :<| tl) -> let (ini :|> _) = pts in evaluate' $ Seq.zipWith blend ini tl+      _              -> error "evaluate: absurd"++    blend p q = p .+^ t *^ (q .-. p)+++tangent   :: (Arity d, Num r, 1 <= n) => BezierSpline n d r -> Vector d r+tangent b = b^?!controlPoints.ix 1  .-. b^?!controlPoints.ix 0++-- | Restrict a Bezier curve to th,e 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+subBezier t u = fst . split u . snd . split t++-- | 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 t b | t < 0 || t > 1 = error "Split parameter out of bounds."+          | otherwise      = let n  = fromIntegral $ natVal (C @n)+                                 ps = collect t $ b^.controlPoints+                             in ( fromPointSeq . Seq.take (n + 1) $ ps+                                , fromPointSeq . Seq.drop n       $ ps+                                )++collect   :: (Arity d, Ord r, Num r) => r -> LSeq n (Point d r) -> Seq (Point d r)+collect t = go . LSeq.toSeq+  where+    go = \case+      ps@(_ :<| Empty) -> ps+      ps@(p :<| tl)    -> let (ini :|> q) = ps in (p :<| go (Seq.zipWith blend ini tl)) :|> q+      _                -> error "collect: absurd"++    blend p q = p .+^ t *^ (q .-. p)++-- {-++-- -- | Merge to 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 :: (Arity d, Ord r, Num r) => (Bezier d r, Bezier d r) -> Bezier d r++-- -}++-- | Approximate Bezier curve by Polyline with given resolution.+approximate :: forall n d r. (KnownNat n, Arity d, Ord r, Fractional r)+            => r -> BezierSpline n d r -> [Point d r]+approximate eps b+    | squaredEuclideanDist p q < eps^2 = [p,q]+    | otherwise                        = let (b1, b2) = split 0.5 b+                                         in approximate eps b1 ++ tail (approximate eps b2)+  where+    p = b^.controlPoints.to LSeq.head+    q = b^.controlPoints.to LSeq.last++-- | Given a point on (or close to) a Bezier curve, return the corresponding parameter value.+--   (For points far away from the curve, the function will return the parameter value of+--   an approximate locally closest point to the input point.)+parameterOf      :: (Arity d, Ord r, Fractional r) => BezierSpline n d r -> Point d r -> r+parameterOf b p = binarySearch (qdA p . evaluate b) treshold (1 - treshold)+  where treshold = 0.0001++binarySearch                                    :: (Ord r, Fractional r) => (r -> r) -> r -> r -> r+binarySearch f l r | abs (f l - f r) < treshold = m+                   | derivative f m  > 0        = binarySearch f l m+                   | otherwise                  = binarySearch f m r+  where m = (l + r) / 2+        treshold = 0.0001++derivative     :: Fractional r => (r -> r) -> r -> r+derivative f x = (f (x + delta) - f x) / delta+  where delta = 0.00001++-- | Snap a point close to a Bezier curve to the curve.+snap   :: (Arity d, Ord r, Fractional r) => BezierSpline n d r -> Point d r -> Point d r+snap b = evaluate b . parameterOf b
src/Data/Geometry/Boundary.hs view
@@ -1,7 +1,8 @@ module Data.Geometry.Boundary where -import           Data.Geometry.Properties-import           Data.Geometry.Transformation+import Control.Lens (iso,Iso)+import Data.Geometry.Properties+import Data.Geometry.Transformation  -------------------------------------------------------------------------------- @@ -12,6 +13,10 @@  type instance NumType (Boundary g)   = NumType g type instance Dimension (Boundary g) = Dimension g++-- | Iso for converting between things with a boundary and without its boundary+_Boundary :: Iso g h (Boundary g) (Boundary h)+_Boundary = iso Boundary (\(Boundary b) -> b)   -- | Result of a query that asks if something is Inside a g, *on* the boundary
src/Data/Geometry/Box.hs view
@@ -1,5 +1,3 @@-{-# LANGUAGE TemplateHaskell  #-}-{-# LANGUAGE ScopedTypeVariables  #-} {-# LANGUAGE UndecidableInstances  #-} {-# LANGUAGE DeriveAnyClass  #-} {-# OPTIONS_GHC -fno-warn-orphans #-}@@ -14,56 +12,16 @@ -- -------------------------------------------------------------------------------- module Data.Geometry.Box( module Data.Geometry.Box.Internal-                        , topSide, leftSide, bottomSide, rightSide-                        , sides, sides'+                        , module Data.Geometry.Box.Corners+                        , module Data.Geometry.Box.Sides                         ) where  import Control.DeepSeq+import Data.Geometry.Box.Corners import Data.Geometry.Box.Internal-import Data.Geometry.LineSegment+import Data.Geometry.Box.Sides import Data.Geometry.Vector  --------------------------------------------------------------------------------  deriving instance (NFData p, NFData r, Arity d) => NFData (Box d p r)---topSide :: Num r => Rectangle p r -> LineSegment 2 p r-topSide = (\(l,r,_,_) -> ClosedLineSegment l r) . corners---- | Oriented from *left to right*-bottomSide :: Num r => Rectangle p r -> LineSegment 2 p r-bottomSide = (\(_,_,r,l) -> ClosedLineSegment l r) . corners-----leftSide  :: Num r => Rectangle p r -> LineSegment 2 p r-leftSide = (\(t,_,_,b) -> ClosedLineSegment b t) . corners---- | The right side, oriented from *bottom* to top-rightSide :: Num r => Rectangle p r -> LineSegment 2 p r-rightSide = (\(_,t,b,_) -> ClosedLineSegment b t) . corners----- | 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 -> ( LineSegment 2 p r-                                   , LineSegment 2 p r-                                   , LineSegment 2 p r-                                   , LineSegment 2 p r-                                   )-sides = (\(t,r,b,l) -> (t,flipSegment r,flipSegment b,l)) . sides'----- | 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 -> ( LineSegment 2 p r-                                      , LineSegment 2 p r-                                      , LineSegment 2 p r-                                      , LineSegment 2 p r-                                      )-sides' r = (topSide r, rightSide r, bottomSide r, leftSide r)
+ src/Data/Geometry/Box/Corners.hs view
@@ -0,0 +1,70 @@+{-# LANGUAGE TemplateHaskell  #-}+module Data.Geometry.Box.Corners( Corners(Corners), northWest, northEast, southEast, southWest+                                , corners, cornersInDirection+                                ) where++import Control.Lens (makeLenses,Ixed(..),Index, IxValue,(%~),(&),(^?!))+import Data.Ext+import Data.Functor.Apply+import Data.Geometry.Box.Internal+import Data.Geometry.Directions+import Data.Geometry.Point+import Data.Semigroup.Foldable.Class+import Data.Semigroup.Traversable.Class+import Data.Util+import GHC.Generics (Generic)++--------------------------------------------------------------------------------++-- | A Quadrant data type+data Corners a = Corners { _northWest  :: !a+                         , _northEast  :: !a+                         , _southEast  :: !a+                         , _southWest  :: !a+                         } deriving (Show,Eq,Ord,Generic,Functor,Foldable,Traversable)+makeLenses ''Corners+++type instance Index   (Corners a) = InterCardinalDirection+type instance IxValue (Corners a) = a++instance Ixed (Corners a) where+  ix = \case+    NorthWest -> northWest+    NorthEast -> northEast+    SouthEast -> southEast+    SouthWest -> southWest++instance Foldable1 Corners+instance Traversable1 Corners where+  traverse1 f (Corners a b c d) = Corners <$> f a <.> f b <.> f c <.> f d++instance Applicative Corners where+  pure x = Corners x x x x+  (Corners f g h i) <*> (Corners a b c d) = Corners (f a) (g b) (h c) (i d)++instance Semigroup a => Semigroup (Corners a) where+  s <> s' = (<>) <$> s <*> s'+instance Monoid a => Monoid (Corners a) where+  mempty = pure mempty+++--------------------------------------------------------------------------------++-- | 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)+corners r     = let w = width r+                    p = (_maxP r)&core %~ _cwMax+                    q = (_minP r)&core %~ _cwMin+                in Corners (p&core.xCoord %~ (subtract w)) p+                           (q&core.xCoord %~ (+ w))        q+++--------------------------------------------------------------------------------++-- | Gets the corners in a particular direction+cornersInDirection     :: CardinalDirection -> Corners p -> Two p+cornersInDirection d c = (\icd -> c^?!ix icd) <$> interCardinalsOf d
src/Data/Geometry/Box/Internal.hs view
@@ -15,8 +15,11 @@  import           Control.DeepSeq import           Control.Lens+import           Data.Bifoldable import           Data.Bifunctor+import           Data.Bitraversable import           Data.Ext+import qualified Data.Foldable as F import           Data.Geometry.Point import           Data.Geometry.Properties import           Data.Geometry.Transformation@@ -25,12 +28,11 @@ import qualified Data.List.NonEmpty as NE import qualified Data.Range as R import qualified Data.Semigroup.Foldable as F-import qualified Data.Foldable as F import qualified Data.Vector.Fixed as FV import           Data.Vinyl.CoRec (asA) import           GHC.Generics (Generic) import           GHC.TypeLits-import           Test.QuickCheck(Arbitrary(..))+import           Test.QuickCheck (Arbitrary(..))  -------------------------------------------------------------------------------- @@ -60,6 +62,10 @@                      } deriving Generic makeLenses ''Box ++++ -- | 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@@ -108,12 +114,14 @@       r `intersect'` s = asA @(R.Range r) $ r `intersect` s  instance Arity d => Bifunctor (Box d) where-  bimap :: forall p q r s. (p -> q) -> (r -> s) -> Box d p r -> Box d q s-  bimap f g (Box mi ma) = Box (bimap g' f mi) (bimap g' f ma)+  bimap = bimapDefault+instance Arity d => Bifoldable (Box d) where+  bifoldMap = bifoldMapDefault+instance Arity d => Bitraversable (Box d) where+  bitraverse f g (Box mi ma) = Box <$> bitraverse (tr g) f mi <*> bitraverse (tr g) f ma     where-      g' :: Functor g => g (Point d r) -> g (Point d s)-      g' = fmap (fmap g)-+      tr    :: (Traversable t, Applicative f) => (r -> f s) -> t (Point d r) -> f (t (Point d s))+      tr g' = traverse $ traverse g'  -- -- In principle this should also just work for Boxes in higher dimensions. It is just -- -- that we need a better way to compute their corners@@ -240,23 +248,7 @@ height = widthIn (C :: C 2)  --- | 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 -> ( Point 2 r :+ p-                                     , Point 2 r :+ p-                                     , Point 2 r :+ p-                                     , Point 2 r :+ p-                                     )-corners r     = let w = width r-                    p = (_maxP r)&core %~ _cwMax-                    q = (_minP r)&core %~ _cwMin-                in ( p&core.xCoord %~ (subtract w)-                   , p-                   , q&core.xCoord %~ (+ w)-                   , q-                   )+--------------------------------------------------------------------------------  -------------------------------------------------------------------------------- -- * Constructing bounding boxes@@ -282,3 +274,6 @@  instance IsBoxable (Box d p r) where   boundingBox (Box m m') = Box (m&extra .~ ()) (m'&extra .~ ())++instance IsBoxable c => IsBoxable (c :+ e) where+  boundingBox = boundingBox . view core
+ src/Data/Geometry/Box/Sides.hs view
@@ -0,0 +1,91 @@+{-# LANGUAGE TemplateHaskell  #-}+module Data.Geometry.Box.Sides( Sides(Sides), north, east, south, west+                              , topSide, bottomSide, leftSide, rightSide+                              , sides, sides'++                              , sideDirections+                              ) where++import Data.Geometry.Directions+import Data.Geometry.Box.Internal+import Data.Geometry.Box.Corners+import Data.Geometry.LineSegment+import Data.Functor.Apply+import Data.Semigroup.Foldable.Class+import Data.Semigroup.Traversable.Class+import GHC.Generics (Generic)+import Control.Lens(makeLenses, Ixed(..), Index, IxValue)++--------------------------------------------------------------------------------++-- | The four sides of a rectangle+data Sides a = Sides { _north :: !a+                     , _east  :: !a+                     , _south :: !a+                     , _west  :: !a+                     } deriving (Show,Read,Eq,Generic,Ord,Foldable,Functor,Traversable)+makeLenses ''Sides++instance Applicative Sides where+  pure x = Sides x x x x+  (Sides f g h i) <*> (Sides a b c d) = Sides (f a) (g b) (h c) (i d)++instance Foldable1 Sides+instance Traversable1 Sides where+  traverse1 f (Sides a b c d) = Sides <$> f a <.> f b <.> f c <.> f d++instance Semigroup a => Semigroup (Sides a) where+  s <> s' = (<>) <$> s <*> s'+instance Monoid a => Monoid (Sides a) where+  mempty = pure mempty+++type instance Index   (Sides a) = CardinalDirection+type instance IxValue (Sides a) = a++instance Ixed (Sides a) where+  ix = \case+    North -> north+    East  -> east+    South -> south+    West  -> west++-- | Constructs a Sides value that indicates the appropriate+-- direction.+sideDirections :: Sides CardinalDirection+sideDirections = Sides North East South West++--------------------------------------------------------------------------------++topSide :: Num r => Rectangle p r -> LineSegment 2 p r+topSide = (\(Corners l r _ _) -> ClosedLineSegment l r) . corners++-- | Oriented from *left to right*+bottomSide :: Num r => Rectangle p r -> LineSegment 2 p r+bottomSide = (\(Corners _ _ r l) -> ClosedLineSegment l r) . corners++--+leftSide  :: Num r => Rectangle p r -> LineSegment 2 p r+leftSide = (\(Corners t _ _ b) -> ClosedLineSegment b t) . corners++-- | The right side, oriented from *bottom* to top+rightSide :: Num r => Rectangle p r -> LineSegment 2 p r+rightSide = (\(Corners _ t b _) -> ClosedLineSegment b t) . corners+++-- | 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)+sides r = let Corners nw ne se sw = corners r+          in Sides (ClosedLineSegment nw ne) (ClosedLineSegment ne se)+                   (ClosedLineSegment se sw) (ClosedLineSegment sw nw)++-- | 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)+sides' r = Sides (topSide r) (rightSide r) (bottomSide r) (leftSide r)
+ src/Data/Geometry/Directions.hs view
@@ -0,0 +1,49 @@+{-# LANGUAGE TemplateHaskell  #-}+module Data.Geometry.Directions( CardinalDirection(..)+                               , _North, _East, _South, _West+                               , oppositeDirection++                                , InterCardinalDirection(..)+                                , _NorthWest, _NorthEast, _SouthEast, _SouthWest++                                , interCardinalsOf+                                ) where++import Control.Lens (makePrisms)+import Data.Util+import GHC.Generics (Generic)++--------------------------------------------------------------------------------++data CardinalDirection = North | East | South | West deriving (Show,Read,Eq,Ord,Enum,Bounded)+makePrisms ''CardinalDirection++--------------------------------------------------------------------------------+-- * Functions on Cardinal Directions++-- | Computes the direction opposite to the given one.+oppositeDirection :: CardinalDirection -> CardinalDirection+oppositeDirection = \case+  North -> South+  East  -> West+  South -> North+  West  -> East++--------------------------------------------------------------------------------++-- | Intercardinal directions+data InterCardinalDirection = NorthWest | NorthEast | SouthEast | SouthWest+  deriving (Show,Read,Eq,Ord,Enum,Generic)+makePrisms ''InterCardinalDirection++--------------------------------------------------------------------------------+-- * Functions on InterCardinal Directions++-- | Get the two intercardinal directions, in increasing order,+-- corresponding to the cardinal direction.+interCardinalsOf :: CardinalDirection -> Two InterCardinalDirection+interCardinalsOf = \case+  North -> Two NorthWest NorthEast+  East  -> Two NorthEast SouthEast+  South -> Two SouthEast SouthWest+  West  -> Two SouthWest NorthWest
+ src/Data/Geometry/Ellipse.hs view
@@ -0,0 +1,56 @@+{-# LANGUAGE TemplateHaskell #-}+module Data.Geometry.Ellipse(+    Ellipse(Ellipse)+  , affineTransformation+  , ellipseMatrix+  , unitEllipse+  , circleToEllipse, ellipseToCircle, _EllipseCircle+  ) where++import Control.Lens+import Data.Ext+import Data.Geometry.Ball+import Data.Geometry.Matrix+import Data.Geometry.Transformation+import Data.Geometry.Point+import Data.Geometry.Properties+import Data.Geometry.Vector++--------------------------------------------------------------------------------++-- | A typre representing planar ellipses+newtype Ellipse r = Ellipse { _affineTransformation :: Transformation 2 r }+                   deriving (Show,Eq,Functor,Foldable,Traversable)+makeLenses ''Ellipse++type instance Dimension (Ellipse r) = 2+type instance NumType   (Ellipse r) = r++instance Num r => IsTransformable (Ellipse r) where+  transformBy t (Ellipse t') = Ellipse $ t |.| t'+++ellipseMatrix :: Iso (Ellipse r) (Ellipse s) (Matrix 3 3 r) (Matrix 3 3 s)+ellipseMatrix = affineTransformation.transformationMatrix++-- | Ellipse representing the unit circle+unitEllipse :: Num r => Ellipse r+unitEllipse = Ellipse $ Transformation identityMatrix++--------------------------------------------------------------------------------+-- | Converting between ellipses and circles++_EllipseCircle :: (Floating r, Eq r) => Prism' (Ellipse r) (Circle () r)+_EllipseCircle = prism' circleToEllipse ellipseToCircle++ellipseToCircle   :: (Num r, Eq r) => Ellipse r -> Maybe (Circle () r)+ellipseToCircle e = case e^.ellipseMatrix of+      Matrix (Vector3 (Vector3 sx 0 x)+                      (Vector3 0 sy y)+                      (Vector3 0 0  1)+             )+           | sx == sy -> Just $ Circle (ext $ Point2 x y) (sx*sx)+      _               -> Nothing++circleToEllipse                            :: Floating r => Circle p r -> Ellipse r+circleToEllipse (Circle (Point v :+ _) rr) = Ellipse $ translation v |.| uniformScaling (sqrt rr)
src/Data/Geometry/HalfLine.hs view
@@ -31,7 +31,6 @@ makeLenses ''HalfLine  deriving instance (Show r, Arity d)   => Show    (HalfLine d r)-deriving instance (Eq r, Arity d)     => Eq      (HalfLine d r) deriving instance (NFData r, Arity d) => NFData  (HalfLine d r)  deriving instance Arity d           => Functor (HalfLine d)@@ -40,6 +39,11 @@  type instance Dimension (HalfLine d r) = d type instance NumType   (HalfLine d r) = r+++instance (Eq r, Fractional r, Arity d) => Eq (HalfLine d r) where+  (HalfLine p u) == (HalfLine q v) = let lam = scalarMultiple u v+                                     in p == q && (signum <$> lam) == Just 1  instance HasStart (HalfLine d r) where   type StartCore  (HalfLine d r) = Point d r
src/Data/Geometry/HalfSpace.hs view
@@ -38,13 +38,14 @@  -------------------------------------------------------------------------------- --- | A Halfspace in \(d\) dimensions.+-- | A Halfspace in \(d\) 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 { _boundingPlane :: HyperPlane d  r }                        deriving Generic makeLenses ''HalfSpace  deriving instance (Arity d, Show r)   => Show    (HalfSpace d r)-deriving instance (Arity d, Eq r)     => Eq      (HalfSpace d r) -- deriving instance (NFData r, Arity d) => NFData  (HalfSpace d r) deriving instance Arity d => Functor     (HalfSpace d) deriving instance Arity d => Foldable    (HalfSpace d)@@ -54,6 +55,12 @@ type instance Dimension (HalfSpace d r) = d  deriving instance (Arity d, Arity (d + 1), Fractional r) => IsTransformable (HalfSpace d r)++instance (Arity d, Eq r, Fractional r) => Eq (HalfSpace d r) where+  (HalfSpace h) == (HalfSpace h') = let u = h^.normalVec+                                        v = h'^.normalVec+                                        d = quadrance (u ^+^ v) - (quadrance u)+                                    in h == h' && signum d == 1  -------------------------------------------------------------------------------- 
src/Data/Geometry/HyperPlane.hs view
@@ -25,12 +25,15 @@ type instance NumType   (HyperPlane d r) = r  deriving instance (Arity d, Show r)   => Show    (HyperPlane d r)-deriving instance (Arity d, Eq r)     => Eq      (HyperPlane d r) deriving instance (NFData r, Arity d) => NFData  (HyperPlane d r) deriving instance Arity d => Functor     (HyperPlane d) deriving instance Arity d => Foldable    (HyperPlane d) deriving instance Arity d => Traversable (HyperPlane d) +instance (Arity d, Eq r, Fractional r) => Eq (HyperPlane d r) where+  (HyperPlane p u) == h@(HyperPlane _ v) = p `intersects` h && u `isScalarMultipleOf` v++ instance (Arity d, Arity (d + 1), Fractional r) => IsTransformable (HyperPlane d r) where   transformBy t (HyperPlane p v) = HyperPlane (transformBy t p) (transformBy t v) @@ -68,12 +71,29 @@  pattern Plane     :: Point 3 r -> Vector 3 r -> Plane r pattern Plane p n = HyperPlane p n+{-# COMPLETE Plane #-} +-- | 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 from3Points p q r = let u = q .-. p                         v = r .-. p                     in HyperPlane p (u `cross` v) +instance OnSideUpDownTest (Plane r) where+  -- >>> (Point3 5 5 5) `onSideUpDown` from3Points origin (Point3 1 0 0) (Point3 0 1 0)+  -- Above+  -- >>> (Point3 5 5 (-5)) `onSideUpDown` from3Points origin (Point3 1 0 0) (Point3 0 1 0)+  -- Below+  -- >>> (Point3 5 5 0) `onSideUpDown` from3Points origin (Point3 1 0 0) (Point3 0 1 0)+  -- On+  q `onSideUpDown` (Plane p n) = let v = q .-. p in case (n `dot` v) `compare` 0 of+                                   LT -> Below+                                   EQ -> On+                                   GT -> Above  type instance IntersectionOf (Line 3 r) (Plane r) = [NoIntersection, Point 3 r, Line 3 r] @@ -107,3 +127,23 @@  instance HasSupportingPlane (HyperPlane d r) where   supportingPlane = id+++-- | 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+planeCoordinatesWith h vup = projectPoint . transformBy (planeCoordinatesTransform h vup)++planeCoordinatesTransform                    :: Num r => Plane r -> Vector 3 r -> Transformation 3 r+planeCoordinatesTransform (HyperPlane o n) v =   rotateTo (Vector3 (v `cross` n) v n)+                                             |.| translation ((-1) *^ toVec o)
src/Data/Geometry/Interval.hs view
@@ -1,7 +1,10 @@ {-# LANGUAGE TemplateHaskell  #-} module Data.Geometry.Interval(                              -- * 1 dimensional Intervals-                               Interval(..)+                               Interval+                             , fromRange, toRange+                             , _Range+                              , pattern OpenInterval                              , pattern ClosedInterval                              , pattern Interval@@ -12,12 +15,13 @@                              , inInterval                              , shiftLeft' +                             , asProperInterval, flipInterval+                              , module Data.Range-                             )-       where+                             ) where  import           Control.DeepSeq-import           Control.Lens (makeLenses, (^.),(%~),(&), Lens')+import           Control.Lens (lens, (^.),(%~),(&), Lens') import           Data.Bifunctor import           Data.Bitraversable import           Data.Ext@@ -34,20 +38,31 @@ --------------------------------------------------------------------------------  -- | An Interval is essentially a 'Data.Range' but with possible payload-newtype Interval a r = GInterval { _unInterval :: Range (r :+ a) }+--+-- We can think of an interval being defined as:+--+-- >>> data Interval a r = Interval (EndPoint (r :+ a)) (EndPoint (r :+ a))+newtype Interval a r = GInterval { toRange :: Range (r :+ a) }                      deriving (Eq,Generic,Arbitrary)-makeLenses ''Interval +_Range :: Lens' (Interval a r) (Range (r :+ a))+_Range = lens toRange (const GInterval)+{-# INLINE _Range #-}++-- | Constrct an interval from a Range+fromRange :: Range (r :+ a) -> Interval a r+fromRange = GInterval+ deriving instance (NFData a, NFData r) => NFData (Interval a r)  instance (Show a, Show r) => Show (Interval a r) where   show ~(Interval l u) = concat [ "Interval (", show l, ") (", show u,")"]  instance Functor (Interval a) where-  fmap = T.fmapDefault+  fmap f (GInterval r) = GInterval $ fmap (first f) r  instance F.Foldable (Interval a) where-  foldMap = T.foldMapDefault+  foldMap f (GInterval r) = foldMap (f . (^.core)) r  instance T.Traversable (Interval a) where   traverse f (GInterval r) = GInterval <$> T.traverse f' r@@ -63,7 +78,7 @@ --  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-x `inInterval` r = x `inRange` (fmap (^.core) $ r^.unInterval )+x `inInterval` r = x `inRange` (fmap (^.core) $ r^._Range )   pattern OpenInterval       :: (r :+ a) -> (r :+ a) -> Interval a r@@ -87,7 +102,8 @@ instance HasStart (Interval a r) where   type StartCore (Interval a r) = r   type StartExtra (Interval a r) = a-  start = unInterval.lower.unEndPoint+  start = _Range.lower.unEndPoint+  {-# INLINE start #-}  class HasEnd t where   type EndCore t@@ -97,7 +113,8 @@ instance HasEnd (Interval a r) where   type EndCore (Interval a r) = r   type EndExtra (Interval a r) = a-  end = unInterval.upper.unEndPoint+  end = _Range.upper.unEndPoint+  {-# INLINE end #-}  type instance Dimension (Interval a r) = 1 type instance NumType   (Interval a r) = r@@ -121,6 +138,17 @@        g (Arg _ x) = x +-- | Shifts the interval to the left by delta+shiftLeft'       :: Num r => r -> Interval a r -> Interval a r+shiftLeft' delta = fmap (subtract delta) -shiftLeft'   :: Num r => r -> Interval a r -> Interval a r-shiftLeft' x = fmap (subtract x)++-- | 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+asProperInterval i | (i^.start.core) > (i^.end.core) = flipInterval i+                   | otherwise                       = i++-- | Flips the start and endpoint of the interval.+flipInterval :: Interval a r -> Interval a r+flipInterval = _Range %~ \(Range s t) -> Range t s
src/Data/Geometry/IntervalTree.hs view
@@ -55,7 +55,7 @@                  => [i] -> IntervalTree i r fromIntervals is = foldr insert (createTree pts) is   where-    endPoints (toRange -> Range' a b) = [a,b]+    endPoints (asRange -> Range' a b) = [a,b]     pts = List.sort . concatMap endPoints $ is  -- | Lists the intervals. We don't guarantee anything about the order@@ -100,7 +100,7 @@                           => i -> IntervalTree i r -> IntervalTree i r insert i (IntervalTree t) = IntervalTree $ insert' t   where-    ri@(Range a b) = toRange i+    ri@(Range a b) = asRange i      insert' Nil = Nil     insert' (Internal l nd@(_splitPoint -> m) r)@@ -119,7 +119,7 @@           => i -> IntervalTree i r -> IntervalTree i r delete i (IntervalTree t) = IntervalTree $ delete' t   where-    ri@(Range a b) = toRange i+    ri@(Range a b) = asRange i      delete' Nil = Nil     delete' (Internal l nd@(_splitPoint -> m) r)@@ -137,15 +137,13 @@  -- | Anything that looks like an interval class IntervalLike i where-  toRange :: i -> Range (NumType i)+  asRange :: i -> Range (NumType i)  instance IntervalLike (Range r) where-  toRange = id+  asRange = id  instance IntervalLike (Interval p r) where-  toRange = fmap (^.core) . _unInterval--+  asRange = fmap (^.core) . toRange  -------------------------------------------------------------------------------- 
src/Data/Geometry/Line.hs view
@@ -80,7 +80,7 @@         _     -> coRec NoIntersection       _     -> error "intersect; line x boundary rect; absurd"     where-      (t,r,b,l) = sides' rect+      Sides t r b l = sides' rect       ints = map (\s -> sl `intersect` toSL s) [t,r,b,l]        nub' = map L.head . L.group . L.sort
src/Data/Geometry/Line/Internal.hs view
@@ -53,6 +53,8 @@ instance (Arity d, Eq r, Fractional r) => Eq (Line d r) where   l@(Line p _) == m = l `isParallelTo` m && p `onLine` m ++ instance (Arbitrary r, Arity d, Num r, Eq r) => Arbitrary (Line d r) where   arbitrary = do p <- arbitrary                  q <- suchThat arbitrary (/= p)@@ -215,29 +217,34 @@     :& (H $ \_              -> Nothing)    -- l is a vertical line (through x=0)     :& RNil + -- | Result of a side test data SideTestUpDown = Below | On | Above deriving (Show,Read,Eq,Ord) --- | 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 `onSideUpDown` (lineThrough origin $ Point2 10 5)--- Above--- >>> Point2 10 10 `onSideUpDown` (lineThrough origin $ Point2 (-10) 5)--- Above--- >>> Point2 5 5 `onSideUpDown` (verticalLine 10)--- Below--- >>> Point2 5 5 `onSideUpDown` (lineThrough origin $ Point2 (-3) (-3))--- On-onSideUpDown                :: (Ord r, Num r) => Point 2 r -> Line 2 r -> SideTestUpDown-q `onSideUpDown` (Line p v) = let r    =  p .+^ v-                                  f z         = (z^.xCoord, -z^.yCoord)-                                  minBy g a b = F.minimumBy (comparing g) [a,b]-                                  maxBy g a b = F.maximumBy (comparing g) [a,b]-                              in case ccw (minBy f p r) (maxBy f p r) q of-                                   CCW      -> Above-                                   CW       -> Below-                                   CoLinear -> On+class OnSideUpDownTest t where+  onSideUpDown :: (d ~ Dimension t, r ~ NumType t, Ord r, Num r)+               => Point d r -> t -> SideTestUpDown++instance OnSideUpDownTest (Line 2 r) where+  -- | 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 `onSideUpDown` (lineThrough origin $ Point2 10 5)+  -- Above+  -- >>> Point2 10 10 `onSideUpDown` (lineThrough origin $ Point2 (-10) 5)+  -- Above+  -- >>> Point2 5 5 `onSideUpDown` (verticalLine 10)+  -- Below+  -- >>> Point2 5 5 `onSideUpDown` (lineThrough origin $ Point2 (-3) (-3))+  -- On+  q `onSideUpDown` (Line p v) = let r    =  p .+^ v+                                    f z         = (z^.xCoord, -z^.yCoord)+                                    minBy g a b = F.minimumBy (comparing g) [a,b]+                                    maxBy g a b = F.maximumBy (comparing g) [a,b]+                                in case ccw (minBy f p r) (maxBy f p r) q of+                                     CCW      -> Above+                                     CW       -> Below+                                     CoLinear -> On  -- | Result of a side test data SideTest = LeftSide | OnLine | RightSide deriving (Show,Read,Eq,Ord)
src/Data/Geometry/LineSegment.hs view
@@ -14,6 +14,7 @@                                 , pattern LineSegment                                 , pattern LineSegment'                                 , pattern ClosedLineSegment+                                , pattern OpenLineSegment                                 , endPoints                                  , _SubLine@@ -26,6 +27,8 @@                                 , segmentLength                                 , sqDistanceToSeg, sqDistanceToSegArg                                 , flipSegment++                                , interpolate                                 ) where  import           Control.Arrow ((&&&))@@ -45,7 +48,7 @@ import           Data.Vinyl import           Data.Vinyl.CoRec import           GHC.TypeLits-import           Test.QuickCheck+import           Test.QuickCheck(Arbitrary(..))  -------------------------------------------------------------------------------- -- * d-dimensional LineSegments@@ -77,12 +80,16 @@ pattern LineSegment'      s t <- ((^.start) &&& (^.end) -> (s,t)) {-# COMPLETE LineSegment' #-} -pattern ClosedLineSegment     :: 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 ClosedLineSegment s t = GLineSegment (ClosedInterval s t) {-# COMPLETE ClosedLineSegment #-} +pattern OpenLineSegment     :: Point d r :+ p -> Point d r :+ p -> LineSegment d p r+pattern OpenLineSegment s t = GLineSegment (OpenInterval s t)+{-# COMPLETE OpenLineSegment #-}+++ type instance Dimension (LineSegment d p r) = d type instance NumType   (LineSegment d p r) = r @@ -187,7 +194,6 @@       :& (H $ coRec . subLineToSegment)       :& RNil - instance (Ord r, Fractional r) =>          (LineSegment 2 p r) `IsIntersectableWith` (Line 2 r) where   nonEmptyIntersection = defaultNonEmptyIntersection@@ -292,3 +298,18 @@ --                   (q&unEndPoint %~ ff)  -- ss'' = ss'^._SubLine++-- | 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+interpolate t (LineSegment' p q) = Point $ (asV p ^* (1-t)) ^+^ (asV q ^* t)+  where+    asV = (^.core.vector)
+ src/Data/Geometry/Matrix.hs view
@@ -0,0 +1,79 @@+--------------------------------------------------------------------------------+-- |+-- Module      :  Data.Geometry.Matrix+-- Copyright   :  (C) Frank Staals+-- License     :  see the LICENSE file+-- Maintainer  :  Frank Staals+--+-- type-indexed matrices.+--+--------------------------------------------------------------------------------+module Data.Geometry.Matrix(+    Matrix(Matrix)+  , identityMatrix++  , multM+  , mult++  , Invertible(..)+  , HasDeterminant(..)+  ) where++import           Control.Lens (imap)+import           Data.Geometry.Matrix.Internal (mkRow)+import           Data.Geometry.Vector+import           Linear.Matrix ((!*),(!*!))+import qualified Linear.Matrix as Lin+import           Unsafe.Coerce (unsafeCoerce)++--------------------------------------------------------------------------------+-- * Matrices++-- | 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))++deriving instance (Show r, Arity n, Arity m) => Show (Matrix n m r)+deriving instance (Eq r, Arity n, Arity m)   => Eq (Matrix n m r)+deriving instance (Ord r, Arity n, Arity m)  => Ord (Matrix n m r)+deriving instance (Arity n, Arity m)         => Functor (Matrix n m)+deriving instance (Arity n, Arity m)         => Foldable (Matrix n m)+deriving instance (Arity n, Arity m)         => Traversable (Matrix n m)++multM :: (Arity r, Arity c, Arity c', Num a) => Matrix r c a -> Matrix c c' a -> Matrix r c' a+(Matrix a) `multM` (Matrix b) = Matrix $ a !*! b++mult :: (Arity m, Arity n, Num r) => Matrix n m r -> Vector m r -> Vector n r+(Matrix m) `mult` v = m !* v++-- | Produces the Identity Matrix+identityMatrix :: (Arity d, Num r) => Matrix d d r+identityMatrix = Matrix $ imap mkRow (pure 1)++class Invertible n r where+  inverse' :: Matrix n n r -> Matrix n n r++instance Fractional r => Invertible 2 r where+  -- >>> inverse' $ Matrix $ Vector2 (Vector2 1 2) (Vector2 3 4.0)+  -- Matrix Vector2 [Vector2 [-2.0,1.0],Vector2 [1.5,-0.5]]+  inverse' (Matrix m) = Matrix . unsafeCoerce . Lin.inv22 . unsafeCoerce $ m++instance Fractional r => Invertible 3 r where+  -- >>> inverse' $ Matrix $ Vector3 (Vector3 1 2 4) (Vector3 4 2 2) (Vector3 1 1 1.0)+  -- Matrix Vector3 [Vector3 [0.0,0.5,-1.0],Vector3 [-0.5,-0.75,3.5],Vector3 [0.5,0.25,-1.5]]+  inverse' (Matrix m) = Matrix . unsafeCoerce . Lin.inv33 . unsafeCoerce $ m++instance Fractional r => Invertible 4 r where+  inverse' (Matrix m) = Matrix . unsafeCoerce . Lin.inv44 . unsafeCoerce $ m+++class Arity d => HasDeterminant d where+  det :: Num r => Matrix d d r -> r++instance HasDeterminant 1 where+  det (Matrix (Vector1 (Vector1 x))) = x+instance HasDeterminant 2 where+  det = Lin.det22 . unsafeCoerce+instance HasDeterminant 3 where+  det = Lin.det33 . unsafeCoerce+instance HasDeterminant 4 where+  det = Lin.det44 . unsafeCoerce
+ src/Data/Geometry/Matrix/Internal.hs view
@@ -0,0 +1,14 @@+{-# LANGUAGE Unsafe #-}+module Data.Geometry.Matrix.Internal where++import           Control.Lens (set)+import           Data.Geometry.Vector+import qualified Data.Vector.Fixed as FV++--------------------------------------------------------------------------------+-- * Helper functions to easily create matrices++-- | Creates a row with zeroes everywhere, except at position i, where the+-- value is the supplied value.+mkRow     :: forall d r. (Arity d, Num r) => Int -> r -> Vector d r+mkRow i x = set (FV.element i) x zero
src/Data/Geometry/PlanarSubdivision.hs view
@@ -24,7 +24,6 @@ import           Data.Geometry.PlanarSubdivision.Basic import           Data.Geometry.PlanarSubdivision.Merge import           Data.Geometry.Polygon-import qualified Data.PlaneGraph as PG import           Data.Proxy  
src/Data/Geometry/PlanarSubdivision/Basic.hs view
@@ -423,13 +423,23 @@                             d''      = PG.nextIncidentEdge d' g                         in g^.dataOf d'' --- | All incoming edges incident to vertex v, in counterclockwise order around v.+-- | All edges incident to vertex v in incoming direction+-- (i.e. pointing into v) in counterclockwise order around v.+--+-- running time: \(O(k)\), where \(k) is the total number of incident edges of v incomingEdges      :: VertexId' s -> PlanarSubdivision s v e f r -> V.Vector (Dart s)-incomingEdges v ps = V.filter (not . isPositive) $ incidentEdges v ps+incomingEdges v ps = orient <$> incidentEdges v ps+  where+    orient d = if headOf d ps == v then d else twin d --- | All outgoing edges incident to vertex v, in counterclockwise order around v.+-- | All edges incident to vertex v in outgoing direction+-- (i.e. pointing away from v) in counterclockwise order around v.+--+-- running time: \(O(k)\), where \(k) is the total number of incident edges of v outgoingEdges      :: VertexId' s -> PlanarSubdivision s v e f r  -> V.Vector (Dart s)-outgoingEdges v ps = V.filter isPositive $ incidentEdges v ps+outgoingEdges v ps = orient <$> incidentEdges v ps+  where+    orient d = if tailOf d ps == v then d else twin d   -- | Gets the neighbours of a particular vertex, in counterclockwise order@@ -437,10 +447,7 @@ -- -- running time: \(O(k)\), where \(k\) is the output size neighboursOf      :: VertexId' s -> PlanarSubdivision s v e f r -> V.Vector (VertexId' s)-neighboursOf v ps = otherVtx <$> incidentEdges v ps-  where-    otherVtx d = let u = tailOf d ps in if u == v then headOf d ps else u-+neighboursOf v ps = flip tailOf ps <$> incomingEdges v ps  -- | The face to the left of the dart --
src/Data/Geometry/Point.hs view
@@ -13,18 +13,17 @@ module Data.Geometry.Point( Point(..)                           , origin, vector                           , pointFromList--                          , coord , unsafeCoord-                           , projectPoint +                          , pattern Point1                           , pattern Point2                           , pattern Point3                           , xCoord, yCoord, zCoord                            , PointFunctor(..) -                          , CCW(..), ccw, ccw'+                          , CCW, ccw, ccw'+                          , pattern CCW, pattern CW, pattern CoLinear                            , ccwCmpAround, cwCmpAround, ccwCmpAroundWith, cwCmpAroundWith                           , sortAround, insertIntoCyclicOrder@@ -34,394 +33,12 @@                           , cmpByDistanceTo                            , squaredEuclideanDist, euclideanDist-                          ) where -import           Control.DeepSeq-import           Control.Lens-import           Data.Aeson-import qualified Data.CircularList as C-import qualified Data.CircularList.Util as CU-import           Data.Ext-import qualified Data.Foldable as F-import           Data.Geometry.Properties-import           Data.Geometry.Vector-import qualified Data.Geometry.Vector as Vec-import qualified Data.List as L-import           Data.Ord (comparing)-import           Data.Proxy-import           GHC.Generics (Generic)-import           GHC.TypeLits-import           Test.QuickCheck (Arbitrary)-import           Text.ParserCombinators.ReadP (ReadP, string,pfail)-import           Text.ParserCombinators.ReadPrec (lift)-import           Text.Read (Read(..),readListPrecDefault, readPrec_to_P,minPrec) ------------------------------------------------------------------------------------- $setup--- >>> :{--- let myVector :: Vector 3 Int---     myVector = Vector3 1 2 3---     myPoint = Point myVector--- :}-------------------------------------------------------------------------------------- * A d-dimensional Point---- | A d-dimensional point.-newtype Point d r = Point { toVec :: Vector d r } deriving (Generic)--instance (Show r, Arity d) => Show (Point d r) where-  show (Point v) = mconcat [ "Point", show $ F.length v , " "-                           , show $ F.toList v-                           ]-instance (Read r, Arity d) => Read (Point d r) where-  readPrec     = lift readPt-  readListPrec = readListPrecDefault--readPt :: forall d r. (Arity d, Read r) => ReadP (Point d r)-readPt = do let d = natVal (Proxy :: Proxy d)-            _  <- string $ "Point" <> show d <> " "-            rs <- readPrec_to_P readPrec minPrec-            case pointFromList rs of-              Just p -> pure p-              _      -> pfail--deriving instance (Eq r, Arity d)        => Eq (Point d r)-deriving instance (Ord r, Arity d)       => Ord (Point d r)-deriving instance Arity d                => Functor (Point d)-deriving instance Arity d                => Foldable (Point d)-deriving instance Arity d                => Traversable (Point d)-deriving instance (Arity d, NFData r)    => NFData (Point d r)-deriving instance (Arity d, Arbitrary r) => Arbitrary (Point d r)--type instance NumType (Point d r) = r-type instance Dimension (Point d r) = d--instance Arity d =>  Affine (Point d) where-  type Diff (Point d) = Vector d--  p .-. q = toVec p ^-^ toVec q-  p .+^ v = Point $ toVec p ^+^ v--instance (FromJSON r, Arity d, KnownNat d) => FromJSON (Point d r) where-  parseJSON = fmap Point . parseJSON--instance (ToJSON r, Arity d) => ToJSON (Point d r) where-  toJSON     = toJSON     . toVec-  toEncoding = toEncoding . toVec---- | Point representing the origin in d dimensions------ >>> origin :: Point 4 Int--- Point4 [0,0,0,0]-origin :: (Arity d, Num r) => Point d r-origin = Point $ pure 0----- ** Accessing points---- | 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) (Vector d r)-vector = lens toVec (const Point)----- | 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 => Int -> Lens' (Point d r) r-unsafeCoord i = vector . singular (ix (i-1))-                -- Points are 1 indexed, vectors are 0 indexed---- | 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   :: forall proxy i d r. (1 <= i, i <= d, ((i - 1) + 1) ~ i-                               , Arity (i - 1), Arity d-                               ) => proxy i -> Lens' (Point d r) r-coord _ = vector . Vec.element (Proxy :: Proxy (i-1))-{-# INLINABLE coord #-}----- somehow these rules don't fire--- {-# SPECIALIZE coord :: C 1 -> Lens' (Point 2 r) r#-}--- {-# SPECIALIZE coord :: C 2 -> Lens' (Point 2 r) r#-}----- | Constructs a point from a list of coordinates------ >>> pointFromList [1,2,3] :: Maybe (Point 3 Int)--- Just Point3 [1,2,3]-pointFromList :: Arity d => [r] -> Maybe (Point d r)-pointFromList = fmap Point . Vec.vectorFromList----- | Project a point down into a lower dimension.-projectPoint :: (Arity i, Arity d, i <= d) => Point d r -> Point i r-projectPoint = Point . prefix . toVec------------------------------------------------------------------------------------- * Convenience functions to construct 2 and 3 dimensional points----- | We provide pattern synonyms Point2 and Point3 for 2 and 3 dimensional points. i.e.--- we can write:------ >>> :{---   let---     f              :: Point 2 r -> r---     f (Point2 x y) = x---   in f (Point2 1 2)--- :}--- 1------ if we want.-pattern Point2       :: r -> r -> Point 2 r-pattern Point2 x y = Point (Vector2 x y)-{-# COMPLETE Point2 #-}---- | Similarly, we can write:------ >>> :{---   let---     g                :: Point 3 r -> r---     g (Point3 x y z) = z---   in g myPoint--- :}--- 3-pattern Point3       :: r -> r -> r -> Point 3 r-pattern Point3 x y z = (Point (Vector3 x y z))-{-# COMPLETE Point3 #-}---- | 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) => Lens' (Point d r) r-xCoord = coord (C :: C 1)-{-# INLINABLE xCoord #-}---- | 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) => Lens' (Point d r) r-yCoord = coord (C :: C 2)-{-# INLINABLE yCoord #-}---- | 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) => Lens' (Point d r) r-zCoord = coord (C :: C 3)-{-# INLINABLE zCoord #-}-------------------------------------------------------------------------------------- * Point Functors---- | Types that we can transform by mapping a function on each point in the structure-class PointFunctor g where-  pmap :: (Point (Dimension (g r)) r -> Point (Dimension (g s)) s) -> g r -> g s--  -- pemap :: (d ~ Dimension (g r)) => (Point d r :+ p -> Point d s :+ p) -> g r -> g s-  -- pemap =--instance PointFunctor (Point d) where-  pmap f = f-------------------------------------------------------------------------------------- * Functions specific to Two Dimensional points--data CCW = CCW | CoLinear | CW-         deriving (Show,Eq)---- | 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 -> Point 2 r -> Point 2 r -> CCW-ccw p q r = case z `compare` 0 of-              LT -> CW-              GT -> CCW-              EQ -> CoLinear-     where-       Vector2 ux uy = q .-. p-       Vector2 vx vy = r .-. p-       z             = ux * vy - uy * vx---- | 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-ccw' p q r = ccw (p^.core) (q^.core) (r^.core)---- | 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.--- running time: O(n log n)-sortAround   :: (Ord r, Num r)-             => Point 2 r :+ q -> [Point 2 r :+ p] -> [Point 2 r :+ p]-sortAround c = L.sortBy (ccwCmpAround c <> cmpByDistanceTo c)----- | Quadrants of two dimensional points. in CCW order-data Quadrant = TopRight | TopLeft | BottomLeft | BottomRight-              deriving (Show,Read,Eq,Ord,Enum,Bounded)---- | 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-quadrantWith (c :+ _) (p :+ _) = case ( (c^.xCoord) `compare` (p^.xCoord)-                                      , (c^.yCoord) `compare` (p^.yCoord) ) of-                                   (EQ, EQ) -> TopRight-                                   (LT, EQ) -> TopRight-                                   (LT, LT) -> TopRight-                                   (EQ, LT) -> TopLeft-                                   (GT, LT) -> TopLeft-                                   (GT, EQ) -> BottomLeft-                                   (GT, GT) -> BottomLeft-                                   (EQ, GT) -> BottomRight-                                   (LT, GT) -> BottomRight---- | Quadrants with respect to the origin-quadrant :: (Ord r, Num r, 1 <= d, 2 <= d, Arity d) => Point d r :+ p -> Quadrant-quadrant = quadrantWith (ext origin)---- | 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]-                                )-partitionIntoQuadrants c pts = (topL, topR, bottomL, bottomR)-  where-    (below',above')   = L.partition (on yCoord) pts-    (bottomL,bottomR) = L.partition (on xCoord) below'-    (topL,topR)       = L.partition (on xCoord) above'--    on l q       = q^.core.l < c^.core.l------ | 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-ccwCmpAroundWith z@(Vector2 zx zy) (c :+ _) (q :+ _) (r :+ _) =-    case (ccw c a q, ccw c a r) of-      (CCW,CCW)      -> cmp-      (CCW,CW)       -> LT-      (CCW,CoLinear) | onZero r  -> GT-                     | otherwise -> LT--      (CW, CCW)      -> GT-      (CW, CW)       -> cmp-      (CW, CoLinear) -> GT--      (CoLinear, CCW) | onZero q  -> LT-                      | otherwise -> GT--      (CoLinear, CW)      -> LT-      (CoLinear,CoLinear) -> case (onZero q, onZero r) of-                               (True, True)   -> EQ-                               (False, False) -> EQ-                               (True, False)  -> LT-                               (False, True)  -> GT-  where-    a = c .+^ z-    b = c .+^ Vector2 (-zy) zx-    -- b is on a perpendicular vector to z--    -- test if the point lies on the ray defined by z, starting in c-    onZero d = case ccw c b d of-                 CCW      -> False-                 CW       -> True-                 CoLinear -> True -- this shouldh appen only when you ask for c itself--    cmp = case ccw c q r of-            CCW      -> LT-            CW       -> GT-            CoLinear -> EQ---- | 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-cwCmpAroundWith z c = flip (ccwCmpAroundWith z c)------ | 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-cmpByDistanceTo (c :+ _) p q = comparing (squaredEuclideanDist c) (p^.core) (q^.core)----- | 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-ccwCmpAround = ccwCmpAroundWith (Vector2 1 0)---- | 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-cwCmpAround = cwCmpAroundWith (Vector2 1 0)----- | 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.------ running time: O(n)-insertIntoCyclicOrder   :: (Ord r, Num r)-                        => Point 2 r :+ q -> Point 2 r :+ p-                        -> C.CList (Point 2 r :+ p) -> C.CList (Point 2 r :+ p)-insertIntoCyclicOrder c = CU.insertOrdBy (ccwCmpAround c <> cmpByDistanceTo c)----- | Squared Euclidean distance between two points-squaredEuclideanDist :: (Num r, Arity d) => Point d r -> Point d r -> r-squaredEuclideanDist = qdA+                          , AsAPoint(..), coord, unsafeCoord, vector'+                          ) where --- | Euclidean distance between two points-euclideanDist :: (Floating r, Arity d) => Point d r -> Point d r -> r-euclideanDist = distanceA+import Data.Geometry.Point.Class+import Data.Geometry.Point.Internal hiding (coord, unsafeCoord)+import Data.Geometry.Point.Orientation.Degenerate+import Data.Geometry.Point.Quadrants
+ src/Data/Geometry/Point/Class.hs view
@@ -0,0 +1,66 @@+module Data.Geometry.Point.Class where++import           Control.Lens+import           Data.Geometry.Point.Internal (Point)+import qualified Data.Geometry.Point.Internal as Internal+import           Data.Geometry.Vector+import           GHC.TypeNats++--------------------------------------------------------------------------------++-- $setup+-- >>> import Data.Geometry.Point.Internal (pattern Point2, pattern Point3)++class ToAPoint point d r where+  toPoint   :: Prism' (point d r) (Point d r)++class AsAPoint p where+  asAPoint :: Lens (p d r) (p d' r') (Point d r) (Point d' r')++vector' :: AsAPoint p => Lens (p d r) (p d r') (Vector d r) (Vector d r')+vector' = asAPoint . lens Internal.toVec (const Internal.Point)++coord   :: (1 <= i, i <= d, KnownNat i, Arity d, AsAPoint p) => proxy i -> Lens' (p d r) r+coord i = asAPoint.Internal.coord i++unsafeCoord   :: (Arity d, AsAPoint p) => Int -> Lens' (p d r) r+unsafeCoord i = asAPoint.Internal.unsafeCoord i++instance ToAPoint Point d r where+  toPoint = prism' id Just++instance AsAPoint Point where+  asAPoint = id+++++-- | 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+xCoord = coord (C :: C 1)+{-# INLINABLE xCoord #-}++-- | 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+yCoord = coord (C :: C 2)+{-# INLINABLE yCoord #-}++-- | 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+zCoord = coord (C :: C 3)+{-# INLINABLE zCoord #-}
+ src/Data/Geometry/Point/Internal.hs view
@@ -0,0 +1,252 @@+{-# LANGUAGE ScopedTypeVariables  #-}+{-# LANGUAGE UndecidableInstances #-}+--------------------------------------------------------------------------------+-- |+-- Module      :  Data.Geometry.Point+-- Copyright   :  (C) Frank Staals+-- License     :  see the LICENSE file+-- Maintainer  :  Frank Staals+--+-- \(d\)-dimensional points.+--+--------------------------------------------------------------------------------+module Data.Geometry.Point.Internal+  ( Point(..)+  , origin, vector+  , pointFromList++  , coord , unsafeCoord++  , projectPoint++  , pattern Point1+  , pattern Point2+  , pattern Point3+  , PointFunctor(..)++  , cmpByDistanceTo+  , squaredEuclideanDist, euclideanDist+  ) where++import           Control.DeepSeq+import           Control.Lens+import           Data.Aeson+import           Data.Ext+import qualified Data.Foldable as F+import           Data.Geometry.Properties+import           Data.Geometry.Vector+import qualified Data.Geometry.Vector as Vec+import           Data.Hashable+import           Data.Ord (comparing)+import           Data.Proxy+import           GHC.Generics (Generic)+import           GHC.TypeLits+import           System.Random (Random(..))+import           Test.QuickCheck (Arbitrary)+import           Text.ParserCombinators.ReadP (ReadP, string,pfail)+import           Text.ParserCombinators.ReadPrec (lift)+import           Text.Read (Read(..),readListPrecDefault, readPrec_to_P,minPrec)+++--------------------------------------------------------------------------------+-- $setup+-- >>> :{+-- let myVector :: Vector 3 Int+--     myVector = Vector3 1 2 3+--     myPoint = Point myVector+-- :}+++--------------------------------------------------------------------------------+-- * A d-dimensional Point++-- | A d-dimensional point.+newtype Point d r = Point { toVec :: Vector d r } deriving (Generic)++instance (Show r, Arity d) => Show (Point d r) where+  show (Point v) = mconcat [ "Point", show $ F.length v , " "+                           , show $ F.toList v+                           ]+instance (Read r, Arity d) => Read (Point d r) where+  readPrec     = lift readPt+  readListPrec = readListPrecDefault++readPt :: forall d r. (Arity d, Read r) => ReadP (Point d r)+readPt = do let d = natVal (Proxy :: Proxy d)+            _  <- string $ "Point" <> show d <> " "+            rs <- readPrec_to_P readPrec minPrec+            case pointFromList rs of+              Just p -> pure p+              _      -> pfail++deriving instance (Eq r, Arity d)        => Eq (Point d r)+deriving instance (Ord r, Arity d)       => Ord (Point d r)+deriving instance Arity d                => Functor (Point d)+deriving instance Arity d                => Foldable (Point d)+deriving instance Arity d                => Traversable (Point d)+deriving instance (Arity d, NFData r)    => NFData (Point d r)+deriving instance (Arity d, Arbitrary r) => Arbitrary (Point d r)+deriving instance (Arity d, Hashable r)  => Hashable (Point d r)+deriving instance (Arity d, Random r)    => Random (Point d r)+++type instance NumType (Point d r) = r+type instance Dimension (Point d r) = d++instance Arity d =>  Affine (Point d) where+  type Diff (Point d) = Vector d++  p .-. q = toVec p ^-^ toVec q+  p .+^ v = Point $ toVec p ^+^ v++instance (FromJSON r, Arity d, KnownNat d) => FromJSON (Point d r) where+  parseJSON = fmap Point . parseJSON++instance (ToJSON r, Arity d) => ToJSON (Point d r) where+  toJSON     = toJSON     . toVec+  toEncoding = toEncoding . toVec++-- | Point representing the origin in d dimensions+--+-- >>> origin :: Point 4 Int+-- Point4 [0,0,0,0]+origin :: (Arity d, Num r) => Point d r+origin = Point $ pure 0+++-- ** Accessing points++-- | 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) (Vector d r)+vector = lens toVec (const Point)+{-# INLINABLE vector #-}++-- | 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 => Int -> Lens' (Point d r) r+unsafeCoord i = vector . singular (ix (i-1))+                -- Points are 1 indexed, vectors are 0 indexed+{-# INLINABLE unsafeCoord #-}++-- | 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   :: forall proxy i d r. (1 <= i, i <= d, Arity d, KnownNat i)+        => proxy i -> Lens' (Point d r) r+coord _ = unsafeCoord $ fromIntegral (natVal $ C @i)+{-# INLINABLE coord #-}++ -- somehow these rules don't fire+-- {-# SPECIALIZE coord :: C 1 -> Lens' (Point 2 r) r#-}+-- {-# SPECIALIZE coord :: C 2 -> Lens' (Point 2 r) r#-}+-- {-# SPECIALIZE coord :: C 3 -> Lens' (Point 3 r) 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)+pointFromList = fmap Point . Vec.vectorFromList+++-- | Project a point down into a lower dimension.+projectPoint :: (Arity i, Arity d, i <= d) => Point d r -> Point i r+projectPoint = Point . prefix . toVec++--------------------------------------------------------------------------------+-- * Convenience functions to construct 1, 2 and 3 dimensional points++-- | We provide pattern synonyms for 1, 2 and 3 dimensional points. i.e.+-- we can write:+--+--+-- >>> :{+--   let+--     f            :: Num r => Point 1 r -> r+--     f (Point1 x) = x + 1+--   in f (Point1 1)+-- :}+-- 2+pattern Point1   :: r -> Point 1 r+pattern Point1 x = Point (Vector1 x)+{-# COMPLETE Point1 #-}+++-- | Pattern synonym for 2 dimensional points+--+-- >>> :{+--   let+--     f              :: Point 2 r -> r+--     f (Point2 x y) = x+--   in f (Point2 1 2)+-- :}+-- 1+pattern Point2       :: r -> r -> Point 2 r+pattern Point2 x y = Point (Vector2 x y)+{-# COMPLETE Point2 #-}++-- | Similarly, we can write:+--+-- >>> :{+--   let+--     g                :: Point 3 r -> r+--     g (Point3 x y z) = z+--   in g myPoint+-- :}+-- 3+pattern Point3       :: r -> r -> r -> Point 3 r+pattern Point3 x y z = (Point (Vector3 x y z))+{-# COMPLETE Point3 #-}++--------------------------------------------------------------------------------+-- * Point Functors++-- | Types that we can transform by mapping a function on each point in the structure+class PointFunctor g where+  pmap :: (Point (Dimension (g r)) r -> Point (Dimension (g s)) s) -> g r -> g s++  -- pemap :: (d ~ Dimension (g r)) => (Point d r :+ p -> Point d s :+ p) -> g r -> g s+  -- pemap =++instance PointFunctor (Point d) where+  pmap f = f+++--------------------------------------------------------------------------------+-- * Functions specific to Two Dimensional points++-- | 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+cmpByDistanceTo (c :+ _) p q = comparing (squaredEuclideanDist c) (p^.core) (q^.core)+++++-- | Squared Euclidean distance between two points+squaredEuclideanDist :: (Num r, Arity d) => Point d r -> Point d r -> r+squaredEuclideanDist = qdA++-- | Euclidean distance between two points+euclideanDist :: (Floating r, Arity d) => Point d r -> Point d r -> r+euclideanDist = distanceA
+ src/Data/Geometry/Point/Orientation.hs view
@@ -0,0 +1,31 @@+module Data.Geometry.Point.Orientation where++import Algorithms.Geometry.SoS.Orientation+import Algorithms.Geometry.SoS.Sign+import Data.Ext+import Data.Geometry.Point.Internal+import Data.Geometry.Vector++--------------------------------------------------------------------------------++--------------------------------------------------------------------------------++newtype StrictCCW = SCCW Sign deriving Eq++pattern CCW :: StrictCCW+pattern CCW = SCCW Negative++pattern CW  :: StrictCCW+pattern CW  = SCCW Positive+{-# COMPLETE CCW, CW #-}++instance Show StrictCCW where+  show = \case+    CCW -> "CCW"+    CW  -> "CW"+++-- | Given three points p q and r determine the orientation when going from p to r via q.+ccw       :: (Ord r, Num r, Ord i)+          => Point 2 r :+ i -> Point 2 r :+ i -> Point 2 r :+ i -> StrictCCW+ccw p q r = SCCW $ sideTest r (Vector2 p q)
+ src/Data/Geometry/Point/Orientation/Degenerate.hs view
@@ -0,0 +1,150 @@+module Data.Geometry.Point.Orientation.Degenerate(+    CCW(..)+  , pattern CCW, pattern CW, pattern CoLinear++  , ccw, ccw'++  , sortAround++  , ccwCmpAroundWith, cwCmpAroundWith+  , ccwCmpAround, cwCmpAround++  , insertIntoCyclicOrder+  ) where++import           Control.Lens+import qualified Data.CircularList as C+import qualified Data.CircularList.Util as CU+import           Data.Ext+import           Data.Geometry.Point.Internal+import           Data.Geometry.Vector+import qualified Data.List as L++--------------------------------------------------------------------------------++-- | Data type for expressing the orientation of three points, with+-- the option of allowing Colinearities.+newtype CCW = CCWWrap Ordering deriving Eq++pattern CCW      :: CCW+pattern CCW      = CCWWrap GT++pattern CW       :: CCW+pattern CW       = CCWWrap LT++pattern CoLinear :: CCW+pattern CoLinear = CCWWrap EQ+{-# COMPLETE CCW, CW, CoLinear #-}++instance Show CCW where+  show = \case+    CCW      -> "CCW"+    CW       -> "CW"+    CoLinear -> "CoLinear"+++-- | 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 -> Point 2 r -> Point 2 r -> CCW+ccw p q r = CCWWrap $ z `compare` 0+            -- case z `compare` 0 of+            --   LT -> CW+            --   GT -> CCW+            --   EQ -> CoLinear+     where+       Vector2 ux uy = q .-. p+       Vector2 vx vy = r .-. p+       z             = ux * vy - uy * vx++-- | 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+ccw' p q r = ccw (p^.core) (q^.core) (r^.core)++-- | 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.+-- running time: O(n log n)+sortAround   :: (Ord r, Num r)+             => Point 2 r :+ q -> [Point 2 r :+ p] -> [Point 2 r :+ p]+sortAround c = L.sortBy (ccwCmpAround c <> cmpByDistanceTo c)+++-- | 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+ccwCmpAroundWith z@(Vector2 zx zy) (c :+ _) (q :+ _) (r :+ _) =+    case (ccw c a q, ccw c a r) of+      (CCW,CCW)      -> cmp+      (CCW,CW)       -> LT+      (CCW,CoLinear) | onZero r  -> GT+                     | otherwise -> LT++      (CW, CCW)      -> GT+      (CW, CW)       -> cmp+      (CW, CoLinear) -> GT++      (CoLinear, CCW) | onZero q  -> LT+                      | otherwise -> GT++      (CoLinear, CW)      -> LT+      (CoLinear,CoLinear) -> case (onZero q, onZero r) of+                               (True, True)   -> EQ+                               (False, False) -> EQ+                               (True, False)  -> LT+                               (False, True)  -> GT+  where+    a = c .+^ z+    b = c .+^ Vector2 (-zy) zx+    -- b is on a perpendicular vector to z++    -- test if the point lies on the ray defined by z, starting in c+    onZero d = case ccw c b d of+                 CCW      -> False+                 CW       -> True+                 CoLinear -> True -- this shouldh appen only when you ask for c itself++    cmp = case ccw c q r of+            CCW      -> LT+            CW       -> GT+            CoLinear -> EQ++-- | 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+cwCmpAroundWith z c = flip (ccwCmpAroundWith z c)++-- | 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+ccwCmpAround = ccwCmpAroundWith (Vector2 1 0)++-- | 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+cwCmpAround = cwCmpAroundWith (Vector2 1 0)+++-- | 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.+--+-- running time: O(n)+insertIntoCyclicOrder   :: (Ord r, Num r)+                        => Point 2 r :+ q -> Point 2 r :+ p+                        -> C.CList (Point 2 r :+ p) -> C.CList (Point 2 r :+ p)+insertIntoCyclicOrder c = CU.insertOrdBy (ccwCmpAround c <> cmpByDistanceTo c)
+ src/Data/Geometry/Point/Quadrants.hs view
@@ -0,0 +1,69 @@+module Data.Geometry.Point.Quadrants where++import           Control.DeepSeq+import           Control.Lens+import           Data.Aeson+import           Data.Ext+import qualified Data.Foldable as F+import           Data.Geometry.Point.Class+import           Data.Geometry.Point.Internal+import           Data.Geometry.Properties+import           Data.Geometry.Vector+import qualified Data.Geometry.Vector as Vec+import           Data.Hashable+import qualified Data.List as L+import           Data.Ord (comparing)+import           Data.Proxy+import           GHC.Generics (Generic)+import           GHC.TypeLits+import           System.Random (Random(..))+import           Test.QuickCheck (Arbitrary)+import           Text.ParserCombinators.ReadP (ReadP, string,pfail)+import           Text.ParserCombinators.ReadPrec (lift)+import           Text.Read (Read(..),readListPrecDefault, readPrec_to_P,minPrec)++--------------------------------------------------------------------------------++-- | Quadrants of two dimensional points. in CCW order+data Quadrant = TopRight | TopLeft | BottomLeft | BottomRight+              deriving (Show,Read,Eq,Ord,Enum,Bounded)++-- | 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+quadrantWith (c :+ _) (p :+ _) = case ( (c^.xCoord) `compare` (p^.xCoord)+                                      , (c^.yCoord) `compare` (p^.yCoord) ) of+                                   (EQ, EQ) -> TopRight+                                   (LT, EQ) -> TopRight+                                   (LT, LT) -> TopRight+                                   (EQ, LT) -> TopLeft+                                   (GT, LT) -> TopLeft+                                   (GT, EQ) -> BottomLeft+                                   (GT, GT) -> BottomLeft+                                   (EQ, GT) -> BottomRight+                                   (LT, GT) -> BottomRight++-- | Quadrants with respect to the origin+quadrant :: (Ord r, Num r, 1 <= d, 2 <= d, Arity d) => Point d r :+ p -> Quadrant+quadrant = quadrantWith (ext origin)++-- | 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]+                                )+partitionIntoQuadrants c pts = (topL, topR, bottomL, bottomR)+  where+    (below',above')   = L.partition (on yCoord) pts+    (bottomL,bottomR) = L.partition (on xCoord) below'+    (topL,topR)       = L.partition (on xCoord) above'++    on l q       = q^.core.l < c^.core.l
src/Data/Geometry/PolyLine.hs view
@@ -5,7 +5,9 @@  import           Control.Lens import           Data.Aeson+import           Data.Bifoldable import           Data.Bifunctor+import           Data.Bitraversable import           Data.Ext import qualified Data.Foldable as F import           Data.Geometry.Box@@ -17,10 +19,18 @@ import           Data.LSeq (LSeq, pattern (:<|)) import qualified Data.LSeq as LSeq import qualified Data.List.NonEmpty as NE-import           GHC.Generics(Generic)+import           GHC.Generics (Generic) import           GHC.TypeLits  --------------------------------------------------------------------------------++--------------------------------------------------------------------------------+-- $setup+-- >>> :{+-- let myPolyLine = fromPointsUnsafe $ map ext [origin, Point2 10.0 10.0, Point2 10.0 20.0]+-- :}++-------------------------------------------------------------------------------- -- * d-dimensional Polygonal Lines (PolyLines)  -- | A Poly line in R^d has at least 2 vertices@@ -50,25 +60,33 @@   pmap f = over points (fmap (first f))  instance Arity d => Bifunctor (PolyLine d) where-  bimap f g (PolyLine pts) = PolyLine $ fmap (bimap (fmap g) f) pts+  bimap = bimapDefault+instance Arity d => Bifoldable (PolyLine d) where+  bifoldMap = bifoldMapDefault+instance Arity d => Bitraversable (PolyLine d) where+  bitraverse f g (PolyLine pts) = PolyLine <$> traverse (bitraverse (traverse g) f) pts  instance (ToJSON p, ToJSON r, Arity d) => ToJSON (PolyLine d p r) where     toEncoding = genericToEncoding defaultOptions instance (FromJSON p, FromJSON r, Arity d, KnownNat d) => FromJSON (PolyLine d p r) +-- | Builds a Polyline from a list of points, if there are sufficiently many points+fromPoints :: [Point d r :+ p] -> Maybe (PolyLine d p r)+fromPoints = fmap PolyLine . LSeq.eval (C @ 2) . LSeq.fromList+ -- | pre: The input list contains at least two points-fromPoints :: [Point d r :+ p] -> PolyLine d p r-fromPoints = PolyLine . LSeq.forceLSeq (C  :: C 2) . LSeq.fromList+fromPointsUnsafe :: [Point d r :+ p] -> PolyLine d p r+fromPointsUnsafe = PolyLine . LSeq.forceLSeq (C @ 2) . LSeq.fromList  -- | pre: The input list contains at least two points. All extra vields are -- initialized with mempty.-fromPoints' :: (Monoid p) => [Point d r] -> PolyLine d p r-fromPoints' = fromPoints . map (\p -> p :+ mempty)+fromPointsUnsafe' :: (Monoid p) => [Point d r] -> PolyLine d p r+fromPointsUnsafe' = fromPointsUnsafe . map (\p -> p :+ mempty)   -- | We consider the line-segment as closed. fromLineSegment                     :: LineSegment d p r -> PolyLine d p r-fromLineSegment ~(LineSegment' p q) = fromPoints [p,q]+fromLineSegment ~(LineSegment' p q) = fromPointsUnsafe [p,q]  -- | Convert to a closed line segment by taking the first two points. asLineSegment                            :: PolyLine d p r -> LineSegment d p r@@ -80,3 +98,23 @@ asLineSegment' (PolyLine pts) = case F.toList pts of                                   [p,q] -> Just $ ClosedLineSegment p q                                   _     -> Nothing++-- | Computes the edges, as linesegments, of an LSeq+edgeSegments    :: Arity d => PolyLine d p r -> LSeq 1 (LineSegment d p r)+edgeSegments pl = let vs = pl^.points+                  in LSeq.zipWith ClosedLineSegment (LSeq.init vs) (LSeq.tail vs)+++-- | Linearly interpolate the polyline with a value in the range+-- \([0,n-1]\), where \(n\) is the number of vertices of the polyline.+--+-- running time: \(O(\log n)\)+--+-- >>> 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+interpolatePoly t pl = let i = floor t in case edgeSegments pl^?ix i of+                         Nothing -> pl^.points.to LSeq.last.core+                         Just e  -> interpolate (t-fromIntegral i) e
src/Data/Geometry/Polygon/Core.hs view
@@ -73,12 +73,15 @@ import           Data.Util import           Data.Vinyl.CoRec (asA) +-- import Data.RealNumber.Rational+ --------------------------------------------------------------------------------  {- $setup+>>> import Data.RealNumber.Rational >>> :{ -- import qualified Data.CircularSeq as C-let simplePoly :: SimplePolygon () Rational+let simplePoly :: SimplePolygon () (RealNumber 10)     simplePoly = SimplePolygon . C.fromList . map ext $ [ Point2 0 0                                                         , Point2 10 0                                                         , Point2 10 10@@ -268,17 +271,17 @@ -- -- -- >>> mapM_ print . polygonVertices $ withIncidentEdges simplePoly--- Point2 [0 % 1,0 % 1] :+ SP LineSegment (Closed (Point2 [1 % 1,11 % 1] :+ ())) (Closed (Point2 [0 % 1,0 % 1] :+ ())) LineSegment (Closed (Point2 [0 % 1,0 % 1] :+ ())) (Closed (Point2 [10 % 1,0 % 1] :+ ()))--- Point2 [10 % 1,0 % 1] :+ SP LineSegment (Closed (Point2 [0 % 1,0 % 1] :+ ())) (Closed (Point2 [10 % 1,0 % 1] :+ ())) LineSegment (Closed (Point2 [10 % 1,0 % 1] :+ ())) (Closed (Point2 [10 % 1,10 % 1] :+ ()))--- Point2 [10 % 1,10 % 1] :+ SP LineSegment (Closed (Point2 [10 % 1,0 % 1] :+ ())) (Closed (Point2 [10 % 1,10 % 1] :+ ())) LineSegment (Closed (Point2 [10 % 1,10 % 1] :+ ())) (Closed (Point2 [5 % 1,15 % 1] :+ ()))--- Point2 [5 % 1,15 % 1] :+ SP LineSegment (Closed (Point2 [10 % 1,10 % 1] :+ ())) (Closed (Point2 [5 % 1,15 % 1] :+ ())) LineSegment (Closed (Point2 [5 % 1,15 % 1] :+ ())) (Closed (Point2 [1 % 1,11 % 1] :+ ()))--- Point2 [1 % 1,11 % 1] :+ SP LineSegment (Closed (Point2 [5 % 1,15 % 1] :+ ())) (Closed (Point2 [1 % 1,11 % 1] :+ ())) LineSegment (Closed (Point2 [1 % 1,11 % 1] :+ ())) (Closed (Point2 [0 % 1,0 % 1] :+ ()))+-- Point2 [0,0] :+ V2 LineSegment (Closed (Point2 [1,11] :+ ())) (Closed (Point2 [0,0] :+ ())) LineSegment (Closed (Point2 [0,0] :+ ())) (Closed (Point2 [10,0] :+ ()))+-- Point2 [10,0] :+ V2 LineSegment (Closed (Point2 [0,0] :+ ())) (Closed (Point2 [10,0] :+ ())) LineSegment (Closed (Point2 [10,0] :+ ())) (Closed (Point2 [10,10] :+ ()))+-- Point2 [10,10] :+ V2 LineSegment (Closed (Point2 [10,0] :+ ())) (Closed (Point2 [10,10] :+ ())) LineSegment (Closed (Point2 [10,10] :+ ())) (Closed (Point2 [5,15] :+ ()))+-- Point2 [5,15] :+ V2 LineSegment (Closed (Point2 [10,10] :+ ())) (Closed (Point2 [5,15] :+ ())) LineSegment (Closed (Point2 [5,15] :+ ())) (Closed (Point2 [1,11] :+ ()))+-- Point2 [1,11] :+ V2 LineSegment (Closed (Point2 [5,15] :+ ())) (Closed (Point2 [1,11] :+ ())) LineSegment (Closed (Point2 [1,11] :+ ())) (Closed (Point2 [0,0] :+ ())) withIncidentEdges                    :: Polygon t p r                                      -> Polygon t (Two (LineSegment 2 p r)) r withIncidentEdges (SimplePolygon vs) =       SimplePolygon $ C.zip3LWith f (C.rotateL vs) vs (C.rotateR vs)   where-    f p c n = c&extra .~ SP (ClosedLineSegment p c) (ClosedLineSegment c n)+    f p c n = c&extra .~ Two (ClosedLineSegment p c) (ClosedLineSegment c n) withIncidentEdges (MultiPolygon vs hs) = MultiPolygon vs' hs'   where     (SimplePolygon vs') = withIncidentEdges $ SimplePolygon vs@@ -565,7 +568,7 @@ -- will be numbered last, in the same order. -- -- >>> numberVertices simplePoly--- SimplePolygon (CSeq [Point2 [0 % 1,0 % 1] :+ SP 0 (),Point2 [10 % 1,0 % 1] :+ SP 1 (),Point2 [10 % 1,10 % 1] :+ SP 2 (),Point2 [5 % 1,15 % 1] :+ SP 3 (),Point2 [1 % 1,11 % 1] :+ SP 4 ()])+-- SimplePolygon (CSeq [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 numberVertices = snd . bimapAccumL (\a p -> (a+1,SP a p)) (\a r -> (a,r)) 0   -- TODO: Make sure that this does not have the same issues as foldl vs foldl'
src/Data/Geometry/PrioritySearchTree.hs view
@@ -26,6 +26,8 @@ import           Data.Geometry.Point import           Data.List.NonEmpty (NonEmpty(..)) import qualified Data.List.NonEmpty as NonEmpty+import           Data.Measured.Class ()+import           Data.Measured.Size import           Data.Ord (comparing, Down(..)) import           Data.Range import qualified Data.Set as Set
+ src/Data/Geometry/QuadTree.hs view
@@ -0,0 +1,203 @@+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TypeApplications #-}+module Data.Geometry.QuadTree-- ( module Data.Geometry.QuadTree.Cell+                             -- , module Data.Geometry.QuadTree.Quadrants+                             -- , module Data.Geometry.QuadTree.Split+                             -- , QuadTree(..)+                             -- , leaves+                             -- , withCells+                             -- )+                             where+++import           Control.Lens (makeLenses, (^.), (.~), (&), (^?!), ix, view)+import           Data.Ext+import qualified Data.Foldable as F+import           Data.Geometry.Box+import           Data.Geometry.Point+import           Data.Geometry.QuadTree.Cell+import           Data.Geometry.QuadTree.Quadrants+import           Data.Geometry.QuadTree.Split+import           Data.Geometry.QuadTree.Tree (Tree(..))+import qualified Data.Geometry.QuadTree.Tree as Tree+import           Data.Geometry.Vector+import           Data.Intersection+import           Data.List.NonEmpty (NonEmpty(..))+import           Data.Tree.Util (TreeNode(..), levels)+import           GHC.Generics (Generic)+--------------------------------------------------------------------------------++-- | QuadTree on the starting cell+data QuadTree v p r = QuadTree { _startingCell  :: !(Cell r)+                               , _tree          :: !(Tree v p)+                               }+                    deriving (Show,Eq,Generic,Functor,Foldable,Traversable)+makeLenses ''QuadTree++--------------------------------------------------------------------------------+-- * Functions operating on the QuadTree (in terms of the 'Tree' type)++withCells    :: (Fractional r, Ord r) => QuadTree v p r -> QuadTree (v :+ Cell r) (p :+ Cell r) r+withCells qt = qt&tree .~ withCellsTree qt++withCellsTree                :: (Fractional r, Ord r)+                             => QuadTree v p r -> Tree (v :+ Cell r) (p :+ Cell r)+withCellsTree (QuadTree c t) = Tree.withCells c t++leaves :: QuadTree v p r -> NonEmpty p+leaves = Tree.leaves . view tree++perLevel :: QuadTree v p r -> NonEmpty (NonEmpty (TreeNode v p))+perLevel = levels . Tree.toRoseTree . view tree+++--------------------------------------------------------------------------------++-- | 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+buildOn c0 builder = QuadTree c0 . builder c0++-- | 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 f c = buildOn c (Tree.build f)++-- | Build a QuadtTree from a set of points.+--+-- pre: the points lie inside the initial given cell.+--+-- running time: \(O(nh)\), where \(n\) is the number of points and+-- \(h\) 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+fromPointsBox c = buildOn c Tree.fromPoints++fromPoints     :: (RealFrac r, Ord r)+               => NonEmpty (Point 2 r :+ p) -> QuadTree () (Maybe (Point 2 r :+ p)) r+fromPoints pts = buildOn c Tree.fromPoints (F.toList pts)+  where+    c = fitsRectangle $ boundingBoxList (view core <$> pts)++-- | Locates the cell containing the given point, if it exists.+--+-- running time: \(O(h)\), where \(h\) is the height of the quadTree+findLeaf                                       :: (Fractional r, Ord r)+                                               => Point 2 r -> QuadTree v p r -> Maybe (p :+ Cell r)+findLeaf q (QuadTree c0 t) | q `intersects` c0  = Just $ findLeaf' c0 t+                           | otherwise          = Nothing+  where+    -- |+    -- pre: p intersects c+    findLeaf' c = \case+      Leaf p    -> p :+ c+      Node _ qs -> let quad = quadrantOf q c+                   in findLeaf' ((splitCell c)^?!ix quad) (qs^?!ix quad)++--------------------------------------------------------------------------------+++fromZeros :: (Fractional r, Ord r, Num a, Eq a, v ~ Quadrants Sign)+          => Cell r -> (Point 2 r -> a) -> QuadTree v (Either v Sign) r+fromZeros = fromZerosWith (limitWidthTo (-1))+++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+fromZerosWith limit c0 f = fromZerosWith' limit c0 (fromSignum f)+++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+fromZerosWith' limit c0 f = build (limit $ shouldSplitZeros f) c0 (f <$> cellCorners c0)++++-- type Sign = Ordering++-- pattern Negative :: Sign+-- pattern Negative = LT+-- pattern Zero :: Sign+-- pattern Zero     = EQ+-- pattern Positive :: Sign+-- pattern Positive = GT+-- {-# COMPLETE Negative, Zero, Positive #-}++-- fromOrdering :: Ordering -> Sign+-- fromOrdering = id+++data Sign = Negative | Zero | Positive deriving (Show,Eq,Ord)++++-- | Interpret an ordering result as a Sign+fromOrdering :: Ordering -> Sign+fromOrdering = \case+    LT -> Negative+    EQ -> Zero+    GT -> Positive++fromSignum   :: (Num a, Eq a) => (b -> a) -> b -> Sign+fromSignum f = \x -> case signum (f x) of+                       -1 -> Negative+                       0  -> Zero+                       1  -> Positive+                       _  -> error "absurd: fromSignum"++-- | 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) -- ^ The function we are evaluating+                 -> Splitter r+                             (Quadrants sign) -- the input are the signs of the corners+                             (Quadrants sign) -- at internal nodes we store signs of corners+                             sign+shouldSplitZeros f (Cell w' p) qs@(Quadrants nw ne se sw) | all sameSign qs = No ne+                                                          | otherwise       = Yes qs qs'+  where+    m = fAt rr rr+    n = fAt rr ww+    e = fAt ww rr+    s = fAt rr 0+    w = fAt 0  rr++    sameSign = (== ne)++    -- signs at the new corners+    qs' = Quadrants (Quadrants nw n m w)+                    (Quadrants n ne e m)+                    (Quadrants m e se s)+                    (Quadrants w m s sw)++    r     = w' - 1+    rr    = pow r+    ww    = pow w'++    fAt x y = f $ p .+^ Vector2 x y+++isZeroCell   :: (Eq sign) => sign -- ^ the zero value+             -> Either v sign -> Bool+isZeroCell z = \case+    Left _  -> True -- if we kept splitting then we must have a sign transition+    Right s -> s == z++--------------------------------------------------------------------------------++++-- | Constructs an empty/complete tree from the starting width+completeTree    :: (Fractional r, Ord r) => Cell r -> QuadTree () () r+completeTree c0 =+    build (\_ w -> if w == 0 then No () else Yes () (pure $ w - 1)) c0 (c0^.cellWidthIndex)++--------------------------------------------------------------------------------
+ src/Data/Geometry/QuadTree/Cell.hs view
@@ -0,0 +1,141 @@+{-# LANGUAGE TemplateHaskell #-}+module Data.Geometry.QuadTree.Cell where++import Control.Lens (makeLenses, (^.),(&),(%~),ix, to)+import Data.Ext+import Data.Geometry.Box+import Data.Geometry.Directions+import Data.Geometry.LineSegment+import Data.Geometry.Point+import Data.Geometry.Properties+import Data.Geometry.QuadTree.Quadrants+import Data.Geometry.Vector++--------------------------------------------------------------------------------++-- | 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 { _cellWidthIndex :: {-# UNPACK #-} !WidthIndex+                   , _lowerLeft      ::                !(Point 2 r)+                   } deriving (Show,Eq,Functor,Foldable,Traversable)+makeLenses ''Cell++-- | Computes a cell that contains the given rectangle+fitsRectangle   :: (RealFrac r, Ord r) => Rectangle p r -> Cell r+fitsRectangle b = Cell w ((b^.to minPoint.core) .-^ Vector2 1 1)+  where+    w = lg' . ceiling . (1+) . maximum . size $ b++    -- "approximate log" that over approximates by a factor of at most two.+    lg'   :: Integer -> WidthIndex+    lg' n = go 1+      where+        go i | floor (pow i) <= n = go (i+1) -- note that the floor does not really do anything+                                             -- since i is integral and >= 1.+             | otherwise  = i++type instance Dimension (Cell r) = 2+type instance NumType   (Cell r) = r++type instance IntersectionOf (Point 2 r) (Cell r) = '[ NoIntersection, Point 2 r]++instance (Ord r, Fractional r) => (Point 2 r) `IsIntersectableWith` (Cell r) where+  nonEmptyIntersection = defaultNonEmptyIntersection+  p `intersect` c = p `intersect` toBox c++pow   :: Fractional r => WidthIndex -> r+pow i = case i `compare` 0 of+          LT -> 1 / (2 ^ (-1*i))+          EQ -> 1+          GT -> 2 ^ i++cellWidth            :: Fractional r => Cell r -> r+cellWidth (Cell w _) = pow w++toBox            :: Fractional r => Cell r -> Box 2 () r+toBox (Cell w p) = box (ext $ p) (ext $ p .+^ Vector2 (pow w) (pow w))++inCell            :: (Fractional r, Ord r) => Point 2 r :+ p -> Cell r -> Bool+inCell (p :+ _) c = p `inBox` toBox c++cellCorners :: Fractional r => Cell r -> Quadrants (Point 2 r)+cellCorners = fmap (^.core) . corners . toBox++-- | Sides are open+cellSides :: Fractional r => Cell r -> Sides (LineSegment 2 () r)+cellSides = fmap (\(ClosedLineSegment p q) -> OpenLineSegment p q) . sides . toBox++splitCell            :: (Num r, Fractional r) => Cell r -> Quadrants (Cell r)+splitCell (Cell w p) = Quadrants (Cell r $ f 0 rr)+                                 (Cell r $ f rr rr)+                                 (Cell r $ f rr 0)+                                 (Cell r p)+  where+    r     = w - 1+    rr    = pow r+    f x y = p .+^ Vector2 x y+++midPoint            :: Fractional r => Cell r -> Point 2 r+midPoint (Cell w p) = let rr = pow (w - 1) in p .+^ Vector2 rr rr+++--------------------------------------------------------------------------------++-- | 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]+partitionPoints c = foldMap (\p -> let q = quadrantOf (p^.core) c in mempty&ix q %~ (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.+--+-- - The northEast quadrants includes its bottom and left side+-- - The southEast quadrant  includes its            left side+-- - The northWest quadrant  includes its bottom          side+-- - The southWest quadrants does not include any of its sides.+--+--+-- >>> 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+quadrantOf q c = let m = midPoint c+                 in case (q^.xCoord < m^.xCoord, q^.yCoord < m^.yCoord) of+                      (False,False) -> NorthEast+                      (False,True)  -> SouthEast+                      (True,False)  -> NorthWest+                      (True,True)   -> SouthWest++++-- | 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))+c `relationTo` me = f <$> Sides b l t r <*> cellSides me+  where+    Sides t r b l = cellSides (c^.extra)+    f e e' | e `intersects` e' = Just c+           | otherwise         = Nothing
+ src/Data/Geometry/QuadTree/Quadrants.hs view
@@ -0,0 +1,16 @@+module Data.Geometry.QuadTree.Quadrants( pattern Quadrants+                                       , Quadrants+                                       , module Data.Geometry.Box.Corners+                                       ) where++import           Data.Geometry.Box.Corners++--------------------------------------------------------------------------------++type Quadrants = Corners++pattern Quadrants         :: a -> a -> a -> a -> Corners a+pattern Quadrants a b c d = Corners a b c d+{-# COMPLETE Quadrants #-}++--------------------------------------------------------------------------------
+ src/Data/Geometry/QuadTree/Split.hs view
@@ -0,0 +1,32 @@+{-# LANGUAGE TemplateHaskell #-}+module Data.Geometry.QuadTree.Split where++import Control.Lens (makePrisms,(^.))+import Data.Geometry.QuadTree.Cell+import Data.Geometry.QuadTree.Quadrants++--------------------------------------------------------------------------------++-- | Data Type to Decide if we should continue splitting the current cell+data Split i v p = No !p | Yes !v (Quadrants i) deriving (Show,Eq,Ord)+makePrisms ''Split++-- | 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 -- ^ smallest allowed width of a cell (i.e. width of a leaf)+                    -> Limiter r i v p+limitWidthTo wMin f = \c pts -> case f c pts of+                                  No p                                -> No (Right p)+                                  Yes v qs | wMin < c^.cellWidthIndex -> Yes v qs+                                           | otherwise                -> No (Left pts)+  -- note that it is important that we still evaluate the function so+  -- that we can distinguish at the last level i.e. between a regular+  -- " we are done splitting (No (Right p))" and a "we are no longer+  -- allowed to split further (No (Left p))"
+ src/Data/Geometry/QuadTree/Tree.hs view
@@ -0,0 +1,116 @@+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TypeApplications #-}+module Data.Geometry.QuadTree.Tree where+++import           Control.Lens (makePrisms)+import           Data.Bifoldable+import           Data.Bifunctor+import           Data.Bitraversable+import           Data.Ext+import qualified Data.Foldable as F+import           Data.Functor.Apply+import           Data.Geometry.Point+import           Data.Geometry.QuadTree.Cell+import           Data.Geometry.QuadTree.Quadrants+import           Data.Geometry.QuadTree.Split+import           Data.List.NonEmpty (NonEmpty(..))+import qualified Data.List.NonEmpty as NonEmpty+import           Data.Semigroup.Foldable.Class+import           Data.Semigroup.Traversable.Class+import qualified Data.Tree as RoseTree+import           Data.Tree.Util (TreeNode(..))++--------------------------------------------------------------------------------++-- | 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+              | Node !v (Quadrants (Tree v p)) -- quadrants are stored lazily on purpose+              deriving (Show,Eq)+makePrisms ''Tree++instance Bifunctor Tree where+  bimap = bimapDefault++instance Bifoldable Tree where+  bifoldMap = bifoldMapDefault++instance Bitraversable Tree where+  bitraverse f g = \case+    Leaf p    -> Leaf <$> g p+    Node v qs -> Node <$> f v <*> traverse (bitraverse f g) qs++instance Bifoldable1 Tree+instance Bitraversable1 Tree where+  bitraverse1 f g = \case+    Leaf p    -> Leaf <$> g p+    Node v qs -> Node <$> f v <.> traverse1 (bitraverse1 f g) qs++-- | Fold on the Tree type.+foldTree     :: (p -> b) -> (v -> Quadrants b -> b) -> Tree v p -> b+foldTree f g = go+  where+    go = \case+      Leaf p    -> f p+      Node v qs -> g v (go <$> qs)++-- | Produce a list of all leaves of a quad tree+leaves :: Tree v p -> NonEmpty p+leaves = NonEmpty.fromList . bifoldMap (const []) (:[])++-- | Converts into a RoseTree+toRoseTree :: Tree v p -> RoseTree.Tree (TreeNode v p)+toRoseTree = foldTree (\p    -> RoseTree.Node (LeafNode p)     [])+                      (\v qs -> RoseTree.Node (InternalNode v) (F.toList qs))++-- | Computes the height of the quadtree+height :: Tree v p -> Integer+height = foldTree (const 1) (\_ -> (1 +) . maximum)+++--------------------------------------------------------------------------------++--------------------------------------------------------------------------------+-- * Functions operating on the QuadTree (in temrs of the 'Tree' type)++-- | Builds a QuadTree+build             :: Fractional r+                  => Splitter r pts v p -> Cell r -> pts -> Tree v p+build shouldSplit = build'+  where+    build' cc pts = case shouldSplit cc pts of+                      No p     -> Leaf p+                      Yes v qs -> Node v $ build' <$> splitCell cc <*> qs++-- | Annotate the tree with its corresponing cells+withCells :: Fractional r => Cell r -> Tree v p -> Tree (v :+ Cell r) (p :+ Cell r)+withCells c0 = \case+  Leaf p    -> Leaf (p :+ c0)+  Node v qs -> Node (v :+ c0) (withCells <$> splitCell c0 <*> qs)+++--------------------------------------------------------------------------------+++-- | Build a QuadtTree from a set of points.+--+-- pre: the points lie inside the initial given cell.+--+-- running time: \(O(nh)\), where \(n\) is the number of points and+-- \(h\) is the height of the resulting quadTree.+fromPoints :: (Fractional r, Ord r)+           => Cell r -> [Point 2 r :+ p]+           -> Tree () (Maybe (Point 2 r :+ p))+fromPoints = build fromPointsF++-- | 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))+fromPointsF c = \case+      []   -> No Nothing+      [p]  -> No (Just p)+      pts  -> Yes () $ partitionPoints c pts+        -- (\cell -> filter (`inCell` cell) pts) <$> splitCell c
src/Data/Geometry/RangeTree.hs view
@@ -2,7 +2,6 @@ module Data.Geometry.RangeTree where  import           Control.Lens hiding (element)-import           Data.BinaryTree (Measured(..)) import           Data.Ext import qualified Data.Foldable as F import           Data.Geometry.Point@@ -11,6 +10,7 @@ import           Data.Geometry.Vector import           Data.List.NonEmpty (NonEmpty(..)) import qualified Data.List.NonEmpty as NonEmpty+import           Data.Measured.Class import           Data.Proxy import           Data.Range import           Data.Semigroup.Foldable
src/Data/Geometry/RangeTree/Generic.hs view
@@ -9,6 +9,8 @@ import           Data.List.NonEmpty (NonEmpty(..)) import qualified Data.List.NonEmpty as NonEmpty import           Data.Range+import           Data.Measured.Class+import           Data.Measured.Size import           Data.Semigroup import           Data.Semigroup.Foldable import qualified Data.Set as Set
src/Data/Geometry/RangeTree/Measure.hs view
@@ -1,6 +1,6 @@ module Data.Geometry.RangeTree.Measure where -import           Data.BinaryTree(Measured(..))+import Data.Measured.Class import Data.Functor.Product(Product(..)) import Data.Functor.Classes 
src/Data/Geometry/SegmentTree/Generic.hs view
@@ -34,6 +34,8 @@ import qualified Data.List as List import           Data.List.NonEmpty (NonEmpty) import qualified Data.List.NonEmpty as NonEmpty+import           Data.Measured.Class+import           Data.Measured.Size import           GHC.Generics (Generic)  --------------------------------------------------------------------------------@@ -73,7 +75,7 @@ --                         AtomicRange -> OpenRange   MinInfinity MaxInfinity  -data BuildLeaf a = LeafSingleton a | LeafRange a a deriving (Show,Eq)+data BuildLeaf a = LeafSingleton !a | LeafRange !a !a deriving (Show,Eq)  -- | Given a sorted list of endpoints, without duplicates, construct a segment tree --@@ -118,7 +120,7 @@                    -> NonEmpty (Interval p r) -> SegmentTree v r fromIntervals f is = foldr (insert . f) (createTree pts mempty) is   where-    endPoints (toRange -> Range' a b) = [a,b]+    endPoints (asRange -> Range' a b) = [a,b]     pts = nub' . NonEmpty.sort . NonEmpty.fromList . concatMap endPoints $ is     nub' = fmap NonEmpty.head . NonEmpty.group1 @@ -186,7 +188,7 @@                          => i -> SegmentTree v r -> SegmentTree v r insert i (SegmentTree t) = SegmentTree $ insertRoot t   where-    ri@(Range a b) = toRange i+    ri@(Range a b) = asRange i     insertRoot t' = maybe t' (flip insert' t') $ getRange t'      insert' inR         lf@(Leaf nd@(LeafData rr _))@@ -209,7 +211,7 @@           => i -> SegmentTree v r -> SegmentTree v r delete i (SegmentTree t) = SegmentTree $ delete' t   where-    (Range _ b) = toRange i+    (Range _ b) = asRange i      delete' (Leaf ld) = Leaf $ ld&leafAssoc %~ deleteAssoc i     delete' (Node l nd@(_splitPoint -> m) r)@@ -254,7 +256,7 @@   instance IntervalLike a => IntervalLike (I a) where-  toRange = toRange . _unI+  asRange = asRange . _unI   fromIntervals' :: (Eq p, Ord r)
src/Data/Geometry/SubLine.hs view
@@ -136,7 +136,7 @@       :& RNil     where       s'  = (fixEndPoints sm)^.subRange-      s'' = bimap (^.extra) id+      s'' = asProperInterval . first (^.extra)           $ s'&start.core .~ toOffset' (s'^.start.extra.core) l               &end.core   .~ toOffset' (s'^.end.extra.core)   l 
src/Data/Geometry/Transformation.hs view
@@ -1,69 +1,37 @@+{-# LANGUAGE Unsafe #-} {-# LANGUAGE UndecidableInstances #-} module Data.Geometry.Transformation where -import           Control.Lens (lens,Lens',set)-import           Unsafe.Coerce(unsafeCoerce)+import           Control.Lens (iso,set,Iso,imap)+import           Data.Geometry.Matrix+import           Data.Geometry.Matrix.Internal (mkRow) import           Data.Geometry.Point import           Data.Geometry.Properties import           Data.Geometry.Vector import qualified Data.Geometry.Vector as V import           Data.Proxy-import qualified Data.Vector.Fixed as FV import           GHC.TypeLits-import           Linear.Matrix ((!*),(!*!))-import qualified Linear.Matrix as Lin ------------------------------------------------------------------------------------ * Matrices --- | 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))--deriving instance (Show r, Arity n, Arity m) => Show (Matrix n m r)-deriving instance (Eq r, Arity n, Arity m)   => Eq (Matrix n m r)-deriving instance (Ord r, Arity n, Arity m)  => Ord (Matrix n m r)-deriving instance (Arity n, Arity m)         => Functor (Matrix n m)--multM :: (Arity r, Arity c, Arity c', Num a) => Matrix r c a -> Matrix c c' a -> Matrix r c' a-(Matrix a) `multM` (Matrix b) = Matrix $ a !*! b--mult :: (Arity m, Arity n, Num r) => Matrix n m r -> Vector m r -> Vector n r-(Matrix m) `mult` v = m !* v---class Invertible n r where-  inverse' :: Matrix n n r -> Matrix n n r--instance Fractional r => Invertible 2 r where-  -- >>> inverse' $ Matrix $ Vector2 (Vector2 1 2) (Vector2 3 4.0)-  -- Matrix Vector2 [Vector2 [-2.0,1.0],Vector2 [1.5,-0.5]]-  inverse' (Matrix m) = Matrix . unsafeCoerce . Lin.inv22 . unsafeCoerce $ m--instance Fractional r => Invertible 3 r where-  -- >>> inverse' $ Matrix $ Vector3 (Vector3 1 2 4) (Vector3 4 2 2) (Vector3 1 1 1.0)-  -- Matrix Vector3 [Vector3 [0.0,0.5,-1.0],Vector3 [-0.5,-0.75,3.5],Vector3 [0.5,0.25,-1.5]]-  inverse' (Matrix m) = Matrix . unsafeCoerce . Lin.inv33 . unsafeCoerce $ m--instance Fractional r => Invertible 4 r where-  inverse' (Matrix m) = Matrix . unsafeCoerce . Lin.inv44 . unsafeCoerce $ m- -------------------------------------------------------------------------------- -- * Transformations  -- | A type representing a Transformation for d dimensional objects newtype Transformation d r = Transformation { _transformationMatrix :: Matrix (d + 1) (d + 1) r } -transformationMatrix :: Lens' (Transformation d r) (Matrix (d + 1) (d + 1) r)-transformationMatrix = lens _transformationMatrix (const Transformation)+transformationMatrix :: Iso (Transformation d r)       (Transformation d       s)+                            (Matrix (d + 1) (d + 1) r) (Matrix (d + 1) (d + 1) s)+transformationMatrix = iso _transformationMatrix Transformation  deriving instance (Show r, Arity (d + 1)) => Show (Transformation d r) deriving instance (Eq r, Arity (d + 1))   => Eq (Transformation d r) deriving instance (Ord r, Arity (d + 1))  => Ord (Transformation d r) deriving instance Arity (d + 1)           => Functor (Transformation d)+deriving instance Arity (d + 1)           => Foldable (Transformation d)+deriving instance Arity (d + 1)           => Traversable (Transformation d)  type instance NumType (Transformation d r) = r - -- | Compose transformations (right to left) (|.|) :: (Num r, Arity (d + 1)) => Transformation d r -> Transformation d r -> Transformation d r (Transformation f) |.| (Transformation g) = Transformation $ f `multM` g@@ -112,16 +80,17 @@  translation   :: (Num r, Arity d, Arity (d + 1))               => Vector d r -> Transformation d r-translation v = Transformation . Matrix $ V.imap transRow (snoc v 1)+translation v = Transformation . Matrix $ imap transRow (snoc v 1)   scaling   :: (Num r, Arity d, Arity (d + 1))           => Vector d r -> Transformation d r-scaling v = Transformation . Matrix $ V.imap mkRow (snoc v 1)+scaling v = Transformation . Matrix $ imap mkRow (snoc v 1)  uniformScaling :: (Num r, Arity d, Arity (d + 1)) => r -> Transformation d r uniformScaling = scaling . pure + -------------------------------------------------------------------------------- -- * Functions that execute transformations @@ -142,14 +111,6 @@ scaleUniformlyBy = transformBy  . uniformScaling  ------------------------------------------------------------------------------------ * Helper functions to easily create matrices---- | Creates a row with zeroes everywhere, except at position i, where the--- value is the supplied value.-mkRow     :: forall d r. (Arity d, Num r) => Int -> r -> Vector d r-mkRow i x = set (FV.element i) x zero- -- | Row in a translation matrix -- transRow     :: forall n r. ( Arity n, Arity (n- 1), ((n - 1) + 1) ~ n --                             , Num r) => Int -> r -> Vector n r@@ -171,3 +132,13 @@                                                              (snoc v        0)                                                              (snoc w        0)                                                              (Vector4 0 0 0 1)++--------------------------------------------------------------------------------+-- * 2D Transformations++-- | Skew transformation that keeps the y-coordinates fixed and shifts+-- the x coordinates.+skewX        :: Num r => r -> Transformation 2 r+skewX lambda = Transformation . Matrix $ Vector3 (Vector3 1 lambda 0)+                                                 (Vector3 0 1      0)+                                                 (Vector3 0 0      1)
src/Data/Geometry/Triangle.hs view
@@ -3,8 +3,11 @@ {-# LANGUAGE UndecidableInstances #-} module Data.Geometry.Triangle where +import           Control.DeepSeq import           Control.Lens+import           Data.Bifoldable import           Data.Bifunctor+import           Data.Bitraversable import           Data.Either (partitionEithers) import           Data.Ext import           Data.Geometry.Ball (Disk, disk)@@ -19,28 +22,48 @@ import qualified Data.Geometry.Vector as V import qualified Data.List as List import           Data.Maybe (mapMaybe)+import           Data.Util import           Data.Vinyl import           Data.Vinyl.CoRec+import           GHC.Generics (Generic) import           GHC.TypeLits - --------------------------------------------------------------------------------  -- | Triangles in \(d\)-dimensional space.-data Triangle d p r = Triangle (Point d r :+ p)-                               (Point d r :+ p)-                               (Point d r :+ p)+data Triangle d p r = Triangle !(Point d r :+ p)+                               !(Point d r :+ p)+                               !(Point d r :+ p)+                      deriving (Generic) -deriving instance (Arity d, Show r, Show p) => Show (Triangle d p r)-deriving instance (Arity d, Read r, Read p) => Read (Triangle d p r)-deriving instance (Arity d, Eq r, Eq p)     => Eq (Triangle d p r)+deriving instance (Arity d, Show r, Show p)     => Show   (Triangle d p r)+deriving instance (Arity d, Read r, Read p)     => Read   (Triangle d p r)+deriving instance (Arity d, Eq r, Eq p)         => Eq     (Triangle d p r) -instance Arity d => Functor (Triangle d p) where-  fmap f (Triangle p q r) = let f' = first (fmap f) in Triangle (f' p) (f' q) (f' r)+instance (Arity d, NFData r, NFData p) => NFData (Triangle d p r) +instance Arity d => Bifunctor  (Triangle d) where bimap = bimapDefault+instance Arity d => Bifoldable (Triangle d) where bifoldMap = bifoldMapDefault +instance Arity d => Bitraversable (Triangle d) where+  bitraverse f g (Triangle p q r) = let tr = bitraverse (traverse g) f in+    Triangle <$> tr p <*> tr q <*> tr r++-- instance Arity d => Functor (Triangle d p) where+--   fmap f (Triangle p q r) = let f' = first (fmap f) in Triangle (f' p) (f' q) (f' r)++instance Field1 (Triangle d p r) (Triangle d p r) (Point d r :+ p) (Point d r :+ p) where+  _1 = lens (\(Triangle p _ _) -> p) (\(Triangle _ q r) p -> Triangle p q r)+instance Field2 (Triangle d p r) (Triangle d p r) (Point d r :+ p) (Point d r :+ p) where+  _2 = lens (\(Triangle _ q _) -> q) (\(Triangle p _ r) q -> Triangle p q r)+instance Field3 (Triangle d p r) (Triangle d p r) (Point d r :+ p) (Point d r :+ p) where+  _3 = lens (\(Triangle _ _ r) -> r) (\(Triangle p q _) r -> Triangle p q r)+ type instance NumType   (Triangle d p r) = r type instance Dimension (Triangle d p r) = d++_TriangleThreePoints :: Iso' (Triangle d p r) (Three (Point d r :+ p))+_TriangleThreePoints = iso (\(Triangle p q r) -> Three p q r) (\(Three p q r) -> Triangle p q r)  instance PointFunctor (Triangle d p) where   pmap f (Triangle p q r) = Triangle (p&core %~ f) (q&core %~ f) (r&core %~ f)
src/Data/Geometry/Vector.hs view
@@ -14,29 +14,29 @@                            , module LV                            , C(..)                            , Affine(..)-                           , qdA, distanceA+                           , quadrance, qdA, distanceA                            , dot, norm, signorm                            , isScalarMultipleOf                            , scalarMultiple                            -- reexports                            , FV.replicate-                           , FV.imap                            , xComponent, yComponent, zComponent                            ) where  import           Control.Applicative (liftA2)-import           Control.Lens(Lens')+import           Control.Lens (Lens')+import           Control.Monad.State import qualified Data.Foldable as F import           Data.Geometry.Properties import           Data.Geometry.Vector.VectorFamily import           Data.Geometry.Vector.VectorFixed (C(..))-import           Data.Maybe import qualified Data.Vector.Fixed as FV import           GHC.TypeLits import           Linear.Affine (Affine(..), qdA, distanceA)-import           Linear.Metric (dot,norm,signorm)-import           Linear.Vector as LV-import           Test.QuickCheck+import           Linear.Metric (dot,norm,signorm,quadrance)+import           Linear.Vector as LV hiding (E(..))+import           System.Random (Random(..))+import           Test.QuickCheck (Arbitrary(..),infiniteList)  -------------------------------------------------------------------------------- @@ -46,13 +46,21 @@ instance (Arbitrary r, Arity d) => Arbitrary (Vector d r) where   arbitrary = vectorFromListUnsafe <$> infiniteList +instance (Random r, Arity d) => Random (Vector d r) where+  randomR (lows,highs) g0 = flip runState g0 $+                            FV.zipWithM (\l h -> state $ randomR (l,h)) lows highs+  random g0 = flip runState g0 $ FV.replicateM (state random)  -- | '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@@ -63,11 +71,20 @@ -- 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-u `isScalarMultipleOf` v = isJust $ scalarMultiple u v+u `isScalarMultipleOf` v = let d = u `dot` v+                               num = quadrance u * quadrance v+                           in num == 0 || 1 == d*d / num+-- u `isScalarMultipleOf` v = isJust $ scalarMultiple u v {-# SPECIALIZE     isScalarMultipleOf :: (Eq r, Fractional r) => Vector 2 r -> Vector 2 r -> Bool  #-}+{-# SPECIALIZE+    isScalarMultipleOf :: (Eq r, Fractional r) => Vector 3 r -> Vector 3 r -> Bool  #-}  -- | scalarMultiple u v computes the scalar labmda s.t. v = lambda * u (if it exists) scalarMultiple     :: (Eq r, Fractional r, Arity d)
src/Data/Geometry/Vector/VectorFamily.hs view
@@ -39,6 +39,7 @@ import           Text.ParserCombinators.ReadPrec (lift) import           Text.Read (Read(..),readListPrecDefault, readPrec_to_P,minPrec) import           Data.Proxy+import           Data.Hashable  -------------------------------------------------------------------------------- -- * d dimensional Vectors@@ -59,8 +60,11 @@ unV = lens _unV (const MKVector) {-# INLINE unV #-} -type Arity d = (ImplicitArity (Peano d), KnownNat d)+-- type Arity d = (ImplicitArity (Peano d), KnownNat d)+class (ImplicitArity (Peano d), KnownNat d) => Arity d+instance (ImplicitArity (Peano d), KnownNat d) => Arity d + deriving instance (Eq r,  Arity d) => Eq  (Vector d r) deriving instance (Ord r, Arity d) => Ord (Vector d r) @@ -69,6 +73,15 @@ deriving instance Arity d => Traversable (Vector d) deriving instance Arity d => Applicative (Vector d) +++instance Arity d => FunctorWithIndex     Int (Vector d) where+  imap = V.imap+instance Arity d => FoldableWithIndex    Int (Vector d)+instance Arity d => TraversableWithIndex Int (Vector d) where+  itraverse = V.imapM++ deriving instance Arity d => Additive (Vector d) deriving instance Arity d => Metric (Vector d) instance Arity d => Affine (Vector d) where@@ -76,6 +89,8 @@   u .-. v = u ^-^ v   p .+^ v = p ^+^ v +deriving instance (Arity d, Hashable r) => Hashable (Vector d r)+ instance Arity d => Ixed (Vector d r) where   ix = element' @@ -167,6 +182,9 @@  -------------------------------------------------------------------------------- -- * Snoccing and consindg++cons   :: (Arity d, Arity (d+1)) => r -> Vector d r -> Vector (d + 1) r+cons x = vectorFromListUnsafe . (x:) . F.toList  -- | Add an element at the back of the vector snoc     :: (Arity (d + 1), Arity d) => Vector d r -> r -> Vector (d + 1) r
src/Data/Geometry/Vector/VectorFamilyPeano.hs view
@@ -5,7 +5,7 @@ import           Control.Applicative (liftA2) import           Control.DeepSeq import           Control.Lens hiding (element)-import           Data.Aeson(FromJSON(..),ToJSON(..))+import           Data.Aeson (FromJSON(..),ToJSON(..)) -- import           Data.Aeson (ToJSON(..),FromJSON(..)) import qualified Data.Foldable as F import qualified Data.Geometry.Vector.VectorFixed as FV@@ -19,6 +19,7 @@ import qualified Linear.V3 as L3 import qualified Linear.V4 as L4 import           Linear.Vector+import           Data.Hashable  -------------------------------------------------------------------------------- -- * Natural number stuff@@ -77,7 +78,9 @@ unVF = lens _unVF (const VectorFamily) {-# INLINE unVF #-} -type ImplicitArity d = (ImplicitPeano d, V.Arity (FromPeano d))+-- type ImplicitArity d = (ImplicitPeano d, V.Arity (FromPeano d))+class (ImplicitPeano d, V.Arity (FromPeano d)) => ImplicitArity d+instance (ImplicitPeano d, V.Arity (FromPeano d)) => ImplicitArity d  instance (Eq r, ImplicitArity d) => Eq (VectorFamily d r) where   (VectorFamily u) == (VectorFamily v) = case (implicitPeano :: SingPeano d) of@@ -187,6 +190,17 @@                            (SS (SS (SS (SS SZ))))     -> rnf v                            (SS (SS (SS (SS (SS _))))) -> rnf v   {-# INLINE rnf #-}+++instance (ImplicitPeano d, Hashable r) => Hashable (VectorFamily d r) where+  hashWithSalt = case (implicitPeano :: SingPeano d) of+                   SZ                         -> hashWithSalt+                   (SS SZ)                    -> hashWithSalt+                   (SS (SS SZ))               -> hashWithSalt+                   (SS (SS (SS SZ)))          -> hashWithSalt+                   (SS (SS (SS (SS SZ))))     -> hashWithSalt+                   (SS (SS (SS (SS (SS _))))) -> hashWithSalt+  instance ImplicitArity d => Ixed (VectorFamily d r) where   ix = element'
src/Data/PlaneGraph/Core.hs view
@@ -13,7 +13,8 @@ -- embedding. -- ---------------------------------------------------------------------------------module Data.PlaneGraph.Core( PlaneGraph(PlaneGraph), graph+module Data.PlaneGraph.Core( -- $setup+                             PlaneGraph(PlaneGraph), graph                            , PlanarGraph                            , VertexData(VertexData), vData, location, vtxDataToExt                            , fromSimplePolygon, fromConnectedSegments@@ -87,7 +88,6 @@  -------------------------------------------------------------------------------- - -- $setup -- >>> import Data.Proxy -- >>> import Data.PlaneGraph.AdjRep(Gr(Gr),Face(Face),Vtx(Vtx))@@ -390,17 +390,26 @@ incidentEdges   :: VertexId' s -> PlaneGraph s v e f r -> V.Vector (Dart s) incidentEdges v = PG.incidentEdges v . _graph --- | All incoming edges incident to vertex v, in counterclockwise order around v.++-- | All edges incident to vertex v in incoming direction+-- (i.e. pointing into v) in counterclockwise order around v. --+-- running time: \(O(k)\), where \(k) is the total number of incident edges of v+-- -- >>> incomingEdges (VertexId 1) smallG--- [Dart (Arc 1) -1]+-- [Dart (Arc 1) +1,Dart (Arc 4) -1,Dart (Arc 3) -1] incomingEdges   :: VertexId' s -> PlaneGraph s v e f r -> V.Vector (Dart s) incomingEdges v = PG.incomingEdges v . _graph --- | All outgoing edges incident to vertex v, in counterclockwise order around v.+++-- | All edges incident to vertex v in incoming direction+-- (i.e. pointing into v) in counterclockwise order around v. --+-- running time: \(O(k)\), where \(k) is the total number of incident edges of v+-- -- >>> outgoingEdges (VertexId 1) smallG--- [Dart (Arc 4) +1,Dart (Arc 3) +1]+-- [Dart (Arc 1) -1,Dart (Arc 4) +1,Dart (Arc 3) +1] outgoingEdges   :: VertexId' s -> PlaneGraph s v e f r  -> V.Vector (Dart s) outgoingEdges v = PG.outgoingEdges v . _graph 
src/Graphics/Camera.hs view
@@ -22,9 +22,10 @@                       ) where  import Control.Lens+import Data.Geometry.Matrix import Data.Geometry.Point-import Data.Geometry.Vector import Data.Geometry.Transformation+import Data.Geometry.Vector  -------------------------------------------------------------------------------- 
test/Data/Geometry/arrangement.ipe.out.ipe view
@@ -133,7 +133,7 @@ <textstyle name="center" begin="\begin{center}" end="\end{center}"/> <textstyle name="itemize" begin="\begin{itemize}" end="\end{itemize}"/> <textstyle name="item" begin="\begin{itemize}\item{}" end="\end{itemize}"/>-</ipestyle><page><group><use pos="172.658536585365 637.048780487804" name="mark/disk(sx)"/><use pos="172.658536585365 637.215447154471" name="mark/disk(sx)"/><use pos="172.658536585365 637.898780487804" name="mark/disk(sx)"/><use pos="172.658536585365 746.000060937506" name="mark/disk(sx)"/><use pos="173.658536585365 638.048780487804" name="mark/disk(sx)"/><use pos="195.199902499989 746.000060937506" name="mark/disk(sx)"/><use pos="252.176396921200 637.048780487804" name="mark/disk(sx)"/><use pos="256.914285714285 707.428571428571" name="mark/disk(sx)"/><use pos="258.512437254286 650.776865588142" name="mark/disk(sx)"/><use pos="278.447793072843 693.970129329472" name="mark/disk(sx)"/><use pos="302.000073125007 745.000060937506" name="mark/disk(sx)"/><use pos="302.461611663469 746.000060937506" name="mark/disk(sx)"/><use pos="303.200073125007 746.000060937506" name="mark/disk(sx)"/><use pos="330.322580645161 661.548387096774" name="mark/disk(sx)"/><use pos="331.322580645161 637.048780487804" name="mark/disk(sx)"/><use pos="331.322580645161 660.923387096774" name="mark/disk(sx)"/><use pos="331.322580645161 661.698387096774" name="mark/disk(sx)"/><use pos="331.322580645161 746.000060937506" name="mark/disk(sx)"/><path>172.658536585365 637.215447154471 m+</ipestyle><page><layer name="alpha"/><view layers="alpha" active="alpha"/><group><use pos="172.658536585365 637.048780487804" name="mark/disk(sx)"/><use pos="172.658536585365 637.215447154471" name="mark/disk(sx)"/><use pos="172.658536585365 637.898780487804" name="mark/disk(sx)"/><use pos="172.658536585365 746.000060937506" name="mark/disk(sx)"/><use pos="173.658536585365 638.048780487804" name="mark/disk(sx)"/><use pos="195.199902499989 746.000060937506" name="mark/disk(sx)"/><use pos="252.176396921200 637.048780487804" name="mark/disk(sx)"/><use pos="256.914285714285 707.428571428571" name="mark/disk(sx)"/><use pos="258.512437254286 650.776865588142" name="mark/disk(sx)"/><use pos="278.447793072843 693.970129329472" name="mark/disk(sx)"/><use pos="302.000073125007 745.000060937506" name="mark/disk(sx)"/><use pos="302.461611663469 746.000060937506" name="mark/disk(sx)"/><use pos="303.200073125007 746.000060937506" name="mark/disk(sx)"/><use pos="330.322580645161 661.548387096774" name="mark/disk(sx)"/><use pos="331.322580645161 637.048780487804" name="mark/disk(sx)"/><use pos="331.322580645161 660.923387096774" name="mark/disk(sx)"/><use pos="331.322580645161 661.698387096774" name="mark/disk(sx)"/><use pos="331.322580645161 746.000060937506" name="mark/disk(sx)"/><path>172.658536585365 637.215447154471 m 173.658536585365 638.048780487804 l </path><path>173.658536585365 638.048780487804 m 256.914285714285 707.428571428571 l