packages feed

hgeometry 0.6.0.0 → 0.7.0.0

raw patch · 116 files changed

+8425/−1073 lines, 116 filesdep +aesondep +approximate-equalitydep +cairodep −Framesdep ~QuickCheckdep ~basedep ~bytestringnew-component:exe:hgeometry-viewerPVP ok

version bump matches the API change (PVP)

Dependencies added: aeson, approximate-equality, cairo, cairo-canvas, colour, dlist, fingertree, gi-cairo, gi-gdk, gi-gtk, haskell-gi-base, quickcheck-instances, reactive-banana, reactive-banana-gi-gtk, reflection, transformers, yaml

Dependencies removed: Frames

Dependency ranges changed: QuickCheck, base, bytestring, containers, criterion, fixed-vector, hexpat, lens, linear, optparse-applicative, semigroupoids, semigroups, singletons, text, vector, vinyl

API changes (from Hackage documentation)

- Algorithms.Geometry.ConvexHull.DivideAndConqueror: instance (GHC.Num.Num r, GHC.Classes.Ord r) => Data.Semigroup.Semigroup (Algorithms.Geometry.ConvexHull.DivideAndConqueror.Merge r p)
- Algorithms.Geometry.DelaunayTriangulation.Types: instance (GHC.Classes.Eq p, GHC.Classes.Eq r) => GHC.Classes.Eq (Algorithms.Geometry.DelaunayTriangulation.Types.Triangulation p r)
- Algorithms.Geometry.DelaunayTriangulation.Types: instance (GHC.Show.Show p, GHC.Show.Show r) => GHC.Show.Show (Algorithms.Geometry.DelaunayTriangulation.Types.Triangulation p r)
- Algorithms.Geometry.LineSegmentIntersection.BentleyOttmann: instance (GHC.Show.Show p, GHC.Show.Show r) => GHC.Show.Show (Algorithms.Geometry.LineSegmentIntersection.BentleyOttmann.Event p r)
- Algorithms.Geometry.LineSegmentIntersection.BentleyOttmann: ordAtNav :: (Ord r, Fractional r) => r -> TreeNavigator r (LineSegment 2 p r)
- Algorithms.Geometry.LineSegmentIntersection.Types: instance (GHC.Classes.Eq p, GHC.Classes.Eq r) => GHC.Classes.Eq (Algorithms.Geometry.LineSegmentIntersection.Types.IntersectionPoint p r)
- Algorithms.Geometry.LineSegmentIntersection.Types: instance (GHC.Show.Show p, GHC.Show.Show r) => GHC.Show.Show (Algorithms.Geometry.LineSegmentIntersection.Types.Associated p r)
- Algorithms.Geometry.LineSegmentIntersection.Types: instance (GHC.Show.Show p, GHC.Show.Show r) => GHC.Show.Show (Algorithms.Geometry.LineSegmentIntersection.Types.IntersectionPoint p r)
- Algorithms.Geometry.LineSegmentIntersection.Types: instance GHC.Classes.Ord r => Data.Semigroup.Semigroup (Algorithms.Geometry.LineSegmentIntersection.Types.Associated p r)
- Algorithms.Geometry.WellSeparatedPairDecomposition.Types: instance (Data.Geometry.Vector.VectorFixed.Arity d, GHC.Classes.Eq r, GHC.Classes.Eq a) => GHC.Classes.Eq (Algorithms.Geometry.WellSeparatedPairDecomposition.Types.NodeData d r a)
- Algorithms.Geometry.WellSeparatedPairDecomposition.Types: instance (Data.Geometry.Vector.VectorFixed.Arity d, GHC.Classes.Eq r, GHC.Classes.Eq p) => GHC.Classes.Eq (Algorithms.Geometry.WellSeparatedPairDecomposition.Types.FindAndCompact d r p)
- Algorithms.Geometry.WellSeparatedPairDecomposition.Types: instance (Data.Geometry.Vector.VectorFixed.Arity d, GHC.Show.Show r, GHC.Show.Show a) => GHC.Show.Show (Algorithms.Geometry.WellSeparatedPairDecomposition.Types.NodeData d r a)
- Algorithms.Geometry.WellSeparatedPairDecomposition.Types: instance (Data.Geometry.Vector.VectorFixed.Arity d, GHC.Show.Show r, GHC.Show.Show p) => GHC.Show.Show (Algorithms.Geometry.WellSeparatedPairDecomposition.Types.FindAndCompact d r p)
- Algorithms.Geometry.WellSeparatedPairDecomposition.Types: instance Data.Semigroup.Semigroup v => Data.BinaryTree.Measured v (Algorithms.Geometry.WellSeparatedPairDecomposition.Types.NodeData d r v)
- Algorithms.Geometry.WellSeparatedPairDecomposition.WSPD: type AlwaysTrueWSPD d = (Arity d, KnownNat d, AlwaysTruePFT d, AlwaysTrueTransformation d)
- Algorithms.Util: instance (GHC.Classes.Eq b, GHC.Classes.Eq a) => GHC.Classes.Eq (Algorithms.Util.SP a b)
- Algorithms.Util: instance (GHC.Classes.Eq c, GHC.Classes.Eq b, GHC.Classes.Eq a) => GHC.Classes.Eq (Algorithms.Util.ST a b c)
- Algorithms.Util: instance (GHC.Classes.Ord b, GHC.Classes.Ord a) => GHC.Classes.Ord (Algorithms.Util.SP a b)
- Algorithms.Util: instance (GHC.Classes.Ord c, GHC.Classes.Ord b, GHC.Classes.Ord a) => GHC.Classes.Ord (Algorithms.Util.ST a b c)
- Algorithms.Util: instance (GHC.Show.Show b, GHC.Show.Show a) => GHC.Show.Show (Algorithms.Util.SP a b)
- Algorithms.Util: instance (GHC.Show.Show c, GHC.Show.Show b, GHC.Show.Show a) => GHC.Show.Show (Algorithms.Util.ST a b c)
- Data.BalBST: instance (GHC.Classes.Eq a, GHC.Classes.Eq k) => GHC.Classes.Eq (Data.BalBST.T k a)
- Data.BalBST: instance (GHC.Classes.Eq b, GHC.Classes.Eq a) => GHC.Classes.Eq (Data.BalBST.Pair a b)
- Data.BalBST: instance (GHC.Classes.Eq b, GHC.Classes.Eq a) => GHC.Classes.Eq (Data.BalBST.Split a b)
- Data.BalBST: instance (GHC.Classes.Eq k, GHC.Classes.Eq a) => GHC.Classes.Eq (Data.BalBST.Tree k a)
- Data.BalBST: instance (GHC.Classes.Ord a, GHC.Classes.Ord k) => GHC.Classes.Ord (Data.BalBST.T k a)
- Data.BalBST: instance (GHC.Show.Show a, GHC.Show.Show k) => GHC.Show.Show (Data.BalBST.T k a)
- Data.BalBST: instance (GHC.Show.Show b, GHC.Show.Show a) => GHC.Show.Show (Data.BalBST.Pair a b)
- Data.BalBST: instance (GHC.Show.Show b, GHC.Show.Show a) => GHC.Show.Show (Data.BalBST.Split a b)
- Data.BalBST: instance (GHC.Show.Show k, GHC.Show.Show a) => GHC.Show.Show (Data.BalBST.Tree k a)
- Data.BinaryTree: instance (GHC.Classes.Eq a, GHC.Classes.Eq v) => GHC.Classes.Eq (Data.BinaryTree.RoseElem v a)
- Data.BinaryTree: instance (GHC.Classes.Eq v, GHC.Classes.Eq a) => GHC.Classes.Eq (Data.BinaryTree.BinLeafTree v a)
- Data.BinaryTree: instance (GHC.Classes.Ord v, GHC.Classes.Ord a) => GHC.Classes.Ord (Data.BinaryTree.BinLeafTree v a)
- Data.BinaryTree: instance (GHC.Read.Read v, GHC.Read.Read a) => GHC.Read.Read (Data.BinaryTree.BinLeafTree v a)
- Data.BinaryTree: instance (GHC.Show.Show a, GHC.Show.Show v) => GHC.Show.Show (Data.BinaryTree.RoseElem v a)
- Data.BinaryTree: instance (GHC.Show.Show v, GHC.Show.Show a) => GHC.Show.Show (Data.BinaryTree.BinLeafTree v a)
- Data.BinaryTree: instance Data.BinaryTree.Measured v a => Data.Semigroup.Semigroup (Data.BinaryTree.BinLeafTree v a)
- Data.BinaryTree: instance Data.Semigroup.Semigroup Data.BinaryTree.Size
- Data.BinaryTree: instance Data.Semigroup.Semigroup a => Data.Semigroup.Semigroup (Data.BinaryTree.Sized a)
- Data.Ext: data (:+) core extra
- Data.Ext: instance (Control.DeepSeq.NFData extra, Control.DeepSeq.NFData core) => Control.DeepSeq.NFData (core Data.Ext.:+ extra)
- Data.Ext: instance (Data.Semigroup.Semigroup core, Data.Semigroup.Semigroup extra) => Data.Semigroup.Semigroup (core Data.Ext.:+ extra)
- Data.Ext: instance (GHC.Classes.Eq extra, GHC.Classes.Eq core) => GHC.Classes.Eq (core Data.Ext.:+ extra)
- Data.Ext: instance (GHC.Classes.Ord extra, GHC.Classes.Ord core) => GHC.Classes.Ord (core Data.Ext.:+ extra)
- Data.Ext: instance (GHC.Enum.Bounded extra, GHC.Enum.Bounded core) => GHC.Enum.Bounded (core Data.Ext.:+ extra)
- Data.Ext: instance (GHC.Read.Read extra, GHC.Read.Read core) => GHC.Read.Read (core Data.Ext.:+ extra)
- Data.Ext: instance (GHC.Show.Show extra, GHC.Show.Show core) => GHC.Show.Show (core Data.Ext.:+ extra)
- Data.Geometry.Ball: instance (GHC.Classes.Eq r, GHC.Classes.Eq p, Data.Geometry.Vector.VectorFixed.Arity d) => GHC.Classes.Eq (Data.Geometry.Ball.Ball d p r)
- Data.Geometry.Ball: instance (GHC.Show.Show r, GHC.Show.Show p, Data.Geometry.Vector.VectorFixed.Arity d) => GHC.Show.Show (Data.Geometry.Ball.Ball d p r)
- Data.Geometry.Ball: instance Data.Geometry.Vector.VectorFixed.Arity d => Data.Bifunctor.Bifunctor (Data.Geometry.Ball.Ball d)
- Data.Geometry.Ball: instance Data.Geometry.Vector.VectorFixed.Arity d => GHC.Base.Functor (Data.Geometry.Ball.Ball d p)
- Data.Geometry.Box: instance (Control.DeepSeq.NFData p, Control.DeepSeq.NFData r, Data.Geometry.Vector.VectorFixed.Arity d) => Control.DeepSeq.NFData (Data.Geometry.Box.Internal.Box d p r)
- Data.Geometry.Box.Internal: instance (Data.Geometry.Vector.VectorFixed.Arity d, GHC.Classes.Ord r) => Data.Geometry.Properties.IsIntersectableWith (Data.Geometry.Point.Point d r) (Data.Geometry.Box.Internal.Box d p r)
- Data.Geometry.Box.Internal: instance (Data.Geometry.Vector.VectorFixed.Arity d, GHC.Classes.Ord r) => Data.Semigroup.Semigroup (Data.Geometry.Box.Internal.CWMax (Data.Geometry.Point.Point d r))
- Data.Geometry.Box.Internal: instance (Data.Geometry.Vector.VectorFixed.Arity d, GHC.Classes.Ord r) => Data.Semigroup.Semigroup (Data.Geometry.Box.Internal.CWMin (Data.Geometry.Point.Point d r))
- Data.Geometry.Box.Internal: instance (Data.Geometry.Vector.VectorFixed.Arity d, GHC.Classes.Ord r, Data.Semigroup.Semigroup p) => Data.Semigroup.Semigroup (Data.Geometry.Box.Internal.Box d p r)
- Data.Geometry.Box.Internal: instance (GHC.Classes.Eq r, GHC.Classes.Eq p, Data.Geometry.Vector.VectorFixed.Arity d) => GHC.Classes.Eq (Data.Geometry.Box.Internal.Box d p r)
- Data.Geometry.Box.Internal: instance (GHC.Classes.Ord r, Data.Geometry.Vector.VectorFixed.Arity d) => Data.Geometry.Properties.IsIntersectableWith (Data.Geometry.Box.Internal.Box d p r) (Data.Geometry.Box.Internal.Box d q r)
- Data.Geometry.Box.Internal: instance (GHC.Classes.Ord r, GHC.Classes.Ord p, Data.Geometry.Vector.VectorFixed.Arity d) => GHC.Classes.Ord (Data.Geometry.Box.Internal.Box d p r)
- Data.Geometry.Box.Internal: instance (GHC.Num.Num r, Data.Geometry.Transformation.AlwaysTruePFT d) => Data.Geometry.Transformation.IsTransformable (Data.Geometry.Box.Internal.Box d p r)
- Data.Geometry.Box.Internal: instance (GHC.Show.Show r, GHC.Show.Show p, Data.Geometry.Vector.VectorFixed.Arity d) => GHC.Show.Show (Data.Geometry.Box.Internal.Box d p r)
- Data.Geometry.HalfLine: instance (Control.DeepSeq.NFData r, Data.Geometry.Vector.VectorFixed.Arity d) => Control.DeepSeq.NFData (Data.Geometry.HalfLine.HalfLine d r)
- Data.Geometry.HalfLine: instance (GHC.Classes.Eq r, Data.Geometry.Vector.VectorFixed.Arity d) => GHC.Classes.Eq (Data.Geometry.HalfLine.HalfLine d r)
- Data.Geometry.HalfLine: instance (GHC.Num.Num r, Data.Geometry.Transformation.AlwaysTruePFT d) => Data.Geometry.Transformation.IsTransformable (Data.Geometry.HalfLine.HalfLine d r)
- Data.Geometry.HalfLine: instance (GHC.Show.Show r, Data.Geometry.Vector.VectorFixed.Arity d) => GHC.Show.Show (Data.Geometry.HalfLine.HalfLine d r)
- Data.Geometry.HalfLine: instance Data.Geometry.Vector.VectorFixed.Arity d => Data.Foldable.Foldable (Data.Geometry.HalfLine.HalfLine d)
- Data.Geometry.HalfLine: instance Data.Geometry.Vector.VectorFixed.Arity d => Data.Traversable.Traversable (Data.Geometry.HalfLine.HalfLine d)
- Data.Geometry.HalfLine: instance Data.Geometry.Vector.VectorFixed.Arity d => GHC.Base.Functor (Data.Geometry.HalfLine.HalfLine d)
- Data.Geometry.IntervalTree: instance (Control.DeepSeq.NFData i, Control.DeepSeq.NFData r) => Control.DeepSeq.NFData (Data.Geometry.IntervalTree.NodeData i r)
- Data.Geometry.IntervalTree: instance (GHC.Classes.Eq i, GHC.Classes.Eq r) => GHC.Classes.Eq (Data.Geometry.IntervalTree.NodeData i r)
- Data.Geometry.IntervalTree: instance (GHC.Classes.Ord i, GHC.Classes.Ord r) => GHC.Classes.Ord (Data.Geometry.IntervalTree.NodeData i r)
- Data.Geometry.IntervalTree: instance (GHC.Show.Show i, GHC.Show.Show r) => GHC.Show.Show (Data.Geometry.IntervalTree.NodeData i r)
- Data.Geometry.Ipe.Attributes: [GDict] :: c a => Proxy a -> GDict c a
- Data.Geometry.Ipe.Attributes: data GDict (c :: k -> Constraint) (a :: k)
- Data.Geometry.Ipe.Attributes: instance Data.Singletons.SingI 'Data.Geometry.Ipe.Attributes.Arrow
- Data.Geometry.Ipe.Attributes: instance Data.Singletons.SingI 'Data.Geometry.Ipe.Attributes.Clip
- Data.Geometry.Ipe.Attributes: instance Data.Singletons.SingI 'Data.Geometry.Ipe.Attributes.Dash
- Data.Geometry.Ipe.Attributes: instance Data.Singletons.SingI 'Data.Geometry.Ipe.Attributes.Fill
- Data.Geometry.Ipe.Attributes: instance Data.Singletons.SingI 'Data.Geometry.Ipe.Attributes.FillRule
- Data.Geometry.Ipe.Attributes: instance Data.Singletons.SingI 'Data.Geometry.Ipe.Attributes.Gradient
- Data.Geometry.Ipe.Attributes: instance Data.Singletons.SingI 'Data.Geometry.Ipe.Attributes.Layer
- Data.Geometry.Ipe.Attributes: instance Data.Singletons.SingI 'Data.Geometry.Ipe.Attributes.LineCap
- Data.Geometry.Ipe.Attributes: instance Data.Singletons.SingI 'Data.Geometry.Ipe.Attributes.LineJoin
- Data.Geometry.Ipe.Attributes: instance Data.Singletons.SingI 'Data.Geometry.Ipe.Attributes.Matrix
- Data.Geometry.Ipe.Attributes: instance Data.Singletons.SingI 'Data.Geometry.Ipe.Attributes.Opacity
- Data.Geometry.Ipe.Attributes: instance Data.Singletons.SingI 'Data.Geometry.Ipe.Attributes.Pen
- Data.Geometry.Ipe.Attributes: instance Data.Singletons.SingI 'Data.Geometry.Ipe.Attributes.Pin
- Data.Geometry.Ipe.Attributes: instance Data.Singletons.SingI 'Data.Geometry.Ipe.Attributes.RArrow
- Data.Geometry.Ipe.Attributes: instance Data.Singletons.SingI 'Data.Geometry.Ipe.Attributes.Size
- Data.Geometry.Ipe.Attributes: instance Data.Singletons.SingI 'Data.Geometry.Ipe.Attributes.Stroke
- Data.Geometry.Ipe.Attributes: instance Data.Singletons.SingI 'Data.Geometry.Ipe.Attributes.Tiling
- Data.Geometry.Ipe.Attributes: instance Data.Singletons.SingI 'Data.Geometry.Ipe.Attributes.Transformations
- Data.Geometry.Ipe.Attributes: instance Data.Singletons.SingKind Data.Geometry.Ipe.Attributes.AttributeUniverse
- Data.Geometry.Ipe.Attributes: instance GHC.Classes.Eq Data.Geometry.Ipe.Attributes.IpeColor
- Data.Geometry.Ipe.Attributes: instance GHC.Classes.Ord Data.Geometry.Ipe.Attributes.IpeColor
- Data.Geometry.Ipe.Attributes: instance GHC.Show.Show Data.Geometry.Ipe.Attributes.IpeColor
- Data.Geometry.Ipe.Attributes: instance forall u (ats :: [u]) (f :: Data.Singletons.TyFun u GHC.Types.* -> GHC.Types.*). Data.Vinyl.Core.RecApplicative ats => GHC.Base.Monoid (Data.Geometry.Ipe.Attributes.Attributes f ats)
- Data.Geometry.Ipe.Attributes: instance forall u (f :: Data.Singletons.TyFun u GHC.Types.* -> GHC.Types.*) (ats :: [u]). Data.Semigroup.Semigroup (Data.Geometry.Ipe.Attributes.Attributes f ats)
- Data.Geometry.Ipe.Attributes: instance forall u (f :: Data.Singletons.TyFun u GHC.Types.* -> GHC.Types.*) (ats :: [u]). Data.Vinyl.TypeLevel.RecAll (Data.Geometry.Ipe.Attributes.Attr f) ats GHC.Classes.Eq => GHC.Classes.Eq (Data.Geometry.Ipe.Attributes.Attributes f ats)
- Data.Geometry.Ipe.Attributes: instance forall u (f :: Data.Singletons.TyFun u GHC.Types.* -> GHC.Types.*) (ats :: [u]). Data.Vinyl.TypeLevel.RecAll (Data.Geometry.Ipe.Attributes.Attr f) ats GHC.Show.Show => GHC.Show.Show (Data.Geometry.Ipe.Attributes.Attributes f ats)
- Data.Geometry.Ipe.Attributes: instance forall u (f :: Data.Singletons.TyFun u GHC.Types.* -> GHC.Types.*) (l :: u). GHC.Base.Monoid (Data.Geometry.Ipe.Attributes.Attr f l)
- Data.Geometry.Ipe.Attributes: instance forall u (f :: u Data.Singletons.~> *) (label :: u). GHC.Classes.Eq (Data.Singletons.Apply f label) => GHC.Classes.Eq (Data.Geometry.Ipe.Attributes.Attr f label)
- Data.Geometry.Ipe.Attributes: instance forall u (f :: u Data.Singletons.~> *) (label :: u). GHC.Classes.Ord (Data.Singletons.Apply f label) => GHC.Classes.Ord (Data.Geometry.Ipe.Attributes.Attr f label)
- Data.Geometry.Ipe.Attributes: instance forall u (f :: u Data.Singletons.~> *) (label :: u). GHC.Read.Read (Data.Singletons.Apply f label) => GHC.Read.Read (Data.Geometry.Ipe.Attributes.Attr f label)
- Data.Geometry.Ipe.Attributes: instance forall u (f :: u Data.Singletons.~> *) (label :: u). GHC.Show.Show (Data.Singletons.Apply f label) => GHC.Show.Show (Data.Geometry.Ipe.Attributes.Attr f label)
- Data.Geometry.Ipe.Attributes: type Colour = Text
- Data.Geometry.Ipe.IpeOut: instance Data.Geometry.Ipe.IpeOut.HasDefaultIpeOut (Data.Geometry.Polygon.SimplePolygon p r)
- Data.Geometry.Ipe.IpeOut: ipeSimplePolygon :: IpeOut (SimplePolygon p r) (Path r)
- Data.Geometry.Ipe.PathParser: instance (Data.Semigroup.Semigroup l, Data.Semigroup.Semigroup r, GHC.Base.Monoid r) => GHC.Base.Monoid (Data.Geometry.Ipe.PathParser.Either' l r)
- Data.Geometry.Ipe.PathParser: instance (GHC.Classes.Eq r, GHC.Classes.Eq l) => GHC.Classes.Eq (Data.Geometry.Ipe.PathParser.Either' l r)
- Data.Geometry.Ipe.PathParser: instance (GHC.Show.Show r, GHC.Show.Show l) => GHC.Show.Show (Data.Geometry.Ipe.PathParser.Either' l r)
- Data.Geometry.Ipe.Reader: instance Data.Geometry.Ipe.PathParser.Coordinate r => Data.Geometry.Ipe.Reader.IpeRead (Data.Geometry.Ipe.Types.Group r)
- Data.Geometry.Ipe.Reader: instance Data.Geometry.Ipe.PathParser.Coordinate r => Data.Geometry.Ipe.Reader.IpeRead (Data.Geometry.Ipe.Types.IpeFile r)
- Data.Geometry.Ipe.Reader: instance Data.Geometry.Ipe.PathParser.Coordinate r => Data.Geometry.Ipe.Reader.IpeRead (Data.Geometry.Ipe.Types.IpeObject r)
- Data.Geometry.Ipe.Reader: instance Data.Geometry.Ipe.PathParser.Coordinate r => Data.Geometry.Ipe.Reader.IpeRead (Data.Geometry.Ipe.Types.IpePage r)
- Data.Geometry.Ipe.Reader: instance Data.Geometry.Ipe.PathParser.Coordinate r => Data.Geometry.Ipe.Reader.IpeRead (Data.Geometry.Ipe.Types.Path r)
- Data.Geometry.Ipe.Reader: instance Data.Geometry.Ipe.PathParser.Coordinate r => Data.Geometry.Ipe.Reader.IpeRead (Data.Geometry.Ipe.Types.PathSegment r)
- Data.Geometry.Ipe.Reader: instance Data.Geometry.Ipe.PathParser.Coordinate r => Data.Geometry.Ipe.Reader.IpeRead (Data.Geometry.PolyLine.PolyLine 2 () r)
- Data.Geometry.Ipe.Reader: instance Data.Geometry.Ipe.PathParser.Coordinate r => Data.Geometry.Ipe.Reader.IpeReadText (Data.Geometry.Ipe.Types.Path r)
- Data.Geometry.Ipe.Reader: instance Data.Geometry.Ipe.PathParser.Coordinate r => Data.Geometry.Ipe.Reader.IpeReadText (Data.Geometry.PolyLine.PolyLine 2 () r)
- Data.Geometry.Ipe.Reader: instance Data.Geometry.Ipe.PathParser.Coordinate r => Data.Geometry.Ipe.Reader.IpeReadText (Data.List.NonEmpty.NonEmpty (Data.Geometry.Ipe.Types.PathSegment r))
- Data.Geometry.Ipe.Reader: instance Data.Geometry.Ipe.Reader.IpeReadText Data.Geometry.Ipe.Attributes.IpeColor
- Data.Geometry.Ipe.Reader: instance forall u (f :: u Data.Singletons.~> *) (at :: u). Data.Geometry.Ipe.Reader.IpeReadText (Data.Singletons.Apply f at) => Data.Geometry.Ipe.Reader.IpeReadAttr (Data.Geometry.Ipe.Attributes.Attr f at)
- Data.Geometry.Ipe.Types: instance GHC.Num.Num r => Data.Geometry.Transformation.IsTransformable (Data.Geometry.Ipe.Types.Group r)
- Data.Geometry.Ipe.Types: instance GHC.Num.Num r => Data.Geometry.Transformation.IsTransformable (Data.Geometry.Ipe.Types.Image r)
- Data.Geometry.Ipe.Types: instance GHC.Num.Num r => Data.Geometry.Transformation.IsTransformable (Data.Geometry.Ipe.Types.IpeObject r)
- Data.Geometry.Ipe.Types: instance GHC.Num.Num r => Data.Geometry.Transformation.IsTransformable (Data.Geometry.Ipe.Types.IpeSymbol r)
- Data.Geometry.Ipe.Types: instance GHC.Num.Num r => Data.Geometry.Transformation.IsTransformable (Data.Geometry.Ipe.Types.MiniPage r)
- Data.Geometry.Ipe.Types: instance GHC.Num.Num r => Data.Geometry.Transformation.IsTransformable (Data.Geometry.Ipe.Types.Path r)
- Data.Geometry.Ipe.Types: instance GHC.Num.Num r => Data.Geometry.Transformation.IsTransformable (Data.Geometry.Ipe.Types.PathSegment r)
- Data.Geometry.Ipe.Types: instance GHC.Num.Num r => Data.Geometry.Transformation.IsTransformable (Data.Geometry.Ipe.Types.TextLabel r)
- Data.Geometry.Ipe.Writer: instance Data.Geometry.Ipe.Writer.IpeWriteText Data.Geometry.Ipe.Attributes.IpeColor
- Data.Geometry.Ipe.Writer: instance Data.Geometry.Ipe.Writer.IpeWriteText r => Data.Geometry.Ipe.Writer.IpeWriteText (Data.Geometry.Polygon.SimplePolygon () r)
- Data.Geometry.Ipe.Writer: instance forall u (f :: u Data.Singletons.~> *) (at :: u). Data.Geometry.Ipe.Writer.IpeWriteText (Data.Singletons.Apply f at) => Data.Geometry.Ipe.Writer.IpeWriteText (Data.Geometry.Ipe.Attributes.Attr f at)
- Data.Geometry.KDTree: instance (GHC.Classes.Eq p, GHC.Classes.Eq r, Data.Geometry.Vector.VectorFixed.Arity d, GHC.TypeLits.KnownNat d) => GHC.Classes.Eq (Data.Geometry.KDTree.KDTree d p r)
- Data.Geometry.KDTree: instance (GHC.Classes.Eq p, GHC.Classes.Eq r, Data.Geometry.Vector.VectorFixed.Arity d, GHC.TypeLits.KnownNat d) => GHC.Classes.Eq (Data.Geometry.KDTree.KDTree' d p r)
- Data.Geometry.KDTree: instance (GHC.Classes.Eq r, Data.Geometry.Vector.VectorFixed.Arity d, GHC.TypeLits.KnownNat d) => GHC.Classes.Eq (Data.Geometry.KDTree.Split d r)
- Data.Geometry.KDTree: instance (GHC.Show.Show p, GHC.Show.Show r, Data.Geometry.Vector.VectorFixed.Arity d, GHC.TypeLits.KnownNat d) => GHC.Show.Show (Data.Geometry.KDTree.KDTree d p r)
- Data.Geometry.KDTree: instance (GHC.Show.Show p, GHC.Show.Show r, Data.Geometry.Vector.VectorFixed.Arity d, GHC.TypeLits.KnownNat d) => GHC.Show.Show (Data.Geometry.KDTree.KDTree' d p r)
- Data.Geometry.KDTree: instance (GHC.Show.Show r, Data.Geometry.Vector.VectorFixed.Arity d, GHC.TypeLits.KnownNat d) => GHC.Show.Show (Data.Geometry.KDTree.Split d r)
- Data.Geometry.KDTree: instance GHC.TypeLits.KnownNat d => GHC.Classes.Eq (Data.Geometry.KDTree.Coord d)
- Data.Geometry.KDTree: instance GHC.TypeLits.KnownNat d => GHC.Enum.Enum (Data.Geometry.KDTree.Coord d)
- Data.Geometry.KDTree: instance GHC.TypeLits.KnownNat d => GHC.Show.Show (Data.Geometry.KDTree.Coord d)
- Data.Geometry.Line: instance (GHC.Num.Num r, Data.Geometry.Transformation.AlwaysTruePFT d) => Data.Geometry.Transformation.IsTransformable (Data.Geometry.Line.Internal.Line d r)
- Data.Geometry.Line.Internal: instance (Control.DeepSeq.NFData r, Data.Geometry.Vector.VectorFixed.Arity d) => Control.DeepSeq.NFData (Data.Geometry.Line.Internal.Line d r)
- Data.Geometry.Line.Internal: instance (GHC.Classes.Eq r, Data.Geometry.Vector.VectorFixed.Arity d) => GHC.Classes.Eq (Data.Geometry.Line.Internal.Line d r)
- Data.Geometry.Line.Internal: instance (GHC.Show.Show r, Data.Geometry.Vector.VectorFixed.Arity d) => GHC.Show.Show (Data.Geometry.Line.Internal.Line d r)
- Data.Geometry.Line.Internal: instance Data.Geometry.Vector.VectorFixed.Arity d => Data.Foldable.Foldable (Data.Geometry.Line.Internal.Line d)
- Data.Geometry.Line.Internal: instance Data.Geometry.Vector.VectorFixed.Arity d => Data.Traversable.Traversable (Data.Geometry.Line.Internal.Line d)
- Data.Geometry.Line.Internal: instance Data.Geometry.Vector.VectorFixed.Arity d => GHC.Base.Functor (Data.Geometry.Line.Internal.Line d)
- Data.Geometry.LineSegment: instance (GHC.Classes.Eq r, GHC.Classes.Eq p, Data.Geometry.Vector.VectorFixed.Arity d) => GHC.Classes.Eq (Data.Geometry.LineSegment.LineSegment d p r)
- Data.Geometry.LineSegment: instance (GHC.Num.Num r, Data.Geometry.Transformation.AlwaysTruePFT d) => Data.Geometry.Transformation.IsTransformable (Data.Geometry.LineSegment.LineSegment d p r)
- Data.Geometry.LineSegment: instance (GHC.Num.Num r, Data.Geometry.Vector.VectorFixed.Arity d) => Data.Geometry.Line.Internal.HasSupportingLine (Data.Geometry.LineSegment.LineSegment d p r)
- Data.Geometry.LineSegment: instance (GHC.Show.Show r, GHC.Show.Show p, Data.Geometry.Vector.VectorFixed.Arity d) => GHC.Show.Show (Data.Geometry.LineSegment.LineSegment d p r)
- Data.Geometry.LineSegment: instance Data.Geometry.Vector.VectorFixed.Arity d => Data.Bifunctor.Bifunctor (Data.Geometry.LineSegment.LineSegment d)
- Data.Geometry.LineSegment: instance Data.Geometry.Vector.VectorFixed.Arity d => Data.Geometry.Box.Internal.IsBoxable (Data.Geometry.LineSegment.LineSegment d p r)
- Data.Geometry.LineSegment: instance Data.Geometry.Vector.VectorFixed.Arity d => GHC.Base.Functor (Data.Geometry.LineSegment.LineSegment d p)
- Data.Geometry.PlanarSubdivision: EdgeData :: !EdgeType -> !e -> EdgeData e
- Data.Geometry.PlanarSubdivision: FaceData :: [h] -> !f -> FaceData h f
- Data.Geometry.PlanarSubdivision: Invisible :: EdgeType
- Data.Geometry.PlanarSubdivision: PlanarSubdivision :: PlanarGraph s Primal_ (VertexData r v) (EdgeData e) (FaceData (Dart s) f) -> PlanarSubdivision s v e f r
- Data.Geometry.PlanarSubdivision: VertexData :: !(Point 2 r) -> !v -> VertexData r v
- Data.Geometry.PlanarSubdivision: Visible :: EdgeType
- Data.Geometry.PlanarSubdivision: [_eData] :: EdgeData e -> !e
- Data.Geometry.PlanarSubdivision: [_edgeType] :: EdgeData e -> !EdgeType
- Data.Geometry.PlanarSubdivision: [_fData] :: FaceData h f -> !f
- Data.Geometry.PlanarSubdivision: [_graph] :: PlanarSubdivision s v e f r -> PlanarGraph s Primal_ (VertexData r v) (EdgeData e) (FaceData (Dart s) f)
- Data.Geometry.PlanarSubdivision: [_holes] :: FaceData h f -> [h]
- Data.Geometry.PlanarSubdivision: [_location] :: VertexData r v -> !(Point 2 r)
- Data.Geometry.PlanarSubdivision: [_vData] :: VertexData r v -> !v
- Data.Geometry.PlanarSubdivision: data EdgeData e
- Data.Geometry.PlanarSubdivision: data EdgeType
- Data.Geometry.PlanarSubdivision: data FaceData h f
- Data.Geometry.PlanarSubdivision: data VertexData r v
- Data.Geometry.PlanarSubdivision: eData :: forall e_a3bij e_a3bwf. Lens (EdgeData e_a3bij) (EdgeData e_a3bwf) e_a3bij e_a3bwf
- Data.Geometry.PlanarSubdivision: edgeType :: forall e_a3bij. Lens' (EdgeData e_a3bij) EdgeType
- Data.Geometry.PlanarSubdivision: fData :: forall h_a3bwu f_a3bwv f_a3bHi. Lens (FaceData h_a3bwu f_a3bwv) (FaceData h_a3bwu f_a3bHi) f_a3bwv f_a3bHi
- Data.Geometry.PlanarSubdivision: fromConnectedSegments :: (Foldable f, Ord r, Num r) => proxy s -> f (LineSegment 2 p r :+ EdgeData e) -> PlanarSubdivision s [p] e () r
- Data.Geometry.PlanarSubdivision: fromConnectedSegments' :: (Foldable f, Ord r, Num r) => proxy s -> f (LineSegment 2 p r :+ e) -> PlanarGraph s Primal_ (VertexData r [p]) e ()
- Data.Geometry.PlanarSubdivision: fromVertices :: proxy s -> CSeq (Point 2 r :+ p) -> PlanarGraph s Primal_ (VertexData r p) () ()
- Data.Geometry.PlanarSubdivision: graph :: forall s_a3bHx v_a3bHy e_a3bHz f_a3bHA r_a3bHB s_a3bO7 v_a3bO8 e_a3bO9 f_a3bOa r_a3bOb. Iso (PlanarSubdivision s_a3bHx v_a3bHy e_a3bHz f_a3bHA r_a3bHB) (PlanarSubdivision s_a3bO7 v_a3bO8 e_a3bO9 f_a3bOa r_a3bOb) (PlanarGraph s_a3bHx Primal_ (VertexData r_a3bHB v_a3bHy) (EdgeData e_a3bHz) (FaceData (Dart s_a3bHx) f_a3bHA)) (PlanarGraph s_a3bO7 Primal_ (VertexData r_a3bOb v_a3bO8) (EdgeData e_a3bO9) (FaceData (Dart s_a3bO7) f_a3bOa))
- Data.Geometry.PlanarSubdivision: holes :: forall h_a3bwu f_a3bwv h_a3bHj. Lens (FaceData h_a3bwu f_a3bwv) (FaceData h_a3bHj f_a3bwv) [h_a3bwu] [h_a3bHj]
- Data.Geometry.PlanarSubdivision: instance (GHC.Classes.Eq f, GHC.Classes.Eq h) => GHC.Classes.Eq (Data.Geometry.PlanarSubdivision.FaceData h f)
- Data.Geometry.PlanarSubdivision: instance (GHC.Classes.Eq v, GHC.Classes.Eq r) => GHC.Classes.Eq (Data.Geometry.PlanarSubdivision.VertexData r v)
- Data.Geometry.PlanarSubdivision: instance (GHC.Classes.Ord f, GHC.Classes.Ord h) => GHC.Classes.Ord (Data.Geometry.PlanarSubdivision.FaceData h f)
- Data.Geometry.PlanarSubdivision: instance (GHC.Classes.Ord v, GHC.Classes.Ord r) => GHC.Classes.Ord (Data.Geometry.PlanarSubdivision.VertexData r v)
- Data.Geometry.PlanarSubdivision: instance (GHC.Show.Show f, GHC.Show.Show h) => GHC.Show.Show (Data.Geometry.PlanarSubdivision.FaceData h f)
- Data.Geometry.PlanarSubdivision: instance (GHC.Show.Show v, GHC.Show.Show r) => GHC.Show.Show (Data.Geometry.PlanarSubdivision.VertexData r v)
- Data.Geometry.PlanarSubdivision: instance Data.Bifunctor.Bifunctor Data.Geometry.PlanarSubdivision.VertexData
- Data.Geometry.PlanarSubdivision: instance Data.Foldable.Foldable (Data.Geometry.PlanarSubdivision.FaceData h)
- Data.Geometry.PlanarSubdivision: instance Data.Foldable.Foldable (Data.Geometry.PlanarSubdivision.VertexData r)
- Data.Geometry.PlanarSubdivision: instance Data.Foldable.Foldable Data.Geometry.PlanarSubdivision.EdgeData
- Data.Geometry.PlanarSubdivision: instance Data.Traversable.Traversable (Data.Geometry.PlanarSubdivision.FaceData h)
- Data.Geometry.PlanarSubdivision: instance Data.Traversable.Traversable (Data.Geometry.PlanarSubdivision.VertexData r)
- Data.Geometry.PlanarSubdivision: instance Data.Traversable.Traversable Data.Geometry.PlanarSubdivision.EdgeData
- Data.Geometry.PlanarSubdivision: instance GHC.Base.Functor (Data.Geometry.PlanarSubdivision.FaceData h)
- Data.Geometry.PlanarSubdivision: instance GHC.Base.Functor (Data.Geometry.PlanarSubdivision.VertexData r)
- Data.Geometry.PlanarSubdivision: instance GHC.Base.Functor Data.Geometry.PlanarSubdivision.EdgeData
- Data.Geometry.PlanarSubdivision: instance GHC.Classes.Eq Data.Geometry.PlanarSubdivision.EdgeType
- Data.Geometry.PlanarSubdivision: instance GHC.Classes.Eq e => GHC.Classes.Eq (Data.Geometry.PlanarSubdivision.EdgeData e)
- Data.Geometry.PlanarSubdivision: instance GHC.Classes.Ord Data.Geometry.PlanarSubdivision.EdgeType
- Data.Geometry.PlanarSubdivision: instance GHC.Classes.Ord e => GHC.Classes.Ord (Data.Geometry.PlanarSubdivision.EdgeData e)
- Data.Geometry.PlanarSubdivision: instance GHC.Read.Read Data.Geometry.PlanarSubdivision.EdgeType
- Data.Geometry.PlanarSubdivision: instance GHC.Show.Show Data.Geometry.PlanarSubdivision.EdgeType
- Data.Geometry.PlanarSubdivision: instance GHC.Show.Show e => GHC.Show.Show (Data.Geometry.PlanarSubdivision.EdgeData e)
- Data.Geometry.PlanarSubdivision: instance forall k (s :: k) v e f r. (GHC.Classes.Eq r, GHC.Classes.Eq v, GHC.Classes.Eq e, GHC.Classes.Eq f) => GHC.Classes.Eq (Data.Geometry.PlanarSubdivision.PlanarSubdivision s v e f r)
- Data.Geometry.PlanarSubdivision: instance forall k (s :: k) v e f r. (GHC.Show.Show r, GHC.Show.Show v, GHC.Show.Show e, GHC.Show.Show f) => GHC.Show.Show (Data.Geometry.PlanarSubdivision.PlanarSubdivision s v e f r)
- Data.Geometry.PlanarSubdivision: instance forall k (s :: k) v e f. GHC.Base.Functor (Data.Geometry.PlanarSubdivision.PlanarSubdivision s v e f)
- Data.Geometry.PlanarSubdivision: location :: forall r_a3b7A v_a3b7B r_a3bi0. Lens (VertexData r_a3b7A v_a3b7B) (VertexData r_a3bi0 v_a3b7B) (Point 2 r_a3b7A) (Point 2 r_a3bi0)
- Data.Geometry.PlanarSubdivision: newtype PlanarSubdivision s v e f r
- Data.Geometry.PlanarSubdivision: vData :: forall r_a3b7A v_a3b7B v_a3bi1. Lens (VertexData r_a3b7A v_a3b7B) (VertexData r_a3b7A v_a3bi1) v_a3b7B v_a3bi1
- Data.Geometry.Point: instance (Data.Geometry.Vector.VectorFixed.Arity d, Control.DeepSeq.NFData r) => Control.DeepSeq.NFData (Data.Geometry.Point.Point d r)
- Data.Geometry.Point: instance (GHC.Classes.Eq r, Data.Geometry.Vector.VectorFixed.Arity d) => GHC.Classes.Eq (Data.Geometry.Point.Point d r)
- Data.Geometry.Point: instance (GHC.Classes.Ord r, Data.Geometry.Vector.VectorFixed.Arity d) => GHC.Classes.Ord (Data.Geometry.Point.Point d r)
- Data.Geometry.Point: instance (GHC.Show.Show r, Data.Geometry.Vector.VectorFixed.Arity d) => GHC.Show.Show (Data.Geometry.Point.Point d r)
- Data.Geometry.Point: instance Data.Geometry.Vector.VectorFixed.Arity d => Data.Foldable.Foldable (Data.Geometry.Point.Point d)
- Data.Geometry.Point: instance Data.Geometry.Vector.VectorFixed.Arity d => Data.Traversable.Traversable (Data.Geometry.Point.Point d)
- Data.Geometry.Point: instance Data.Geometry.Vector.VectorFixed.Arity d => GHC.Base.Functor (Data.Geometry.Point.Point d)
- Data.Geometry.Point: instance Data.Geometry.Vector.VectorFixed.Arity d => Linear.Affine.Affine (Data.Geometry.Point.Point d)
- Data.Geometry.Point: type (<=.) i d = (Index' (i - 1) d, Arity d)
- Data.Geometry.PolyLine: instance (GHC.Classes.Eq r, GHC.Classes.Eq p, Data.Geometry.Vector.VectorFixed.Arity d) => GHC.Classes.Eq (Data.Geometry.PolyLine.PolyLine d p r)
- Data.Geometry.PolyLine: instance (GHC.Classes.Ord r, GHC.Classes.Ord p, Data.Geometry.Vector.VectorFixed.Arity d) => GHC.Classes.Ord (Data.Geometry.PolyLine.PolyLine d p r)
- Data.Geometry.PolyLine: instance (GHC.Num.Num r, Data.Geometry.Transformation.AlwaysTruePFT d) => Data.Geometry.Transformation.IsTransformable (Data.Geometry.PolyLine.PolyLine d p r)
- Data.Geometry.PolyLine: instance (GHC.Show.Show r, GHC.Show.Show p, Data.Geometry.Vector.VectorFixed.Arity d) => GHC.Show.Show (Data.Geometry.PolyLine.PolyLine d p r)
- Data.Geometry.PolyLine: instance Data.Geometry.Vector.VectorFixed.Arity d => Data.Bifunctor.Bifunctor (Data.Geometry.PolyLine.PolyLine d)
- Data.Geometry.PolyLine: instance Data.Geometry.Vector.VectorFixed.Arity d => Data.Geometry.Box.Internal.IsBoxable (Data.Geometry.PolyLine.PolyLine d p r)
- Data.Geometry.PolyLine: instance Data.Geometry.Vector.VectorFixed.Arity d => GHC.Base.Functor (Data.Geometry.PolyLine.PolyLine d p)
- Data.Geometry.PolyLine: instance Data.Semigroup.Semigroup (Data.Geometry.PolyLine.PolyLine d p r)
- Data.Geometry.Polygon: holes :: forall p r. Lens' (Polygon Multi p r) [Polygon Simple p r]
- Data.Geometry.Polygon: instance GHC.Num.Num r => Data.Geometry.Transformation.IsTransformable (Data.Geometry.Polygon.Polygon t p r)
- Data.Geometry.Polygon.Convex: instance (GHC.Classes.Eq r, GHC.Classes.Eq p) => GHC.Classes.Eq (Data.Geometry.Polygon.Convex.ConvexPolygon p r)
- Data.Geometry.Polygon.Convex: instance (GHC.Show.Show r, GHC.Show.Show p) => GHC.Show.Show (Data.Geometry.Polygon.Convex.ConvexPolygon p r)
- Data.Geometry.Polygon.Convex: instance GHC.Num.Num r => Data.Geometry.Transformation.IsTransformable (Data.Geometry.Polygon.Convex.ConvexPolygon p r)
- Data.Geometry.SegmentTree.Generic: instance (Control.DeepSeq.NFData r, Control.DeepSeq.NFData v) => Control.DeepSeq.NFData (Data.Geometry.SegmentTree.Generic.SegmentTree v r)
- Data.Geometry.SegmentTree.Generic: instance (GHC.Classes.Eq v, GHC.Classes.Eq r) => GHC.Classes.Eq (Data.Geometry.SegmentTree.Generic.LeafData v r)
- Data.Geometry.SegmentTree.Generic: instance (GHC.Classes.Eq v, GHC.Classes.Eq r) => GHC.Classes.Eq (Data.Geometry.SegmentTree.Generic.NodeData v r)
- Data.Geometry.SegmentTree.Generic: instance (GHC.Show.Show v, GHC.Show.Show r) => GHC.Show.Show (Data.Geometry.SegmentTree.Generic.LeafData v r)
- Data.Geometry.SegmentTree.Generic: instance (GHC.Show.Show v, GHC.Show.Show r) => GHC.Show.Show (Data.Geometry.SegmentTree.Generic.NodeData v r)
- Data.Geometry.SegmentTree.Generic: instance Data.Semigroup.Semigroup Data.Geometry.SegmentTree.Generic.Count
- Data.Geometry.Slab: instance (GHC.Classes.Eq a, GHC.Classes.Eq r) => GHC.Classes.Eq (Data.Geometry.Slab.Slab o a r)
- Data.Geometry.Slab: instance (GHC.Show.Show r, GHC.Show.Show a) => GHC.Show.Show (Data.Geometry.Slab.Slab o a r)
- Data.Geometry.SubLine: instance (GHC.Classes.Eq r, GHC.Classes.Eq p, Data.Geometry.Vector.VectorFixed.Arity d) => GHC.Classes.Eq (Data.Geometry.SubLine.SubLine d p r)
- Data.Geometry.SubLine: instance (GHC.Show.Show r, GHC.Show.Show p, Data.Geometry.Vector.VectorFixed.Arity d) => GHC.Show.Show (Data.Geometry.SubLine.SubLine d p r)
- Data.Geometry.SubLine: instance Data.Geometry.Vector.VectorFixed.Arity d => Data.Foldable.Foldable (Data.Geometry.SubLine.SubLine d p)
- Data.Geometry.SubLine: instance Data.Geometry.Vector.VectorFixed.Arity d => Data.Traversable.Traversable (Data.Geometry.SubLine.SubLine d p)
- Data.Geometry.SubLine: instance Data.Geometry.Vector.VectorFixed.Arity d => GHC.Base.Functor (Data.Geometry.SubLine.SubLine d p)
- Data.Geometry.Transformation: instance (Data.Geometry.Vector.VectorFixed.Arity n, Data.Geometry.Vector.VectorFixed.Arity m) => GHC.Base.Functor (Data.Geometry.Transformation.Matrix n m)
- Data.Geometry.Transformation: instance (GHC.Classes.Eq r, Data.Geometry.Vector.VectorFixed.Arity (1 GHC.TypeLits.+ d)) => GHC.Classes.Eq (Data.Geometry.Transformation.Transformation d r)
- Data.Geometry.Transformation: instance (GHC.Classes.Eq r, Data.Geometry.Vector.VectorFixed.Arity n, Data.Geometry.Vector.VectorFixed.Arity m) => GHC.Classes.Eq (Data.Geometry.Transformation.Matrix n m r)
- Data.Geometry.Transformation: instance (GHC.Classes.Ord r, Data.Geometry.Vector.VectorFixed.Arity (1 GHC.TypeLits.+ d)) => GHC.Classes.Ord (Data.Geometry.Transformation.Transformation d r)
- Data.Geometry.Transformation: instance (GHC.Classes.Ord r, Data.Geometry.Vector.VectorFixed.Arity n, Data.Geometry.Vector.VectorFixed.Arity m) => GHC.Classes.Ord (Data.Geometry.Transformation.Matrix n m r)
- Data.Geometry.Transformation: instance (GHC.Num.Num r, Data.Geometry.Vector.VectorFixed.Arity d, Data.Geometry.Vector.VectorFixed.AlwaysTrueDestruct d (1 GHC.TypeLits.+ d)) => Data.Geometry.Transformation.IsTransformable (Data.Geometry.Point.Point d r)
- Data.Geometry.Transformation: instance (GHC.Show.Show r, Data.Geometry.Vector.VectorFixed.Arity (1 GHC.TypeLits.+ d)) => GHC.Show.Show (Data.Geometry.Transformation.Transformation d r)
- Data.Geometry.Transformation: instance (GHC.Show.Show r, Data.Geometry.Vector.VectorFixed.Arity n, Data.Geometry.Vector.VectorFixed.Arity m) => GHC.Show.Show (Data.Geometry.Transformation.Matrix n m r)
- Data.Geometry.Transformation: instance Data.Geometry.Vector.VectorFixed.Arity (1 GHC.TypeLits.+ d) => GHC.Base.Functor (Data.Geometry.Transformation.Transformation d)
- Data.Geometry.Transformation: type AlwaysTruePFT d = AlwaysTrueDestruct d (1 + d)
- Data.Geometry.Transformation: type AlwaysTrueTransformation d = (Arity (1 + d), AlwaysTrueSnoc d, Arity d, Index' ((1 + d) - 1) (1 + d))
- Data.Geometry.Triangle: instance (GHC.Classes.Eq r, GHC.Classes.Eq p) => GHC.Classes.Eq (Data.Geometry.Triangle.Triangle p r)
- Data.Geometry.Triangle: instance (GHC.Show.Show r, GHC.Show.Show p) => GHC.Show.Show (Data.Geometry.Triangle.Triangle p r)
- Data.Geometry.Triangle: instance Data.Geometry.Point.PointFunctor (Data.Geometry.Triangle.Triangle p)
- Data.Geometry.Triangle: instance GHC.Base.Functor (Data.Geometry.Triangle.Triangle p)
- Data.Geometry.Triangle: instance GHC.Num.Num r => Data.Geometry.Transformation.IsTransformable (Data.Geometry.Triangle.Triangle d r)
- Data.Geometry.Vector.VectorFixed: class Prefix i d
- Data.Geometry.Vector.VectorFixed: imap :: Arity d => (Int -> r -> s) -> Vector d r -> Vector d s
- Data.Geometry.Vector.VectorFixed: instance (Data.Geometry.Vector.VectorFixed.Arity d, Control.DeepSeq.NFData r) => Control.DeepSeq.NFData (Data.Geometry.Vector.VectorFixed.Vector d r)
- Data.Geometry.Vector.VectorFixed: instance (Data.Vector.Fixed.Cont.Arity i, Data.Vector.Fixed.Cont.Arity d, Data.Geometry.Vector.VectorFixed.Prefix i d) => Data.Geometry.Vector.VectorFixed.Prefix (Data.Vector.Fixed.Cont.S i) (Data.Vector.Fixed.Cont.S d)
- Data.Geometry.Vector.VectorFixed: instance (GHC.Classes.Eq r, Data.Geometry.Vector.VectorFixed.Arity d) => GHC.Classes.Eq (Data.Geometry.Vector.VectorFixed.Vector d r)
- Data.Geometry.Vector.VectorFixed: instance (GHC.Classes.Ord r, Data.Geometry.Vector.VectorFixed.Arity d) => GHC.Classes.Ord (Data.Geometry.Vector.VectorFixed.Vector d r)
- Data.Geometry.Vector.VectorFixed: instance (GHC.Show.Show r, Data.Geometry.Vector.VectorFixed.Arity d) => GHC.Show.Show (Data.Geometry.Vector.VectorFixed.Vector d r)
- Data.Geometry.Vector.VectorFixed: instance Data.Geometry.Vector.VectorFixed.Arity d => Data.Foldable.Foldable (Data.Geometry.Vector.VectorFixed.Vector d)
- Data.Geometry.Vector.VectorFixed: instance Data.Geometry.Vector.VectorFixed.Arity d => Data.Traversable.Traversable (Data.Geometry.Vector.VectorFixed.Vector d)
- Data.Geometry.Vector.VectorFixed: instance Data.Geometry.Vector.VectorFixed.Arity d => Data.Vector.Fixed.Cont.Vector (Data.Geometry.Vector.VectorFixed.Vector d) r
- Data.Geometry.Vector.VectorFixed: instance Data.Geometry.Vector.VectorFixed.Arity d => GHC.Base.Applicative (Data.Geometry.Vector.VectorFixed.Vector d)
- Data.Geometry.Vector.VectorFixed: instance Data.Geometry.Vector.VectorFixed.Arity d => GHC.Base.Functor (Data.Geometry.Vector.VectorFixed.Vector d)
- Data.Geometry.Vector.VectorFixed: instance Data.Geometry.Vector.VectorFixed.Arity d => Linear.Affine.Affine (Data.Geometry.Vector.VectorFixed.Vector d)
- Data.Geometry.Vector.VectorFixed: instance Data.Geometry.Vector.VectorFixed.Arity d => Linear.Metric.Metric (Data.Geometry.Vector.VectorFixed.Vector d)
- Data.Geometry.Vector.VectorFixed: instance Data.Geometry.Vector.VectorFixed.Arity d => Linear.Vector.Additive (Data.Geometry.Vector.VectorFixed.Vector d)
- Data.Geometry.Vector.VectorFixed: instance Data.Geometry.Vector.VectorFixed.Prefix Data.Vector.Fixed.Cont.Z d
- Data.Geometry.Vector.VectorFixed: prefix' :: Prefix i d => Vec d r -> Vec i r
- Data.Geometry.Vector.VectorFixed: type AlwaysTrueDestruct pd d = (Arity pd, ToPeano d ~ S (ToPeano pd))
- Data.Geometry.Vector.VectorFixed: type AlwaysTrueSnoc d = ToPeano (1 + d) ~ S (ToPeano d)
- Data.Geometry.Vector.VectorFixed: type Arity (n :: Nat) = Arity (ToPeano n)
- Data.Geometry.Vector.VectorFixed: type Index' i d = Index (ToPeano i) (ToPeano d)
- Data.PlanarGraph: Dual_ :: World
- Data.PlanarGraph: Primal_ :: World
- Data.PlanarGraph: eDataOf :: Dart s -> Lens' (PlanarGraph s w v e f) e
- Data.PlanarGraph: fDataOf :: FaceId s w -> Lens' (PlanarGraph s w v e f) f
- Data.PlanarGraph: instance forall k (s :: k) (w :: Data.PlanarGraph.World) v e f. (GHC.Classes.Eq f, GHC.Classes.Eq e, GHC.Classes.Eq v) => GHC.Classes.Eq (Data.PlanarGraph.PlanarGraph s w v e f)
- Data.PlanarGraph: instance forall k (s :: k) (w :: Data.PlanarGraph.World) v e f. (GHC.Show.Show f, GHC.Show.Show e, GHC.Show.Show v) => GHC.Show.Show (Data.PlanarGraph.PlanarGraph s w v e f)
- Data.PlanarGraph: vDataOf :: VertexId s w -> Lens' (PlanarGraph s w v e f) v
- Data.PlaneGraph: faceToSimplePolygon :: FaceId s w -> PlaneGraph s w p e f r -> SimplePolygon p r :+ f
- Data.PlaneGraph: type PlaneGraph s w v e f r = PlanarGraph s w (Point 2 r :+ v) e f
- Data.Seq: instance Data.Semigroup.Semigroup (Data.Seq.LSeq n a)
- Data.Seq: instance Data.Semigroup.Semigroup (Data.Seq.ViewL n a)
- Data.Seq: instance Data.Semigroup.Semigroup (Data.Seq.ViewR n a)
- Data.Seq2: instance Data.Semigroup.Semigroup (Data.Seq2.Seq2 a)
- Data.Seq2: instance Data.Semigroup.Semigroup (Data.Seq2.ViewL1 a)
- Data.Util: instance (Data.Semigroup.Semigroup a, Data.Semigroup.Semigroup b) => Data.Semigroup.Semigroup (Data.Util.SP a b)
- Data.Util: instance (GHC.Classes.Eq b, GHC.Classes.Eq a) => GHC.Classes.Eq (Data.Util.SP a b)
- Data.Util: instance (GHC.Classes.Eq c, GHC.Classes.Eq b, GHC.Classes.Eq a) => GHC.Classes.Eq (Data.Util.STR a b c)
- Data.Util: instance (GHC.Classes.Ord b, GHC.Classes.Ord a) => GHC.Classes.Ord (Data.Util.SP a b)
- Data.Util: instance (GHC.Classes.Ord c, GHC.Classes.Ord b, GHC.Classes.Ord a) => GHC.Classes.Ord (Data.Util.STR a b c)
- Data.Util: instance (GHC.Show.Show b, GHC.Show.Show a) => GHC.Show.Show (Data.Util.SP a b)
- Data.Util: instance (GHC.Show.Show c, GHC.Show.Show b, GHC.Show.Show a) => GHC.Show.Show (Data.Util.STR a b c)
+ Algorithms.Geometry.ConvexHull.DivideAndConqueror: instance (GHC.Num.Num r, GHC.Classes.Ord r) => GHC.Base.Semigroup (Algorithms.Geometry.ConvexHull.DivideAndConqueror.Merge r p)
+ Algorithms.Geometry.DelaunayTriangulation.Types: instance (GHC.Classes.Eq r, GHC.Classes.Eq p) => GHC.Classes.Eq (Algorithms.Geometry.DelaunayTriangulation.Types.Triangulation p r)
+ Algorithms.Geometry.DelaunayTriangulation.Types: instance (GHC.Show.Show r, GHC.Show.Show p) => GHC.Show.Show (Algorithms.Geometry.DelaunayTriangulation.Types.Triangulation p r)
+ Algorithms.Geometry.LineSegmentIntersection: hasInteriorIntersections :: (Ord r, Fractional r) => [LineSegment 2 p r] -> Bool
+ Algorithms.Geometry.LineSegmentIntersection: hasSelfIntersections :: (Ord r, Fractional r) => Polygon t p r -> Bool
+ Algorithms.Geometry.LineSegmentIntersection.BentleyOttmann: asEventPts :: Ord r => LineSegment 2 p r -> [Event p r]
+ Algorithms.Geometry.LineSegmentIntersection.BentleyOttmann: instance (GHC.Show.Show r, GHC.Show.Show p) => GHC.Show.Show (Algorithms.Geometry.LineSegmentIntersection.BentleyOttmann.Event p r)
+ Algorithms.Geometry.LineSegmentIntersection.BentleyOttmann: interiorIntersections :: (Ord r, Fractional r) => [LineSegment 2 p r] -> Intersections p r
+ Algorithms.Geometry.LineSegmentIntersection.BentleyOttmann: isClosedStart :: Eq r => Point 2 r -> LineSegment 2 p r -> Bool
+ Algorithms.Geometry.LineSegmentIntersection.BentleyOttmann: ordAt :: (Fractional r, Ord r) => r -> Compare (LineSegment 2 p r)
+ Algorithms.Geometry.LineSegmentIntersection.BentleyOttmann: xCoordAt :: (Fractional r, Ord r) => r -> LineSegment 2 p r -> r
+ Algorithms.Geometry.LineSegmentIntersection.Types: instance (GHC.Classes.Eq r, GHC.Classes.Eq p) => GHC.Classes.Eq (Algorithms.Geometry.LineSegmentIntersection.Types.IntersectionPoint p r)
+ Algorithms.Geometry.LineSegmentIntersection.Types: instance (GHC.Show.Show r, GHC.Show.Show p) => GHC.Show.Show (Algorithms.Geometry.LineSegmentIntersection.Types.Associated p r)
+ Algorithms.Geometry.LineSegmentIntersection.Types: instance (GHC.Show.Show r, GHC.Show.Show p) => GHC.Show.Show (Algorithms.Geometry.LineSegmentIntersection.Types.IntersectionPoint p r)
+ Algorithms.Geometry.LineSegmentIntersection.Types: instance GHC.Classes.Ord r => GHC.Base.Semigroup (Algorithms.Geometry.LineSegmentIntersection.Types.Associated p r)
+ Algorithms.Geometry.LineSegmentIntersection.Types: isEndPointIntersection :: Associated p r -> Bool
+ Algorithms.Geometry.LowerEnvelope.DualCH: intersect' :: forall r a. (Ord r, Fractional r) => Line 2 r :+ a -> Line 2 r :+ a -> Point 2 r :+ (a, a)
+ Algorithms.Geometry.LowerEnvelope.DualCH: lowerEnvelope :: (Ord r, Fractional r) => NonEmpty (Line 2 r :+ a) -> Envelope a r
+ Algorithms.Geometry.LowerEnvelope.DualCH: lowerEnvelopeWith :: (Fractional r, Eq r) => UpperHullAlgorithm (Line 2 r :+ a) r -> NonEmpty (Line 2 r :+ a) -> Envelope a r
+ Algorithms.Geometry.LowerEnvelope.DualCH: type Envelope a r = NonEmpty (Line 2 r :+ a)
+ Algorithms.Geometry.LowerEnvelope.DualCH: type UpperHullAlgorithm a r = NonEmpty (Point 2 r :+ a) -> NonEmpty (Point 2 r :+ a)
+ Algorithms.Geometry.LowerEnvelope.DualCH: vertices :: (Ord r, Fractional r) => Envelope a r -> [Point 2 r :+ (a, a)]
+ Algorithms.Geometry.PolygonTriangulation.MakeMonotone: End :: VertexType
+ Algorithms.Geometry.PolygonTriangulation.MakeMonotone: Merge :: VertexType
+ Algorithms.Geometry.PolygonTriangulation.MakeMonotone: Regular :: VertexType
+ Algorithms.Geometry.PolygonTriangulation.MakeMonotone: SS :: !(OrdSeq (LineSegment 2 Int r)) -> !(IntMap Int) -> StatusStruct r
+ Algorithms.Geometry.PolygonTriangulation.MakeMonotone: Split :: VertexType
+ Algorithms.Geometry.PolygonTriangulation.MakeMonotone: Start :: VertexType
+ Algorithms.Geometry.PolygonTriangulation.MakeMonotone: [_helper] :: StatusStruct r -> !(IntMap Int)
+ Algorithms.Geometry.PolygonTriangulation.MakeMonotone: [_statusStruct] :: StatusStruct r -> !(OrdSeq (LineSegment 2 Int r))
+ Algorithms.Geometry.PolygonTriangulation.MakeMonotone: classifyVertices :: (Num r, Ord r) => Polygon t p r -> Polygon t (p :+ VertexType) r
+ Algorithms.Geometry.PolygonTriangulation.MakeMonotone: classifyVertices' :: (Num r, Ord r) => SimplePolygon p r -> SimplePolygon (p :+ VertexType) r
+ Algorithms.Geometry.PolygonTriangulation.MakeMonotone: cmpSweep :: Ord r => Point 2 r :+ e -> Point 2 r :+ e -> Ordering
+ Algorithms.Geometry.PolygonTriangulation.MakeMonotone: computeDiagonals :: forall t r p. (Fractional r, Ord r) => Polygon t p r -> [LineSegment 2 p r]
+ Algorithms.Geometry.PolygonTriangulation.MakeMonotone: connectToLeft :: (Fractional r, Ord r) => Int -> Point 2 r -> Sweep p r ()
+ Algorithms.Geometry.PolygonTriangulation.MakeMonotone: data StatusStruct r
+ Algorithms.Geometry.PolygonTriangulation.MakeMonotone: data VertexType
+ Algorithms.Geometry.PolygonTriangulation.MakeMonotone: deleteAt :: (Fractional r, Ord r) => Point 2 r -> LineSegment 2 p r -> OrdSeq (LineSegment 2 p r) -> OrdSeq (LineSegment 2 p r)
+ Algorithms.Geometry.PolygonTriangulation.MakeMonotone: getEventType :: Event r -> Sweep p r VertexType
+ Algorithms.Geometry.PolygonTriangulation.MakeMonotone: getHelper :: Int -> Sweep p r (SP (Point 2 r :+ Int) VertexType)
+ Algorithms.Geometry.PolygonTriangulation.MakeMonotone: getIdx :: Event r -> Int
+ Algorithms.Geometry.PolygonTriangulation.MakeMonotone: getVertexType :: Int -> Sweep p r VertexType
+ Algorithms.Geometry.PolygonTriangulation.MakeMonotone: handle :: (Fractional r, Ord r) => Event r -> Sweep p r ()
+ Algorithms.Geometry.PolygonTriangulation.MakeMonotone: handleEnd :: (Fractional r, Ord r) => Int -> Event r -> Sweep p r ()
+ Algorithms.Geometry.PolygonTriangulation.MakeMonotone: handleMerge :: (Fractional r, Ord r) => Int -> Event r -> Sweep p r ()
+ Algorithms.Geometry.PolygonTriangulation.MakeMonotone: handleRegularL :: (Fractional r, Ord r) => Int -> Event r -> Sweep p r ()
+ Algorithms.Geometry.PolygonTriangulation.MakeMonotone: handleRegularR :: (Fractional r, Ord r) => Int -> Event r -> Sweep p r ()
+ Algorithms.Geometry.PolygonTriangulation.MakeMonotone: handleSplit :: (Fractional r, Ord r) => Int -> Event r -> Sweep p r ()
+ Algorithms.Geometry.PolygonTriangulation.MakeMonotone: handleStart :: (Fractional r, Ord r) => Int -> Event r -> Sweep p r ()
+ Algorithms.Geometry.PolygonTriangulation.MakeMonotone: helper :: forall r_a3Q8C. Lens' (StatusStruct r_a3Q8C) (IntMap Int)
+ Algorithms.Geometry.PolygonTriangulation.MakeMonotone: insertAt :: (Ord r, Fractional r) => Point 2 r -> LineSegment 2 q r -> OrdSeq (LineSegment 2 q r) -> OrdSeq (LineSegment 2 q r)
+ Algorithms.Geometry.PolygonTriangulation.MakeMonotone: instance GHC.Classes.Eq Algorithms.Geometry.PolygonTriangulation.MakeMonotone.VertexType
+ Algorithms.Geometry.PolygonTriangulation.MakeMonotone: instance GHC.Read.Read Algorithms.Geometry.PolygonTriangulation.MakeMonotone.VertexType
+ Algorithms.Geometry.PolygonTriangulation.MakeMonotone: instance GHC.Show.Show Algorithms.Geometry.PolygonTriangulation.MakeMonotone.VertexType
+ Algorithms.Geometry.PolygonTriangulation.MakeMonotone: instance GHC.Show.Show r => GHC.Show.Show (Algorithms.Geometry.PolygonTriangulation.MakeMonotone.StatusStruct r)
+ Algorithms.Geometry.PolygonTriangulation.MakeMonotone: isLeftVertex :: Ord r => Int -> Event r -> Bool
+ Algorithms.Geometry.PolygonTriangulation.MakeMonotone: ix' :: Int -> Lens' (Vector a) a
+ Algorithms.Geometry.PolygonTriangulation.MakeMonotone: lookupLE :: (Ord r, Fractional r) => Point 2 r -> OrdSeq (LineSegment 2 Int r) -> Maybe (LineSegment 2 Int r)
+ Algorithms.Geometry.PolygonTriangulation.MakeMonotone: makeMonotone :: (Fractional r, Ord r) => proxy s -> Polygon t p r -> PlanarSubdivision s p PolygonEdgeType PolygonFaceData r
+ Algorithms.Geometry.PolygonTriangulation.MakeMonotone: statusStruct :: forall r_a3Q8C r_a3Qjl. Lens (StatusStruct r_a3Q8C) (StatusStruct r_a3Qjl) (OrdSeq (LineSegment 2 Int r_a3Q8C)) (OrdSeq (LineSegment 2 Int r_a3Qjl))
+ Algorithms.Geometry.PolygonTriangulation.MakeMonotone: tell' :: LineSegment 2 Int r -> Sweep p r ()
+ Algorithms.Geometry.PolygonTriangulation.MakeMonotone: tellIfMerge :: Int -> Point 2 r -> Int -> Sweep p r ()
+ Algorithms.Geometry.PolygonTriangulation.MakeMonotone: type Event r = Point 2 r :+ (Two (LineSegment 2 Int r))
+ Algorithms.Geometry.PolygonTriangulation.MakeMonotone: type Sweep p r = WriterT (DList (LineSegment 2 Int r)) (StateT (StatusStruct r) (Reader (Vector (VertexInfo p r))))
+ Algorithms.Geometry.PolygonTriangulation.MakeMonotone: type VertexInfo p r = STR (Point 2 r) p VertexType
+ Algorithms.Geometry.PolygonTriangulation.Triangulate: computeDiagonals :: (Ord r, Fractional r) => Polygon t p r -> [LineSegment 2 p r]
+ Algorithms.Geometry.PolygonTriangulation.Triangulate: computeDiagonals' :: (Ord r, Fractional r) => Polygon t p r -> (Polygon t p r, [LineSegment 2 p r])
+ Algorithms.Geometry.PolygonTriangulation.Triangulate: triangulate :: (Ord r, Fractional r) => proxy s -> Polygon t p r -> PlanarSubdivision s p PolygonEdgeType PolygonFaceData r
+ Algorithms.Geometry.PolygonTriangulation.Triangulate: triangulate' :: (Ord r, Fractional r) => proxy s -> Polygon t p r -> PlaneGraph s p PolygonEdgeType PolygonFaceData r
+ Algorithms.Geometry.PolygonTriangulation.TriangulateMonotone: L :: LR
+ Algorithms.Geometry.PolygonTriangulation.TriangulateMonotone: R :: LR
+ Algorithms.Geometry.PolygonTriangulation.TriangulateMonotone: chainOf :: P p r -> LR
+ Algorithms.Geometry.PolygonTriangulation.TriangulateMonotone: computeDiagonals :: (Ord r, Num r) => MonotonePolygon p r -> [LineSegment 2 p r]
+ Algorithms.Geometry.PolygonTriangulation.TriangulateMonotone: data LR
+ Algorithms.Geometry.PolygonTriangulation.TriangulateMonotone: instance GHC.Classes.Eq Algorithms.Geometry.PolygonTriangulation.TriangulateMonotone.LR
+ Algorithms.Geometry.PolygonTriangulation.TriangulateMonotone: instance GHC.Show.Show Algorithms.Geometry.PolygonTriangulation.TriangulateMonotone.LR
+ Algorithms.Geometry.PolygonTriangulation.TriangulateMonotone: isInside :: (Ord r, Num r) => P p r -> (P p r, P p r) -> Bool
+ Algorithms.Geometry.PolygonTriangulation.TriangulateMonotone: mergeBy :: (a -> a -> Ordering) -> [a] -> [a] -> [a]
+ Algorithms.Geometry.PolygonTriangulation.TriangulateMonotone: process :: (Ord r, Num r) => P p r -> Stack (P p r) -> SP (Stack (P p r)) [LineSegment 2 p r]
+ Algorithms.Geometry.PolygonTriangulation.TriangulateMonotone: seg :: P p r -> P p r -> LineSegment 2 p r
+ Algorithms.Geometry.PolygonTriangulation.TriangulateMonotone: splitPolygon :: Ord r => MonotonePolygon p r -> ([Point 2 r :+ (LR :+ p)], [Point 2 r :+ (LR :+ p)])
+ Algorithms.Geometry.PolygonTriangulation.TriangulateMonotone: testPoly5 :: SimplePolygon () Rational
+ Algorithms.Geometry.PolygonTriangulation.TriangulateMonotone: toVtx :: P p r -> Point 2 r :+ p
+ Algorithms.Geometry.PolygonTriangulation.TriangulateMonotone: triangulate :: (Ord r, Fractional r) => proxy s -> MonotonePolygon p r -> PlanarSubdivision s p PolygonEdgeType PolygonFaceData r
+ Algorithms.Geometry.PolygonTriangulation.TriangulateMonotone: triangulate' :: (Ord r, Fractional r) => proxy s -> MonotonePolygon p r -> PlaneGraph s p PolygonEdgeType PolygonFaceData r
+ Algorithms.Geometry.PolygonTriangulation.TriangulateMonotone: type MonotonePolygon p r = SimplePolygon p r
+ Algorithms.Geometry.PolygonTriangulation.TriangulateMonotone: type P p r = Point 2 r :+ (LR :+ p)
+ Algorithms.Geometry.PolygonTriangulation.TriangulateMonotone: type Stack a = [a]
+ Algorithms.Geometry.PolygonTriangulation.Types: Diagonal :: PolygonEdgeType
+ Algorithms.Geometry.PolygonTriangulation.Types: Original :: PolygonEdgeType
+ Algorithms.Geometry.PolygonTriangulation.Types: constructGraph :: forall proxy r s p. (Fractional r, Ord r) => proxy s -> LineSegment 2 p r -> [LineSegment 2 p r] -> [LineSegment 2 p r] -> PlaneGraph s p PolygonEdgeType PolygonFaceData r
+ Algorithms.Geometry.PolygonTriangulation.Types: constructSubdivision :: forall proxy r s p. (Fractional r, Ord r) => proxy s -> LineSegment 2 p r -> [LineSegment 2 p r] -> [LineSegment 2 p r] -> PlanarSubdivision s p PolygonEdgeType PolygonFaceData r
+ Algorithms.Geometry.PolygonTriangulation.Types: data PolygonEdgeType
+ Algorithms.Geometry.PolygonTriangulation.Types: instance GHC.Classes.Eq Algorithms.Geometry.PolygonTriangulation.Types.PolygonEdgeType
+ Algorithms.Geometry.PolygonTriangulation.Types: instance GHC.Read.Read Algorithms.Geometry.PolygonTriangulation.Types.PolygonEdgeType
+ Algorithms.Geometry.PolygonTriangulation.Types: instance GHC.Show.Show Algorithms.Geometry.PolygonTriangulation.Types.PolygonEdgeType
+ Algorithms.Geometry.Sweep: Tagged :: a -> Tagged a
+ Algorithms.Geometry.Sweep: Timed :: (Tagged s t) -> a -> Timed s t a
+ Algorithms.Geometry.Sweep: [atTime] :: Timed s t a -> (Tagged s t) -> a
+ Algorithms.Geometry.Sweep: [unTag] :: Tagged a -> a
+ Algorithms.Geometry.Sweep: coerceTo :: proxy s -> f (Timed s' t k) v -> f (Timed s t k) v
+ Algorithms.Geometry.Sweep: compare_ :: forall s t k. (Ord k, Reifies s t) => Timed s t k -> Timed s t k -> Ordering
+ Algorithms.Geometry.Sweep: constT :: proxy s -> Int -> Timed s Int Int
+ Algorithms.Geometry.Sweep: getTime :: Timed s Int Int
+ Algorithms.Geometry.Sweep: instance (Data.Reflection.Reifies s t, GHC.Classes.Ord k) => GHC.Classes.Eq (Algorithms.Geometry.Sweep.Timed s t k)
+ Algorithms.Geometry.Sweep: instance (Data.Reflection.Reifies s t, GHC.Classes.Ord k) => GHC.Classes.Ord (Algorithms.Geometry.Sweep.Timed s t k)
+ Algorithms.Geometry.Sweep: instance GHC.Classes.Eq a => GHC.Classes.Eq (Algorithms.Geometry.Sweep.Tagged s a)
+ Algorithms.Geometry.Sweep: instance GHC.Classes.Ord a => GHC.Classes.Ord (Algorithms.Geometry.Sweep.Tagged s a)
+ Algorithms.Geometry.Sweep: instance GHC.Show.Show a => GHC.Show.Show (Algorithms.Geometry.Sweep.Tagged s a)
+ Algorithms.Geometry.Sweep: newtype Tagged (s :: *) a
+ Algorithms.Geometry.Sweep: newtype Timed s t a
+ Algorithms.Geometry.Sweep: query :: forall s v. Ord (Timed s Int Int) => Map (Timed s Int Int) v -> Maybe v
+ Algorithms.Geometry.Sweep: runAt :: forall s0 t k r f v. Ord k => t -> f (Timed s0 t k) v -> (forall s. Reifies s t => f (Timed s t k) v -> r) -> r
+ Algorithms.Geometry.Sweep: tag :: proxy s -> a -> Tagged s a
+ Algorithms.Geometry.Sweep: test1 :: Int -> Bool
+ Algorithms.Geometry.Sweep: test2 :: Int -> Maybe String
+ Algorithms.Geometry.Sweep: test2M :: Reifies s Int => proxy s -> Map (Timed s Int Int) String
+ Algorithms.Geometry.Sweep: unTagged :: f (Timed s t k) v -> f (Timed () t k) v
+ Algorithms.Geometry.WellSeparatedPairDecomposition.Types: instance (Data.Geometry.Vector.VectorFamily.Arity d, GHC.Classes.Eq r, GHC.Classes.Eq a) => GHC.Classes.Eq (Algorithms.Geometry.WellSeparatedPairDecomposition.Types.NodeData d r a)
+ Algorithms.Geometry.WellSeparatedPairDecomposition.Types: instance (Data.Geometry.Vector.VectorFamily.Arity d, GHC.Classes.Eq r, GHC.Classes.Eq p) => GHC.Classes.Eq (Algorithms.Geometry.WellSeparatedPairDecomposition.Types.FindAndCompact d r p)
+ Algorithms.Geometry.WellSeparatedPairDecomposition.Types: instance (Data.Geometry.Vector.VectorFamily.Arity d, GHC.Show.Show r, GHC.Show.Show a) => GHC.Show.Show (Algorithms.Geometry.WellSeparatedPairDecomposition.Types.NodeData d r a)
+ Algorithms.Geometry.WellSeparatedPairDecomposition.Types: instance (Data.Geometry.Vector.VectorFamily.Arity d, GHC.Show.Show r, GHC.Show.Show p) => GHC.Show.Show (Algorithms.Geometry.WellSeparatedPairDecomposition.Types.FindAndCompact d r p)
+ Algorithms.Geometry.WellSeparatedPairDecomposition.Types: instance GHC.Base.Semigroup v => Data.BinaryTree.Measured v (Algorithms.Geometry.WellSeparatedPairDecomposition.Types.NodeData d r v)
+ Algorithms.Util: instance (GHC.Classes.Eq a, GHC.Classes.Eq b) => GHC.Classes.Eq (Algorithms.Util.SP a b)
+ Algorithms.Util: instance (GHC.Classes.Eq a, GHC.Classes.Eq b, GHC.Classes.Eq c) => GHC.Classes.Eq (Algorithms.Util.ST a b c)
+ Algorithms.Util: instance (GHC.Classes.Ord a, GHC.Classes.Ord b) => GHC.Classes.Ord (Algorithms.Util.SP a b)
+ Algorithms.Util: instance (GHC.Classes.Ord a, GHC.Classes.Ord b, GHC.Classes.Ord c) => GHC.Classes.Ord (Algorithms.Util.ST a b c)
+ Algorithms.Util: instance (GHC.Show.Show a, GHC.Show.Show b) => GHC.Show.Show (Algorithms.Util.SP a b)
+ Algorithms.Util: instance (GHC.Show.Show a, GHC.Show.Show b, GHC.Show.Show c) => GHC.Show.Show (Algorithms.Util.ST a b c)
+ Data.BalBST: delete :: Eq a => a -> BalBST k a -> BalBST k a
+ Data.BalBST: instance (GHC.Classes.Eq a, GHC.Classes.Eq b) => GHC.Classes.Eq (Data.BalBST.Pair a b)
+ Data.BalBST: instance (GHC.Classes.Eq a, GHC.Classes.Eq b) => GHC.Classes.Eq (Data.BalBST.Split a b)
+ Data.BalBST: instance (GHC.Classes.Eq a, GHC.Classes.Eq k) => GHC.Classes.Eq (Data.BalBST.Tree k a)
+ Data.BalBST: instance (GHC.Classes.Eq k, GHC.Classes.Eq a) => GHC.Classes.Eq (Data.BalBST.T k a)
+ Data.BalBST: instance (GHC.Classes.Ord k, GHC.Classes.Ord a) => GHC.Classes.Ord (Data.BalBST.T k a)
+ Data.BalBST: instance (GHC.Show.Show a, GHC.Show.Show b) => GHC.Show.Show (Data.BalBST.Pair a b)
+ Data.BalBST: instance (GHC.Show.Show a, GHC.Show.Show b) => GHC.Show.Show (Data.BalBST.Split a b)
+ Data.BalBST: instance (GHC.Show.Show a, GHC.Show.Show k) => GHC.Show.Show (Data.BalBST.Tree k a)
+ Data.BalBST: instance (GHC.Show.Show k, GHC.Show.Show a) => GHC.Show.Show (Data.BalBST.T k a)
+ Data.BalBST: lookupLE :: Ord k => k -> BalBST k a -> Maybe a
+ Data.BalBST: lookupMax :: BalBST k b -> Maybe b
+ Data.BalBST: lookupMin :: BalBST k b -> Maybe b
+ Data.BinaryTree: instance (GHC.Classes.Eq a, GHC.Classes.Eq v) => GHC.Classes.Eq (Data.BinaryTree.BinLeafTree v a)
+ Data.BinaryTree: instance (GHC.Classes.Eq v, GHC.Classes.Eq a) => GHC.Classes.Eq (Data.BinaryTree.RoseElem v a)
+ Data.BinaryTree: instance (GHC.Classes.Ord a, GHC.Classes.Ord v) => GHC.Classes.Ord (Data.BinaryTree.BinLeafTree v a)
+ Data.BinaryTree: instance (GHC.Read.Read a, GHC.Read.Read v) => GHC.Read.Read (Data.BinaryTree.BinLeafTree v a)
+ Data.BinaryTree: instance (GHC.Show.Show a, GHC.Show.Show v) => GHC.Show.Show (Data.BinaryTree.BinLeafTree v a)
+ Data.BinaryTree: instance (GHC.Show.Show v, GHC.Show.Show a) => GHC.Show.Show (Data.BinaryTree.RoseElem v a)
+ Data.BinaryTree: instance Data.BinaryTree.Measured v a => GHC.Base.Semigroup (Data.BinaryTree.BinLeafTree v a)
+ Data.BinaryTree: instance GHC.Base.Semigroup Data.BinaryTree.Size
+ Data.BinaryTree: instance GHC.Base.Semigroup a => GHC.Base.Semigroup (Data.BinaryTree.Sized a)
+ Data.CircularSeq: instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Data.CircularSeq.CSeq a)
+ Data.CircularSeq: instance GHC.Generics.Generic (Data.CircularSeq.CSeq a)
+ Data.Ext: data core (:+) extra
+ Data.Ext: instance (Control.DeepSeq.NFData core, Control.DeepSeq.NFData extra) => Control.DeepSeq.NFData (core Data.Ext.:+ extra)
+ Data.Ext: instance (Data.Aeson.Types.FromJSON.FromJSON core, Data.Aeson.Types.FromJSON.FromJSON extra) => Data.Aeson.Types.FromJSON.FromJSON (core Data.Ext.:+ extra)
+ Data.Ext: instance (Data.Aeson.Types.ToJSON.ToJSON core, Data.Aeson.Types.ToJSON.ToJSON extra) => Data.Aeson.Types.ToJSON.ToJSON (core Data.Ext.:+ extra)
+ Data.Ext: instance (GHC.Base.Semigroup core, GHC.Base.Semigroup extra) => GHC.Base.Semigroup (core Data.Ext.:+ extra)
+ Data.Ext: instance (GHC.Classes.Eq core, GHC.Classes.Eq extra) => GHC.Classes.Eq (core Data.Ext.:+ extra)
+ Data.Ext: instance (GHC.Classes.Ord core, GHC.Classes.Ord extra) => GHC.Classes.Ord (core Data.Ext.:+ extra)
+ Data.Ext: instance (GHC.Enum.Bounded core, GHC.Enum.Bounded extra) => GHC.Enum.Bounded (core Data.Ext.:+ extra)
+ Data.Ext: instance (GHC.Read.Read core, GHC.Read.Read extra) => GHC.Read.Read (core Data.Ext.:+ extra)
+ Data.Ext: instance (GHC.Show.Show core, GHC.Show.Show extra) => GHC.Show.Show (core Data.Ext.:+ extra)
+ Data.Geometry: (*^) :: (Functor f, Num a) => a -> f a -> f a
+ Data.Geometry: (.+^) :: (Affine p, Num a) => p a -> Diff p a -> p a
+ Data.Geometry: (.-.) :: (Affine p, Num a) => p a -> p a -> Diff p a
+ Data.Geometry: (.-^) :: (Affine p, Num a) => p a -> Diff p a -> p a
+ Data.Geometry: (^*) :: (Functor f, Num a) => f a -> a -> f a
+ Data.Geometry: (^+^) :: (Additive f, Num a) => f a -> f a -> f a
+ Data.Geometry: (^-^) :: (Additive f, Num a) => f a -> f a -> f a
+ Data.Geometry: (^/) :: (Functor f, Fractional a) => f a -> a -> f a
+ Data.Geometry: C :: C
+ Data.Geometry: E :: forall x (f :: * -> *). Functor f => x -> f x -> t x -> f t x -> E
+ Data.Geometry: MKVector :: VectorFamily (Peano d) r -> Vector
+ Data.Geometry: Multi :: PolygonType
+ Data.Geometry: PolyLine :: Seq2 (Point d r :+ p) -> PolyLine d p r
+ Data.Geometry: Simple :: PolygonType
+ Data.Geometry: [MultiPolygon] :: CSeq (Point 2 r :+ p) -> [Polygon Simple p r] -> Polygon Multi p r
+ Data.Geometry: [SimplePolygon] :: CSeq (Point 2 r :+ p) -> Polygon Simple p r
+ Data.Geometry: [_points] :: PolyLine d p r -> Seq2 (Point d r :+ p)
+ Data.Geometry: [_unV] :: Vector -> VectorFamily (Peano d) r
+ Data.Geometry: [el] :: E -> forall x (f :: * -> *). Functor f => x -> f x -> t x -> f t x
+ Data.Geometry: area :: Fractional r => Polygon t p r -> r
+ Data.Geometry: asLineSegment :: PolyLine d p r -> LineSegment d p r
+ Data.Geometry: asLineSegment' :: PolyLine d p r -> Maybe (LineSegment d p r)
+ Data.Geometry: asSimplePolygon :: Polygon t p r -> SimplePolygon p r
+ Data.Geometry: basis :: (Additive t, Traversable t, Num a) => [t a]
+ Data.Geometry: basisFor :: (Traversable t, Num a) => t b -> [t a]
+ Data.Geometry: bitraverseVertices :: (Applicative f, Traversable t) => (p -> f q) -> (r -> f s) -> t (Point 2 r :+ p) -> f (t (Point 2 s :+ q))
+ Data.Geometry: centroid :: Fractional r => SimplePolygon p r -> Point 2 r
+ Data.Geometry: class Functor f => Additive (f :: * -> *)
+ Data.Geometry: class Additive Diff p => Affine (p :: * -> *) where {
+ Data.Geometry: cmpExtreme :: (Num r, Ord r) => Vector 2 r -> Point 2 r :+ p -> Point 2 r :+ q -> Ordering
+ Data.Geometry: cross :: Num r => Vector 3 r -> Vector 3 r -> Vector 3 r
+ Data.Geometry: data C (n :: Nat)
+ Data.Geometry: data Polygon (t :: PolygonType) p r
+ Data.Geometry: data PolygonType
+ Data.Geometry: destruct :: (Arity d, Arity (d + 1)) => Vector (d + 1) r -> (r, Vector d r)
+ Data.Geometry: distanceA :: (Floating a, Foldable Diff p, Affine p) => p a -> p a -> a
+ Data.Geometry: dot :: (Metric f, Num a) => f a -> f a -> a
+ Data.Geometry: element :: forall proxy i d r. (Arity d, KnownNat i, (i + 1) <= d) => proxy i -> Lens' (Vector d r) r
+ Data.Geometry: element' :: forall d r. Arity d => Int -> Traversal' (Vector d r) r
+ Data.Geometry: extremesLinear :: (Ord r, Num r) => Vector 2 r -> Polygon t p r -> (Point 2 r :+ p, Point 2 r :+ p)
+ Data.Geometry: fromLineSegment :: LineSegment d p r -> PolyLine d p r
+ Data.Geometry: fromPoints' :: (Monoid p) => [Point d r] -> PolyLine d p r
+ Data.Geometry: holeList :: Polygon t p r -> [Polygon Simple p r]
+ Data.Geometry: imap :: (Vector v a, Vector v b) => Int -> a -> b -> v a -> v b
+ Data.Geometry: inPolygon :: forall t p r. (Fractional r, Ord r) => Point 2 r -> Polygon t p r -> PointLocationResult
+ Data.Geometry: infixl 7 *^
+ Data.Geometry: init :: (Arity d, Arity (d + 1)) => Vector (d + 1) r -> Vector d r
+ Data.Geometry: insidePolygon :: (Fractional r, Ord r) => Point 2 r -> Polygon t p r -> Bool
+ Data.Geometry: isCounterClockwise :: (Eq r, Fractional r) => Polygon t p r -> Bool
+ Data.Geometry: isScalarMultipleOf :: (Eq r, Fractional r, Arity d) => Vector d r -> Vector d r -> Bool
+ Data.Geometry: lerp :: (Additive f, Num a) => a -> f a -> f a -> f a
+ Data.Geometry: liftI2 :: Additive f => a -> b -> c -> f a -> f b -> f c
+ Data.Geometry: liftU2 :: Additive f => a -> a -> a -> f a -> f a -> f a
+ Data.Geometry: listEdges :: Polygon t p r -> [LineSegment 2 p r]
+ Data.Geometry: negated :: (Functor f, Num a) => f a -> f a
+ Data.Geometry: newtype E (t :: * -> *)
+ Data.Geometry: newtype PolyLine d p r
+ Data.Geometry: newtype Vector (d :: Nat) (r :: *)
+ Data.Geometry: norm :: (Metric f, Floating a) => f a -> a
+ Data.Geometry: numberVertices :: Polygon t p r -> Polygon t (SP Int p) r
+ Data.Geometry: onBoundary :: (Fractional r, Ord r) => Point 2 r -> Polygon t p r -> Bool
+ Data.Geometry: outer :: (Functor f, Functor g, Num a) => f a -> g a -> f g a
+ Data.Geometry: outerBoundary :: forall t p r. Lens' (Polygon t p r) (CSeq (Point 2 r :+ p))
+ Data.Geometry: outerBoundaryEdge :: Int -> Polygon t p r -> LineSegment 2 p r
+ Data.Geometry: outerBoundaryEdges :: Polygon t p r -> CSeq (LineSegment 2 p r)
+ Data.Geometry: outerVertex :: Int -> Lens' (Polygon t p r) (Point 2 r :+ p)
+ Data.Geometry: points :: forall d_a2oFY p_a2oFZ r_a2oG0 d_a2oGG p_a2oGH r_a2oGI. Iso (PolyLine d_a2oFY p_a2oFZ r_a2oG0) (PolyLine d_a2oGG p_a2oGH r_a2oGI) (Seq2 ((:+) (Point d_a2oFY r_a2oG0) p_a2oFZ)) (Seq2 ((:+) (Point d_a2oGG r_a2oGI) p_a2oGH))
+ Data.Geometry: polygonHoles :: forall p r. Lens' (Polygon Multi p r) [Polygon Simple p r]
+ Data.Geometry: polygonVertices :: Polygon t p r -> NonEmpty (Point 2 r :+ p)
+ Data.Geometry: prefix :: forall i d r. (Arity d, Arity i, i <= d) => Vector d r -> Vector i r
+ Data.Geometry: qdA :: (Affine p, Foldable Diff p, Num a) => p a -> p a -> a
+ Data.Geometry: replicate :: Vector v a => a -> v a
+ Data.Geometry: reverseOuterBoundary :: Polygon t p r -> Polygon t p r
+ Data.Geometry: scalarMultiple :: (Eq r, Fractional r, Arity d) => Vector d r -> Vector d r -> Maybe r
+ Data.Geometry: scaled :: (Traversable t, Num a) => t a -> t t a
+ Data.Geometry: signedArea :: Fractional r => SimplePolygon p r -> r
+ Data.Geometry: signorm :: (Metric f, Floating a) => f a -> f a
+ Data.Geometry: snoc :: (Arity (d + 1), Arity d) => Vector d r -> r -> Vector (d + 1) r
+ Data.Geometry: sumV :: (Foldable f, Additive v, Num a) => f v a -> v a
+ Data.Geometry: toClockwiseOrder :: (Eq r, Fractional r) => Polygon t p r -> Polygon t p r
+ Data.Geometry: toCounterClockWiseOrder :: (Eq r, Fractional r) => Polygon t p r -> Polygon t p r
+ Data.Geometry: toEdges :: CSeq (Point 2 r :+ p) -> CSeq (LineSegment 2 p r)
+ Data.Geometry: type Arity d = (ImplicitArity (Peano d), KnownNat d)
+ Data.Geometry: type MultiPolygon = Polygon Multi
+ Data.Geometry: type SimplePolygon = Polygon Simple
+ Data.Geometry: type SomePolygon p r = Either (Polygon Simple p r) (Polygon Multi p r)
+ Data.Geometry: type family Diff (p :: * -> *) :: * -> *;
+ Data.Geometry: unV :: Lens (Vector d r) (Vector d s) (VectorFamily (Peano d) r) (VectorFamily (Peano d) s)
+ Data.Geometry: unit :: (Additive t, Num a) => ASetter' t a a -> t a
+ Data.Geometry: vectorFromList :: Arity d => [r] -> Maybe (Vector d r)
+ Data.Geometry: vectorFromListUnsafe :: Arity d => [r] -> Vector d r
+ Data.Geometry: withIncidentEdges :: Polygon t p r -> Polygon t (Two (LineSegment 2 p r)) r
+ Data.Geometry: zero :: (Additive f, Num a) => f a
+ Data.Geometry: }
+ Data.Geometry.Ball: instance (Control.DeepSeq.NFData p, Control.DeepSeq.NFData r, Data.Geometry.Vector.VectorFamily.Arity d) => Control.DeepSeq.NFData (Data.Geometry.Ball.Ball d p r)
+ Data.Geometry.Ball: instance (GHC.Classes.Eq r, GHC.Classes.Eq p, Data.Geometry.Vector.VectorFamily.Arity d) => GHC.Classes.Eq (Data.Geometry.Ball.Ball d p r)
+ Data.Geometry.Ball: instance (GHC.Show.Show r, GHC.Show.Show p, Data.Geometry.Vector.VectorFamily.Arity d) => GHC.Show.Show (Data.Geometry.Ball.Ball d p r)
+ Data.Geometry.Ball: instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Bifunctor.Bifunctor (Data.Geometry.Ball.Ball d)
+ Data.Geometry.Ball: instance Data.Geometry.Vector.VectorFamily.Arity d => GHC.Base.Functor (Data.Geometry.Ball.Ball d p)
+ Data.Geometry.Boundary: instance Data.Foldable.Foldable Data.Geometry.Boundary.Boundary
+ Data.Geometry.Boundary: instance Data.Traversable.Traversable Data.Geometry.Boundary.Boundary
+ Data.Geometry.Boundary: instance GHC.Base.Functor Data.Geometry.Boundary.Boundary
+ Data.Geometry.Box: instance (Control.DeepSeq.NFData p, Control.DeepSeq.NFData r, Data.Geometry.Vector.VectorFamily.Arity d) => Control.DeepSeq.NFData (Data.Geometry.Box.Internal.Box d p r)
+ Data.Geometry.Box.Internal: fromCenter :: (Arity d, Fractional r) => Point d r -> Vector d r -> Box d () r
+ Data.Geometry.Box.Internal: instance (Data.Geometry.Vector.VectorFamily.Arity d, GHC.Classes.Ord r) => Data.Geometry.Properties.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.Vector.VectorFamily.Arity d, GHC.Classes.Ord r, GHC.Base.Semigroup p) => GHC.Base.Semigroup (Data.Geometry.Box.Internal.Box d p r)
+ Data.Geometry.Box.Internal: instance (GHC.Classes.Eq r, GHC.Classes.Eq p, Data.Geometry.Vector.VectorFamily.Arity d) => GHC.Classes.Eq (Data.Geometry.Box.Internal.Box d p r)
+ Data.Geometry.Box.Internal: instance (GHC.Classes.Ord r, Data.Geometry.Vector.VectorFamily.Arity d) => Data.Geometry.Properties.IsIntersectableWith (Data.Geometry.Box.Internal.Box d p r) (Data.Geometry.Box.Internal.Box d q r)
+ Data.Geometry.Box.Internal: instance (GHC.Classes.Ord r, GHC.Classes.Ord p, Data.Geometry.Vector.VectorFamily.Arity d) => GHC.Classes.Ord (Data.Geometry.Box.Internal.Box d p r)
+ Data.Geometry.Box.Internal: 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.Box.Internal.Box d p r)
+ Data.Geometry.Box.Internal: instance (GHC.Show.Show r, GHC.Show.Show p, Data.Geometry.Vector.VectorFamily.Arity d) => GHC.Show.Show (Data.Geometry.Box.Internal.Box d p r)
+ Data.Geometry.Box.Internal: instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Bifunctor.Bifunctor (Data.Geometry.Box.Internal.Box d)
+ Data.Geometry.HalfLine: instance (Control.DeepSeq.NFData r, Data.Geometry.Vector.VectorFamily.Arity d) => Control.DeepSeq.NFData (Data.Geometry.HalfLine.HalfLine d r)
+ 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.HalfLine: 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.HalfLine.HalfLine d r)
+ Data.Geometry.HalfLine: instance (GHC.Show.Show r, Data.Geometry.Vector.VectorFamily.Arity d) => GHC.Show.Show (Data.Geometry.HalfLine.HalfLine d r)
+ Data.Geometry.HalfLine: instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Foldable.Foldable (Data.Geometry.HalfLine.HalfLine d)
+ Data.Geometry.HalfLine: instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Traversable.Traversable (Data.Geometry.HalfLine.HalfLine d)
+ Data.Geometry.HalfLine: instance Data.Geometry.Vector.VectorFamily.Arity d => GHC.Base.Functor (Data.Geometry.HalfLine.HalfLine d)
+ Data.Geometry.IntervalTree: instance (Control.DeepSeq.NFData r, Control.DeepSeq.NFData i) => Control.DeepSeq.NFData (Data.Geometry.IntervalTree.NodeData i r)
+ Data.Geometry.IntervalTree: instance (GHC.Classes.Eq r, GHC.Classes.Eq i) => GHC.Classes.Eq (Data.Geometry.IntervalTree.NodeData i r)
+ Data.Geometry.IntervalTree: instance (GHC.Classes.Ord r, GHC.Classes.Ord i) => GHC.Classes.Ord (Data.Geometry.IntervalTree.NodeData i r)
+ Data.Geometry.IntervalTree: instance (GHC.Show.Show r, GHC.Show.Show i) => GHC.Show.Show (Data.Geometry.IntervalTree.NodeData i r)
+ Data.Geometry.Ipe.Attributes: instance Data.Foldable.Foldable Data.Geometry.Ipe.Attributes.IpeValue
+ Data.Geometry.Ipe.Attributes: instance Data.Singletons.Internal.SingI 'Data.Geometry.Ipe.Attributes.Arrow
+ Data.Geometry.Ipe.Attributes: instance Data.Singletons.Internal.SingI 'Data.Geometry.Ipe.Attributes.Clip
+ Data.Geometry.Ipe.Attributes: instance Data.Singletons.Internal.SingI 'Data.Geometry.Ipe.Attributes.Dash
+ Data.Geometry.Ipe.Attributes: instance Data.Singletons.Internal.SingI 'Data.Geometry.Ipe.Attributes.Fill
+ Data.Geometry.Ipe.Attributes: instance Data.Singletons.Internal.SingI 'Data.Geometry.Ipe.Attributes.FillRule
+ Data.Geometry.Ipe.Attributes: instance Data.Singletons.Internal.SingI 'Data.Geometry.Ipe.Attributes.Gradient
+ Data.Geometry.Ipe.Attributes: instance Data.Singletons.Internal.SingI 'Data.Geometry.Ipe.Attributes.Layer
+ Data.Geometry.Ipe.Attributes: instance Data.Singletons.Internal.SingI 'Data.Geometry.Ipe.Attributes.LineCap
+ Data.Geometry.Ipe.Attributes: instance Data.Singletons.Internal.SingI 'Data.Geometry.Ipe.Attributes.LineJoin
+ Data.Geometry.Ipe.Attributes: instance Data.Singletons.Internal.SingI 'Data.Geometry.Ipe.Attributes.Matrix
+ Data.Geometry.Ipe.Attributes: instance Data.Singletons.Internal.SingI 'Data.Geometry.Ipe.Attributes.Opacity
+ Data.Geometry.Ipe.Attributes: instance Data.Singletons.Internal.SingI 'Data.Geometry.Ipe.Attributes.Pen
+ Data.Geometry.Ipe.Attributes: instance Data.Singletons.Internal.SingI 'Data.Geometry.Ipe.Attributes.Pin
+ Data.Geometry.Ipe.Attributes: instance Data.Singletons.Internal.SingI 'Data.Geometry.Ipe.Attributes.RArrow
+ Data.Geometry.Ipe.Attributes: instance Data.Singletons.Internal.SingI 'Data.Geometry.Ipe.Attributes.Size
+ Data.Geometry.Ipe.Attributes: instance Data.Singletons.Internal.SingI 'Data.Geometry.Ipe.Attributes.Stroke
+ Data.Geometry.Ipe.Attributes: instance Data.Singletons.Internal.SingI 'Data.Geometry.Ipe.Attributes.Tiling
+ Data.Geometry.Ipe.Attributes: instance Data.Singletons.Internal.SingI 'Data.Geometry.Ipe.Attributes.Transformations
+ Data.Geometry.Ipe.Attributes: instance Data.Singletons.Internal.SingKind Data.Geometry.Ipe.Attributes.AttributeUniverse
+ Data.Geometry.Ipe.Attributes: instance Data.Traversable.Traversable Data.Geometry.Ipe.Attributes.IpeValue
+ Data.Geometry.Ipe.Attributes: instance GHC.Base.Functor Data.Geometry.Ipe.Attributes.IpeValue
+ Data.Geometry.Ipe.Attributes: instance GHC.Classes.Eq r => GHC.Classes.Eq (Data.Geometry.Ipe.Attributes.IpeColor r)
+ Data.Geometry.Ipe.Attributes: instance GHC.Classes.Ord r => GHC.Classes.Ord (Data.Geometry.Ipe.Attributes.IpeColor r)
+ Data.Geometry.Ipe.Attributes: instance GHC.Show.Show r => GHC.Show.Show (Data.Geometry.Ipe.Attributes.IpeColor r)
+ Data.Geometry.Ipe.Attributes: instance forall u (ats :: [u]) (f :: Data.Singletons.Internal.TyFun u * -> *). Data.Vinyl.Core.RecApplicative ats => GHC.Base.Monoid (Data.Geometry.Ipe.Attributes.Attributes f ats)
+ Data.Geometry.Ipe.Attributes: instance forall u (f :: Data.Singletons.Internal.TyFun u * -> *) (ats :: [u]). Data.Vinyl.TypeLevel.RecAll (Data.Geometry.Ipe.Attributes.Attr f) ats GHC.Classes.Eq => GHC.Classes.Eq (Data.Geometry.Ipe.Attributes.Attributes f ats)
+ Data.Geometry.Ipe.Attributes: instance forall u (f :: Data.Singletons.Internal.TyFun u * -> *) (ats :: [u]). Data.Vinyl.TypeLevel.RecAll (Data.Geometry.Ipe.Attributes.Attr f) ats GHC.Show.Show => GHC.Show.Show (Data.Geometry.Ipe.Attributes.Attributes f ats)
+ Data.Geometry.Ipe.Attributes: instance forall u (f :: Data.Singletons.Internal.TyFun u * -> *) (ats :: [u]). GHC.Base.Semigroup (Data.Geometry.Ipe.Attributes.Attributes f ats)
+ Data.Geometry.Ipe.Attributes: instance forall u (f :: Data.Singletons.Internal.TyFun u * -> *) (l :: u). GHC.Base.Monoid (Data.Geometry.Ipe.Attributes.Attr f l)
+ Data.Geometry.Ipe.Attributes: instance forall u (f :: Data.Singletons.Internal.TyFun u * -> *) (l :: u). GHC.Base.Semigroup (Data.Geometry.Ipe.Attributes.Attr f l)
+ Data.Geometry.Ipe.Attributes: instance forall u (f :: u Data.Singletons.Internal.~> *) (label :: u). GHC.Classes.Eq (Data.Singletons.Internal.Apply f label) => GHC.Classes.Eq (Data.Geometry.Ipe.Attributes.Attr f label)
+ Data.Geometry.Ipe.Attributes: instance forall u (f :: u Data.Singletons.Internal.~> *) (label :: u). GHC.Classes.Ord (Data.Singletons.Internal.Apply f label) => GHC.Classes.Ord (Data.Geometry.Ipe.Attributes.Attr f label)
+ Data.Geometry.Ipe.Attributes: instance forall u (f :: u Data.Singletons.Internal.~> *) (label :: u). GHC.Read.Read (Data.Singletons.Internal.Apply f label) => GHC.Read.Read (Data.Geometry.Ipe.Attributes.Attr f label)
+ Data.Geometry.Ipe.Attributes: instance forall u (f :: u Data.Singletons.Internal.~> *) (label :: u). GHC.Show.Show (Data.Singletons.Internal.Apply f label) => GHC.Show.Show (Data.Geometry.Ipe.Attributes.Attr f label)
+ Data.Geometry.Ipe.FromIpe: _asMultiPolygon :: Prism' (Path r) (MultiPolygon () r)
+ Data.Geometry.Ipe.FromIpe: class HasDefaultFromIpe g where {
+ Data.Geometry.Ipe.FromIpe: defaultFromIpe :: (HasDefaultFromIpe g, (r ~ NumType g)) => Prism' (IpeObject r) (g :+ IpeAttributes (DefaultFromIpe g) r)
+ Data.Geometry.Ipe.FromIpe: instance Data.Geometry.Ipe.FromIpe.HasDefaultFromIpe (Data.Geometry.LineSegment.LineSegment 2 () r)
+ Data.Geometry.Ipe.FromIpe: instance Data.Geometry.Ipe.FromIpe.HasDefaultFromIpe (Data.Geometry.PolyLine.PolyLine 2 () r)
+ Data.Geometry.Ipe.FromIpe: instance Data.Geometry.Ipe.FromIpe.HasDefaultFromIpe (Data.Geometry.Polygon.MultiPolygon () r)
+ Data.Geometry.Ipe.FromIpe: instance Data.Geometry.Ipe.FromIpe.HasDefaultFromIpe (Data.Geometry.Polygon.SimplePolygon () r)
+ Data.Geometry.Ipe.FromIpe: pathToPolygon :: Path r -> Maybe (Either (SimplePolygon () r) (MultiPolygon () r))
+ Data.Geometry.Ipe.FromIpe: polygonToPath :: Polygon t () r -> Path r
+ Data.Geometry.Ipe.FromIpe: readAll :: (HasDefaultFromIpe g, r ~ NumType g, Foldable f) => f (IpePage r) -> [g :+ IpeAttributes (DefaultFromIpe g) r]
+ Data.Geometry.Ipe.FromIpe: readAllFrom :: (HasDefaultFromIpe g, r ~ NumType g, Coordinate r, Eq r) => FilePath -> IO [g :+ IpeAttributes (DefaultFromIpe g) r]
+ Data.Geometry.Ipe.FromIpe: type family DefaultFromIpe g :: * -> *;
+ Data.Geometry.Ipe.FromIpe: }
+ Data.Geometry.Ipe.IpeOut: instance Data.Geometry.Ipe.IpeOut.HasDefaultIpeOut (Data.Geometry.Polygon.Polygon t p r)
+ Data.Geometry.Ipe.IpeOut: instance Data.Geometry.Ipe.IpeOut.HasDefaultIpeOut (Data.Geometry.Polygon.SomePolygon p r)
+ Data.Geometry.Ipe.IpeOut: ipePolygon :: IpeOut (Polygon t p r) (Path r)
+ Data.Geometry.Ipe.IpeOut: line :: (Fractional r, Ord r) => IpeOut (Line 2 r) (IpeObject' Path r)
+ Data.Geometry.Ipe.IpeOut: lineWith :: forall p r. (Ord r, Fractional r) => Rectangle p r -> IpeOut (Line 2 r) (IpeObject' Path r)
+ Data.Geometry.Ipe.PathParser: instance (GHC.Base.Semigroup l, GHC.Base.Semigroup r) => GHC.Base.Semigroup (Data.Geometry.Ipe.PathParser.Either' l r)
+ Data.Geometry.Ipe.PathParser: instance (GHC.Base.Semigroup l, GHC.Base.Semigroup r, GHC.Base.Monoid r) => GHC.Base.Monoid (Data.Geometry.Ipe.PathParser.Either' l r)
+ Data.Geometry.Ipe.PathParser: instance (GHC.Classes.Eq l, GHC.Classes.Eq r) => GHC.Classes.Eq (Data.Geometry.Ipe.PathParser.Either' l r)
+ Data.Geometry.Ipe.PathParser: instance (GHC.Show.Show l, GHC.Show.Show r) => GHC.Show.Show (Data.Geometry.Ipe.PathParser.Either' l r)
+ Data.Geometry.Ipe.Reader: class Fractional r => Coordinate r
+ Data.Geometry.Ipe.Reader: fromSeq :: (Coordinate r, Ord r, Fractional r) => Integer -> Maybe (Int, Integer) -> r
+ Data.Geometry.Ipe.Reader: instance (Data.Geometry.Ipe.PathParser.Coordinate r, GHC.Classes.Eq r) => Data.Geometry.Ipe.Reader.IpeRead (Data.Geometry.Ipe.Types.Group r)
+ Data.Geometry.Ipe.Reader: instance (Data.Geometry.Ipe.PathParser.Coordinate r, GHC.Classes.Eq r) => Data.Geometry.Ipe.Reader.IpeRead (Data.Geometry.Ipe.Types.IpeFile r)
+ Data.Geometry.Ipe.Reader: instance (Data.Geometry.Ipe.PathParser.Coordinate r, GHC.Classes.Eq r) => Data.Geometry.Ipe.Reader.IpeRead (Data.Geometry.Ipe.Types.IpeObject r)
+ Data.Geometry.Ipe.Reader: instance (Data.Geometry.Ipe.PathParser.Coordinate r, GHC.Classes.Eq r) => Data.Geometry.Ipe.Reader.IpeRead (Data.Geometry.Ipe.Types.IpePage r)
+ Data.Geometry.Ipe.Reader: instance (Data.Geometry.Ipe.PathParser.Coordinate r, GHC.Classes.Eq r) => Data.Geometry.Ipe.Reader.IpeRead (Data.Geometry.Ipe.Types.Path r)
+ Data.Geometry.Ipe.Reader: instance (Data.Geometry.Ipe.PathParser.Coordinate r, GHC.Classes.Eq r) => Data.Geometry.Ipe.Reader.IpeReadText (Data.Geometry.Ipe.Types.Path r)
+ Data.Geometry.Ipe.Reader: instance (Data.Geometry.Ipe.PathParser.Coordinate r, GHC.Classes.Eq r) => Data.Geometry.Ipe.Reader.IpeReadText (GHC.Base.NonEmpty (Data.Geometry.Ipe.Types.PathSegment r))
+ Data.Geometry.Ipe.Reader: instance Data.Geometry.Ipe.PathParser.Coordinate r => Data.Geometry.Ipe.Reader.IpeReadText (Data.Colour.RGB.RGB r)
+ Data.Geometry.Ipe.Reader: instance Data.Geometry.Ipe.PathParser.Coordinate r => Data.Geometry.Ipe.Reader.IpeReadText (Data.Geometry.Ipe.Attributes.IpeColor r)
+ Data.Geometry.Ipe.Reader: instance forall u (f :: u Data.Singletons.Internal.~> *) (at :: u). Data.Geometry.Ipe.Reader.IpeReadText (Data.Singletons.Internal.Apply f at) => Data.Geometry.Ipe.Reader.IpeReadAttr (Data.Geometry.Ipe.Attributes.Attr f at)
+ Data.Geometry.Ipe.Types: flattenGroups :: [IpeObject r] -> [IpeObject r]
+ Data.Geometry.Ipe.Types: instance GHC.Real.Fractional r => Data.Geometry.Transformation.IsTransformable (Data.Geometry.Ipe.Types.Group r)
+ Data.Geometry.Ipe.Types: instance GHC.Real.Fractional r => Data.Geometry.Transformation.IsTransformable (Data.Geometry.Ipe.Types.Image r)
+ Data.Geometry.Ipe.Types: instance GHC.Real.Fractional r => Data.Geometry.Transformation.IsTransformable (Data.Geometry.Ipe.Types.IpeObject r)
+ Data.Geometry.Ipe.Types: instance GHC.Real.Fractional r => Data.Geometry.Transformation.IsTransformable (Data.Geometry.Ipe.Types.IpeSymbol r)
+ Data.Geometry.Ipe.Types: instance GHC.Real.Fractional r => Data.Geometry.Transformation.IsTransformable (Data.Geometry.Ipe.Types.MiniPage r)
+ Data.Geometry.Ipe.Types: instance GHC.Real.Fractional r => Data.Geometry.Transformation.IsTransformable (Data.Geometry.Ipe.Types.Path r)
+ Data.Geometry.Ipe.Types: instance GHC.Real.Fractional r => Data.Geometry.Transformation.IsTransformable (Data.Geometry.Ipe.Types.PathSegment r)
+ Data.Geometry.Ipe.Types: instance GHC.Real.Fractional r => Data.Geometry.Transformation.IsTransformable (Data.Geometry.Ipe.Types.TextLabel r)
+ Data.Geometry.Ipe.Writer: instance (Data.Geometry.Ipe.Writer.IpeWrite l, Data.Geometry.Ipe.Writer.IpeWrite r) => Data.Geometry.Ipe.Writer.IpeWrite (Data.Either.Either l r)
+ Data.Geometry.Ipe.Writer: instance (Data.Geometry.Ipe.Writer.IpeWriteText l, Data.Geometry.Ipe.Writer.IpeWriteText r) => Data.Geometry.Ipe.Writer.IpeWriteText (Data.Either.Either l r)
+ Data.Geometry.Ipe.Writer: instance Data.Geometry.Ipe.Writer.IpeWriteText r => Data.Geometry.Ipe.Writer.IpeWriteText (Data.Colour.RGB.RGB r)
+ Data.Geometry.Ipe.Writer: instance Data.Geometry.Ipe.Writer.IpeWriteText r => Data.Geometry.Ipe.Writer.IpeWriteText (Data.Geometry.Ipe.Attributes.IpeColor r)
+ Data.Geometry.Ipe.Writer: instance Data.Geometry.Ipe.Writer.IpeWriteText r => Data.Geometry.Ipe.Writer.IpeWriteText (Data.Geometry.Polygon.Polygon t () r)
+ Data.Geometry.Ipe.Writer: instance forall u (f :: u Data.Singletons.Internal.~> *) (at :: u). Data.Geometry.Ipe.Writer.IpeWriteText (Data.Singletons.Internal.Apply f at) => Data.Geometry.Ipe.Writer.IpeWriteText (Data.Geometry.Ipe.Attributes.Attr f at)
+ Data.Geometry.KDTree: instance (GHC.Classes.Eq p, GHC.Classes.Eq r, Data.Geometry.Vector.VectorFamily.Arity d, GHC.TypeNats.KnownNat d) => GHC.Classes.Eq (Data.Geometry.KDTree.KDTree d p r)
+ Data.Geometry.KDTree: instance (GHC.Classes.Eq p, GHC.Classes.Eq r, Data.Geometry.Vector.VectorFamily.Arity d, GHC.TypeNats.KnownNat d) => GHC.Classes.Eq (Data.Geometry.KDTree.KDTree' d p r)
+ Data.Geometry.KDTree: instance (GHC.Classes.Eq r, Data.Geometry.Vector.VectorFamily.Arity d, GHC.TypeNats.KnownNat d) => GHC.Classes.Eq (Data.Geometry.KDTree.Split d r)
+ Data.Geometry.KDTree: instance (GHC.Show.Show p, GHC.Show.Show r, Data.Geometry.Vector.VectorFamily.Arity d, GHC.TypeNats.KnownNat d) => GHC.Show.Show (Data.Geometry.KDTree.KDTree d p r)
+ Data.Geometry.KDTree: instance (GHC.Show.Show p, GHC.Show.Show r, Data.Geometry.Vector.VectorFamily.Arity d, GHC.TypeNats.KnownNat d) => GHC.Show.Show (Data.Geometry.KDTree.KDTree' d p r)
+ Data.Geometry.KDTree: instance (GHC.Show.Show r, Data.Geometry.Vector.VectorFamily.Arity d, GHC.TypeNats.KnownNat d) => GHC.Show.Show (Data.Geometry.KDTree.Split d r)
+ Data.Geometry.KDTree: instance GHC.TypeNats.KnownNat d => GHC.Classes.Eq (Data.Geometry.KDTree.Coord d)
+ Data.Geometry.KDTree: instance GHC.TypeNats.KnownNat d => GHC.Enum.Enum (Data.Geometry.KDTree.Coord d)
+ Data.Geometry.KDTree: instance GHC.TypeNats.KnownNat d => GHC.Show.Show (Data.Geometry.KDTree.Coord d)
+ Data.Geometry.Line: instance (GHC.Classes.Ord r, GHC.Real.Fractional r) => Data.Geometry.Properties.IsIntersectableWith (Data.Geometry.Line.Internal.Line 2 r) (Data.Geometry.Boundary.Boundary (Data.Geometry.Box.Internal.Rectangle p r))
+ Data.Geometry.Line: instance (GHC.Classes.Ord r, GHC.Real.Fractional r) => Data.Geometry.Properties.IsIntersectableWith (Data.Geometry.Line.Internal.Line 2 r) (Data.Geometry.Box.Internal.Rectangle p r)
+ Data.Geometry.Line: instance (GHC.Real.Fractional r, Data.Geometry.Vector.VectorFamily.Arity d, Data.Geometry.Vector.VectorFamily.Arity (d GHC.TypeNats.+ 1)) => Data.Geometry.Transformation.IsTransformable (Data.Geometry.Line.Internal.Line d r)
+ Data.Geometry.Line.Internal: cmpSlope :: (Num r, Ord r) => Line 2 r -> Line 2 r -> Ordering
+ Data.Geometry.Line.Internal: instance (Control.DeepSeq.NFData r, Data.Geometry.Vector.VectorFamily.Arity d) => Control.DeepSeq.NFData (Data.Geometry.Line.Internal.Line d r)
+ Data.Geometry.Line.Internal: instance (GHC.Classes.Eq r, Data.Geometry.Vector.VectorFamily.Arity d) => GHC.Classes.Eq (Data.Geometry.Line.Internal.Line d r)
+ Data.Geometry.Line.Internal: instance (GHC.Show.Show r, Data.Geometry.Vector.VectorFamily.Arity d) => GHC.Show.Show (Data.Geometry.Line.Internal.Line d r)
+ Data.Geometry.Line.Internal: instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Foldable.Foldable (Data.Geometry.Line.Internal.Line d)
+ Data.Geometry.Line.Internal: instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Traversable.Traversable (Data.Geometry.Line.Internal.Line d)
+ Data.Geometry.Line.Internal: instance Data.Geometry.Vector.VectorFamily.Arity d => GHC.Base.Functor (Data.Geometry.Line.Internal.Line d)
+ Data.Geometry.Line.Internal: onLine2 :: (Ord r, Num r) => Point 2 r -> Line 2 r -> Bool
+ Data.Geometry.LineSegment: Closed :: !a -> EndPoint a
+ Data.Geometry.LineSegment: GInterval :: Range (r :+ a) -> Interval a r
+ Data.Geometry.LineSegment: Open :: !a -> EndPoint a
+ Data.Geometry.LineSegment: Range :: !(EndPoint a) -> !(EndPoint a) -> Range a
+ Data.Geometry.LineSegment: [_lower] :: Range a -> !(EndPoint a)
+ Data.Geometry.LineSegment: [_unInterval] :: Interval a r -> Range (r :+ a)
+ Data.Geometry.LineSegment: [_upper] :: Range a -> !(EndPoint a)
+ Data.Geometry.LineSegment: class HasEnd t where {
+ Data.Geometry.LineSegment: class HasStart t where {
+ Data.Geometry.LineSegment: clipLower :: Ord a => EndPoint a -> Range a -> Maybe (Range a)
+ Data.Geometry.LineSegment: clipUpper :: Ord a => EndPoint a -> Range a -> Maybe (Range a)
+ Data.Geometry.LineSegment: covers :: (Ord a) => Range a -> Range a -> Bool
+ Data.Geometry.LineSegment: data EndPoint a
+ Data.Geometry.LineSegment: data Range a
+ Data.Geometry.LineSegment: end :: HasEnd t => Lens' t (EndCore t :+ EndExtra t)
+ Data.Geometry.LineSegment: inInterval :: Ord r => r -> Interval a r -> Bool
+ Data.Geometry.LineSegment: inRange :: Ord a => a -> Range a -> Bool
+ Data.Geometry.LineSegment: instance (GHC.Classes.Eq r, GHC.Classes.Eq p, Data.Geometry.Vector.VectorFamily.Arity d) => GHC.Classes.Eq (Data.Geometry.LineSegment.LineSegment d p r)
+ Data.Geometry.LineSegment: instance (GHC.Num.Num r, Data.Geometry.Vector.VectorFamily.Arity d) => Data.Geometry.Line.Internal.HasSupportingLine (Data.Geometry.LineSegment.LineSegment d p r)
+ Data.Geometry.LineSegment: 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.LineSegment.LineSegment d p r)
+ Data.Geometry.LineSegment: instance (GHC.Show.Show r, GHC.Show.Show p, Data.Geometry.Vector.VectorFamily.Arity d) => GHC.Show.Show (Data.Geometry.LineSegment.LineSegment d p r)
+ Data.Geometry.LineSegment: instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Bifunctor.Bifunctor (Data.Geometry.LineSegment.LineSegment d)
+ Data.Geometry.LineSegment: instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Geometry.Box.Internal.IsBoxable (Data.Geometry.LineSegment.LineSegment d p r)
+ Data.Geometry.LineSegment: instance Data.Geometry.Vector.VectorFamily.Arity d => GHC.Base.Functor (Data.Geometry.LineSegment.LineSegment d p)
+ Data.Geometry.LineSegment: isClosed :: EndPoint a -> Bool
+ Data.Geometry.LineSegment: isOpen :: EndPoint a -> Bool
+ Data.Geometry.LineSegment: isValid :: Ord a => Range a -> Bool
+ Data.Geometry.LineSegment: lower :: forall a_a1Ji7. Lens' (Range a_a1Ji7) (EndPoint a_a1Ji7)
+ Data.Geometry.LineSegment: newtype Interval a r
+ Data.Geometry.LineSegment: prettyShow :: Show a => Range a -> String
+ Data.Geometry.LineSegment: shiftLeft :: Num r => r -> Range r -> Range r
+ Data.Geometry.LineSegment: shiftLeft' :: Num r => r -> Interval a r -> Interval a r
+ Data.Geometry.LineSegment: shiftRight :: Num r => r -> Range r -> Range r
+ Data.Geometry.LineSegment: start :: HasStart t => Lens' t (StartCore t :+ StartExtra t)
+ Data.Geometry.LineSegment: type family StartExtra t;
+ Data.Geometry.LineSegment: unEndPoint :: Lens (EndPoint a) (EndPoint b) a b
+ Data.Geometry.LineSegment: upper :: forall a_a1Ji7. Lens' (Range a_a1Ji7) (EndPoint a_a1Ji7)
+ Data.Geometry.LineSegment: }
+ Data.Geometry.PlanarSubdivision: fromPolygons :: (Ord r, Fractional r) => proxy s -> NonEmpty (SimplePolygon p r :+ f) -> f -> PlanarSubdivision s (Maybe p) () f r
+ Data.Geometry.PlanarSubdivision: instance (GHC.Classes.Eq f, GHC.Classes.Eq p) => GHC.Classes.Eq (Data.Geometry.PlanarSubdivision.HoleData f p)
+ Data.Geometry.PlanarSubdivision: instance (GHC.Show.Show f, GHC.Show.Show p) => GHC.Show.Show (Data.Geometry.PlanarSubdivision.HoleData f p)
+ Data.Geometry.PlanarSubdivision.Basic: Dual :: World
+ Data.Geometry.PlanarSubdivision.Basic: FaceData :: (Seq h) -> !f -> FaceData h f
+ Data.Geometry.PlanarSubdivision.Basic: FaceId :: VertexId s (DualOf w) -> FaceId s w
+ Data.Geometry.PlanarSubdivision.Basic: Inside :: PolygonFaceData
+ Data.Geometry.PlanarSubdivision.Basic: Outside :: PolygonFaceData
+ Data.Geometry.PlanarSubdivision.Basic: PlanarSubdivision :: Vector (Component s r) -> Vector (Raw s (VertexId' (Wrap s)) v) -> Vector (Raw s (Dart (Wrap s)) e) -> Vector (Raw s (FaceId' (Wrap s)) f) -> PlanarSubdivision s v e f r
+ Data.Geometry.PlanarSubdivision.Basic: Primal :: World
+ Data.Geometry.PlanarSubdivision.Basic: Raw :: {-# UNPACK #-} !(ComponentId s) -> {-# UNPACK #-} !ia -> !a -> Raw s ia a
+ Data.Geometry.PlanarSubdivision.Basic: VertexData :: !(Point 2 r) -> !v -> VertexData r v
+ Data.Geometry.PlanarSubdivision.Basic: VertexId :: Int -> VertexId s
+ Data.Geometry.PlanarSubdivision.Basic: [_compId] :: Raw s ia a -> {-# UNPACK #-} !(ComponentId s)
+ Data.Geometry.PlanarSubdivision.Basic: [_dataVal] :: Raw s ia a -> !a
+ Data.Geometry.PlanarSubdivision.Basic: [_idxVal] :: Raw s ia a -> {-# UNPACK #-} !ia
+ Data.Geometry.PlanarSubdivision.Basic: [_unFaceId] :: FaceId s w -> VertexId s (DualOf w)
+ Data.Geometry.PlanarSubdivision.Basic: [_unVertexId] :: VertexId s -> Int
+ Data.Geometry.PlanarSubdivision.Basic: boundary' :: Dart s -> PlanarSubdivision s v e f r -> Vector (Dart s)
+ Data.Geometry.PlanarSubdivision.Basic: boundaryVertices :: FaceId' s -> PlanarSubdivision s v e f r -> Vector (VertexId' s)
+ Data.Geometry.PlanarSubdivision.Basic: class HasDataOf g i where {
+ Data.Geometry.PlanarSubdivision.Basic: component :: ComponentId s -> Lens' (PlanarSubdivision s v e f r) (Component s r)
+ Data.Geometry.PlanarSubdivision.Basic: components :: forall s_a33Mr v_a33Ms e_a33Mt f_a33Mu r_a33Mv r_a33YO. Lens (PlanarSubdivision s_a33Mr v_a33Ms e_a33Mt f_a33Mu r_a33Mv) (PlanarSubdivision s_a33Mr v_a33Ms e_a33Mt f_a33Mu r_a33YO) (Vector (Component s_a33Mr r_a33Mv)) (Vector (Component s_a33Mr r_a33YO))
+ Data.Geometry.PlanarSubdivision.Basic: dartMapping :: () => PlanarSubdivision s v e f r -> Vector (Dart Wrap s, Dart s)
+ Data.Geometry.PlanarSubdivision.Basic: darts' :: PlanarSubdivision s v e f r -> Vector (Dart s)
+ Data.Geometry.PlanarSubdivision.Basic: data ComponentId s
+ Data.Geometry.PlanarSubdivision.Basic: data Dart s
+ Data.Geometry.PlanarSubdivision.Basic: data FaceData h f
+ Data.Geometry.PlanarSubdivision.Basic: data PlanarGraph s (w :: World) v e f
+ Data.Geometry.PlanarSubdivision.Basic: data PlanarSubdivision s v e f r
+ Data.Geometry.PlanarSubdivision.Basic: data PlaneGraph s v e f r
+ Data.Geometry.PlanarSubdivision.Basic: data PolygonFaceData
+ Data.Geometry.PlanarSubdivision.Basic: data Raw s ia a
+ Data.Geometry.PlanarSubdivision.Basic: data VertexData r v
+ Data.Geometry.PlanarSubdivision.Basic: data World
+ Data.Geometry.PlanarSubdivision.Basic: dataOf :: HasDataOf g i => i -> Lens' g (DataOf g i)
+ Data.Geometry.PlanarSubdivision.Basic: dataVal :: forall s_a33k5 ia_a33k6 a_a33k7 a_a33M0. Lens (Raw s_a33k5 ia_a33k6 a_a33k7) (Raw s_a33k5 ia_a33k6 a_a33M0) a_a33k7 a_a33M0
+ Data.Geometry.PlanarSubdivision.Basic: dual :: Getter (PlanarGraph s w v e f) (PlanarGraph s (DualOf w) f e v)
+ Data.Geometry.PlanarSubdivision.Basic: edgeSegment :: Dart s -> PlanarSubdivision s v e f r -> LineSegment 2 v r :+ e
+ Data.Geometry.PlanarSubdivision.Basic: edgeSegments :: PlanarSubdivision s v e f r -> Vector (Dart s, LineSegment 2 v r :+ e)
+ Data.Geometry.PlanarSubdivision.Basic: edges :: PlanarSubdivision s v e f r -> Vector (Dart s, e)
+ Data.Geometry.PlanarSubdivision.Basic: edges' :: PlanarSubdivision s v e f r -> Vector (Dart s)
+ Data.Geometry.PlanarSubdivision.Basic: endPointData :: Dart s -> PlanarSubdivision s v e f r -> (VertexData r v, VertexData r v)
+ Data.Geometry.PlanarSubdivision.Basic: endPoints :: Dart s -> PlanarSubdivision s v e f r -> (VertexId' s, VertexId' s)
+ Data.Geometry.PlanarSubdivision.Basic: endPointsOf :: Dart s -> Getter (PlanarSubdivision s v e f r) (VertexData r v, VertexData r v)
+ Data.Geometry.PlanarSubdivision.Basic: fData :: forall h_a337R f_a337S f_a33jJ. Lens (FaceData h_a337R f_a337S) (FaceData h_a337R f_a33jJ) f_a337S f_a33jJ
+ Data.Geometry.PlanarSubdivision.Basic: faces :: PlanarSubdivision s v e f r -> Vector (FaceId' s, FaceData (Dart s) f)
+ Data.Geometry.PlanarSubdivision.Basic: faces' :: PlanarSubdivision s v e f r -> Vector (FaceId' s)
+ Data.Geometry.PlanarSubdivision.Basic: fromConnectedSegments :: (Foldable f, Ord r, Fractional r) => proxy s -> f (LineSegment 2 p r :+ e) -> PlanarSubdivision s (NonEmpty p) e () r
+ Data.Geometry.PlanarSubdivision.Basic: fromPlaneGraph :: forall s v e f r. (Ord r, Fractional r) => PlaneGraph s v e f r -> PlanarSubdivision s v e f r
+ Data.Geometry.PlanarSubdivision.Basic: fromPlaneGraph' :: forall s v e f r. PlaneGraph s v e f r -> Dart s -> PlanarSubdivision s v e f r
+ Data.Geometry.PlanarSubdivision.Basic: fromSimplePolygon :: (Ord r, Fractional r) => proxy s -> SimplePolygon p r -> f -> f -> PlanarSubdivision s p () f r
+ Data.Geometry.PlanarSubdivision.Basic: headOf :: Dart s -> PlanarSubdivision s v e f r -> VertexId' s
+ Data.Geometry.PlanarSubdivision.Basic: holes :: forall h_a337R f_a337S h_a33jK. Lens (FaceData h_a337R f_a337S) (FaceData h_a33jK f_a337S) (Seq h_a337R) (Seq h_a33jK)
+ Data.Geometry.PlanarSubdivision.Basic: holesOf :: FaceId' s -> PlanarSubdivision s v e f r -> Seq (Dart s)
+ Data.Geometry.PlanarSubdivision.Basic: incidentEdges :: VertexId' s -> PlanarSubdivision s v e f r -> Vector (Dart s)
+ Data.Geometry.PlanarSubdivision.Basic: incomingEdges :: VertexId' s -> PlanarSubdivision s v e f r -> Vector (Dart s)
+ Data.Geometry.PlanarSubdivision.Basic: instance (Data.Aeson.Types.FromJSON.FromJSON h, Data.Aeson.Types.FromJSON.FromJSON f) => Data.Aeson.Types.FromJSON.FromJSON (Data.Geometry.PlanarSubdivision.Basic.FaceData h f)
+ Data.Geometry.PlanarSubdivision.Basic: instance (Data.Aeson.Types.ToJSON.ToJSON h, Data.Aeson.Types.ToJSON.ToJSON f) => Data.Aeson.Types.ToJSON.ToJSON (Data.Geometry.PlanarSubdivision.Basic.FaceData h f)
+ Data.Geometry.PlanarSubdivision.Basic: instance (GHC.Classes.Eq h, GHC.Classes.Eq f) => GHC.Classes.Eq (Data.Geometry.PlanarSubdivision.Basic.FaceData h f)
+ Data.Geometry.PlanarSubdivision.Basic: instance (GHC.Classes.Ord h, GHC.Classes.Ord f) => GHC.Classes.Ord (Data.Geometry.PlanarSubdivision.Basic.FaceData h f)
+ Data.Geometry.PlanarSubdivision.Basic: instance (GHC.Show.Show h, GHC.Show.Show f) => GHC.Show.Show (Data.Geometry.PlanarSubdivision.Basic.FaceData h f)
+ Data.Geometry.PlanarSubdivision.Basic: instance Data.Bifunctor.Bifunctor Data.Geometry.PlanarSubdivision.Basic.FaceData
+ Data.Geometry.PlanarSubdivision.Basic: instance Data.Foldable.Foldable (Data.Geometry.PlanarSubdivision.Basic.FaceData h)
+ Data.Geometry.PlanarSubdivision.Basic: instance Data.Traversable.Traversable (Data.Geometry.PlanarSubdivision.Basic.FaceData h)
+ Data.Geometry.PlanarSubdivision.Basic: instance GHC.Base.Functor (Data.Geometry.PlanarSubdivision.Basic.FaceData h)
+ Data.Geometry.PlanarSubdivision.Basic: instance GHC.Classes.Eq Data.Geometry.PlanarSubdivision.Basic.PolygonFaceData
+ Data.Geometry.PlanarSubdivision.Basic: instance GHC.Generics.Generic (Data.Geometry.PlanarSubdivision.Basic.FaceData h f)
+ Data.Geometry.PlanarSubdivision.Basic: instance GHC.Read.Read Data.Geometry.PlanarSubdivision.Basic.PolygonFaceData
+ Data.Geometry.PlanarSubdivision.Basic: instance GHC.Show.Show Data.Geometry.PlanarSubdivision.Basic.PolygonFaceData
+ Data.Geometry.PlanarSubdivision.Basic: instance forall k (s :: k) ia a. (GHC.Classes.Eq ia, GHC.Classes.Eq a) => GHC.Classes.Eq (Data.Geometry.PlanarSubdivision.Basic.Raw s ia a)
+ Data.Geometry.PlanarSubdivision.Basic: instance forall k (s :: k) ia a. (GHC.Show.Show ia, GHC.Show.Show a) => GHC.Show.Show (Data.Geometry.PlanarSubdivision.Basic.Raw s ia a)
+ Data.Geometry.PlanarSubdivision.Basic: instance forall k (s :: k) ia. Data.Foldable.Foldable (Data.Geometry.PlanarSubdivision.Basic.Raw s ia)
+ Data.Geometry.PlanarSubdivision.Basic: instance forall k (s :: k) ia. Data.Traversable.Traversable (Data.Geometry.PlanarSubdivision.Basic.Raw s ia)
+ Data.Geometry.PlanarSubdivision.Basic: instance forall k (s :: k) ia. GHC.Base.Functor (Data.Geometry.PlanarSubdivision.Basic.Raw s ia)
+ Data.Geometry.PlanarSubdivision.Basic: instance forall k (s :: k) v e f r. (GHC.Classes.Eq r, GHC.Classes.Eq v, GHC.Classes.Eq e, GHC.Classes.Eq f) => GHC.Classes.Eq (Data.Geometry.PlanarSubdivision.Basic.PlanarSubdivision s v e f r)
+ Data.Geometry.PlanarSubdivision.Basic: instance forall k (s :: k) v e f r. (GHC.Show.Show r, GHC.Show.Show v, GHC.Show.Show e, GHC.Show.Show f) => GHC.Show.Show (Data.Geometry.PlanarSubdivision.Basic.PlanarSubdivision s v e f r)
+ Data.Geometry.PlanarSubdivision.Basic: instance forall k (s :: k) v e f r. Data.Geometry.Box.Internal.IsBoxable (Data.Geometry.PlanarSubdivision.Basic.PlanarSubdivision s v e f r)
+ Data.Geometry.PlanarSubdivision.Basic: instance forall k (s :: k) v e f r. Data.PlanarGraph.HasDataOf (Data.Geometry.PlanarSubdivision.Basic.PlanarSubdivision s v e f r) (Data.PlanarGraph.Dart s)
+ Data.Geometry.PlanarSubdivision.Basic: instance forall k (s :: k) v e f r. Data.PlanarGraph.HasDataOf (Data.Geometry.PlanarSubdivision.Basic.PlanarSubdivision s v e f r) (Data.PlanarGraph.FaceId' s)
+ Data.Geometry.PlanarSubdivision.Basic: instance forall k (s :: k) v e f r. Data.PlanarGraph.HasDataOf (Data.Geometry.PlanarSubdivision.Basic.PlanarSubdivision s v e f r) (Data.PlanarGraph.VertexId' s)
+ Data.Geometry.PlanarSubdivision.Basic: instance forall k (s :: k) v e f. GHC.Base.Functor (Data.Geometry.PlanarSubdivision.Basic.PlanarSubdivision s v e f)
+ Data.Geometry.PlanarSubdivision.Basic: instance forall k (s :: k). GHC.Classes.Eq (Data.Geometry.PlanarSubdivision.Basic.ComponentId s)
+ Data.Geometry.PlanarSubdivision.Basic: instance forall k (s :: k). GHC.Classes.Ord (Data.Geometry.PlanarSubdivision.Basic.ComponentId s)
+ Data.Geometry.PlanarSubdivision.Basic: instance forall k (s :: k). GHC.Enum.Bounded (Data.Geometry.PlanarSubdivision.Basic.ComponentId s)
+ Data.Geometry.PlanarSubdivision.Basic: instance forall k (s :: k). GHC.Enum.Enum (Data.Geometry.PlanarSubdivision.Basic.ComponentId s)
+ Data.Geometry.PlanarSubdivision.Basic: instance forall k (s :: k). GHC.Generics.Generic (Data.Geometry.PlanarSubdivision.Basic.ComponentId s)
+ Data.Geometry.PlanarSubdivision.Basic: instance forall k (s :: k). GHC.Show.Show (Data.Geometry.PlanarSubdivision.Basic.ComponentId s)
+ Data.Geometry.PlanarSubdivision.Basic: internalFaces :: (Ord r, Fractional r) => PlanarSubdivision s v e f r -> Vector (FaceId' s, FaceData (Dart s) f)
+ Data.Geometry.PlanarSubdivision.Basic: leftFace :: Dart s -> PlanarSubdivision s v e f r -> FaceId' s
+ Data.Geometry.PlanarSubdivision.Basic: location :: forall r_a2SAw v_a2SAx r_a2SLX. Lens (VertexData r_a2SAw v_a2SAx) (VertexData r_a2SLX v_a2SAx) (Point 2 r_a2SAw) (Point 2 r_a2SLX)
+ Data.Geometry.PlanarSubdivision.Basic: locationOf :: VertexId' s -> Lens' (PlanarSubdivision s v e f r) (Point 2 r)
+ Data.Geometry.PlanarSubdivision.Basic: neighboursOf :: VertexId' s -> PlanarSubdivision s v e f r -> Vector (VertexId' s)
+ Data.Geometry.PlanarSubdivision.Basic: newtype FaceId s w
+ Data.Geometry.PlanarSubdivision.Basic: newtype VertexId s (w :: World)
+ Data.Geometry.PlanarSubdivision.Basic: nextIncidentEdge :: Dart s -> PlanarSubdivision s v e f r -> Dart s
+ Data.Geometry.PlanarSubdivision.Basic: numDarts :: PlanarSubdivision s v e f r -> Int
+ Data.Geometry.PlanarSubdivision.Basic: numEdges :: PlanarSubdivision s v e f r -> Int
+ Data.Geometry.PlanarSubdivision.Basic: numFaces :: PlanarSubdivision s v e f r -> Int
+ Data.Geometry.PlanarSubdivision.Basic: numVertices :: PlanarSubdivision s v e f r -> Int
+ Data.Geometry.PlanarSubdivision.Basic: outerBoundaryDarts :: FaceId' s -> PlanarSubdivision s v e f r -> Vector (Dart s)
+ Data.Geometry.PlanarSubdivision.Basic: outerFaceId :: PlanarSubdivision s v e f r -> FaceId' s
+ Data.Geometry.PlanarSubdivision.Basic: outgoingEdges :: VertexId' s -> PlanarSubdivision s v e f r -> Vector (Dart s)
+ Data.Geometry.PlanarSubdivision.Basic: rawDartData :: forall s_a33Mr v_a33Ms e_a33Mt f_a33Mu r_a33Mv e_a33YP. Lens (PlanarSubdivision s_a33Mr v_a33Ms e_a33Mt f_a33Mu r_a33Mv) (PlanarSubdivision s_a33Mr v_a33Ms e_a33YP f_a33Mu r_a33Mv) (Vector (Raw s_a33Mr (Dart (Wrap s_a33Mr)) e_a33Mt)) (Vector (Raw s_a33Mr (Dart (Wrap s_a33Mr)) e_a33YP))
+ Data.Geometry.PlanarSubdivision.Basic: rawFaceBoundary :: FaceId' s -> PlanarSubdivision s v e f r -> SimplePolygon v r :+ f
+ Data.Geometry.PlanarSubdivision.Basic: rawFaceData :: forall s_a33Mr v_a33Ms e_a33Mt f_a33Mu r_a33Mv f_a33YQ. Lens (PlanarSubdivision s_a33Mr v_a33Ms e_a33Mt f_a33Mu r_a33Mv) (PlanarSubdivision s_a33Mr v_a33Ms e_a33Mt f_a33YQ r_a33Mv) (Vector (Raw s_a33Mr (FaceId' (Wrap s_a33Mr)) f_a33Mu)) (Vector (Raw s_a33Mr (FaceId' (Wrap s_a33Mr)) f_a33YQ))
+ Data.Geometry.PlanarSubdivision.Basic: rawFacePolygon :: FaceId' s -> PlanarSubdivision s v e f r -> SomePolygon v r :+ f
+ Data.Geometry.PlanarSubdivision.Basic: rawFacePolygons :: PlanarSubdivision s v e f r -> Vector (FaceId' s, SomePolygon v r :+ f)
+ Data.Geometry.PlanarSubdivision.Basic: rawVertexData :: forall s_a33Mr v_a33Ms e_a33Mt f_a33Mu r_a33Mv v_a33YR. Lens (PlanarSubdivision s_a33Mr v_a33Ms e_a33Mt f_a33Mu r_a33Mv) (PlanarSubdivision s_a33Mr v_a33YR e_a33Mt f_a33Mu r_a33Mv) (Vector (Raw s_a33Mr (VertexId' (Wrap s_a33Mr)) v_a33Ms)) (Vector (Raw s_a33Mr (VertexId' (Wrap s_a33Mr)) v_a33YR))
+ Data.Geometry.PlanarSubdivision.Basic: rightFace :: Dart s -> PlanarSubdivision s v e f r -> FaceId' s
+ Data.Geometry.PlanarSubdivision.Basic: tailOf :: Dart s -> PlanarSubdivision s v e f r -> VertexId' s
+ Data.Geometry.PlanarSubdivision.Basic: twin :: Dart s -> Dart s
+ Data.Geometry.PlanarSubdivision.Basic: type Component s r = PlaneGraph (Wrap s) (VertexId' s) (Dart s) (FaceData (Dart s) (FaceId' s)) r
+ Data.Geometry.PlanarSubdivision.Basic: type FaceId' s = FaceId s Primal
+ Data.Geometry.PlanarSubdivision.Basic: type VertexId' s = VertexId s Primal
+ Data.Geometry.PlanarSubdivision.Basic: type family DataOf g i;
+ Data.Geometry.PlanarSubdivision.Basic: vData :: forall r_a2SAw v_a2SAx v_a2SLY. Lens (VertexData r_a2SAw v_a2SAx) (VertexData r_a2SAw v_a2SLY) v_a2SAx v_a2SLY
+ Data.Geometry.PlanarSubdivision.Basic: vertices :: PlanarSubdivision s v e f r -> Vector (VertexId' s, VertexData r v)
+ Data.Geometry.PlanarSubdivision.Basic: vertices' :: PlanarSubdivision s v e f r -> Vector (VertexId' s)
+ Data.Geometry.PlanarSubdivision.Basic: }
+ Data.Geometry.PlanarSubdivision.Draw: drawPlanarSubdivision :: forall s v e f r. IpeOut (PlanarSubdivision s v e f r) (IpeObject r)
+ Data.Geometry.Point: ccw' :: (Ord r, Num r) => Point 2 r :+ a -> Point 2 r :+ b -> Point 2 r :+ c -> 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 (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.Show.Show r, Data.Geometry.Vector.VectorFamily.Arity d) => GHC.Show.Show (Data.Geometry.Point.Point d r)
+ 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: projectPoint :: (Arity i, Arity d, i <= d) => Point d r -> Point i r
+ Data.Geometry.PolyLine: instance (GHC.Classes.Eq r, GHC.Classes.Eq p, Data.Geometry.Vector.VectorFamily.Arity d) => GHC.Classes.Eq (Data.Geometry.PolyLine.PolyLine d p r)
+ Data.Geometry.PolyLine: instance (GHC.Classes.Ord r, GHC.Classes.Ord p, Data.Geometry.Vector.VectorFamily.Arity d) => GHC.Classes.Ord (Data.Geometry.PolyLine.PolyLine d p r)
+ Data.Geometry.PolyLine: 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.PolyLine.PolyLine d p r)
+ Data.Geometry.PolyLine: instance (GHC.Show.Show r, GHC.Show.Show p, Data.Geometry.Vector.VectorFamily.Arity d) => GHC.Show.Show (Data.Geometry.PolyLine.PolyLine d p r)
+ Data.Geometry.PolyLine: instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Bifunctor.Bifunctor (Data.Geometry.PolyLine.PolyLine d)
+ Data.Geometry.PolyLine: instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Geometry.Box.Internal.IsBoxable (Data.Geometry.PolyLine.PolyLine d p r)
+ Data.Geometry.PolyLine: instance Data.Geometry.Vector.VectorFamily.Arity d => GHC.Base.Functor (Data.Geometry.PolyLine.PolyLine d p)
+ Data.Geometry.PolyLine: instance GHC.Base.Semigroup (Data.Geometry.PolyLine.PolyLine d p r)
+ Data.Geometry.Polygon: bitraverseVertices :: (Applicative f, Traversable t) => (p -> f q) -> (r -> f s) -> t (Point 2 r :+ p) -> f (t (Point 2 s :+ q))
+ Data.Geometry.Polygon: instance (Control.DeepSeq.NFData p, Control.DeepSeq.NFData r) => Control.DeepSeq.NFData (Data.Geometry.Polygon.Polygon t p r)
+ Data.Geometry.Polygon: instance Data.Bifoldable.Bifoldable (Data.Geometry.Polygon.Polygon t)
+ Data.Geometry.Polygon: instance Data.Bifunctor.Bifunctor (Data.Geometry.Polygon.Polygon t)
+ Data.Geometry.Polygon: instance Data.Bitraversable.Bitraversable (Data.Geometry.Polygon.Polygon t)
+ Data.Geometry.Polygon: instance GHC.Real.Fractional r => Data.Geometry.Transformation.IsTransformable (Data.Geometry.Polygon.Polygon t p r)
+ Data.Geometry.Polygon: listEdges :: Polygon t p r -> [LineSegment 2 p r]
+ Data.Geometry.Polygon: numberVertices :: Polygon t p r -> Polygon t (SP Int p) r
+ Data.Geometry.Polygon: polygonHoles :: forall p r. Lens' (Polygon Multi p r) [Polygon Simple p r]
+ Data.Geometry.Polygon: reverseOuterBoundary :: Polygon t p r -> Polygon t p r
+ Data.Geometry.Polygon: type SomePolygon p r = Either (Polygon Simple p r) (Polygon Multi p r)
+ Data.Geometry.Polygon: withIncidentEdges :: Polygon t p r -> Polygon t (Two (LineSegment 2 p r)) r
+ Data.Geometry.Polygon.Convex: instance (Control.DeepSeq.NFData p, Control.DeepSeq.NFData r) => Control.DeepSeq.NFData (Data.Geometry.Polygon.Convex.ConvexPolygon p r)
+ Data.Geometry.Polygon.Convex: instance (GHC.Classes.Eq p, GHC.Classes.Eq r) => GHC.Classes.Eq (Data.Geometry.Polygon.Convex.ConvexPolygon p r)
+ Data.Geometry.Polygon.Convex: instance (GHC.Show.Show p, GHC.Show.Show r) => GHC.Show.Show (Data.Geometry.Polygon.Convex.ConvexPolygon p r)
+ Data.Geometry.Polygon.Convex: instance GHC.Real.Fractional r => Data.Geometry.Transformation.IsTransformable (Data.Geometry.Polygon.Convex.ConvexPolygon p r)
+ Data.Geometry.SegmentTree.Generic: instance (Control.DeepSeq.NFData v, Control.DeepSeq.NFData r) => Control.DeepSeq.NFData (Data.Geometry.SegmentTree.Generic.SegmentTree v r)
+ Data.Geometry.SegmentTree.Generic: instance (GHC.Classes.Eq r, GHC.Classes.Eq v) => GHC.Classes.Eq (Data.Geometry.SegmentTree.Generic.LeafData v r)
+ Data.Geometry.SegmentTree.Generic: instance (GHC.Classes.Eq r, GHC.Classes.Eq v) => GHC.Classes.Eq (Data.Geometry.SegmentTree.Generic.NodeData v r)
+ Data.Geometry.SegmentTree.Generic: instance (GHC.Show.Show r, GHC.Show.Show v) => GHC.Show.Show (Data.Geometry.SegmentTree.Generic.LeafData v r)
+ Data.Geometry.SegmentTree.Generic: instance (GHC.Show.Show r, GHC.Show.Show v) => GHC.Show.Show (Data.Geometry.SegmentTree.Generic.NodeData v r)
+ Data.Geometry.SegmentTree.Generic: instance GHC.Base.Semigroup Data.Geometry.SegmentTree.Generic.Count
+ Data.Geometry.Slab: instance (GHC.Classes.Eq r, GHC.Classes.Eq a) => GHC.Classes.Eq (Data.Geometry.Slab.Slab o a r)
+ Data.Geometry.Slab: instance (GHC.Real.Fractional r, GHC.Classes.Ord r, Data.Geometry.Slab.HasBoundingLines o) => Data.Geometry.Properties.IsIntersectableWith (Data.Geometry.LineSegment.LineSegment 2 a r) (Data.Geometry.Slab.Slab o a r)
+ Data.Geometry.Slab: instance (GHC.Show.Show a, GHC.Show.Show r) => GHC.Show.Show (Data.Geometry.Slab.Slab o a r)
+ Data.Geometry.SubLine: instance (GHC.Classes.Eq r, GHC.Classes.Eq p, Data.Geometry.Vector.VectorFamily.Arity d) => GHC.Classes.Eq (Data.Geometry.SubLine.SubLine d p r)
+ Data.Geometry.SubLine: instance (GHC.Show.Show r, GHC.Show.Show p, Data.Geometry.Vector.VectorFamily.Arity d) => GHC.Show.Show (Data.Geometry.SubLine.SubLine d p r)
+ Data.Geometry.SubLine: instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Bifunctor.Bifunctor (Data.Geometry.SubLine.SubLine d)
+ Data.Geometry.SubLine: instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Foldable.Foldable (Data.Geometry.SubLine.SubLine d p)
+ Data.Geometry.SubLine: instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Traversable.Traversable (Data.Geometry.SubLine.SubLine d p)
+ Data.Geometry.SubLine: instance Data.Geometry.Vector.VectorFamily.Arity d => GHC.Base.Functor (Data.Geometry.SubLine.SubLine d p)
+ Data.Geometry.SubLine: onSubLine :: (Ord r, Fractional r, Arity d) => Point d r -> SubLine d p r -> Bool
+ Data.Geometry.SubLine: onSubLine2 :: (Ord r, Num r) => Point 2 r -> SubLine 2 p r -> Bool
+ 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 (d GHC.TypeNats.+ 1)) => GHC.Classes.Eq (Data.Geometry.Transformation.Transformation d r)
+ 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 (d GHC.TypeNats.+ 1)) => GHC.Classes.Ord (Data.Geometry.Transformation.Transformation d 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.Real.Fractional r, Data.Geometry.Vector.VectorFamily.Arity d, Data.Geometry.Vector.VectorFamily.Arity (d GHC.TypeNats.+ 1)) => Data.Geometry.Transformation.IsTransformable (Data.Geometry.Vector.VectorFamily.Vector d r)
+ Data.Geometry.Transformation: instance (GHC.Show.Show r, Data.Geometry.Vector.VectorFamily.Arity (d GHC.TypeNats.+ 1)) => GHC.Show.Show (Data.Geometry.Transformation.Transformation 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 Data.Geometry.Vector.VectorFamily.Arity (d GHC.TypeNats.+ 1) => GHC.Base.Functor (Data.Geometry.Transformation.Transformation d)
+ Data.Geometry.Triangle: instance (Data.Geometry.Vector.VectorFamily.Arity d, GHC.Show.Show r, GHC.Show.Show p) => GHC.Show.Show (Data.Geometry.Triangle.Triangle d p r)
+ Data.Geometry.Triangle: 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.Triangle.Triangle d p 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: C :: C
+ Data.Geometry.Vector: data C (n :: Nat)
+ Data.Geometry.Vector: imap :: (Vector v a, Vector v b) => Int -> a -> b -> v a -> v b
+ Data.Geometry.Vector: instance GHC.Classes.Eq r => GHC.Base.Semigroup (Data.Geometry.Vector.ScalarMultiple r)
+ Data.Geometry.Vector: replicate :: Vector v a => a -> v a
+ Data.Geometry.Vector: signorm :: (Metric f, Floating a) => f a -> f a
+ Data.Geometry.Vector.VectorFamily: MKVector :: VectorFamily (Peano d) r -> Vector
+ Data.Geometry.Vector.VectorFamily: [_unV] :: Vector -> VectorFamily (Peano d) r
+ Data.Geometry.Vector.VectorFamily: cross :: Num r => Vector 3 r -> Vector 3 r -> Vector 3 r
+ Data.Geometry.Vector.VectorFamily: destruct :: (Arity d, Arity (d + 1)) => Vector (d + 1) r -> (r, Vector d r)
+ Data.Geometry.Vector.VectorFamily: element :: forall proxy i d r. (Arity d, KnownNat i, (i + 1) <= d) => proxy i -> Lens' (Vector d r) r
+ Data.Geometry.Vector.VectorFamily: element' :: forall d r. Arity d => Int -> Traversal' (Vector d r) r
+ Data.Geometry.Vector.VectorFamily: init :: (Arity d, Arity (d + 1)) => Vector (d + 1) r -> Vector d r
+ Data.Geometry.Vector.VectorFamily: instance (Control.DeepSeq.NFData r, Data.Geometry.Vector.VectorFamily.Arity d) => Control.DeepSeq.NFData (Data.Geometry.Vector.VectorFamily.Vector d r)
+ Data.Geometry.Vector.VectorFamily: instance (Data.Aeson.Types.FromJSON.FromJSON r, Data.Geometry.Vector.VectorFamily.Arity d) => Data.Aeson.Types.FromJSON.FromJSON (Data.Geometry.Vector.VectorFamily.Vector d r)
+ Data.Geometry.Vector.VectorFamily: instance (Data.Aeson.Types.ToJSON.ToJSON r, Data.Geometry.Vector.VectorFamily.Arity d) => Data.Aeson.Types.ToJSON.ToJSON (Data.Geometry.Vector.VectorFamily.Vector d r)
+ Data.Geometry.Vector.VectorFamily: instance (Data.Geometry.Vector.VectorFamily.Arity d, GHC.Show.Show r) => GHC.Show.Show (Data.Geometry.Vector.VectorFamily.Vector d r)
+ Data.Geometry.Vector.VectorFamily: instance (GHC.Classes.Eq r, Data.Geometry.Vector.VectorFamily.Arity d) => GHC.Classes.Eq (Data.Geometry.Vector.VectorFamily.Vector d r)
+ Data.Geometry.Vector.VectorFamily: instance (GHC.Classes.Ord r, Data.Geometry.Vector.VectorFamily.Arity d) => GHC.Classes.Ord (Data.Geometry.Vector.VectorFamily.Vector d r)
+ Data.Geometry.Vector.VectorFamily: instance Data.Geometry.Vector.VectorFamily.Arity d => Control.Lens.At.Ixed (Data.Geometry.Vector.VectorFamily.Vector d r)
+ Data.Geometry.Vector.VectorFamily: instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Foldable.Foldable (Data.Geometry.Vector.VectorFamily.Vector d)
+ Data.Geometry.Vector.VectorFamily: instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Traversable.Traversable (Data.Geometry.Vector.VectorFamily.Vector d)
+ Data.Geometry.Vector.VectorFamily: instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Vector.Fixed.Cont.Vector (Data.Geometry.Vector.VectorFamily.Vector d) r
+ Data.Geometry.Vector.VectorFamily: instance Data.Geometry.Vector.VectorFamily.Arity d => GHC.Base.Applicative (Data.Geometry.Vector.VectorFamily.Vector d)
+ Data.Geometry.Vector.VectorFamily: instance Data.Geometry.Vector.VectorFamily.Arity d => GHC.Base.Functor (Data.Geometry.Vector.VectorFamily.Vector d)
+ Data.Geometry.Vector.VectorFamily: instance Data.Geometry.Vector.VectorFamily.Arity d => Linear.Affine.Affine (Data.Geometry.Vector.VectorFamily.Vector d)
+ Data.Geometry.Vector.VectorFamily: instance Data.Geometry.Vector.VectorFamily.Arity d => Linear.Metric.Metric (Data.Geometry.Vector.VectorFamily.Vector d)
+ Data.Geometry.Vector.VectorFamily: instance Data.Geometry.Vector.VectorFamily.Arity d => Linear.Vector.Additive (Data.Geometry.Vector.VectorFamily.Vector d)
+ Data.Geometry.Vector.VectorFamily: last :: forall d r. (KnownNat d, Arity (d + 1)) => Vector (d + 1) r -> r
+ Data.Geometry.Vector.VectorFamily: newtype Vector (d :: Nat) (r :: *)
+ Data.Geometry.Vector.VectorFamily: prefix :: forall i d r. (Arity d, Arity i, i <= d) => Vector d r -> Vector i r
+ Data.Geometry.Vector.VectorFamily: snoc :: (Arity (d + 1), Arity d) => Vector d r -> r -> Vector (d + 1) r
+ Data.Geometry.Vector.VectorFamily: type Arity d = (ImplicitArity (Peano d), KnownNat d)
+ Data.Geometry.Vector.VectorFamily: unV :: Lens (Vector d r) (Vector d s) (VectorFamily (Peano d) r) (VectorFamily (Peano d) s)
+ Data.Geometry.Vector.VectorFamily: vectorFromList :: Arity d => [r] -> Maybe (Vector d r)
+ Data.Geometry.Vector.VectorFamily: vectorFromListUnsafe :: Arity d => [r] -> Vector d r
+ Data.Geometry.Vector.VectorFamilyPeano: VectorFamily :: VectorFamilyF d r -> VectorFamily
+ Data.Geometry.Vector.VectorFamilyPeano: [SS] :: !(SingPeano d) -> SingPeano (S d)
+ Data.Geometry.Vector.VectorFamilyPeano: [SZ] :: SingPeano Z
+ Data.Geometry.Vector.VectorFamilyPeano: [_unVF] :: VectorFamily -> VectorFamilyF d r
+ Data.Geometry.Vector.VectorFamilyPeano: class ImplicitPeano (d :: PeanoNum)
+ Data.Geometry.Vector.VectorFamilyPeano: data SingPeano (d :: PeanoNum)
+ Data.Geometry.Vector.VectorFamilyPeano: destruct :: (ImplicitArity d, ImplicitArity (S d)) => VectorFamily (S d) r -> (r, VectorFamily d r)
+ Data.Geometry.Vector.VectorFamilyPeano: elem0 :: Int -> Traversal' (VectorFamily Z r) r
+ Data.Geometry.Vector.VectorFamilyPeano: elem1 :: Int -> Traversal' (VectorFamily One r) r
+ Data.Geometry.Vector.VectorFamilyPeano: elem2 :: Int -> Traversal' (VectorFamily Two r) r
+ Data.Geometry.Vector.VectorFamilyPeano: elem3 :: Int -> Traversal' (VectorFamily Three r) r
+ Data.Geometry.Vector.VectorFamilyPeano: elem4 :: Int -> Traversal' (VectorFamily Four r) r
+ Data.Geometry.Vector.VectorFamilyPeano: elemD :: Arity (FromPeano (Many d)) => Int -> Traversal' (VectorFamily (Many d) r) r
+ Data.Geometry.Vector.VectorFamilyPeano: element' :: forall d r. ImplicitArity d => Int -> Traversal' (VectorFamily d r) r
+ Data.Geometry.Vector.VectorFamilyPeano: implicitPeano :: ImplicitPeano d => SingPeano d
+ Data.Geometry.Vector.VectorFamilyPeano: instance (Control.DeepSeq.NFData r, Data.Geometry.Vector.VectorFamilyPeano.ImplicitArity d) => Control.DeepSeq.NFData (Data.Geometry.Vector.VectorFamilyPeano.VectorFamily d r)
+ Data.Geometry.Vector.VectorFamilyPeano: instance (Data.Aeson.Types.FromJSON.FromJSON r, Data.Geometry.Vector.VectorFamilyPeano.ImplicitArity d) => Data.Aeson.Types.FromJSON.FromJSON (Data.Geometry.Vector.VectorFamilyPeano.VectorFamily d r)
+ Data.Geometry.Vector.VectorFamilyPeano: instance (Data.Aeson.Types.ToJSON.ToJSON r, Data.Geometry.Vector.VectorFamilyPeano.ImplicitArity d) => Data.Aeson.Types.ToJSON.ToJSON (Data.Geometry.Vector.VectorFamilyPeano.VectorFamily d r)
+ Data.Geometry.Vector.VectorFamilyPeano: instance (Data.Geometry.Vector.VectorFamilyPeano.ImplicitArity d, GHC.Show.Show r) => GHC.Show.Show (Data.Geometry.Vector.VectorFamilyPeano.VectorFamily d r)
+ Data.Geometry.Vector.VectorFamilyPeano: instance (GHC.Classes.Eq r, Data.Geometry.Vector.VectorFamilyPeano.ImplicitArity d) => GHC.Classes.Eq (Data.Geometry.Vector.VectorFamilyPeano.VectorFamily d r)
+ Data.Geometry.Vector.VectorFamilyPeano: instance (GHC.Classes.Ord r, Data.Geometry.Vector.VectorFamilyPeano.ImplicitArity d) => GHC.Classes.Ord (Data.Geometry.Vector.VectorFamilyPeano.VectorFamily d r)
+ Data.Geometry.Vector.VectorFamilyPeano: instance Data.Geometry.Vector.VectorFamilyPeano.ImplicitArity d => Control.Lens.At.Ixed (Data.Geometry.Vector.VectorFamilyPeano.VectorFamily d r)
+ Data.Geometry.Vector.VectorFamilyPeano: instance Data.Geometry.Vector.VectorFamilyPeano.ImplicitArity d => Data.Foldable.Foldable (Data.Geometry.Vector.VectorFamilyPeano.VectorFamily d)
+ Data.Geometry.Vector.VectorFamilyPeano: instance Data.Geometry.Vector.VectorFamilyPeano.ImplicitArity d => Data.Traversable.Traversable (Data.Geometry.Vector.VectorFamilyPeano.VectorFamily d)
+ Data.Geometry.Vector.VectorFamilyPeano: instance Data.Geometry.Vector.VectorFamilyPeano.ImplicitArity d => Data.Vector.Fixed.Cont.Vector (Data.Geometry.Vector.VectorFamilyPeano.VectorFamily d) r
+ Data.Geometry.Vector.VectorFamilyPeano: instance Data.Geometry.Vector.VectorFamilyPeano.ImplicitArity d => GHC.Base.Applicative (Data.Geometry.Vector.VectorFamilyPeano.VectorFamily d)
+ Data.Geometry.Vector.VectorFamilyPeano: instance Data.Geometry.Vector.VectorFamilyPeano.ImplicitArity d => GHC.Base.Functor (Data.Geometry.Vector.VectorFamilyPeano.VectorFamily d)
+ Data.Geometry.Vector.VectorFamilyPeano: instance Data.Geometry.Vector.VectorFamilyPeano.ImplicitArity d => Linear.Affine.Affine (Data.Geometry.Vector.VectorFamilyPeano.VectorFamily d)
+ Data.Geometry.Vector.VectorFamilyPeano: instance Data.Geometry.Vector.VectorFamilyPeano.ImplicitArity d => Linear.Metric.Metric (Data.Geometry.Vector.VectorFamilyPeano.VectorFamily d)
+ Data.Geometry.Vector.VectorFamilyPeano: instance Data.Geometry.Vector.VectorFamilyPeano.ImplicitArity d => Linear.Vector.Additive (Data.Geometry.Vector.VectorFamilyPeano.VectorFamily d)
+ Data.Geometry.Vector.VectorFamilyPeano: instance Data.Geometry.Vector.VectorFamilyPeano.ImplicitPeano 'Data.Vector.Fixed.Cont.Z
+ Data.Geometry.Vector.VectorFamilyPeano: instance Data.Geometry.Vector.VectorFamilyPeano.ImplicitPeano d => Data.Geometry.Vector.VectorFamilyPeano.ImplicitPeano ('Data.Vector.Fixed.Cont.S d)
+ Data.Geometry.Vector.VectorFamilyPeano: newtype VectorFamily (d :: PeanoNum) (r :: *)
+ Data.Geometry.Vector.VectorFamilyPeano: snoc :: (ImplicitArity d, ImplicitArity (S d), (1 + FromPeano d) ~ (FromPeano d + 1)) => VectorFamily d r -> r -> VectorFamily (S d) r
+ Data.Geometry.Vector.VectorFamilyPeano: type Four = S Three
+ Data.Geometry.Vector.VectorFamilyPeano: type ImplicitArity d = (ImplicitPeano d, Arity (FromPeano d))
+ Data.Geometry.Vector.VectorFamilyPeano: type Many d = S (S (S (S (S d))))
+ Data.Geometry.Vector.VectorFamilyPeano: type One = S Z
+ Data.Geometry.Vector.VectorFamilyPeano: type Three = S Two
+ Data.Geometry.Vector.VectorFamilyPeano: type Two = S One
+ Data.Geometry.Vector.VectorFamilyPeano: unVF :: Lens (VectorFamily d r) (VectorFamily d t) (VectorFamilyF d r) (VectorFamilyF d t)
+ Data.Geometry.Vector.VectorFamilyPeano: vectorFromList :: ImplicitArity d => [r] -> Maybe (VectorFamily d r)
+ Data.Geometry.Vector.VectorFamilyPeano: vectorFromListUnsafe :: ImplicitArity d => [r] -> VectorFamily d r
+ Data.Geometry.Vector.VectorFixed: instance (Data.Aeson.Types.FromJSON.FromJSON r, Data.Vector.Fixed.Cont.Arity d, GHC.TypeNats.KnownNat d) => Data.Aeson.Types.FromJSON.FromJSON (Data.Geometry.Vector.VectorFixed.Vector d r)
+ Data.Geometry.Vector.VectorFixed: instance (Data.Aeson.Types.ToJSON.ToJSON r, Data.Vector.Fixed.Cont.Arity d) => Data.Aeson.Types.ToJSON.ToJSON (Data.Geometry.Vector.VectorFixed.Vector d r)
+ Data.Geometry.Vector.VectorFixed: instance (Data.Vector.Fixed.Cont.Arity d, Control.DeepSeq.NFData r) => Control.DeepSeq.NFData (Data.Geometry.Vector.VectorFixed.Vector d r)
+ Data.Geometry.Vector.VectorFixed: instance (GHC.Classes.Eq r, Data.Vector.Fixed.Cont.Arity d) => GHC.Classes.Eq (Data.Geometry.Vector.VectorFixed.Vector d r)
+ Data.Geometry.Vector.VectorFixed: instance (GHC.Classes.Ord r, Data.Vector.Fixed.Cont.Arity d) => GHC.Classes.Ord (Data.Geometry.Vector.VectorFixed.Vector d r)
+ Data.Geometry.Vector.VectorFixed: instance (GHC.Show.Show r, Data.Vector.Fixed.Cont.Arity d) => GHC.Show.Show (Data.Geometry.Vector.VectorFixed.Vector d r)
+ Data.Geometry.Vector.VectorFixed: instance Data.Vector.Fixed.Cont.Arity d => Data.Foldable.Foldable (Data.Geometry.Vector.VectorFixed.Vector d)
+ Data.Geometry.Vector.VectorFixed: instance Data.Vector.Fixed.Cont.Arity d => Data.Traversable.Traversable (Data.Geometry.Vector.VectorFixed.Vector d)
+ Data.Geometry.Vector.VectorFixed: instance Data.Vector.Fixed.Cont.Arity d => Data.Vector.Fixed.Cont.Vector (Data.Geometry.Vector.VectorFixed.Vector d) r
+ Data.Geometry.Vector.VectorFixed: instance Data.Vector.Fixed.Cont.Arity d => GHC.Base.Applicative (Data.Geometry.Vector.VectorFixed.Vector d)
+ Data.Geometry.Vector.VectorFixed: instance Data.Vector.Fixed.Cont.Arity d => GHC.Base.Functor (Data.Geometry.Vector.VectorFixed.Vector d)
+ Data.Geometry.Vector.VectorFixed: instance Data.Vector.Fixed.Cont.Arity d => Linear.Affine.Affine (Data.Geometry.Vector.VectorFixed.Vector d)
+ Data.Geometry.Vector.VectorFixed: instance Data.Vector.Fixed.Cont.Arity d => Linear.Metric.Metric (Data.Geometry.Vector.VectorFixed.Vector d)
+ Data.Geometry.Vector.VectorFixed: instance Data.Vector.Fixed.Cont.Arity d => Linear.Vector.Additive (Data.Geometry.Vector.VectorFixed.Vector d)
+ Data.Geometry.Vector.VectorFixed: last :: forall d r. (Arity d, Arity (d + 1)) => Vector (d + 1) r -> r
+ Data.Geometry.Vector.VectorFixed: toV2 :: Vector 2 a -> V2 a
+ Data.OrdSeq: Elem :: a -> Elem a
+ Data.OrdSeq: Key :: !a -> Key a
+ Data.OrdSeq: NoKey :: Key a
+ Data.OrdSeq: OrdSeq :: FingerTree (Key a) (Elem a) -> OrdSeq a
+ Data.OrdSeq: [_asFingerTree] :: OrdSeq a -> FingerTree (Key a) (Elem a)
+ Data.OrdSeq: [getElem] :: Elem a -> a
+ Data.OrdSeq: [getKey] :: Key a -> !a
+ Data.OrdSeq: data Key a
+ Data.OrdSeq: deleteAll :: Ord a => a -> OrdSeq a -> OrdSeq a
+ Data.OrdSeq: deleteAllBy :: Compare a -> a -> OrdSeq a -> OrdSeq a
+ Data.OrdSeq: fromAscList' :: [a] -> OrdSeq a
+ Data.OrdSeq: fromListBy :: Compare a -> [a] -> OrdSeq a
+ Data.OrdSeq: fromListByOrd :: Ord a => [a] -> OrdSeq a
+ Data.OrdSeq: insert :: Ord a => a -> OrdSeq a -> OrdSeq a
+ Data.OrdSeq: insertBy :: Compare a -> a -> OrdSeq a -> OrdSeq a
+ Data.OrdSeq: instance Data.FingerTree.Measured (Data.OrdSeq.Key a) (Data.OrdSeq.Elem a)
+ Data.OrdSeq: instance Data.Foldable.Foldable Data.OrdSeq.Elem
+ Data.OrdSeq: instance Data.Foldable.Foldable Data.OrdSeq.OrdSeq
+ Data.OrdSeq: instance Data.Traversable.Traversable Data.OrdSeq.Elem
+ Data.OrdSeq: instance GHC.Base.Functor Data.OrdSeq.Elem
+ Data.OrdSeq: instance GHC.Base.Monoid (Data.OrdSeq.Key a)
+ Data.OrdSeq: instance GHC.Base.Monoid (Data.OrdSeq.OrdSeq a)
+ Data.OrdSeq: instance GHC.Base.Semigroup (Data.OrdSeq.Key a)
+ Data.OrdSeq: instance GHC.Base.Semigroup (Data.OrdSeq.OrdSeq a)
+ Data.OrdSeq: instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.OrdSeq.Elem a)
+ Data.OrdSeq: instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.OrdSeq.Key a)
+ Data.OrdSeq: instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.OrdSeq.OrdSeq a)
+ Data.OrdSeq: instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.OrdSeq.Elem a)
+ Data.OrdSeq: instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.OrdSeq.Key a)
+ Data.OrdSeq: instance GHC.Show.Show a => GHC.Show.Show (Data.OrdSeq.Elem a)
+ Data.OrdSeq: instance GHC.Show.Show a => GHC.Show.Show (Data.OrdSeq.Key a)
+ Data.OrdSeq: instance GHC.Show.Show a => GHC.Show.Show (Data.OrdSeq.OrdSeq a)
+ Data.OrdSeq: liftCmp :: (a -> a -> Ordering) -> Key a -> Key a -> Ordering
+ Data.OrdSeq: lookupBy :: Compare a -> a -> OrdSeq a -> Maybe a
+ Data.OrdSeq: lookupMax :: OrdSeq a -> Maybe a
+ Data.OrdSeq: lookupMin :: OrdSeq a -> Maybe a
+ Data.OrdSeq: mapMonotonic :: (a -> b) -> OrdSeq a -> OrdSeq b
+ Data.OrdSeq: maxView :: OrdSeq a -> Maybe (a, OrdSeq a)
+ Data.OrdSeq: memberBy :: Compare a -> a -> OrdSeq a -> Bool
+ Data.OrdSeq: minView :: OrdSeq a -> Maybe (a, OrdSeq a)
+ Data.OrdSeq: newtype Elem a
+ Data.OrdSeq: newtype OrdSeq a
+ Data.OrdSeq: splitBy :: Compare a -> a -> OrdSeq a -> (OrdSeq a, OrdSeq a, OrdSeq a)
+ Data.OrdSeq: splitMonotonic :: (a -> Bool) -> OrdSeq a -> (OrdSeq a, OrdSeq a)
+ Data.OrdSeq: splitOn :: Ord b => (a -> b) -> b -> OrdSeq a -> (OrdSeq a, OrdSeq a, OrdSeq a)
+ Data.OrdSeq: type Compare a = a -> a -> Ordering
+ Data.OrdSeq: viewl :: OrdSeq a -> ViewL OrdSeq a
+ Data.OrdSeq: viewr :: OrdSeq a -> ViewR OrdSeq a
+ Data.Permutation: previous :: Vector v a => v a -> Int -> a
+ Data.PlanarGraph: Dual :: World
+ Data.PlanarGraph: Primal :: World
+ Data.PlanarGraph: allDarts :: [Dart s]
+ Data.PlanarGraph: boundary' :: Dart s -> PlanarGraph s w v e f -> Vector (Dart s)
+ Data.PlanarGraph: buildFromJSON :: Vector (VertexId' s :+ v) -> Vector ((VertexId' s, VertexId' s) :+ e) -> Vector (FaceId' s :+ f) -> [(VertexId' s, Vector (VertexId' s))] -> PlanarGraph s Primal v e f
+ Data.PlanarGraph: class HasDataOf g i where {
+ Data.PlanarGraph: dataOf :: HasDataOf g i => i -> Lens' g (DataOf g i)
+ Data.PlanarGraph: findDart :: VertexId s w -> VertexId s w -> EdgeOracle s w (Dart s) -> Maybe (Dart s)
+ Data.PlanarGraph: instance forall k (s :: k) (w :: Data.PlanarGraph.World) v e f. Data.PlanarGraph.HasDataOf (Data.PlanarGraph.PlanarGraph s w v e f) (Data.PlanarGraph.Dart s)
+ Data.PlanarGraph: instance forall k (s :: k) (w :: Data.PlanarGraph.World) v e f. Data.PlanarGraph.HasDataOf (Data.PlanarGraph.PlanarGraph s w v e f) (Data.PlanarGraph.FaceId s w)
+ Data.PlanarGraph: instance forall k (s :: k) (w :: Data.PlanarGraph.World) v e f. Data.PlanarGraph.HasDataOf (Data.PlanarGraph.PlanarGraph s w v e f) (Data.PlanarGraph.VertexId s w)
+ Data.PlanarGraph: instance forall k (s :: k) (w :: Data.PlanarGraph.World). Data.Aeson.Types.FromJSON.FromJSON (Data.PlanarGraph.FaceId s w)
+ Data.PlanarGraph: instance forall k (s :: k) (w :: Data.PlanarGraph.World). Data.Aeson.Types.FromJSON.FromJSON (Data.PlanarGraph.VertexId s w)
+ Data.PlanarGraph: instance forall k (s :: k) (w :: Data.PlanarGraph.World). Data.Aeson.Types.ToJSON.ToJSON (Data.PlanarGraph.FaceId s w)
+ Data.PlanarGraph: instance forall k (s :: k) (w :: Data.PlanarGraph.World). Data.Aeson.Types.ToJSON.ToJSON (Data.PlanarGraph.VertexId s w)
+ Data.PlanarGraph: instance forall k v e f (s :: k) (w :: Data.PlanarGraph.World). (Data.Aeson.Types.ToJSON.ToJSON v, Data.Aeson.Types.ToJSON.ToJSON e, Data.Aeson.Types.ToJSON.ToJSON f) => Data.Aeson.Types.ToJSON.ToJSON (Data.PlanarGraph.PlanarGraph s w v e f)
+ Data.PlanarGraph: instance forall k v e f (s :: k) (w :: Data.PlanarGraph.World). (GHC.Classes.Eq v, GHC.Classes.Eq e, GHC.Classes.Eq f) => GHC.Classes.Eq (Data.PlanarGraph.PlanarGraph s w v e f)
+ Data.PlanarGraph: instance forall k v e f (s :: k) (w :: Data.PlanarGraph.World). (GHC.Show.Show v, GHC.Show.Show e, GHC.Show.Show f) => GHC.Show.Show (Data.PlanarGraph.PlanarGraph s w v e f)
+ Data.PlanarGraph: instance forall k v e f (s :: k). (Data.Aeson.Types.FromJSON.FromJSON v, Data.Aeson.Types.FromJSON.FromJSON e, Data.Aeson.Types.FromJSON.FromJSON f) => Data.Aeson.Types.FromJSON.FromJSON (Data.PlanarGraph.PlanarGraph s 'Data.PlanarGraph.Primal v e f)
+ Data.PlanarGraph: nextEdge :: Dart s -> PlanarGraph s w v e f -> Dart s
+ Data.PlanarGraph: nextIncidentEdge :: Dart s -> PlanarGraph s w v e f -> Dart s
+ Data.PlanarGraph: prevEdge :: Dart s -> PlanarGraph s w v e f -> Dart s
+ Data.PlanarGraph: prevIncidentEdge :: Dart s -> PlanarGraph s w v e f -> Dart s
+ Data.PlanarGraph: rawDartData :: Lens (PlanarGraph s w v e f) (PlanarGraph s w v e' f) (Vector e) (Vector e')
+ Data.PlanarGraph: toAdjacencyLists :: PlanarGraph s w v e f -> [(VertexId s w, Vector (VertexId s w))]
+ Data.PlanarGraph: type FaceId' s = FaceId s Primal
+ Data.PlanarGraph: type VertexId' s = VertexId s Primal
+ Data.PlanarGraph: type family DataOf g i;
+ Data.PlanarGraph: }
+ Data.PlaneGraph: Dual :: World
+ Data.PlaneGraph: FaceId :: VertexId s (DualOf w) -> FaceId s w
+ Data.PlaneGraph: PlaneGraph :: PlanarGraph s Primal (VertexData r v) e f -> PlaneGraph s v e f r
+ Data.PlaneGraph: Primal :: World
+ Data.PlaneGraph: VertexData :: !(Point 2 r) -> !v -> VertexData r v
+ Data.PlaneGraph: VertexId :: Int -> VertexId s
+ Data.PlaneGraph: [_unFaceId] :: FaceId s w -> VertexId s (DualOf w)
+ Data.PlaneGraph: [_unVertexId] :: VertexId s -> Int
+ Data.PlaneGraph: boundary :: FaceId' s -> PlaneGraph s v e f r -> Vector (Dart s)
+ Data.PlaneGraph: boundary' :: Dart s -> PlaneGraph s v e f r -> Vector (Dart s)
+ Data.PlaneGraph: boundaryVertices :: FaceId' s -> PlaneGraph s v e f r -> Vector (VertexId' s)
+ Data.PlaneGraph: class HasDataOf g i where {
+ Data.PlaneGraph: dartData :: Lens (PlaneGraph s v e f r) (PlaneGraph s v e' f r) (Vector (Dart s, e)) (Vector (Dart s, e'))
+ Data.PlaneGraph: darts' :: PlaneGraph s v e f r -> Vector (Dart s)
+ Data.PlaneGraph: data Dart s
+ Data.PlaneGraph: data PlanarGraph s (w :: World) v e f
+ Data.PlaneGraph: data VertexData r v
+ Data.PlaneGraph: data World
+ Data.PlaneGraph: dataOf :: HasDataOf g i => i -> Lens' g (DataOf g i)
+ Data.PlaneGraph: dual :: Getter (PlanarGraph s w v e f) (PlanarGraph s (DualOf w) f e v)
+ Data.PlaneGraph: edgeSegment :: Dart s -> PlaneGraph s v e f r -> LineSegment 2 v r :+ e
+ Data.PlaneGraph: edgeSegments :: PlaneGraph s v e f r -> Vector (Dart s, LineSegment 2 v r :+ e)
+ Data.PlaneGraph: edges :: PlaneGraph s v e f r -> Vector (Dart s, e)
+ Data.PlaneGraph: edges' :: PlaneGraph s v e f r -> Vector (Dart s)
+ Data.PlaneGraph: endPointData :: Dart s -> PlaneGraph s v e f r -> (VertexData r v, VertexData r v)
+ Data.PlaneGraph: endPoints :: Dart s -> PlaneGraph s v e f r -> (VertexId' s, VertexId' s)
+ Data.PlaneGraph: endPointsOf :: Dart s -> Getter (PlaneGraph s v e f r) (VertexData r v, VertexData r v)
+ Data.PlaneGraph: faceData :: Lens (PlaneGraph s v e f r) (PlaneGraph s v e f' r) (Vector f) (Vector f')
+ Data.PlaneGraph: faces :: PlaneGraph s v e f r -> Vector (FaceId' s, f)
+ Data.PlaneGraph: faces' :: PlaneGraph s v e f r -> Vector (FaceId' s)
+ Data.PlaneGraph: faces'' :: (Ord r, Fractional r) => PlaneGraph s v e f r -> ((FaceId' s, f), Vector (FaceId' s, f))
+ Data.PlaneGraph: fromAdjacencyLists :: forall s w h. (Foldable h, Functor h) => [(VertexId s w, h (VertexId s w))] -> PlanarGraph s w () () ()
+ Data.PlaneGraph: fromConnectedSegments :: (Foldable f, Ord r, Num r) => proxy s -> f (LineSegment 2 p r :+ e) -> PlaneGraph s (NonEmpty p) e () r
+ Data.PlaneGraph: fromSimplePolygon :: proxy s -> SimplePolygon p r -> f -> f -> PlaneGraph s p () f r
+ Data.PlaneGraph: graph :: forall s_a2SMd v_a2SMe e_a2SMf f_a2SMg r_a2SMh s_a2Ta9 v_a2Taa e_a2Tab f_a2Tac r_a2Tad. Iso (PlaneGraph s_a2SMd v_a2SMe e_a2SMf f_a2SMg r_a2SMh) (PlaneGraph s_a2Ta9 v_a2Taa e_a2Tab f_a2Tac r_a2Tad) (PlanarGraph s_a2SMd Primal (VertexData r_a2SMh v_a2SMe) e_a2SMf f_a2SMg) (PlanarGraph s_a2Ta9 Primal (VertexData r_a2Tad v_a2Taa) e_a2Tab f_a2Tac)
+ Data.PlaneGraph: headOf :: Dart s -> PlaneGraph s v e f r -> VertexId' s
+ Data.PlaneGraph: incidentEdges :: VertexId' s -> PlaneGraph s v e f r -> Vector (Dart s)
+ Data.PlaneGraph: incomingEdges :: VertexId' s -> PlaneGraph s v e f r -> Vector (Dart s)
+ Data.PlaneGraph: instance (Data.Aeson.Types.FromJSON.FromJSON r, Data.Aeson.Types.FromJSON.FromJSON v) => Data.Aeson.Types.FromJSON.FromJSON (Data.PlaneGraph.VertexData r v)
+ Data.PlaneGraph: instance (Data.Aeson.Types.ToJSON.ToJSON r, Data.Aeson.Types.ToJSON.ToJSON v) => Data.Aeson.Types.ToJSON.ToJSON (Data.PlaneGraph.VertexData r v)
+ Data.PlaneGraph: instance (GHC.Classes.Eq r, GHC.Classes.Eq v) => GHC.Classes.Eq (Data.PlaneGraph.VertexData r v)
+ Data.PlaneGraph: instance (GHC.Classes.Ord r, GHC.Classes.Ord v) => GHC.Classes.Ord (Data.PlaneGraph.VertexData r v)
+ Data.PlaneGraph: instance (GHC.Show.Show r, GHC.Show.Show v) => GHC.Show.Show (Data.PlaneGraph.VertexData r v)
+ Data.PlaneGraph: instance Data.Bifunctor.Bifunctor Data.PlaneGraph.VertexData
+ Data.PlaneGraph: instance Data.Foldable.Foldable (Data.PlaneGraph.VertexData r)
+ Data.PlaneGraph: instance Data.Traversable.Traversable (Data.PlaneGraph.VertexData r)
+ Data.PlaneGraph: instance GHC.Base.Functor (Data.PlaneGraph.VertexData r)
+ Data.PlaneGraph: instance forall k (s :: k) v e f r. (Data.Aeson.Types.FromJSON.FromJSON r, Data.Aeson.Types.FromJSON.FromJSON v, Data.Aeson.Types.FromJSON.FromJSON e, Data.Aeson.Types.FromJSON.FromJSON f) => Data.Aeson.Types.FromJSON.FromJSON (Data.PlaneGraph.PlaneGraph s v e f r)
+ Data.PlaneGraph: instance forall k (s :: k) v e f r. (Data.Aeson.Types.ToJSON.ToJSON r, Data.Aeson.Types.ToJSON.ToJSON v, Data.Aeson.Types.ToJSON.ToJSON e, Data.Aeson.Types.ToJSON.ToJSON f) => Data.Aeson.Types.ToJSON.ToJSON (Data.PlaneGraph.PlaneGraph s v e f r)
+ Data.PlaneGraph: instance forall k (s :: k) v e f r. (GHC.Classes.Eq r, GHC.Classes.Eq v, GHC.Classes.Eq e, GHC.Classes.Eq f) => GHC.Classes.Eq (Data.PlaneGraph.PlaneGraph s v e f r)
+ Data.PlaneGraph: instance forall k (s :: k) v e f r. (GHC.Show.Show r, GHC.Show.Show v, GHC.Show.Show e, GHC.Show.Show f) => GHC.Show.Show (Data.PlaneGraph.PlaneGraph s v e f r)
+ Data.PlaneGraph: instance forall k (s :: k) v e f r. Data.Geometry.Box.Internal.IsBoxable (Data.PlaneGraph.PlaneGraph s v e f r)
+ Data.PlaneGraph: instance forall k (s :: k) v e f r. Data.PlanarGraph.HasDataOf (Data.PlaneGraph.PlaneGraph s v e f r) (Data.PlanarGraph.Dart s)
+ Data.PlaneGraph: instance forall k (s :: k) v e f r. Data.PlanarGraph.HasDataOf (Data.PlaneGraph.PlaneGraph s v e f r) (Data.PlanarGraph.FaceId' s)
+ Data.PlaneGraph: instance forall k (s :: k) v e f r. Data.PlanarGraph.HasDataOf (Data.PlaneGraph.PlaneGraph s v e f r) (Data.PlanarGraph.VertexId' s)
+ Data.PlaneGraph: instance forall k (s :: k) v e f. GHC.Base.Functor (Data.PlaneGraph.PlaneGraph s v e f)
+ Data.PlaneGraph: internalFaces :: (Ord r, Fractional r) => PlaneGraph s v e f r -> Vector (FaceId' s, f)
+ Data.PlaneGraph: leftFace :: Dart s -> PlaneGraph s v e f r -> FaceId' s
+ Data.PlaneGraph: location :: forall r_a2SAw v_a2SAx r_a2SLX. Lens (VertexData r_a2SAw v_a2SAx) (VertexData r_a2SLX v_a2SAx) (Point 2 r_a2SAw) (Point 2 r_a2SLX)
+ Data.PlaneGraph: locationOf :: VertexId' s -> Lens' (PlaneGraph s v e f r) (Point 2 r)
+ Data.PlaneGraph: neighboursOf :: VertexId' s -> PlaneGraph s v e f r -> Vector (VertexId' s)
+ Data.PlaneGraph: newtype FaceId s w
+ Data.PlaneGraph: newtype PlaneGraph s v e f r
+ Data.PlaneGraph: newtype VertexId s (w :: World)
+ Data.PlaneGraph: nextEdge :: Dart s -> PlaneGraph s v e f r -> Dart s
+ Data.PlaneGraph: nextIncidentEdge :: Dart s -> PlaneGraph s v e f r -> Dart s
+ Data.PlaneGraph: numDarts :: PlaneGraph s v e f r -> Int
+ Data.PlaneGraph: numEdges :: PlaneGraph s v e f r -> Int
+ Data.PlaneGraph: numFaces :: PlaneGraph s v e f r -> Int
+ Data.PlaneGraph: numVertices :: PlaneGraph s v e f r -> Int
+ Data.PlaneGraph: outerFaceDart :: (Ord r, Fractional r) => PlaneGraph s v e f r -> Dart s
+ Data.PlaneGraph: outerFaceId :: (Ord r, Fractional r) => PlaneGraph s v e f r -> FaceId' s
+ Data.PlaneGraph: outgoingEdges :: VertexId' s -> PlaneGraph s v e f r -> Vector (Dart s)
+ Data.PlaneGraph: prevEdge :: Dart s -> PlaneGraph s v e f r -> Dart s
+ Data.PlaneGraph: prevIncidentEdge :: Dart s -> PlaneGraph s v e f r -> Dart s
+ Data.PlaneGraph: rawDartData :: Lens (PlaneGraph s v e f r) (PlaneGraph s v e' f r) (Vector e) (Vector e')
+ Data.PlaneGraph: rawFaceBoundary :: FaceId' s -> PlaneGraph s v e f r -> SimplePolygon v r :+ f
+ Data.PlaneGraph: rawFacePolygon :: FaceId' s -> PlaneGraph s v e f r -> SimplePolygon v r :+ f
+ Data.PlaneGraph: rawFacePolygons :: PlaneGraph s v e f r -> Vector (FaceId' s, SimplePolygon v r :+ f)
+ Data.PlaneGraph: rightFace :: Dart s -> PlaneGraph s v e f r -> FaceId' s
+ Data.PlaneGraph: tailOf :: Dart s -> PlaneGraph s v e f r -> VertexId' s
+ Data.PlaneGraph: twin :: Dart s -> Dart s
+ Data.PlaneGraph: type FaceId' s = FaceId s Primal
+ Data.PlaneGraph: type VertexId' s = VertexId s Primal
+ Data.PlaneGraph: type family DataOf g i;
+ Data.PlaneGraph: vData :: forall r_a2SAw v_a2SAx v_a2SLY. Lens (VertexData r_a2SAw v_a2SAx) (VertexData r_a2SAw v_a2SLY) v_a2SAx v_a2SLY
+ Data.PlaneGraph: vertexData :: Lens (PlaneGraph s v e f r) (PlaneGraph s v' e f r) (Vector v) (Vector v')
+ Data.PlaneGraph: vertexDataOf :: VertexId' s -> Lens' (PlaneGraph s v e f r) (VertexData r v)
+ Data.PlaneGraph: vertices :: PlaneGraph s v e f r -> Vector (VertexId' s, VertexData r v)
+ Data.PlaneGraph: vertices' :: PlaneGraph s v e f r -> Vector (VertexId' s)
+ Data.PlaneGraph: vtxDataToExt :: VertexData r v -> Point 2 r :+ v
+ Data.PlaneGraph: }
+ Data.PlaneGraph.Draw: drawPlaneGraph :: forall s v e f r. IpeOut (PlaneGraph s v e f r) (IpeObject r)
+ Data.Seq: instance GHC.Base.Semigroup (Data.Seq.LSeq n a)
+ Data.Seq: instance GHC.Base.Semigroup (Data.Seq.ViewL n a)
+ Data.Seq: instance GHC.Base.Semigroup (Data.Seq.ViewR n a)
+ Data.Seq2: instance GHC.Base.Semigroup (Data.Seq2.Seq2 a)
+ Data.Seq2: instance GHC.Base.Semigroup (Data.Seq2.ViewL1 a)
+ Data.Sequence.Util: binarySearchVec :: Vector v a => (a -> Bool) -> v a -> Maybe Int
+ Data.SlowSeq: Key :: a -> Key a
+ Data.SlowSeq: NoKey :: Key a
+ Data.SlowSeq: OrdSeq :: Seq a -> OrdSeq a
+ Data.SlowSeq: [_asSeq] :: OrdSeq a -> Seq a
+ Data.SlowSeq: [getKey] :: Key a -> a
+ Data.SlowSeq: data Key a
+ Data.SlowSeq: deleteAll :: Ord a => a -> OrdSeq a -> OrdSeq a
+ Data.SlowSeq: deleteAllBy :: Compare a -> a -> OrdSeq a -> OrdSeq a
+ Data.SlowSeq: fromAscList' :: [a] -> OrdSeq a
+ Data.SlowSeq: fromListBy :: Compare a -> [a] -> OrdSeq a
+ Data.SlowSeq: fromListByOrd :: Ord a => [a] -> OrdSeq a
+ Data.SlowSeq: insert :: Ord a => a -> OrdSeq a -> OrdSeq a
+ Data.SlowSeq: insertBy :: Compare a -> a -> OrdSeq a -> OrdSeq a
+ Data.SlowSeq: instance Data.Foldable.Foldable Data.SlowSeq.OrdSeq
+ Data.SlowSeq: instance GHC.Base.Monoid (Data.SlowSeq.Key a)
+ Data.SlowSeq: instance GHC.Base.Monoid (Data.SlowSeq.OrdSeq a)
+ Data.SlowSeq: instance GHC.Base.Semigroup (Data.SlowSeq.Key a)
+ Data.SlowSeq: instance GHC.Base.Semigroup (Data.SlowSeq.OrdSeq a)
+ Data.SlowSeq: instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.SlowSeq.Key a)
+ Data.SlowSeq: instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.SlowSeq.OrdSeq a)
+ Data.SlowSeq: instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.SlowSeq.Key a)
+ Data.SlowSeq: instance GHC.Show.Show a => GHC.Show.Show (Data.SlowSeq.Key a)
+ Data.SlowSeq: instance GHC.Show.Show a => GHC.Show.Show (Data.SlowSeq.OrdSeq a)
+ Data.SlowSeq: liftCmp :: (a -> a -> Ordering) -> Key a -> Key a -> Ordering
+ Data.SlowSeq: lookupBy :: Compare a -> a -> OrdSeq a -> Maybe a
+ Data.SlowSeq: lookupMax :: OrdSeq a -> Maybe a
+ Data.SlowSeq: lookupMin :: OrdSeq a -> Maybe a
+ Data.SlowSeq: mapMonotonic :: (a -> b) -> OrdSeq a -> OrdSeq b
+ Data.SlowSeq: maxView :: OrdSeq a -> Maybe (a, OrdSeq a)
+ Data.SlowSeq: memberBy :: Compare a -> a -> OrdSeq a -> Bool
+ Data.SlowSeq: minView :: OrdSeq a -> Maybe (a, OrdSeq a)
+ Data.SlowSeq: newtype OrdSeq a
+ Data.SlowSeq: split :: (a -> Bool) -> Seq a -> (Seq a, Seq a)
+ Data.SlowSeq: splitBy :: Compare a -> a -> OrdSeq a -> (OrdSeq a, OrdSeq a, OrdSeq a)
+ Data.SlowSeq: splitMonotonic :: (a -> Bool) -> OrdSeq a -> (OrdSeq a, OrdSeq a)
+ Data.SlowSeq: splitOn :: Ord b => (a -> b) -> b -> OrdSeq a -> (OrdSeq a, OrdSeq a, OrdSeq a)
+ Data.SlowSeq: type Compare a = a -> a -> Ordering
+ Data.SlowSeq: viewl :: OrdSeq a -> ViewL OrdSeq a
+ Data.SlowSeq: viewr :: OrdSeq a -> ViewR OrdSeq a
+ Data.Util: instance (GHC.Base.Semigroup a, GHC.Base.Semigroup b) => GHC.Base.Semigroup (Data.Util.SP a b)
+ Data.Util: instance (GHC.Classes.Eq a, GHC.Classes.Eq b) => GHC.Classes.Eq (Data.Util.SP a b)
+ Data.Util: instance (GHC.Classes.Eq a, GHC.Classes.Eq b, GHC.Classes.Eq c) => GHC.Classes.Eq (Data.Util.STR a b c)
+ Data.Util: instance (GHC.Classes.Ord a, GHC.Classes.Ord b) => GHC.Classes.Ord (Data.Util.SP a b)
+ Data.Util: instance (GHC.Classes.Ord a, GHC.Classes.Ord b, GHC.Classes.Ord c) => GHC.Classes.Ord (Data.Util.STR a b c)
+ Data.Util: instance (GHC.Show.Show a, GHC.Show.Show b) => GHC.Show.Show (Data.Util.SP a b)
+ Data.Util: instance (GHC.Show.Show a, GHC.Show.Show b, GHC.Show.Show c) => GHC.Show.Show (Data.Util.STR a b c)
+ Data.Yaml.Util: decodeYaml :: FromJSON a => ByteString -> Either ParseException a
+ Data.Yaml.Util: decodeYamlFile :: FromJSON a => FilePath -> IO (Either ParseException a)
+ Data.Yaml.Util: encodeYaml :: ToJSON a => a -> ByteString
+ Data.Yaml.Util: printYaml :: ToJSON a => a -> IO ()
+ Test.QuickCheck.HGeometryInstances: instance (GHC.TypeNats.KnownNat n, Test.QuickCheck.Arbitrary.Arbitrary a) => Test.QuickCheck.Arbitrary.Arbitrary (Data.Seq.LSeq n a)
+ Test.QuickCheck.HGeometryInstances: instance (Test.QuickCheck.Arbitrary.Arbitrary a, GHC.Classes.Ord a) => Test.QuickCheck.Arbitrary.Arbitrary (Data.OrdSeq.OrdSeq a)
+ Test.QuickCheck.HGeometryInstances: instance (Test.QuickCheck.Arbitrary.Arbitrary a, Test.QuickCheck.Arbitrary.Arbitrary v) => Test.QuickCheck.Arbitrary.Arbitrary (Data.BinaryTree.BinLeafTree v a)
+ Test.QuickCheck.HGeometryInstances: instance (Test.QuickCheck.Arbitrary.Arbitrary c, Test.QuickCheck.Arbitrary.Arbitrary e) => Test.QuickCheck.Arbitrary.Arbitrary (c Data.Ext.:+ e)
+ Test.QuickCheck.HGeometryInstances: instance (Test.QuickCheck.Arbitrary.Arbitrary r, Data.Geometry.Vector.VectorFamily.Arity d) => Test.QuickCheck.Arbitrary.Arbitrary (Data.Geometry.Point.Point d r)
+ Test.QuickCheck.HGeometryInstances: instance (Test.QuickCheck.Arbitrary.Arbitrary r, Data.Geometry.Vector.VectorFamily.Arity d) => Test.QuickCheck.Arbitrary.Arbitrary (Data.Geometry.Vector.VectorFamily.Vector d r)
+ Test.QuickCheck.HGeometryInstances: instance (Test.QuickCheck.Arbitrary.Arbitrary r, Data.Geometry.Vector.VectorFamily.Arity d, GHC.Classes.Ord r) => Test.QuickCheck.Arbitrary.Arbitrary (Data.Geometry.Box.Internal.Box d () r)
+ Test.QuickCheck.HGeometryInstances: instance (Test.QuickCheck.Arbitrary.Arbitrary r, Data.Geometry.Vector.VectorFamily.Arity d, GHC.Num.Num r, GHC.Classes.Eq r) => Test.QuickCheck.Arbitrary.Arbitrary (Data.Geometry.Line.Internal.Line d r)
+ Test.QuickCheck.HGeometryInstances: instance (Test.QuickCheck.Arbitrary.Arbitrary r, GHC.Classes.Ord r) => Test.QuickCheck.Arbitrary.Arbitrary (Data.Range.Range r)
+ Test.QuickCheck.HGeometryInstances: instance (Test.QuickCheck.Arbitrary.Arbitrary r, Test.QuickCheck.Arbitrary.Arbitrary p, Data.Geometry.Vector.VectorFamily.Arity d) => Test.QuickCheck.Arbitrary.Arbitrary (Data.Geometry.LineSegment.LineSegment d p r)
+ Test.QuickCheck.HGeometryInstances: instance (Test.QuickCheck.Arbitrary.Arbitrary r, Test.QuickCheck.Arbitrary.Arbitrary p, Data.Geometry.Vector.VectorFamily.Arity d, GHC.Classes.Ord r, GHC.Classes.Ord p, GHC.Num.Num r) => Test.QuickCheck.Arbitrary.Arbitrary (Data.Geometry.SubLine.SubLine d p r)
+ Test.QuickCheck.HGeometryInstances: instance (Test.QuickCheck.Arbitrary.Arbitrary r, Test.QuickCheck.Arbitrary.Arbitrary p, GHC.Classes.Ord r, GHC.Classes.Ord p) => Test.QuickCheck.Arbitrary.Arbitrary (Data.Geometry.Interval.Interval p r)
+ Test.QuickCheck.HGeometryInstances: instance Test.QuickCheck.Arbitrary.Arbitrary a => Test.QuickCheck.Arbitrary.Arbitrary (Data.BinaryTree.BinaryTree a)
+ Test.QuickCheck.HGeometryInstances: instance Test.QuickCheck.Arbitrary.Arbitrary a => Test.QuickCheck.Arbitrary.Arbitrary (Data.Seq2.Seq2 a)
+ Test.QuickCheck.HGeometryInstances: instance Test.QuickCheck.Arbitrary.Arbitrary r => Test.QuickCheck.Arbitrary.Arbitrary (Data.Range.EndPoint r)
- Algorithms.Geometry.DelaunayTriangulation.Types: neighbours :: forall p_a3De0 r_a3De1. Lens' (Triangulation p_a3De0 r_a3De1) (Vector (CList VertexID))
+ Algorithms.Geometry.DelaunayTriangulation.Types: neighbours :: forall p_a3M9c r_a3M9d. Lens' (Triangulation p_a3M9c r_a3M9d) (Vector (CList VertexID))
- Algorithms.Geometry.DelaunayTriangulation.Types: positions :: forall p_a3De0 r_a3De1 p_a3Dhq. Lens (Triangulation p_a3De0 r_a3De1) (Triangulation p_a3Dhq r_a3De1) (Vector ((:+) (Point 2 r_a3De1) p_a3De0)) (Vector ((:+) (Point 2 r_a3De1) p_a3Dhq))
+ Algorithms.Geometry.DelaunayTriangulation.Types: positions :: forall p_a3M9c r_a3M9d p_a3MdY. Lens (Triangulation p_a3M9c r_a3M9d) (Triangulation p_a3MdY r_a3M9d) (Vector ((:+) (Point 2 r_a3M9d) p_a3M9c)) (Vector ((:+) (Point 2 r_a3M9d) p_a3MdY))
- Algorithms.Geometry.DelaunayTriangulation.Types: toPlanarSubdivision :: proxy s -> Triangulation p r -> PlanarSubdivision s p () () r
+ Algorithms.Geometry.DelaunayTriangulation.Types: toPlanarSubdivision :: (Ord r, Fractional r) => proxy s -> Triangulation p r -> PlanarSubdivision s p () () r
- Algorithms.Geometry.DelaunayTriangulation.Types: toPlaneGraph :: forall proxy s p r. proxy s -> Triangulation p r -> PlaneGraph s Primal_ p () () r
+ Algorithms.Geometry.DelaunayTriangulation.Types: toPlaneGraph :: forall proxy s p r. proxy s -> Triangulation p r -> PlaneGraph s p () () r
- Algorithms.Geometry.DelaunayTriangulation.Types: vertexIds :: forall p_a3De0 r_a3De1. Lens' (Triangulation p_a3De0 r_a3De1) (Map (Point 2 r_a3De1) VertexID)
+ Algorithms.Geometry.DelaunayTriangulation.Types: vertexIds :: forall p_a3M9c r_a3M9d. Lens' (Triangulation p_a3M9c r_a3M9d) (Map (Point 2 r_a3M9d) VertexID)
- Algorithms.Geometry.LineSegmentIntersection.BentleyOttmann: handle :: (Ord r, Fractional r) => Event p r -> EventQueue p r -> StatusStructure p r -> [IntersectionPoint p r]
+ Algorithms.Geometry.LineSegmentIntersection.BentleyOttmann: handle :: forall r p. (Ord r, Fractional r) => Event p r -> EventQueue p r -> StatusStructure p r -> [IntersectionPoint p r]
- Algorithms.Geometry.LineSegmentIntersection.BentleyOttmann: type StatusStructure p r = BalBST r (LineSegment 2 p r)
+ Algorithms.Geometry.LineSegmentIntersection.BentleyOttmann: type StatusStructure p r = OrdSeq (LineSegment 2 p r)
- Algorithms.Geometry.LineSegmentIntersection.Types: associatedSegs :: forall p_a3wne r_a3wnf p_a3wzu. Lens (IntersectionPoint p_a3wne r_a3wnf) (IntersectionPoint p_a3wzu r_a3wnf) (Associated p_a3wne r_a3wnf) (Associated p_a3wzu r_a3wnf)
+ Algorithms.Geometry.LineSegmentIntersection.Types: associatedSegs :: forall p_a2uCP r_a2uCQ p_a2uRN. Lens (IntersectionPoint p_a2uCP r_a2uCQ) (IntersectionPoint p_a2uRN r_a2uCQ) (Associated p_a2uCP r_a2uCQ) (Associated p_a2uRN r_a2uCQ)
- Algorithms.Geometry.LineSegmentIntersection.Types: intersectionPoint :: forall p_a3wne r_a3wnf. Lens' (IntersectionPoint p_a3wne r_a3wnf) (Point 2 r_a3wnf)
+ Algorithms.Geometry.LineSegmentIntersection.Types: intersectionPoint :: forall p_a2uCP r_a2uCQ. Lens' (IntersectionPoint p_a2uCP r_a2uCQ) (Point 2 r_a2uCQ)
- Algorithms.Geometry.SmallestEnclosingBall.Types: definingPoints :: forall p_a3srd r_a3sre p_a3sEo. Lens (DiskResult p_a3srd r_a3sre) (DiskResult p_a3sEo r_a3sre) (TwoOrThree ((:+) (Point 2 r_a3sre) p_a3srd)) (TwoOrThree ((:+) (Point 2 r_a3sre) p_a3sEo))
+ Algorithms.Geometry.SmallestEnclosingBall.Types: definingPoints :: forall p_a3KgM r_a3KgN p_a3KtD. Lens (DiskResult p_a3KgM r_a3KgN) (DiskResult p_a3KtD r_a3KgN) (TwoOrThree ((:+) (Point 2 r_a3KgN) p_a3KgM)) (TwoOrThree ((:+) (Point 2 r_a3KgN) p_a3KtD))
- Algorithms.Geometry.SmallestEnclosingBall.Types: enclosingDisk :: forall p_a3srd r_a3sre. Lens' (DiskResult p_a3srd r_a3sre) (Disk () r_a3sre)
+ Algorithms.Geometry.SmallestEnclosingBall.Types: enclosingDisk :: forall p_a3KgM r_a3KgN. Lens' (DiskResult p_a3KgM r_a3KgN) (Disk () r_a3KgN)
- Algorithms.Geometry.WellSeparatedPairDecomposition.Types: bBox :: forall d_a3lc7 r_a3lc8 a_a3lc9 d_a3lfc r_a3lfd. Lens (NodeData d_a3lc7 r_a3lc8 a_a3lc9) (NodeData d_a3lfc r_a3lfd a_a3lc9) (Box d_a3lc7 () r_a3lc8) (Box d_a3lfc () r_a3lfd)
+ Algorithms.Geometry.WellSeparatedPairDecomposition.Types: bBox :: forall d_a2qoM r_a2qoN a_a2qoO d_a2qtB r_a2qtC. Lens (NodeData d_a2qoM r_a2qoN a_a2qoO) (NodeData d_a2qtB r_a2qtC a_a2qoO) (Box d_a2qoM () r_a2qoN) (Box d_a2qtB () r_a2qtC)
- Algorithms.Geometry.WellSeparatedPairDecomposition.Types: leftPart :: forall d_a3lqS r_a3lqT p_a3lqU. Lens' (FindAndCompact d_a3lqS r_a3lqT p_a3lqU) (Seq ((:+) (Point d_a3lqS r_a3lqT) p_a3lqU))
+ Algorithms.Geometry.WellSeparatedPairDecomposition.Types: leftPart :: forall d_a2qF6 r_a2qF7 p_a2qF8. Lens' (FindAndCompact d_a2qF6 r_a2qF7 p_a2qF8) (Seq ((:+) (Point d_a2qF6 r_a2qF7) p_a2qF8))
- Algorithms.Geometry.WellSeparatedPairDecomposition.Types: nodeData :: forall d_a3lc7 r_a3lc8 a_a3lc9 a_a3lfe. Lens (NodeData d_a3lc7 r_a3lc8 a_a3lc9) (NodeData d_a3lc7 r_a3lc8 a_a3lfe) a_a3lc9 a_a3lfe
+ Algorithms.Geometry.WellSeparatedPairDecomposition.Types: nodeData :: forall d_a2qoM r_a2qoN a_a2qoO a_a2qtD. Lens (NodeData d_a2qoM r_a2qoN a_a2qoO) (NodeData d_a2qoM r_a2qoN a_a2qtD) a_a2qoO a_a2qtD
- Algorithms.Geometry.WellSeparatedPairDecomposition.Types: rightPart :: forall d_a3lqS r_a3lqT p_a3lqU. Lens' (FindAndCompact d_a3lqS r_a3lqT p_a3lqU) (Seq ((:+) (Point d_a3lqS r_a3lqT) p_a3lqU))
+ Algorithms.Geometry.WellSeparatedPairDecomposition.Types: rightPart :: forall d_a2qF6 r_a2qF7 p_a2qF8. Lens' (FindAndCompact d_a2qF6 r_a2qF7 p_a2qF8) (Seq ((:+) (Point d_a2qF6 r_a2qF7) p_a2qF8))
- Algorithms.Geometry.WellSeparatedPairDecomposition.Types: shortSide :: forall d_a3lqS r_a3lqT p_a3lqU. Lens' (FindAndCompact d_a3lqS r_a3lqT p_a3lqU) ShortSide
+ Algorithms.Geometry.WellSeparatedPairDecomposition.Types: shortSide :: forall d_a2qF6 r_a2qF7 p_a2qF8. Lens' (FindAndCompact d_a2qF6 r_a2qF7 p_a2qF8) ShortSide
- Algorithms.Geometry.WellSeparatedPairDecomposition.Types: splitDim :: forall d_a3lc7 r_a3lc8 a_a3lc9. Lens' (NodeData d_a3lc7 r_a3lc8 a_a3lc9) Int
+ Algorithms.Geometry.WellSeparatedPairDecomposition.Types: splitDim :: forall d_a2qoM r_a2qoN a_a2qoO. Lens' (NodeData d_a2qoM r_a2qoN a_a2qoO) Int
- Algorithms.Geometry.WellSeparatedPairDecomposition.WSPD: areWellSeparated :: (AlwaysTrueWSPD d, Fractional r, Ord r) => r -> SplitTree d p r a -> SplitTree d p r a -> Bool
+ Algorithms.Geometry.WellSeparatedPairDecomposition.WSPD: areWellSeparated :: (Arity d, Arity (d + 1), Fractional r, Ord r) => r -> SplitTree d p r a -> SplitTree d p r a -> Bool
- Algorithms.Geometry.WellSeparatedPairDecomposition.WSPD: boxBox :: (Fractional r, Ord r, AlwaysTruePFT d, AlwaysTrueTransformation d) => r -> Box d p r -> Box d p r -> Bool
+ Algorithms.Geometry.WellSeparatedPairDecomposition.WSPD: boxBox :: (Fractional r, Ord r, Arity d, Arity (d + 1)) => r -> Box d p r -> Box d p r -> Bool
- Algorithms.Geometry.WellSeparatedPairDecomposition.WSPD: fairSplitTree :: (Fractional r, Ord r, Arity d, Index' 0 d, KnownNat d, Show r, Show p) => NonEmpty (Point d r :+ p) -> SplitTree d p r ()
+ Algorithms.Geometry.WellSeparatedPairDecomposition.WSPD: fairSplitTree :: (Fractional r, Ord r, Arity d, 1 <= d, Show r, Show p) => NonEmpty (Point d r :+ p) -> SplitTree d p r ()
- Algorithms.Geometry.WellSeparatedPairDecomposition.WSPD: fairSplitTree' :: (Fractional r, Ord r, Arity d, Index' 0 d, KnownNat d, Show r, Show p) => Int -> Vector d (PointSeq d (Idx :+ p) r) -> BinLeafTree Int (Point d r :+ p)
+ Algorithms.Geometry.WellSeparatedPairDecomposition.WSPD: fairSplitTree' :: (Fractional r, Ord r, Arity d, 1 <= d, Show r, Show p) => Int -> Vector d (PointSeq d (Idx :+ p) r) -> BinLeafTree Int (Point d r :+ p)
- Algorithms.Geometry.WellSeparatedPairDecomposition.WSPD: findPairs :: (Floating r, Ord r, AlwaysTrueWSPD d) => r -> SplitTree d p r a -> SplitTree d p r a -> [WSP d p r a]
+ Algorithms.Geometry.WellSeparatedPairDecomposition.WSPD: findPairs :: (Floating r, Ord r, Arity d, Arity (d + 1)) => r -> SplitTree d p r a -> SplitTree d p r a -> [WSP d p r a]
- Algorithms.Geometry.WellSeparatedPairDecomposition.WSPD: reIndexPoints :: (Arity d, Index' 0 d) => Vector d (PointSeq d (Idx :+ p) r) -> Vector d (PointSeq d (Idx :+ p) r)
+ Algorithms.Geometry.WellSeparatedPairDecomposition.WSPD: reIndexPoints :: (Arity d, 1 <= d) => Vector d (PointSeq d (Idx :+ p) r) -> Vector d (PointSeq d (Idx :+ p) r)
- Algorithms.Geometry.WellSeparatedPairDecomposition.WSPD: wellSeparatedPairs :: (Floating r, Ord r, AlwaysTrueWSPD d) => r -> SplitTree d p r a -> [WSP d p r a]
+ Algorithms.Geometry.WellSeparatedPairDecomposition.WSPD: wellSeparatedPairs :: (Floating r, Ord r, Arity d, Arity (d + 1)) => r -> SplitTree d p r a -> [WSP d p r a]
- Data.BalBST: Nav :: (a -> k -> Bool) -> (a -> a -> k) -> TreeNavigator k a
+ Data.BalBST: Nav :: a -> k -> Bool -> a -> a -> k -> TreeNavigator k a
- Data.Geometry.Ball: center :: forall d_a1MIE p_a1MIF r_a1MIG d_a1MKU p_a1MKV. Lens (Ball d_a1MIE p_a1MIF r_a1MIG) (Ball d_a1MKU p_a1MKV r_a1MIG) ((:+) (Point d_a1MIE r_a1MIG) p_a1MIF) ((:+) (Point d_a1MKU r_a1MIG) p_a1MKV)
+ Data.Geometry.Ball: center :: forall d_a2FhO p_a2FhP r_a2FhQ d_a2Fkv p_a2Fkw. Lens (Ball d_a2FhO p_a2FhP r_a2FhQ) (Ball d_a2Fkv p_a2Fkw r_a2FhQ) ((:+) (Point d_a2FhO r_a2FhQ) p_a2FhP) ((:+) (Point d_a2Fkv r_a2FhQ) p_a2Fkw)
- Data.Geometry.Ball: squaredRadius :: forall d_a1MIE p_a1MIF r_a1MIG. Lens' (Ball d_a1MIE p_a1MIF r_a1MIG) r_a1MIG
+ Data.Geometry.Ball: squaredRadius :: forall d_a2FhO p_a2FhP r_a2FhQ. Lens' (Ball d_a2FhO p_a2FhP r_a2FhQ) r_a2FhQ
- Data.Geometry.Box.Internal: cwMax :: forall a_a1Df5 a_a1Dtb. Iso (CWMax a_a1Df5) (CWMax a_a1Dtb) a_a1Df5 a_a1Dtb
+ Data.Geometry.Box.Internal: cwMax :: forall a_a1ZyX a_a1ZNQ. Iso (CWMax a_a1ZyX) (CWMax a_a1ZNQ) a_a1ZyX a_a1ZNQ
- Data.Geometry.Box.Internal: cwMin :: forall a_a1D2y a_a1DeZ. Iso (CWMin a_a1D2y) (CWMin a_a1DeZ) a_a1D2y a_a1DeZ
+ Data.Geometry.Box.Internal: cwMin :: forall a_a1Zml a_a1ZyR. Iso (CWMin a_a1Zml) (CWMin a_a1ZyR) a_a1Zml a_a1ZyR
- Data.Geometry.Box.Internal: maxP :: forall d_a1Dti p_a1Dtj r_a1Dtk. Lens' (Box d_a1Dti p_a1Dtj r_a1Dtk) ((:+) (CWMax (Point d_a1Dti r_a1Dtk)) p_a1Dtj)
+ Data.Geometry.Box.Internal: maxP :: forall d_a1ZNX p_a1ZNY r_a1ZNZ. Lens' (Box d_a1ZNX p_a1ZNY r_a1ZNZ) ((:+) (CWMax (Point d_a1ZNX r_a1ZNZ)) p_a1ZNY)
- Data.Geometry.Box.Internal: minP :: forall d_a1Dti p_a1Dtj r_a1Dtk. Lens' (Box d_a1Dti p_a1Dtj r_a1Dtk) ((:+) (CWMin (Point d_a1Dti r_a1Dtk)) p_a1Dtj)
+ Data.Geometry.Box.Internal: minP :: forall d_a1ZNX p_a1ZNY r_a1ZNZ. Lens' (Box d_a1ZNX p_a1ZNY r_a1ZNZ) ((:+) (CWMin (Point d_a1ZNX r_a1ZNZ)) p_a1ZNY)
- Data.Geometry.Box.Internal: widthIn :: forall proxy p i d r. (Arity d, Num r, Index' (i - 1) d) => proxy i -> Box d p r -> r
+ Data.Geometry.Box.Internal: widthIn :: forall proxy p i d r. (Arity d, Arity (i - 1), Num r, ((i - 1) + 1) <= d) => proxy i -> Box d p r -> r
- Data.Geometry.HalfLine: halfLineDirection :: forall d_a1QUk r_a1QUl. Lens' (HalfLine d_a1QUk r_a1QUl) (Vector d_a1QUk r_a1QUl)
+ Data.Geometry.HalfLine: halfLineDirection :: forall d_a2JLv r_a2JLw. Lens' (HalfLine d_a2JLv r_a2JLw) (Vector d_a2JLv r_a2JLw)
- Data.Geometry.HalfLine: startPoint :: forall d_a1QUk r_a1QUl. Lens' (HalfLine d_a1QUk r_a1QUl) (Point d_a1QUk r_a1QUl)
+ Data.Geometry.HalfLine: startPoint :: forall d_a2JLv r_a2JLw. Lens' (HalfLine d_a2JLv r_a2JLw) (Point d_a2JLv r_a2JLw)
- Data.Geometry.Interval: class HasEnd t where type EndCore t type EndExtra t where {
+ Data.Geometry.Interval: class HasEnd t where {
- Data.Geometry.Interval: class HasStart t where type StartCore t type StartExtra t where {
+ Data.Geometry.Interval: class HasStart t where {
- Data.Geometry.Interval.Util: unL :: forall r_a17Yt r_a182N. Iso (L r_a17Yt) (L r_a182N) (EndPoint r_a17Yt) (EndPoint r_a182N)
+ Data.Geometry.Interval.Util: unL :: forall r_a1Nbb r_a1NfR. Iso (L r_a1Nbb) (L r_a1NfR) (EndPoint r_a1Nbb) (EndPoint r_a1NfR)
- Data.Geometry.Interval.Util: unR :: forall r_a182T r_a18dr. Iso (R r_a182T) (R r_a18dr) (EndPoint r_a182T) (EndPoint r_a18dr)
+ Data.Geometry.Interval.Util: unR :: forall r_a1NfX r_a1Nqi. Iso (R r_a1NfX) (R r_a1Nqi) (EndPoint r_a1NfX) (EndPoint r_a1Nqi)
- Data.Geometry.IntervalTree: intervalsLeft :: forall i_a2QgX r_a2QgY. Lens' (NodeData i_a2QgX r_a2QgY) (Map (L r_a2QgY) [i_a2QgX])
+ Data.Geometry.IntervalTree: intervalsLeft :: forall i_a1PKp r_a1PKq. Lens' (NodeData i_a1PKp r_a1PKq) (Map (L r_a1PKq) [i_a1PKp])
- Data.Geometry.IntervalTree: intervalsRight :: forall i_a2QgX r_a2QgY. Lens' (NodeData i_a2QgX r_a2QgY) (Map (R r_a2QgY) [i_a2QgX])
+ Data.Geometry.IntervalTree: intervalsRight :: forall i_a1PKp r_a1PKq. Lens' (NodeData i_a1PKp r_a1PKq) (Map (R r_a1PKq) [i_a1PKp])
- Data.Geometry.IntervalTree: splitPoint :: forall i_a2QgX r_a2QgY. Lens' (NodeData i_a2QgX r_a2QgY) r_a2QgY
+ Data.Geometry.IntervalTree: splitPoint :: forall i_a1PKp r_a1PKq. Lens' (NodeData i_a1PKp r_a1PKq) r_a1PKq
- Data.Geometry.IntervalTree: unIntervalTree :: forall i_a2QpZ r_a2Qq0 i_a2Qwc r_a2Qwd. Iso (IntervalTree i_a2QpZ r_a2Qq0) (IntervalTree i_a2Qwc r_a2Qwd) (BinaryTree (NodeData i_a2QpZ r_a2Qq0)) (BinaryTree (NodeData i_a2Qwc r_a2Qwd))
+ Data.Geometry.IntervalTree: unIntervalTree :: forall i_a1PUa r_a1PUb i_a1Q1a r_a1Q1b. Iso (IntervalTree i_a1PUa r_a1PUb) (IntervalTree i_a1Q1a r_a1Q1b) (BinaryTree (NodeData i_a1PUa r_a1PUb)) (BinaryTree (NodeData i_a1Q1a r_a1Q1b))
- Data.Geometry.Ipe.Attributes: IpeColor :: (IpeValue Colour) -> IpeColor
+ Data.Geometry.Ipe.Attributes: IpeColor :: (IpeValue (RGB r)) -> IpeColor r
- Data.Geometry.Ipe.Attributes: arrowName :: forall r_aZgC. Lens' (IpeArrow r_aZgC) Text
+ Data.Geometry.Ipe.Attributes: arrowName :: forall r_aKOp. Lens' (IpeArrow r_aKOp) Text
- Data.Geometry.Ipe.Attributes: arrowSize :: forall r_aZgC r_a10iH. Lens (IpeArrow r_aZgC) (IpeArrow r_a10iH) (IpeSize r_aZgC) (IpeSize r_a10iH)
+ Data.Geometry.Ipe.Attributes: arrowSize :: forall r_aKOp r_aLZH. Lens (IpeArrow r_aKOp) (IpeArrow r_aLZH) (IpeSize r_aKOp) (IpeSize r_aLZH)
- Data.Geometry.Ipe.Attributes: getAttr :: forall f_aYNo label_aYNp f_aZat label_aZau. Iso (Attr f_aYNo label_aYNp) (Attr f_aZat label_aZau) (Maybe (Apply f_aYNo label_aYNp :: Type)) (Maybe (Apply f_aZat label_aZau :: Type))
+ Data.Geometry.Ipe.Attributes: getAttr :: forall f_aK5S label_aK5T f_aKFi label_aKFj. Iso (Attr f_aK5S label_aK5T) (Attr f_aKFi label_aKFj) (Maybe (Apply f_aK5S label_aK5T)) (Maybe (Apply f_aKFi label_aKFj))
- Data.Geometry.Ipe.Attributes: newtype IpeColor
+ Data.Geometry.Ipe.Attributes: newtype IpeColor r
- Data.Geometry.Ipe.Attributes: type CommonAttributes = '[Layer, Matrix, Pin, Transformations]
+ Data.Geometry.Ipe.Attributes: type CommonAttributes = [Layer, Matrix, Pin, Transformations]
- Data.Geometry.Ipe.Attributes: type GroupAttributes = CommonAttributes ++ '[Clip]
+ Data.Geometry.Ipe.Attributes: type GroupAttributes = CommonAttributes ++ '[ 'Clip]
- Data.Geometry.Ipe.Attributes: type PathAttributes = CommonAttributes ++ '[Stroke, Fill, Dash, Pen, LineCap, LineJoin, FillRule, Arrow, RArrow, Opacity, Tiling, Gradient]
+ Data.Geometry.Ipe.Attributes: type PathAttributes = CommonAttributes ++ [Stroke, Fill, Dash, Pen, LineCap, LineJoin, FillRule, Arrow, RArrow, Opacity, Tiling, Gradient]
- Data.Geometry.Ipe.Attributes: type SymbolAttributes = CommonAttributes ++ '[Stroke, Fill, Pen, Size]
+ Data.Geometry.Ipe.Attributes: type SymbolAttributes = CommonAttributes ++ [Stroke, Fill, Pen, Size]
- Data.Geometry.Ipe.Attributes: unAttrs :: forall f_aZaD ats_aZaE f_aZfu ats_aZfv. Iso (Attributes f_aZaD ats_aZaE) (Attributes f_aZfu ats_aZfv) (Rec (Attr f_aZaD :: u_aZaC -> Type) ats_aZaE) (Rec (Attr f_aZfu :: u_aZaC -> Type) ats_aZfv)
+ Data.Geometry.Ipe.Attributes: unAttrs :: forall f_aKFs ats_aKFt f_aKNJ ats_aKNK. Iso (Attributes f_aKFs ats_aKFt) (Attributes f_aKNJ ats_aKNK) (Rec (Attr f_aKFs) ats_aKFt) (Rec (Attr f_aKNJ) ats_aKNK)
- Data.Geometry.Ipe.FromIpe: _asSimplePolygon :: Prism' (Path r) (SimplePolygon () r)
+ Data.Geometry.Ipe.FromIpe: _asSimplePolygon :: Prism' (Path r) (Polygon Simple () r)
- Data.Geometry.Ipe.IpeOut: IpeOut :: (g -> i) -> IpeOut g i
+ Data.Geometry.Ipe.IpeOut: IpeOut :: g -> i -> IpeOut g i
- Data.Geometry.Ipe.IpeOut: class ToObject (DefaultIpeOut g) => HasDefaultIpeOut g where type DefaultIpeOut g :: * -> * where {
+ Data.Geometry.Ipe.IpeOut: class ToObject (DefaultIpeOut g) => HasDefaultIpeOut g where {
- Data.Geometry.Ipe.PathParser: class Num r => Coordinate r
+ Data.Geometry.Ipe.PathParser: class Fractional r => Coordinate r
- Data.Geometry.Ipe.PathParser: defaultFromSeq :: (Ord r, Fractional r) => Integer -> Maybe Integer -> r
+ Data.Geometry.Ipe.PathParser: defaultFromSeq :: (Ord r, Fractional r) => Integer -> Maybe (Int, Integer) -> r
- Data.Geometry.Ipe.PathParser: fromSeq :: Coordinate r => Integer -> Maybe Integer -> r
+ Data.Geometry.Ipe.PathParser: fromSeq :: (Coordinate r, Ord r, Fractional r) => Integer -> Maybe (Int, Integer) -> r
- Data.Geometry.Ipe.Reader: readIpeFile :: Coordinate r => FilePath -> IO (Either ConversionError (IpeFile r))
+ Data.Geometry.Ipe.Reader: readIpeFile :: (Coordinate r, Eq r) => FilePath -> IO (Either ConversionError (IpeFile r))
- Data.Geometry.Ipe.Reader: readRawIpeFile :: Coordinate r => FilePath -> IO (Either ConversionError (IpeFile r))
+ Data.Geometry.Ipe.Reader: readRawIpeFile :: (Coordinate r, Eq r) => FilePath -> IO (Either ConversionError (IpeFile r))
- Data.Geometry.Ipe.Reader: readSinglePageFile :: Coordinate r => FilePath -> IO (Either ConversionError (IpePage r))
+ Data.Geometry.Ipe.Reader: readSinglePageFile :: (Coordinate r, Eq r) => FilePath -> IO (Either ConversionError (IpePage r))
- Data.Geometry.Ipe.Types: _ArcSegment :: forall r_a21sF. Prism' (PathSegment r_a21sF) ()
+ Data.Geometry.Ipe.Types: _ArcSegment :: forall r_a3exU. Prism' (PathSegment r_a3exU) ()
- Data.Geometry.Ipe.Types: _ArcTo :: forall r_a21Kv. Prism' (Operation r_a21Kv) (Matrix 3 3 r_a21Kv, Point 2 r_a21Kv)
+ Data.Geometry.Ipe.Types: _ArcTo :: forall r_a3eQ4. Prism' (Operation r_a3eQ4) (Matrix 3 3 r_a3eQ4, Point 2 r_a3eQ4)
- Data.Geometry.Ipe.Types: _ClosePath :: forall r_a21Kv. Prism' (Operation r_a21Kv) ()
+ Data.Geometry.Ipe.Types: _ClosePath :: forall r_a3eQ4. Prism' (Operation r_a3eQ4) ()
- Data.Geometry.Ipe.Types: _ClosedSpline :: forall r_a21Kv. Prism' (Operation r_a21Kv) [Point 2 r_a21Kv]
+ Data.Geometry.Ipe.Types: _ClosedSpline :: forall r_a3eQ4. Prism' (Operation r_a3eQ4) [Point 2 r_a3eQ4]
- Data.Geometry.Ipe.Types: _ClosedSplineSegment :: forall r_a21sF. Prism' (PathSegment r_a21sF) ()
+ Data.Geometry.Ipe.Types: _ClosedSplineSegment :: forall r_a3exU. Prism' (PathSegment r_a3exU) ()
- Data.Geometry.Ipe.Types: _CubicBezierSegment :: forall r_a21sF. Prism' (PathSegment r_a21sF) ()
+ Data.Geometry.Ipe.Types: _CubicBezierSegment :: forall r_a3exU. Prism' (PathSegment r_a3exU) ()
- Data.Geometry.Ipe.Types: _CurveTo :: forall r_a21Kv. Prism' (Operation r_a21Kv) (Point 2 r_a21Kv, Point 2 r_a21Kv, Point 2 r_a21Kv)
+ Data.Geometry.Ipe.Types: _CurveTo :: forall r_a3eQ4. Prism' (Operation r_a3eQ4) (Point 2 r_a3eQ4, Point 2 r_a3eQ4, Point 2 r_a3eQ4)
- Data.Geometry.Ipe.Types: _Ellipse :: forall r_a21Kv. Prism' (Operation r_a21Kv) (Matrix 3 3 r_a21Kv)
+ Data.Geometry.Ipe.Types: _Ellipse :: forall r_a3eQ4. Prism' (Operation r_a3eQ4) (Matrix 3 3 r_a3eQ4)
- Data.Geometry.Ipe.Types: _EllipseSegment :: forall r_a21sF. Prism' (PathSegment r_a21sF) (Matrix 3 3 r_a21sF)
+ Data.Geometry.Ipe.Types: _EllipseSegment :: forall r_a3exU. Prism' (PathSegment r_a3exU) (Matrix 3 3 r_a3exU)
- Data.Geometry.Ipe.Types: _IpeGroup :: forall r_a221g. Prism' (IpeObject r_a221g) (IpeObject' Group r_a221g)
+ Data.Geometry.Ipe.Types: _IpeGroup :: forall r_a3faD. Prism' (IpeObject r_a3faD) (IpeObject' Group r_a3faD)
- Data.Geometry.Ipe.Types: _IpeImage :: forall r_a221g. Prism' (IpeObject r_a221g) (IpeObject' Image r_a221g)
+ Data.Geometry.Ipe.Types: _IpeImage :: forall r_a3faD. Prism' (IpeObject r_a3faD) (IpeObject' Image r_a3faD)
- Data.Geometry.Ipe.Types: _IpeMiniPage :: forall r_a221g. Prism' (IpeObject r_a221g) (IpeObject' MiniPage r_a221g)
+ Data.Geometry.Ipe.Types: _IpeMiniPage :: forall r_a3faD. Prism' (IpeObject r_a3faD) (IpeObject' MiniPage r_a3faD)
- Data.Geometry.Ipe.Types: _IpePath :: forall r_a221g. Prism' (IpeObject r_a221g) (IpeObject' Path r_a221g)
+ Data.Geometry.Ipe.Types: _IpePath :: forall r_a3faD. Prism' (IpeObject r_a3faD) (IpeObject' Path r_a3faD)
- Data.Geometry.Ipe.Types: _IpeTextLabel :: forall r_a221g. Prism' (IpeObject r_a221g) (IpeObject' TextLabel r_a221g)
+ Data.Geometry.Ipe.Types: _IpeTextLabel :: forall r_a3faD. Prism' (IpeObject r_a3faD) (IpeObject' TextLabel r_a3faD)
- Data.Geometry.Ipe.Types: _IpeUse :: forall r_a221g. Prism' (IpeObject r_a221g) (IpeObject' IpeSymbol r_a221g)
+ Data.Geometry.Ipe.Types: _IpeUse :: forall r_a3faD. Prism' (IpeObject r_a3faD) (IpeObject' IpeSymbol r_a3faD)
- Data.Geometry.Ipe.Types: _LineTo :: forall r_a21Kv. Prism' (Operation r_a21Kv) (Point 2 r_a21Kv)
+ Data.Geometry.Ipe.Types: _LineTo :: forall r_a3eQ4. Prism' (Operation r_a3eQ4) (Point 2 r_a3eQ4)
- Data.Geometry.Ipe.Types: _MoveTo :: forall r_a21Kv. Prism' (Operation r_a21Kv) (Point 2 r_a21Kv)
+ Data.Geometry.Ipe.Types: _MoveTo :: forall r_a3eQ4. Prism' (Operation r_a3eQ4) (Point 2 r_a3eQ4)
- Data.Geometry.Ipe.Types: _PolyLineSegment :: forall r_a21sF. Prism' (PathSegment r_a21sF) (PolyLine 2 () r_a21sF)
+ Data.Geometry.Ipe.Types: _PolyLineSegment :: forall r_a3exU. Prism' (PathSegment r_a3exU) (PolyLine 2 () r_a3exU)
- Data.Geometry.Ipe.Types: _PolygonPath :: forall r_a21sF. Prism' (PathSegment r_a21sF) (SimplePolygon () r_a21sF)
+ Data.Geometry.Ipe.Types: _PolygonPath :: forall r_a3exU. Prism' (PathSegment r_a3exU) (SimplePolygon () r_a3exU)
- Data.Geometry.Ipe.Types: _QCurveTo :: forall r_a21Kv. Prism' (Operation r_a21Kv) (Point 2 r_a21Kv, Point 2 r_a21Kv)
+ Data.Geometry.Ipe.Types: _QCurveTo :: forall r_a3eQ4. Prism' (Operation r_a3eQ4) (Point 2 r_a3eQ4, Point 2 r_a3eQ4)
- Data.Geometry.Ipe.Types: _QuadraticBezierSegment :: forall r_a21sF. Prism' (PathSegment r_a21sF) ()
+ Data.Geometry.Ipe.Types: _QuadraticBezierSegment :: forall r_a3exU. Prism' (PathSegment r_a3exU) ()
- Data.Geometry.Ipe.Types: _Spline :: forall r_a21Kv. Prism' (Operation r_a21Kv) [Point 2 r_a21Kv]
+ Data.Geometry.Ipe.Types: _Spline :: forall r_a3eQ4. Prism' (Operation r_a3eQ4) [Point 2 r_a3eQ4]
- Data.Geometry.Ipe.Types: _SplineSegment :: forall r_a21sF. Prism' (PathSegment r_a21sF) ()
+ Data.Geometry.Ipe.Types: _SplineSegment :: forall r_a3exU. Prism' (PathSegment r_a3exU) ()
- Data.Geometry.Ipe.Types: applyMatrices :: Num r => IpeFile r -> IpeFile r
+ Data.Geometry.Ipe.Types: applyMatrices :: Fractional r => IpeFile r -> IpeFile r
- Data.Geometry.Ipe.Types: applyMatricesPage :: Num r => IpePage r -> IpePage r
+ Data.Geometry.Ipe.Types: applyMatricesPage :: Fractional r => IpePage r -> IpePage r
- Data.Geometry.Ipe.Types: applyMatrix :: Num r => IpeObject r -> IpeObject r
+ Data.Geometry.Ipe.Types: applyMatrix :: Fractional r => IpeObject r -> IpeObject r
- Data.Geometry.Ipe.Types: content :: forall r_a22Gd r_a22Js. Lens (IpePage r_a22Gd) (IpePage r_a22Js) [IpeObject r_a22Gd] [IpeObject r_a22Js]
+ Data.Geometry.Ipe.Types: content :: forall r_a3fWP r_a3g0x. Lens (IpePage r_a3fWP) (IpePage r_a3g0x) [IpeObject r_a3fWP] [IpeObject r_a3g0x]
- Data.Geometry.Ipe.Types: data AttrMapSym0 (l_a220R :: TyFun Type (TyFun AttributeUniverse Type -> Type))
+ Data.Geometry.Ipe.Types: data AttrMapSym0 (l_a3fah :: TyFun Type (TyFun AttributeUniverse Type -> Type))
- Data.Geometry.Ipe.Types: data AttrMapSym1 (l_a220U :: Type) (l_a220T :: TyFun AttributeUniverse Type)
+ Data.Geometry.Ipe.Types: data AttrMapSym1 (l_a3faf :: Type) (l_a3fae :: TyFun AttributeUniverse Type)
- Data.Geometry.Ipe.Types: groupItems :: forall r_a221o r_a22fP. Iso (Group r_a221o) (Group r_a22fP) [IpeObject r_a221o] [IpeObject r_a22fP]
+ Data.Geometry.Ipe.Types: groupItems :: forall r_a3faL r_a3frx. Iso (Group r_a3faL) (Group r_a3frx) [IpeObject r_a3faL] [IpeObject r_a3frx]
- Data.Geometry.Ipe.Types: imageData :: forall r_a20YX. Lens' (Image r_a20YX) ()
+ Data.Geometry.Ipe.Types: imageData :: forall r_a3e0l. Lens' (Image r_a3e0l) ()
- Data.Geometry.Ipe.Types: layers :: forall r_a22Gd. Lens' (IpePage r_a22Gd) [LayerName]
+ Data.Geometry.Ipe.Types: layers :: forall r_a3fWP. Lens' (IpePage r_a3fWP) [LayerName]
- Data.Geometry.Ipe.Types: pages :: forall r_a22JR r_a22Ol. Lens (IpeFile r_a22JR) (IpeFile r_a22Ol) (NonEmpty (IpePage r_a22JR)) (NonEmpty (IpePage r_a22Ol))
+ Data.Geometry.Ipe.Types: pages :: forall r_a3g0W r_a3g5Q. Lens (IpeFile r_a3g0W) (IpeFile r_a3g5Q) (NonEmpty (IpePage r_a3g0W)) (NonEmpty (IpePage r_a3g5Q))
- Data.Geometry.Ipe.Types: pathSegments :: forall r_a21yJ r_a21Ki. Iso (Path r_a21yJ) (Path r_a21Ki) (ViewL1 (PathSegment r_a21yJ)) (ViewL1 (PathSegment r_a21Ki))
+ Data.Geometry.Ipe.Types: pathSegments :: forall r_a3eGq r_a3ePR. Iso (Path r_a3eGq) (Path r_a3ePR) (ViewL1 (PathSegment r_a3eGq)) (ViewL1 (PathSegment r_a3ePR))
- Data.Geometry.Ipe.Types: preamble :: forall r_a22JR. Lens' (IpeFile r_a22JR) (Maybe IpePreamble)
+ Data.Geometry.Ipe.Types: preamble :: forall r_a3g0W. Lens' (IpeFile r_a3g0W) (Maybe IpePreamble)
- Data.Geometry.Ipe.Types: rect :: forall r_a20YX r_a21aK. Lens (Image r_a20YX) (Image r_a21aK) (Rectangle () r_a20YX) (Rectangle () r_a21aK)
+ Data.Geometry.Ipe.Types: rect :: forall r_a3e0l r_a3ecQ. Lens (Image r_a3e0l) (Image r_a3ecQ) (Rectangle () r_a3e0l) (Rectangle () r_a3ecQ)
- Data.Geometry.Ipe.Types: styles :: forall r_a22JR. Lens' (IpeFile r_a22JR) [IpeStyle]
+ Data.Geometry.Ipe.Types: styles :: forall r_a3g0W. Lens' (IpeFile r_a3g0W) [IpeStyle]
- Data.Geometry.Ipe.Types: symbolName :: forall r_a21b4. Lens' (IpeSymbol r_a21b4) Text
+ Data.Geometry.Ipe.Types: symbolName :: forall r_a3eda. Lens' (IpeSymbol r_a3eda) Text
- Data.Geometry.Ipe.Types: symbolPoint :: forall r_a21b4 r_a21sl. Lens (IpeSymbol r_a21b4) (IpeSymbol r_a21sl) (Point 2 r_a21b4) (Point 2 r_a21sl)
+ Data.Geometry.Ipe.Types: symbolPoint :: forall r_a3eda r_a3exA. Lens (IpeSymbol r_a3eda) (IpeSymbol r_a3exA) (Point 2 r_a3eda) (Point 2 r_a3exA)
- Data.Geometry.Ipe.Types: type AttrMapSym2 (t_a220P :: Type) (t_a220Q :: AttributeUniverse) = AttrMap t_a220P t_a220Q
+ Data.Geometry.Ipe.Types: type AttrMapSym2 (t_a3fac :: Type) (t_a3fad :: AttributeUniverse) = AttrMap t_a3fac t_a3fad
- Data.Geometry.Ipe.Types: views :: forall r_a22Gd. Lens' (IpePage r_a22Gd) [View]
+ Data.Geometry.Ipe.Types: views :: forall r_a3fWP. Lens' (IpePage r_a3fWP) [View]
- Data.Geometry.KDTree: asSingleton :: (Index' 0 d, Arity d) => PointSet (LSeq 1) d p r -> Either (Point d r :+ p) (PointSet (LSeq 2) d p r)
+ Data.Geometry.KDTree: asSingleton :: (1 <= d, Arity d) => PointSet (LSeq 1) d p r -> Either (Point d r :+ p) (PointSet (LSeq 2) d p r)
- Data.Geometry.KDTree: build :: (Index' 0 d, Arity d, KnownNat d, Ord r) => Coord d -> PointSet (LSeq 1) d p r -> BinLeafTree (Split' d r) (Point d r :+ p)
+ Data.Geometry.KDTree: build :: (1 <= d, Arity d, Ord r) => Coord d -> PointSet (LSeq 1) d p r -> BinLeafTree (Split' d r) (Point d r :+ p)
- Data.Geometry.KDTree: buildKDTree :: (Arity d, KnownNat d, Index' 0 d, Ord r) => [Point d r :+ p] -> KDTree d p r
+ Data.Geometry.KDTree: buildKDTree :: (Arity d, 1 <= d, Ord r) => [Point d r :+ p] -> KDTree d p r
- Data.Geometry.KDTree: buildKDTree' :: (Arity d, KnownNat d, Index' 0 d, Ord r) => NonEmpty (Point d r :+ p) -> KDTree' d p r
+ Data.Geometry.KDTree: buildKDTree' :: (Arity d, 1 <= d, Ord r) => NonEmpty (Point d r :+ p) -> KDTree' d p r
- Data.Geometry.Line.Internal: anchorPoint :: forall d_a1tq4 r_a1tq5. Lens' (Line d_a1tq4 r_a1tq5) (Point d_a1tq4 r_a1tq5)
+ Data.Geometry.Line.Internal: anchorPoint :: forall d_a1oSx r_a1oSy. Lens' (Line d_a1oSx r_a1oSy) (Point d_a1oSx r_a1oSy)
- Data.Geometry.Line.Internal: direction :: forall d_a1tq4 r_a1tq5. Lens' (Line d_a1tq4 r_a1tq5) (Vector d_a1tq4 r_a1tq5)
+ Data.Geometry.Line.Internal: direction :: forall d_a1oSx r_a1oSy. Lens' (Line d_a1oSx r_a1oSy) (Vector d_a1oSx r_a1oSy)
- Data.Geometry.PlanarSubdivision: fromPolygon :: proxy s -> SimplePolygon p r -> f -> f -> PlanarSubdivision s p () f r
+ Data.Geometry.PlanarSubdivision: fromPolygon :: forall proxy t p f r s. (Ord r, Fractional r) => proxy s -> Polygon t p r -> f -> f -> PlanarSubdivision s p () f r
- Data.Geometry.Point: coord :: forall proxy i d r. (Index' (i - 1) d, Arity d) => proxy i -> Lens' (Point d r) r
+ 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: partitionIntoQuadrants :: (Ord r, 1 <=. d, 2 <=. 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])
+ Data.Geometry.Point: 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])
- Data.Geometry.Point: quadrant :: (Ord r, Num r, 1 <=. d, 2 <=. d) => Point d r :+ p -> Quadrant
+ Data.Geometry.Point: quadrant :: (Ord r, Num r, 1 <= d, 2 <= d, Arity d) => Point d r :+ p -> Quadrant
- Data.Geometry.Point: quadrantWith :: (Ord r, 1 <=. d, 2 <=. d) => Point d r :+ q -> Point d r :+ p -> Quadrant
+ Data.Geometry.Point: quadrantWith :: (Ord r, 1 <= d, 2 <= d, Arity d) => Point d r :+ q -> Point d r :+ p -> Quadrant
- Data.Geometry.Point: xCoord :: (1 <=. d) => Lens' (Point d r) r
+ Data.Geometry.Point: xCoord :: (1 <= d, Arity d) => Lens' (Point d r) r
- Data.Geometry.Point: yCoord :: (2 <=. d) => Lens' (Point d r) r
+ Data.Geometry.Point: yCoord :: (2 <= d, Arity d) => Lens' (Point d r) r
- Data.Geometry.Point: zCoord :: (3 <=. d) => Lens' (Point d r) r
+ Data.Geometry.Point: zCoord :: (3 <= d, Arity d) => Lens' (Point d r) r
- Data.Geometry.PolyLine: points :: forall d_a1WaB p_a1WaC r_a1WaD d_a1Wb9 p_a1Wba r_a1Wbb. Iso (PolyLine d_a1WaB p_a1WaC r_a1WaD) (PolyLine d_a1Wb9 p_a1Wba r_a1Wbb) (Seq2 ((:+) (Point d_a1WaB r_a1WaD) p_a1WaC)) (Seq2 ((:+) (Point d_a1Wb9 r_a1Wbb) p_a1Wba))
+ Data.Geometry.PolyLine: points :: forall d_a2oFY p_a2oFZ r_a2oG0 d_a2oGG p_a2oGH r_a2oGI. Iso (PolyLine d_a2oFY p_a2oFZ r_a2oG0) (PolyLine d_a2oGG p_a2oGH r_a2oGI) (Seq2 ((:+) (Point d_a2oFY r_a2oG0) p_a2oFZ)) (Seq2 ((:+) (Point d_a2oGG r_a2oGI) p_a2oGH))
- Data.Geometry.Polygon.Convex: simplePolygon :: forall p_a2vyu r_a2vyv p_a2vE1 r_a2vE2. Iso (ConvexPolygon p_a2vyu r_a2vyv) (ConvexPolygon p_a2vE1 r_a2vE2) (SimplePolygon p_a2vyu r_a2vyv) (SimplePolygon p_a2vE1 r_a2vE2)
+ Data.Geometry.Polygon.Convex: simplePolygon :: forall p_a2Zej r_a2Zek p_a2Zij r_a2Zik. Iso (ConvexPolygon p_a2Zej r_a2Zek) (ConvexPolygon p_a2Zij r_a2Zik) (SimplePolygon p_a2Zej r_a2Zek) (SimplePolygon p_a2Zij r_a2Zik)
- Data.Geometry.Properties: class IsIntersectableWith g h where g `intersects` h = nonEmptyIntersection (Identity g) (Identity h) $ g `intersect` h nonEmptyIntersection = defaultNonEmptyIntersection
+ Data.Geometry.Properties: class IsIntersectableWith g h
- Data.Geometry.SegmentTree.Generic: assoc :: forall v_a2WDR r_a2WDS v_a2WJE. Lens (NodeData v_a2WDR r_a2WDS) (NodeData v_a2WJE r_a2WDS) v_a2WDR v_a2WJE
+ Data.Geometry.SegmentTree.Generic: assoc :: forall v_a1Szp r_a1Szq v_a1SGo. Lens (NodeData v_a1Szp r_a1Szq) (NodeData v_a1SGo r_a1Szq) v_a1Szp v_a1SGo
- Data.Geometry.SegmentTree.Generic: atomicRange :: forall v_a2WK4 r_a2WK5 r_a2WV1. Lens (LeafData v_a2WK4 r_a2WK5) (LeafData v_a2WK4 r_a2WV1) (AtomicRange r_a2WK5) (AtomicRange r_a2WV1)
+ Data.Geometry.SegmentTree.Generic: atomicRange :: forall v_a1SGO r_a1SGP r_a1SUc. Lens (LeafData v_a1SGO r_a1SGP) (LeafData v_a1SGO r_a1SUc) (AtomicRange r_a1SGP) (AtomicRange r_a1SUc)
- Data.Geometry.SegmentTree.Generic: leafAssoc :: forall v_a2WK4 r_a2WK5 v_a2WV2. Lens (LeafData v_a2WK4 r_a2WK5) (LeafData v_a2WV2 r_a2WK5) v_a2WK4 v_a2WV2
+ Data.Geometry.SegmentTree.Generic: leafAssoc :: forall v_a1SGO r_a1SGP v_a1SUd. Lens (LeafData v_a1SGO r_a1SGP) (LeafData v_a1SUd r_a1SGP) v_a1SGO v_a1SUd
- Data.Geometry.SegmentTree.Generic: range :: forall v_a2WDR r_a2WDS. Lens' (NodeData v_a2WDR r_a2WDS) (Range r_a2WDS)
+ Data.Geometry.SegmentTree.Generic: range :: forall v_a1Szp r_a1Szq. Lens' (NodeData v_a1Szp r_a1Szq) (Range r_a1Szq)
- Data.Geometry.SegmentTree.Generic: splitPoint :: forall v_a2WDR r_a2WDS. Lens' (NodeData v_a2WDR r_a2WDS) (EndPoint r_a2WDS)
+ Data.Geometry.SegmentTree.Generic: splitPoint :: forall v_a1Szp r_a1Szq. Lens' (NodeData v_a1Szp r_a1Szq) (EndPoint r_a1Szq)
- Data.Geometry.SegmentTree.Generic: unSegmentTree :: forall v_a2WVg r_a2WVh v_a2X2c r_a2X2d. Iso (SegmentTree v_a2WVg r_a2WVh) (SegmentTree v_a2X2c r_a2X2d) (BinLeafTree (NodeData v_a2WVg r_a2WVh) (LeafData v_a2WVg r_a2WVh)) (BinLeafTree (NodeData v_a2X2c r_a2X2d) (LeafData v_a2X2c r_a2X2d))
+ Data.Geometry.SegmentTree.Generic: unSegmentTree :: forall v_a1SUr r_a1SUs v_a1T1w r_a1T1x. Iso (SegmentTree v_a1SUr r_a1SUs) (SegmentTree v_a1T1w r_a1T1x) (BinLeafTree (NodeData v_a1SUr r_a1SUs) (LeafData v_a1SUr r_a1SUs)) (BinLeafTree (NodeData v_a1T1w r_a1T1x) (LeafData v_a1T1w r_a1T1x))
- Data.Geometry.Slab: unSlab :: forall o_a1TcB a_a1TcC r_a1TcD o_a1Thw a_a1Thx r_a1Thy. Iso (Slab o_a1TcB a_a1TcC r_a1TcD) (Slab o_a1Thw a_a1Thx r_a1Thy) (Interval a_a1TcC r_a1TcD) (Interval a_a1Thx r_a1Thy)
+ Data.Geometry.Slab: unSlab :: forall o_a2Clh a_a2Cli r_a2Clj o_a2CqB a_a2CqC r_a2CqD. Iso (Slab o_a2Clh a_a2Cli r_a2Clj) (Slab o_a2CqB a_a2CqC r_a2CqD) (Interval a_a2Cli r_a2Clj) (Interval a_a2CqC r_a2CqD)
- Data.Geometry.SubLine: line :: forall d_a1xgl p_a1xgm r_a1xgn d_a1xgZ. Lens (SubLine d_a1xgl p_a1xgm r_a1xgn) (SubLine d_a1xgZ p_a1xgm r_a1xgn) (Line d_a1xgl r_a1xgn) (Line d_a1xgZ r_a1xgn)
+ Data.Geometry.SubLine: line :: forall d_a2gO9 p_a2gOa r_a2gOb d_a2gOW. Lens (SubLine d_a2gO9 p_a2gOa r_a2gOb) (SubLine d_a2gOW p_a2gOa r_a2gOb) (Line d_a2gO9 r_a2gOb) (Line d_a2gOW r_a2gOb)
- Data.Geometry.SubLine: subRange :: forall d_a1xgl p_a1xgm r_a1xgn p_a1xh0. Lens (SubLine d_a1xgl p_a1xgm r_a1xgn) (SubLine d_a1xgl p_a1xh0 r_a1xgn) (Interval p_a1xgm r_a1xgn) (Interval p_a1xh0 r_a1xgn)
+ Data.Geometry.SubLine: subRange :: forall d_a2gO9 p_a2gOa r_a2gOb p_a2gOX. Lens (SubLine d_a2gO9 p_a2gOa r_a2gOb) (SubLine d_a2gO9 p_a2gOX r_a2gOb) (Interval p_a2gOa r_a2gOb) (Interval p_a2gOX r_a2gOb)
- Data.Geometry.Transformation: (|.|) :: (Num r, Arity (1 + d)) => Transformation d r -> Transformation d r -> Transformation d r
+ Data.Geometry.Transformation: (|.|) :: (Num r, Arity (d + 1)) => Transformation d r -> Transformation d r -> Transformation d r
- Data.Geometry.Transformation: Transformation :: Matrix (1 + d) (1 + d) r -> Transformation d r
+ Data.Geometry.Transformation: Transformation :: Matrix (d + 1) (d + 1) r -> Transformation d r
- Data.Geometry.Transformation: [_transformationMatrix] :: Transformation d r -> Matrix (1 + d) (1 + d) r
+ Data.Geometry.Transformation: [_transformationMatrix] :: Transformation d r -> Matrix (d + 1) (d + 1) r
- Data.Geometry.Transformation: scaleBy :: (IsTransformable g, Num (NumType g), AlwaysTrueTransformation (Dimension g)) => Vector (Dimension g) (NumType g) -> g -> g
+ Data.Geometry.Transformation: scaleBy :: (IsTransformable g, Num (NumType g), Arity (Dimension g), Arity (Dimension g + 1)) => Vector (Dimension g) (NumType g) -> g -> g
- Data.Geometry.Transformation: scaleUniformlyBy :: (IsTransformable g, Num (NumType g), AlwaysTrueTransformation (Dimension g)) => NumType g -> g -> g
+ Data.Geometry.Transformation: scaleUniformlyBy :: (IsTransformable g, Num (NumType g), Arity (Dimension g), Arity (Dimension g + 1)) => NumType g -> g -> g
- Data.Geometry.Transformation: scaling :: (Num r, Arity (1 + d), AlwaysTrueSnoc d, Arity d) => Vector d r -> Transformation d r
+ Data.Geometry.Transformation: scaling :: (Num r, Arity d, Arity (d + 1)) => Vector d r -> Transformation d r
- Data.Geometry.Transformation: transRow :: forall n r. (Arity n, Index' (n - 1) n, Num r) => Int -> r -> Vector n r
+ Data.Geometry.Transformation: transRow :: forall n r. (Arity n, Arity (n + 1), Num r) => Int -> r -> Vector (n + 1) r
- Data.Geometry.Transformation: transformPointFunctor :: (PointFunctor g, Num r, d ~ Dimension (g r), AlwaysTruePFT d) => Transformation d r -> g r -> g r
+ Data.Geometry.Transformation: transformPointFunctor :: (PointFunctor g, Fractional r, d ~ Dimension (g r), Arity d, Arity (d + 1)) => Transformation d r -> g r -> g r
- Data.Geometry.Transformation: transformationMatrix :: Lens' (Transformation d r) (Matrix (1 + d) (1 + d) r)
+ Data.Geometry.Transformation: transformationMatrix :: Lens' (Transformation d r) (Matrix (d + 1) (d + 1) r)
- Data.Geometry.Transformation: translateBy :: (IsTransformable g, Num (NumType g), AlwaysTrueTransformation (Dimension g)) => Vector (Dimension g) (NumType g) -> g -> g
+ Data.Geometry.Transformation: translateBy :: (IsTransformable g, Num (NumType g), Arity (Dimension g), Arity (Dimension g + 1)) => Vector (Dimension g) (NumType g) -> g -> g
- Data.Geometry.Transformation: translation :: (Num r, Arity (1 + d), AlwaysTrueSnoc d, Arity d, Index' ((1 + d) - 1) (1 + d)) => Vector d r -> Transformation d r
+ Data.Geometry.Transformation: translation :: (Num r, Arity d, Arity (d + 1)) => Vector d r -> Transformation d r
- Data.Geometry.Transformation: uniformScaling :: (Num r, Arity (1 + d), AlwaysTrueSnoc d, Arity d) => r -> Transformation d r
+ Data.Geometry.Transformation: uniformScaling :: (Num r, Arity d, Arity (d + 1)) => r -> Transformation d r
- Data.Geometry.Triangle: Triangle :: (Point 2 r :+ p) -> (Point 2 r :+ p) -> (Point 2 r :+ p) -> Triangle p r
+ Data.Geometry.Triangle: Triangle :: (Point d r :+ p) -> (Point d r :+ p) -> (Point d r :+ p) -> Triangle d p r
- Data.Geometry.Triangle: area :: Fractional r => Triangle p r -> r
+ Data.Geometry.Triangle: area :: Fractional r => Triangle 2 p r -> r
- Data.Geometry.Triangle: data Triangle p r
+ Data.Geometry.Triangle: data Triangle d p r
- Data.Geometry.Triangle: doubleArea :: Num r => Triangle p r -> r
+ Data.Geometry.Triangle: doubleArea :: Num r => Triangle 2 p r -> r
- Data.Geometry.Triangle: inscribedDisk :: (Eq r, Fractional r) => Triangle p r -> Maybe (Disk () r)
+ Data.Geometry.Triangle: inscribedDisk :: (Eq r, Fractional r) => Triangle 2 p r -> Maybe (Disk () r)
- Data.Geometry.Vector: class Additive (Diff p) => Affine (p :: * -> *) where type Diff (p :: * -> *) :: * -> * where {
+ Data.Geometry.Vector: class Additive Diff p => Affine (p :: * -> *) where {
- Data.Geometry.Vector: distanceA :: (Floating a, Foldable (Diff p), Affine p) => p a -> p a -> a
+ Data.Geometry.Vector: distanceA :: (Floating a, Foldable Diff p, Affine p) => p a -> p a -> a
- Data.Geometry.Vector: dot :: Metric f => forall a. Num a => f a -> f a -> a
+ Data.Geometry.Vector: dot :: (Metric f, Num a) => f a -> f a -> a
- Data.Geometry.Vector: norm :: Metric f => forall a. Floating a => f a -> a
+ Data.Geometry.Vector: norm :: (Metric f, Floating a) => f a -> a
- Data.Geometry.Vector: qdA :: (Affine p, Foldable (Diff p), Num a) => p a -> p a -> a
+ Data.Geometry.Vector: qdA :: (Affine p, Foldable Diff p, Num a) => p a -> p a -> a
- Data.Geometry.Vector.VectorFixed: Vector :: Vec (ToPeano d) r -> Vector
+ Data.Geometry.Vector.VectorFixed: Vector :: Vec d r -> Vector
- Data.Geometry.Vector.VectorFixed: [_unV] :: Vector -> Vec (ToPeano d) r
+ Data.Geometry.Vector.VectorFixed: [_unV] :: Vector -> Vec d r
- Data.Geometry.Vector.VectorFixed: destruct :: AlwaysTrueDestruct predD d => Vector d r -> (r, Vector predD r)
+ Data.Geometry.Vector.VectorFixed: destruct :: (Arity d, Arity (d + 1), 1 <= (d + 1)) => Vector (d + 1) r -> (r, Vector d r)
- Data.Geometry.Vector.VectorFixed: element :: forall proxy i d r. (Arity d, Index' i d) => proxy i -> Lens' (Vector d r) r
+ Data.Geometry.Vector.VectorFixed: element :: forall proxy i d r. (Arity d, Arity i, (i + 1) <= d) => proxy i -> Lens' (Vector d r) r
- Data.Geometry.Vector.VectorFixed: element' :: forall d r. (KnownNat d, Arity d) => Int -> Traversal' (Vector d r) r
+ Data.Geometry.Vector.VectorFixed: element' :: forall d r. Arity d => Int -> Traversal' (Vector d r) r
- Data.Geometry.Vector.VectorFixed: init :: AlwaysTrueDestruct predD d => Vector d r -> Vector predD r
+ Data.Geometry.Vector.VectorFixed: init :: (Arity d, Arity (d + 1)) => Vector (d + 1) r -> Vector d r
- Data.Geometry.Vector.VectorFixed: prefix :: (Prefix (ToPeano i) (ToPeano d)) => Vector d r -> Vector i r
+ Data.Geometry.Vector.VectorFixed: prefix :: forall i d r. (Arity d, Arity i, i <= d) => Vector d r -> Vector i r
- Data.Geometry.Vector.VectorFixed: snoc :: (AlwaysTrueSnoc d, Arity d) => Vector d r -> r -> Vector (1 + d) r
+ Data.Geometry.Vector.VectorFixed: snoc :: (Arity (d + 1), Arity d) => Vector d r -> r -> Vector (d + 1) r
- Data.Geometry.Vector.VectorFixed: unV :: Lens' (Vector d r) (Vec (ToPeano d) r)
+ Data.Geometry.Vector.VectorFixed: unV :: Lens' (Vector d r) (Vec d r)
- Data.Permutation: indexes :: forall a_aEzZ. Lens' (Permutation a_aEzZ) (Vector (Int, Int))
+ Data.Permutation: indexes :: forall a_a1wrM. Lens' (Permutation a_a1wrM) (Vector (Int, Int))
- Data.Permutation: orbits :: forall a_aEzZ a_aECH. Lens (Permutation a_aEzZ) (Permutation a_aECH) (Vector (Orbit a_aEzZ)) (Vector (Orbit a_aECH))
+ Data.Permutation: orbits :: forall a_a1wrM a_a1wuT. Lens (Permutation a_a1wrM) (Permutation a_a1wuT) (Vector (Orbit a_a1wrM)) (Vector (Orbit a_a1wuT))
- Data.PlanarGraph: Dart :: !(Arc s) -> !Direction -> Dart s
+ Data.PlanarGraph: Dart :: {-# UNPACK #-} !(Arc s) -> {-# UNPACK #-} !Direction -> Dart s
- Data.PlanarGraph: FaceId :: VertexId s (Dual w) -> FaceId s w
+ Data.PlanarGraph: FaceId :: VertexId s (DualOf w) -> FaceId s w
- Data.PlanarGraph: [_arc] :: Dart s -> !(Arc s)
+ Data.PlanarGraph: [_arc] :: Dart s -> {-# UNPACK #-} !(Arc s)
- Data.PlanarGraph: [_direction] :: Dart s -> !Direction
+ Data.PlanarGraph: [_direction] :: Dart s -> {-# UNPACK #-} !Direction
- Data.PlanarGraph: [_unFaceId] :: FaceId s w -> VertexId s (Dual w)
+ Data.PlanarGraph: [_unFaceId] :: FaceId s w -> VertexId s (DualOf w)
- Data.PlanarGraph: arc :: forall s_a1cP8 s_a1d6L. Lens (Dart s_a1cP8) (Dart s_a1d6L) (Arc s_a1cP8) (Arc s_a1d6L)
+ Data.PlanarGraph: arc :: forall s_a1zg0 s_a1zwA. Lens (Dart s_a1zg0) (Dart s_a1zwA) (Arc s_a1zg0) (Arc s_a1zwA)
- Data.PlanarGraph: direction :: forall s_a1cP8. Lens' (Dart s_a1cP8) Direction
+ Data.PlanarGraph: direction :: forall s_a1zg0. Lens' (Dart s_a1zg0) Direction
- Data.PlanarGraph: dual :: PlanarGraph s w v e f -> PlanarGraph s (Dual w) f e v
+ Data.PlanarGraph: dual :: Getter (PlanarGraph s w v e f) (PlanarGraph s (DualOf w) f e v)
- Data.PlanarGraph: edgeOracle :: PlanarGraph s w v e f -> EdgeOracle s w ()
+ Data.PlanarGraph: edgeOracle :: PlanarGraph s w v e f -> EdgeOracle s w (Dart s)
- Data.PlanarGraph: embedding :: forall s_a1dkO w_a1dkP v_a1dkQ e_a1dkR f_a1dkS s_a1dr3 w_a1dr4. Lens (PlanarGraph s_a1dkO w_a1dkP v_a1dkQ e_a1dkR f_a1dkS) (PlanarGraph s_a1dr3 w_a1dr4 v_a1dkQ e_a1dkR f_a1dkS) (Permutation (Dart s_a1dkO)) (Permutation (Dart s_a1dr3))
+ Data.PlanarGraph: embedding :: Getter (PlanarGraph s w v e f) (Permutation (Dart s))
- Data.PlanarGraph: faceData :: forall s_a1dkO w_a1dkP v_a1dkQ e_a1dkR f_a1dkS w_a1dr5 f_a1dr6. Lens (PlanarGraph s_a1dkO w_a1dkP v_a1dkQ e_a1dkR f_a1dkS) (PlanarGraph s_a1dkO w_a1dr5 v_a1dkQ e_a1dkR f_a1dr6) (Vector f_a1dkS) (Vector f_a1dr6)
+ Data.PlanarGraph: faceData :: Lens (PlanarGraph s w v e f) (PlanarGraph s w v e f') (Vector f) (Vector f')
- Data.PlanarGraph: fromAdjacencyLists :: forall s w f. (Foldable f, Functor f) => [(VertexId s w, f (VertexId s w))] -> PlanarGraph s w () () ()
+ Data.PlanarGraph: fromAdjacencyLists :: forall s w h. (Foldable h, Functor h) => [(VertexId s w, h (VertexId s w))] -> PlanarGraph s w () () ()
- Data.PlanarGraph: planarGraph :: [[(Dart s, e)]] -> PlanarGraph s Primal_ () e ()
+ Data.PlanarGraph: planarGraph :: [[(Dart s, e)]] -> PlanarGraph s Primal () e ()
- Data.PlanarGraph: vertexData :: forall s_a1dkO w_a1dkP v_a1dkQ e_a1dkR f_a1dkS w_a1dr9 v_a1dra. Lens (PlanarGraph s_a1dkO w_a1dkP v_a1dkQ e_a1dkR f_a1dkS) (PlanarGraph s_a1dkO w_a1dr9 v_a1dra e_a1dkR f_a1dkS) (Vector v_a1dkQ) (Vector v_a1dra)
+ Data.PlanarGraph: vertexData :: Lens (PlanarGraph s w v e f) (PlanarGraph s w v' e f) (Vector v) (Vector v')
- Data.PlaneGraph: withEdgeDistances :: (Point 2 r -> Point 2 r -> a) -> PlaneGraph s w p e f r -> PlaneGraph s w p (a :+ e) f r
+ Data.PlaneGraph: withEdgeDistances :: (Point 2 r -> Point 2 r -> a) -> PlaneGraph s p e f r -> PlaneGraph s p (a :+ e) f r
- Data.Range: lower :: forall a_aQ5e. Lens' (Range a_aQ5e) (EndPoint a_aQ5e)
+ Data.Range: lower :: forall a_a1Ji7. Lens' (Range a_a1Ji7) (EndPoint a_a1Ji7)
- Data.Range: upper :: forall a_aQ5e. Lens' (Range a_aQ5e) (EndPoint a_aQ5e)
+ Data.Range: upper :: forall a_a1Ji7. Lens' (Range a_a1Ji7) (EndPoint a_a1Ji7)
- Data.UnBounded: unUnBounded :: forall a_aiMP a_amqc. Traversal (UnBounded a_aiMP) (UnBounded a_amqc) a_aiMP a_amqc
+ Data.UnBounded: unUnBounded :: forall a_a2d8w a_a2e5G. Traversal (UnBounded a_a2d8w) (UnBounded a_a2e5G) a_a2d8w a_a2e5G

Files

README.md view
@@ -47,7 +47,7 @@ * A KD-Tree. The base tree is static.  HGeometry also includes a datastructure/data type for planar graphs. In-particular, it has a `EdgeOracle' data structure, that can be built in $O(n)$+particular, it has a `EdgeOracle` data structure, that can be built in \(O(n)\) time that can test if the graph contains an edge in constant time.  Numeric Types
+ benchmark/Algorithms/Geometry/ConvexHull/Bench.hs view
@@ -0,0 +1,72 @@+module Algorithms.Geometry.ConvexHull.Bench where++import qualified Algorithms.Geometry.ConvexHull.DivideAndConqueror as DivideAndConqueror+import qualified Algorithms.Geometry.ConvexHull.GrahamScan as GrahamScan++-- | copies of the convex hull algo with different point types+import qualified Algorithms.Geometry.ConvexHull.GrahamV2   as GV+import qualified Algorithms.Geometry.ConvexHull.GrahamFam  as GFam+import qualified Algorithms.Geometry.ConvexHull.GrahamFamPeano  as GPeano+import qualified Algorithms.Geometry.ConvexHull.GrahamFam6  as GFam6+import qualified Algorithms.Geometry.ConvexHull.GrahamFixed as GFix+++import           Benchmark.Util+import           Control.DeepSeq+import           Criterion.Main+import           Criterion.Types+import           Data.Ext+import           Data.Geometry.Point+import           Data.List.NonEmpty (NonEmpty(..))+import qualified Data.List.NonEmpty as NonEmpty+import           Data.Proxy+import           Test.QuickCheck+import           Test.QuickCheck.HGeometryInstances ()++--------------------------------------------------------------------------------++main :: IO ()+main = defaultMainWith cfg [ benchmark ]+  where+    cfg = defaultConfig { reportFile = Just "bench.html" }++benchmark :: Benchmark+benchmark = bgroup "convexHullBench"+    [ env (genPts (Proxy :: Proxy Int) 10000) benchBuild+    ]++--------------------------------------------------------------------------------++genPts     :: (Ord r, Arbitrary r) => proxy r -> Int -> IO (NonEmpty (Point 2 r :+ ()))+genPts _ n = generate (NonEmpty.fromList <$> vectorOf n arbitrary)++-- | Benchmark building the convexHull+benchBuild    :: (Ord r, Num r, NFData r) => NonEmpty (Point 2 r :+ ()) -> Benchmark+benchBuild ps = bgroup "build" [ bgroup (show n) (build $ take' n ps)+                               | n <- sizes' ps+                               ]+  where+    take' n = NonEmpty.fromList . NonEmpty.take n+    sizes' _ = [2000]++    build pts = [ bench "sort"                 $ nf NonEmpty.sort pts+                , bench "sort_Linear.V2"       $ nf NonEmpty.sort ptsV2+                , bench "sort_FamPeano"        $ nf NonEmpty.sort ptsFamPeano+                , bench "sort_Family"          $ nf NonEmpty.sort ptsFam+                , bench "sort_Family6"         $ nf NonEmpty.sort ptsFam6+                , bench "sort_Fixed"           $ nf NonEmpty.sort ptsFix++                , bench "grahamScan"           $ nf GrahamScan.convexHull pts+                , bench "grahamScan_Linear.V2" $ nf GV.convexHull         ptsV2+                , bench "grahamScan_FamPeano"  $ nf GPeano.convexHull     ptsFamPeano+                , bench "grahamScan_Family"    $ nf GFam.convexHull       ptsFam+                , bench "grahamScan_Fixed"     $ nf GFix.convexHull       ptsFix++                , bench "Div&Conq"             $ nf DivideAndConqueror.convexHull pts+                ]+      where+        ptsV2       = fmap (GV.fromP) pts+        ptsFamPeano = fmap (GPeano.fromP) pts+        ptsFam      = fmap (GFam.fromP) pts+        ptsFam6     = fmap (GFam6.fromP) pts+        ptsFix      = fmap (GFix.fromP) pts
+ benchmark/Algorithms/Geometry/ConvexHull/GrahamFam.hs view
@@ -0,0 +1,103 @@+{-# LANGUAGE UndecidableInstances #-}+module Algorithms.Geometry.ConvexHull.GrahamFam( convexHull+                                               , upperHull+                                               , lowerHull, fromP+                                               ) where++import           Control.DeepSeq+import           Control.Lens ((^.))+import           Data.Ext+import           Data.Geometry.Point+import qualified Data.Geometry.Vector.VectorFamily as VF+import           Data.List.NonEmpty (NonEmpty(..))+import qualified Data.List.NonEmpty as NonEmpty+import           Data.Monoid+import           GHC.TypeLits+++newtype MyPoint d r = MyPoint (VF.Vector d r)++deriving instance (VF.Arity d, Eq r)  => Eq (MyPoint d r)+deriving instance (VF.Arity d, Ord r) => Ord (MyPoint d r)+deriving instance (VF.Arity d, Show r) => Show (MyPoint d r)+deriving instance (NFData (VF.Vector d r)) => NFData (MyPoint d r)++pattern MyPoint2 x y = MyPoint (VF.Vector2 x y)+++-- instance (NFData r, Arity d) => NFData (MyPoint d r)  where+--   rnf (MyPoint x y) = rnf (x,y)+--   rnf (MyP p)       = rnf p++toP                    :: MyPoint 2 r :+ e -> Point 2 r :+ e+toP (MyPoint2 x y :+ e) = Point2 x y :+ e++fromP                   :: Point 2 r :+ e -> MyPoint 2 r :+ e+fromP (Point2 x y :+ e) = MyPoint2 x y :+ e+++subt :: Num r => MyPoint 2 r -> MyPoint 2 r -> MyPoint 2 r+(MyPoint2 x y) `subt` (MyPoint2 a b) = MyPoint2 (x-a) (y-b)++newtype ConvexPolygon p r = ConvexPolygon [Point 2 r :+ p] deriving (Show,Eq,NFData)++-- | \(O(n \log n)\) time ConvexHull using Graham-Scan. The resulting polygon is+-- given in clockwise order.+convexHull            :: (Ord r, Num r)+                      => NonEmpty (MyPoint 2 r :+ p) -> ConvexPolygon p r+convexHull (p :| []) = ConvexPolygon $ [toP p]+convexHull ps        = let ps' = NonEmpty.toList . NonEmpty.sortBy incXdecY $ ps+                           uh  = NonEmpty.tail . hull' $         ps'+                           lh  = NonEmpty.tail . hull' $ reverse ps'+                       in ConvexPolygon . map toP . reverse $ lh ++ uh++upperHull  :: (Ord r, Num r) => NonEmpty (MyPoint 2 r :+ p) -> NonEmpty (MyPoint 2 r :+ p)+upperHull = hull id+++lowerHull :: (Ord r, Num r) => NonEmpty (MyPoint 2 r :+ p) -> NonEmpty (MyPoint 2 r :+ p)+lowerHull = hull reverse+++-- | Helper function so that that can compute both the upper or the lower hull, depending+-- on the function f+hull               :: (Ord r, Num r)+                   => ([MyPoint 2 r :+ p] -> [MyPoint 2 r :+ p])+                   -> NonEmpty (MyPoint 2 r :+ p) -> NonEmpty (MyPoint 2 r :+ p)+hull _ h@(_ :| []) = h+hull f pts         = hull' .  f+                   . NonEmpty.toList . NonEmpty.sortBy incXdecY $ pts++incXdecY  :: Ord r => (MyPoint 2 r) :+ p -> (MyPoint 2 r) :+ q -> Ordering+incXdecY (MyPoint2 px py :+ _) (MyPoint2 qx qy :+ _) =+  compare px qx <> compare qy py+++-- | Precondition: The list of input points is sorted+hull'          :: (Ord r, Num r) => [MyPoint 2 r :+ p] -> NonEmpty (MyPoint 2 r :+ p)+hull' (a:b:ps) = NonEmpty.fromList $ hull'' [b,a] ps+  where+    hull'' h []      = h+    hull'' h (p:ps') = hull'' (cleanMiddle (p:h)) ps'++    cleanMiddle h@[_,_]                         = h+    cleanMiddle h@(z:y:x:rest)+      | rightTurn (x^.core) (y^.core) (z^.core) = h+      | otherwise                               = cleanMiddle (z:x:rest)+    cleanMiddle _                               = error "cleanMiddle: too few points"++rightTurn       :: (Ord r, Num r) => MyPoint 2 r -> MyPoint 2 r -> MyPoint 2 r -> Bool+rightTurn a b c = ccwP a b c == CW++++ccwP :: (Ord r, Num r) => MyPoint 2 r -> MyPoint 2 r -> MyPoint 2 r -> CCW+ccwP p q r = case z `compare` 0 of+              LT -> CW+              GT -> CCW+              EQ -> CoLinear+     where++       MyPoint2 ux uy = q `subt` p+       MyPoint2 vx vy = r `subt` p+       z              = ux * vy - uy * vx
+ benchmark/Algorithms/Geometry/ConvexHull/GrahamFam6.hs view
@@ -0,0 +1,103 @@+{-# LANGUAGE UndecidableInstances #-}+module Algorithms.Geometry.ConvexHull.GrahamFam6( convexHull+                                                , upperHull+                                                , lowerHull, fromP+                                                ) where++import           Control.DeepSeq+import           Control.Lens ((^.))+import           Data.Ext+import           Data.Geometry.Point+import qualified Data.Geometry.Vector.VectorFamily6 as VF+import           Data.List.NonEmpty (NonEmpty(..))+import qualified Data.List.NonEmpty as NonEmpty+import           Data.Monoid+import           GHC.TypeLits+++newtype MyPoint d r = MyPoint (VF.Vector d r)++deriving instance (VF.Arity d, Eq r)  => Eq (MyPoint d r)+deriving instance (VF.Arity d, Ord r) => Ord (MyPoint d r)+deriving instance (VF.Arity d, Show r) => Show (MyPoint d r)+deriving instance (NFData (VF.Vector d r)) => NFData (MyPoint d r)++pattern MyPoint2 x y = MyPoint (VF.Vector2 x y)+++-- instance (NFData r, Arity d) => NFData (MyPoint d r)  where+--   rnf (MyPoint x y) = rnf (x,y)+--   rnf (MyP p)       = rnf p++toP                    :: MyPoint 2 r :+ e -> Point 2 r :+ e+toP (MyPoint2 x y :+ e) = Point2 x y :+ e++fromP                   :: Point 2 r :+ e -> MyPoint 2 r :+ e+fromP (Point2 x y :+ e) = MyPoint2 x y :+ e+++subt :: Num r => MyPoint 2 r -> MyPoint 2 r -> MyPoint 2 r+(MyPoint2 x y) `subt` (MyPoint2 a b) = MyPoint2 (x-a) (y-b)++newtype ConvexPolygon p r = ConvexPolygon [Point 2 r :+ p] deriving (Show,Eq,NFData)++-- | \(O(n \log n)\) time ConvexHull using Graham-Scan. The resulting polygon is+-- given in clockwise order.+convexHull            :: (Ord r, Num r)+                      => NonEmpty (MyPoint 2 r :+ p) -> ConvexPolygon p r+convexHull (p :| []) = ConvexPolygon $ [toP p]+convexHull ps        = let ps' = NonEmpty.toList . NonEmpty.sortBy incXdecY $ ps+                           uh  = NonEmpty.tail . hull' $         ps'+                           lh  = NonEmpty.tail . hull' $ reverse ps'+                       in ConvexPolygon . map toP . reverse $ lh ++ uh++upperHull  :: (Ord r, Num r) => NonEmpty (MyPoint 2 r :+ p) -> NonEmpty (MyPoint 2 r :+ p)+upperHull = hull id+++lowerHull :: (Ord r, Num r) => NonEmpty (MyPoint 2 r :+ p) -> NonEmpty (MyPoint 2 r :+ p)+lowerHull = hull reverse+++-- | Helper function so that that can compute both the upper or the lower hull, depending+-- on the function f+hull               :: (Ord r, Num r)+                   => ([MyPoint 2 r :+ p] -> [MyPoint 2 r :+ p])+                   -> NonEmpty (MyPoint 2 r :+ p) -> NonEmpty (MyPoint 2 r :+ p)+hull _ h@(_ :| []) = h+hull f pts         = hull' .  f+                   . NonEmpty.toList . NonEmpty.sortBy incXdecY $ pts++incXdecY  :: Ord r => (MyPoint 2 r) :+ p -> (MyPoint 2 r) :+ q -> Ordering+incXdecY (MyPoint2 px py :+ _) (MyPoint2 qx qy :+ _) =+  compare px qx <> compare qy py+++-- | Precondition: The list of input points is sorted+hull'          :: (Ord r, Num r) => [MyPoint 2 r :+ p] -> NonEmpty (MyPoint 2 r :+ p)+hull' (a:b:ps) = NonEmpty.fromList $ hull'' [b,a] ps+  where+    hull'' h []      = h+    hull'' h (p:ps') = hull'' (cleanMiddle (p:h)) ps'++    cleanMiddle h@[_,_]                         = h+    cleanMiddle h@(z:y:x:rest)+      | rightTurn (x^.core) (y^.core) (z^.core) = h+      | otherwise                               = cleanMiddle (z:x:rest)+    cleanMiddle _                               = error "cleanMiddle: too few points"++rightTurn       :: (Ord r, Num r) => MyPoint 2 r -> MyPoint 2 r -> MyPoint 2 r -> Bool+rightTurn a b c = ccwP a b c == CW++++ccwP :: (Ord r, Num r) => MyPoint 2 r -> MyPoint 2 r -> MyPoint 2 r -> CCW+ccwP p q r = case z `compare` 0 of+              LT -> CW+              GT -> CCW+              EQ -> CoLinear+     where++       MyPoint2 ux uy = q `subt` p+       MyPoint2 vx vy = r `subt` p+       z              = ux * vy - uy * vx
+ benchmark/Algorithms/Geometry/ConvexHull/GrahamFamPeano.hs view
@@ -0,0 +1,107 @@+{-# LANGUAGE UndecidableInstances #-}+module Algorithms.Geometry.ConvexHull.GrahamFamPeano( convexHull+                                                    , upperHull+                                                    , lowerHull, fromP+                                                    ) where++import           Control.DeepSeq+import           Control.Lens ((^.))+import           Data.Ext+import           Data.Geometry.Point+import qualified Data.Vector.Fixed.Cont as V+import qualified Data.Geometry.Vector.VectorFamilyPeano as VF+import           Data.List.NonEmpty (NonEmpty(..))+import qualified Data.List.NonEmpty as NonEmpty+import           Data.Monoid+import           GHC.TypeLits+import qualified Linear.V2 as V2+++newtype MyPoint d r = MyPoint (VF.VectorFamily d r)++deriving instance (VF.ImplicitArity d, Eq r)  => Eq (MyPoint d r)+deriving instance (VF.ImplicitArity d, Ord r) => Ord (MyPoint d r)+deriving instance (VF.ImplicitArity d, Show r) => Show (MyPoint d r)+deriving instance (NFData (VF.VectorFamily d r)) => NFData (MyPoint d r)++pattern Vector2 x y = VF.VectorFamily (V2.V2 x y)++pattern MyPoint2 x y = MyPoint (Vector2 x y)+++-- instance (NFData r, Arity d) => NFData (MyPoint d r)  where+--   rnf (MyPoint x y) = rnf (x,y)+--   rnf (MyP p)       = rnf p++toP                    :: MyPoint VF.Two r :+ e -> Point 2 r :+ e+toP (MyPoint2 x y :+ e) = Point2 x y :+ e++fromP                   :: Point 2 r :+ e -> MyPoint VF.Two r :+ e+fromP (Point2 x y :+ e) = MyPoint2 x y :+ e+++subt :: Num r => MyPoint VF.Two r -> MyPoint VF.Two r -> MyPoint VF.Two r+(MyPoint2 x y) `subt` (MyPoint2 a b) = MyPoint2 (x-a) (y-b)++newtype ConvexPolygon p r = ConvexPolygon [Point 2 r :+ p] deriving (Show,Eq,NFData)++-- | \(O(n \log n)\) time ConvexHull using Graham-Scan. The resulting polygon is+-- given in clockwise order.+convexHull            :: (Ord r, Num r)+                      => NonEmpty (MyPoint VF.Two r :+ p) -> ConvexPolygon p r+convexHull (p :| []) = ConvexPolygon $ [toP p]+convexHull ps        = let ps' = NonEmpty.toList . NonEmpty.sortBy incXdecY $ ps+                           uh  = NonEmpty.tail . hull' $         ps'+                           lh  = NonEmpty.tail . hull' $ reverse ps'+                       in ConvexPolygon . map toP . reverse $ lh ++ uh++upperHull  :: (Ord r, Num r) => NonEmpty (MyPoint VF.Two r :+ p) -> NonEmpty (MyPoint VF.Two r :+ p)+upperHull = hull id+++lowerHull :: (Ord r, Num r) => NonEmpty (MyPoint VF.Two r :+ p) -> NonEmpty (MyPoint VF.Two r :+ p)+lowerHull = hull reverse+++-- | Helper function so that that can compute both the upper or the lower hull, depending+-- on the function f+hull               :: (Ord r, Num r)+                   => ([MyPoint VF.Two r :+ p] -> [MyPoint VF.Two r :+ p])+                   -> NonEmpty (MyPoint VF.Two r :+ p) -> NonEmpty (MyPoint VF.Two r :+ p)+hull _ h@(_ :| []) = h+hull f pts         = hull' .  f+                   . NonEmpty.toList . NonEmpty.sortBy incXdecY $ pts++incXdecY  :: Ord r => (MyPoint VF.Two r) :+ p -> (MyPoint VF.Two r) :+ q -> Ordering+incXdecY (MyPoint2 px py :+ _) (MyPoint2 qx qy :+ _) =+  compare px qx <> compare qy py+++-- | Precondition: The list of input points is sorted+hull'          :: (Ord r, Num r) => [MyPoint VF.Two r :+ p] -> NonEmpty (MyPoint VF.Two r :+ p)+hull' (a:b:ps) = NonEmpty.fromList $ hull'' [b,a] ps+  where+    hull'' h []      = h+    hull'' h (p:ps') = hull'' (cleanMiddle (p:h)) ps'++    cleanMiddle h@[_,_]                         = h+    cleanMiddle h@(z:y:x:rest)+      | rightTurn (x^.core) (y^.core) (z^.core) = h+      | otherwise                               = cleanMiddle (z:x:rest)+    cleanMiddle _                               = error "cleanMiddle: too few points"++rightTurn       :: (Ord r, Num r) => MyPoint VF.Two r -> MyPoint VF.Two r -> MyPoint VF.Two r -> Bool+rightTurn a b c = ccwP a b c == CW++++ccwP :: (Ord r, Num r) => MyPoint VF.Two r -> MyPoint VF.Two r -> MyPoint VF.Two r -> CCW+ccwP p q r = case z `compare` 0 of+              LT -> CW+              GT -> CCW+              EQ -> CoLinear+     where++       MyPoint2 ux uy = q `subt` p+       MyPoint2 vx vy = r `subt` p+       z              = ux * vy - uy * vx
+ benchmark/Algorithms/Geometry/ConvexHull/GrahamFixed.hs view
@@ -0,0 +1,104 @@+{-# LANGUAGE UndecidableInstances #-}+module Algorithms.Geometry.ConvexHull.GrahamFixed( convexHull+                                                 , upperHull+                                                 , lowerHull, fromP+                                                 ) where++import           Control.DeepSeq+import           Control.Lens ((^.))+import           Data.Ext+import           Data.Geometry.Point+import           Data.Vector.Fixed (Arity)+import qualified Data.Geometry.Vector.VectorFixed as VF+import           Data.List.NonEmpty (NonEmpty(..))+import qualified Data.List.NonEmpty as NonEmpty+import           Data.Monoid+import           GHC.TypeLits+++newtype MyPoint d r = MyPoint (VF.Vector d r)++deriving instance (Arity d, Eq r)  => Eq (MyPoint d r)+deriving instance (Arity d, Ord r) => Ord (MyPoint d r)+deriving instance (Arity d, Show r) => Show (MyPoint d r)+deriving instance (NFData (VF.Vector d r)) => NFData (MyPoint d r)++pattern MyPoint2 x y = MyPoint (VF.Vector2 x y)+++-- instance (NFData r, Arity d) => NFData (MyPoint d r)  where+--   rnf (MyPoint x y) = rnf (x,y)+--   rnf (MyP p)       = rnf p++toP                    :: MyPoint 2 r :+ e -> Point 2 r :+ e+toP (MyPoint2 x y :+ e) = Point2 x y :+ e++fromP                   :: Point 2 r :+ e -> MyPoint 2 r :+ e+fromP (Point2 x y :+ e) = MyPoint2 x y :+ e+++subt :: Num r => MyPoint 2 r -> MyPoint 2 r -> MyPoint 2 r+(MyPoint2 x y) `subt` (MyPoint2 a b) = MyPoint2 (x-a) (y-b)++newtype ConvexPolygon p r = ConvexPolygon [Point 2 r :+ p] deriving (Show,Eq,NFData)++-- | \(O(n \log n)\) time ConvexHull using Graham-Scan. The resulting polygon is+-- given in clockwise order.+convexHull            :: (Ord r, Num r)+                      => NonEmpty (MyPoint 2 r :+ p) -> ConvexPolygon p r+convexHull (p :| []) = ConvexPolygon $ [toP p]+convexHull ps        = let ps' = NonEmpty.toList . NonEmpty.sortBy incXdecY $ ps+                           uh  = NonEmpty.tail . hull' $         ps'+                           lh  = NonEmpty.tail . hull' $ reverse ps'+                       in ConvexPolygon . map toP . reverse $ lh ++ uh++upperHull  :: (Ord r, Num r) => NonEmpty (MyPoint 2 r :+ p) -> NonEmpty (MyPoint 2 r :+ p)+upperHull = hull id+++lowerHull :: (Ord r, Num r) => NonEmpty (MyPoint 2 r :+ p) -> NonEmpty (MyPoint 2 r :+ p)+lowerHull = hull reverse+++-- | Helper function so that that can compute both the upper or the lower hull, depending+-- on the function f+hull               :: (Ord r, Num r)+                   => ([MyPoint 2 r :+ p] -> [MyPoint 2 r :+ p])+                   -> NonEmpty (MyPoint 2 r :+ p) -> NonEmpty (MyPoint 2 r :+ p)+hull _ h@(_ :| []) = h+hull f pts         = hull' .  f+                   . NonEmpty.toList . NonEmpty.sortBy incXdecY $ pts++incXdecY  :: Ord r => (MyPoint 2 r) :+ p -> (MyPoint 2 r) :+ q -> Ordering+incXdecY (MyPoint2 px py :+ _) (MyPoint2 qx qy :+ _) =+  compare px qx <> compare qy py+++-- | Precondition: The list of input points is sorted+hull'          :: (Ord r, Num r) => [MyPoint 2 r :+ p] -> NonEmpty (MyPoint 2 r :+ p)+hull' (a:b:ps) = NonEmpty.fromList $ hull'' [b,a] ps+  where+    hull'' h []      = h+    hull'' h (p:ps') = hull'' (cleanMiddle (p:h)) ps'++    cleanMiddle h@[_,_]                         = h+    cleanMiddle h@(z:y:x:rest)+      | rightTurn (x^.core) (y^.core) (z^.core) = h+      | otherwise                               = cleanMiddle (z:x:rest)+    cleanMiddle _                               = error "cleanMiddle: too few points"++rightTurn       :: (Ord r, Num r) => MyPoint 2 r -> MyPoint 2 r -> MyPoint 2 r -> Bool+rightTurn a b c = ccwP a b c == CW++++ccwP :: (Ord r, Num r) => MyPoint 2 r -> MyPoint 2 r -> MyPoint 2 r -> CCW+ccwP p q r = case z `compare` 0 of+              LT -> CW+              GT -> CCW+              EQ -> CoLinear+     where++       MyPoint2 ux uy = q `subt` p+       MyPoint2 vx vy = r `subt` p+       z              = ux * vy - uy * vx
+ benchmark/Algorithms/Geometry/ConvexHull/GrahamV2.hs view
@@ -0,0 +1,95 @@+{-# Language DeriveGeneric #-}+module Algorithms.Geometry.ConvexHull.GrahamV2( convexHull+                                              , upperHull+                                              , lowerHull, fromP+                                              ) where+++import           Control.DeepSeq+import           Control.Lens ((^.))+import           Data.Ext+import           Data.Geometry.Point+import           Data.List.NonEmpty (NonEmpty(..))+import qualified Data.List.NonEmpty as NonEmpty+import           Data.Monoid+import           GHC.Generics+import qualified Linear.V2 as V2++++newtype MyPoint r = MKPoint (V2.V2 r) deriving (Show,Eq,Ord,Generic)+-- data MyPoint r = MyPoint !r !r deriving (Show,Eq,Ord,Generic)++pattern MyPoint x y = MKPoint (V2.V2 x y)++instance NFData r => NFData (MyPoint r)+++toP (MyPoint x y :+ e) = Point2 x y :+ e+fromP (Point2 x y :+ e) = MyPoint x y :+ e++(MyPoint x y) `subt` (MyPoint a b) = MyPoint (x-a) (y-b)+++newtype ConvexPolygon p r = ConvexPolygon [Point 2 r :+ p] deriving (Show,Eq,NFData)++-- | \(O(n \log n)\) time ConvexHull using Graham-Scan. The resulting polygon is+-- given in clockwise order.+convexHull            :: (Ord r, Num r)+                      => NonEmpty (MyPoint r :+ p) -> ConvexPolygon p r+convexHull (p :| []) = ConvexPolygon $ [toP p]+convexHull ps        = let ps' = NonEmpty.toList . NonEmpty.sortBy incXdecY $ ps+                           uh  = NonEmpty.tail . hull' $         ps'+                           lh  = NonEmpty.tail . hull' $ reverse ps'+                       in ConvexPolygon . map toP . reverse $ lh ++ uh++upperHull  :: (Ord r, Num r) => NonEmpty (MyPoint r :+ p) -> NonEmpty (MyPoint r :+ p)+upperHull = hull id+++lowerHull :: (Ord r, Num r) => NonEmpty (MyPoint r :+ p) -> NonEmpty (MyPoint r :+ p)+lowerHull = hull reverse+++-- | Helper function so that that can compute both the upper or the lower hull, depending+-- on the function f+hull               :: (Ord r, Num r)+                   => ([MyPoint r :+ p] -> [MyPoint r :+ p])+                   -> NonEmpty (MyPoint r :+ p) -> NonEmpty (MyPoint r :+ p)+hull _ h@(_ :| []) = h+hull f pts         = hull' .  f+                   . NonEmpty.toList . NonEmpty.sortBy incXdecY $ pts++incXdecY  :: Ord r => (MyPoint r) :+ p -> (MyPoint r) :+ q -> Ordering+incXdecY (MyPoint px py :+ _) (MyPoint qx qy :+ _) =+  compare px qx <> compare qy py+++-- | Precondition: The list of input points is sorted+hull'          :: (Ord r, Num r) => [MyPoint r :+ p] -> NonEmpty (MyPoint r :+ p)+hull' (a:b:ps) = NonEmpty.fromList $ hull'' [b,a] ps+  where+    hull'' h []      = h+    hull'' h (p:ps') = hull'' (cleanMiddle (p:h)) ps'++    cleanMiddle h@[_,_]                         = h+    cleanMiddle h@(z:y:x:rest)+      | rightTurn (x^.core) (y^.core) (z^.core) = h+      | otherwise                               = cleanMiddle (z:x:rest)+    cleanMiddle _                               = error "cleanMiddle: too few points"++rightTurn       :: (Ord r, Num r) => MyPoint r -> MyPoint r -> MyPoint r -> Bool+rightTurn a b c = ccwP a b c == CW++++ccwP :: (Ord r, Num r) => MyPoint r -> MyPoint r -> MyPoint r -> CCW+ccwP p q r = case z `compare` 0 of+              LT -> CW+              GT -> CCW+              EQ -> CoLinear+     where++       MyPoint ux uy = q `subt` p+       MyPoint vx vy = r `subt` p+       z             = ux * vy - uy * vx
+ benchmark/Benchmark/Util.hs view
@@ -0,0 +1,7 @@+module Benchmark.Util where++++-- | Generates different size benchmarks+sizes    :: Foldable f => f a -> [Int]+sizes xs = let n = length xs in (\i -> n*i `div` 100) <$> [5,10..100]
benchmark/Benchmarks.hs view
@@ -1,69 +1,6 @@ module Main where -import           Control.DeepSeq-import           Control.Lens-import           Criterion.Main-import           Data.Ext-import           Data.Geometry.Interval-import qualified Data.Geometry.IntervalTree as IT-import           Data.Geometry.SegmentTree (I(..))-import qualified Data.Geometry.SegmentTree as SegTree-import qualified Data.List.NonEmpty as NonEmpty-import           QuickCheck.Instances-import           Test.QuickCheck----- | generates n random intervals-genIntervals                  :: (Ord r, Arbitrary r)-                              => proxy r -> Int -> IO [Interval () r]-genIntervals _ n | n <= 0     = error "genIntervals: need n > 0"-                 | otherwise  = generate (vectorOf n arbitrary)--genQueries                      :: (Ord r, Arbitrary r)-                                => proxy r -> Int -> IO [r]-genQueries _ n | n <= 0     = error "genQueries: need n > 0"-               | otherwise  = generate (vectorOf n arbitrary)----- genQuerySetup     :: (Ord r, Arbitrary r)---                   => proxy r -> Int -> IO (Int,IT.IntervalTree (I (Interval () r)) r, [r])--- genQuerySetup p n = (\is qs -> (n, IT.fromIntervals . fmap I $ is, qs))---                  <$> genIntervals p n---                  <*> genQueries   p n---main = defaultMain [-  bgroup "IntervalTree" [ env (genIntervals (I (5 :: Int)) (100000 :: Int)) benchBuild-                         -- env (genIntervals (I (5 :: Int)) (100000 :: Int)) benchQueryIT-                        ]-  ]--benchBuild    :: (Ord r, NFData r) => [Interval () r] -> Benchmark-benchBuild is = bgroup "build" [ bench (show n) $ nf IT.fromIntervals (take n is')-                               | n <- sizes is-                               ]-  where-    is' = I <$> is--benchQueryIT    :: (Ord r, Arbitrary r, NFData r) => [Interval () r] -> Benchmark-benchQueryIT is = bgroup "queries"-    [ env (setup n) (\(t,qs) ->-                        bench ("queries on size" ++ show n) $ whnf (queryAll t) qs)-    | n <- sizes is-    ]-  where-    is'        = I <$> is-    r          = is^.to head.start.core-    setup n    = (IT.fromIntervals (take n is'),) <$> genQueries (I r) 100000-    queryAll t = map (flip IT.search t)----- benchQueryIT          :: Ord r---                       => (Int, IT.IntervalTree (I (Interval () r)) r, [r]) -> Benchmark--- benchQueryIT (n,t,qs) = bgroup "queries" [ bench "query" $ whnf (flip IT.search t) q---                                          | q <- qs---                                          ]-+import qualified Algorithms.Geometry.ConvexHull.Bench as M -sizes    :: [a] -> [Int]-sizes xs = let n = length xs in (\i -> n*i `div` 100) <$> [5,10..100]+main :: IO ()+main = M.main
+ benchmark/Data/Geometry/IntervalTreeBench.hs view
@@ -0,0 +1,79 @@+module Data.Geometry.IntervalTreeBench where++import           Benchmark.Util+import           Control.DeepSeq+import           Control.Lens+import           Criterion.Main+import           Criterion.Types+import           Data.Ext+import           Data.Geometry.Interval+import qualified Data.Geometry.IntervalTree as IT+import           Data.Geometry.SegmentTree (I(..))+import qualified Data.Geometry.SegmentTree as SegTree+import qualified Data.List.NonEmpty as NonEmpty+import           Debug.Trace+import           Test.QuickCheck+import           Test.QuickCheck.HGeometryInstances ()++--------------------------------------------------------------------------------++main :: IO ()+main = defaultMainWith cfg [ intervalBench ]+  where+    cfg = defaultConfig { reportFile = Just "bench.html" }++intervalBench :: Benchmark+intervalBench = bgroup "IntervalTree"+    [ -- env (genIntervals (I (5 :: Int)) 1000) benchBuild+      env (genIntervals (I (5 :: Int)) 100) benchQueryIT+    ]++--------------------------------------------------------------------------------++-- | generates n random intervals+genIntervals                  :: (Ord r, Arbitrary r)+                              => proxy r -> Int -> IO [Interval () r]+genIntervals _ n | n <= 0     = error "genIntervals: need n > 0"+                 | otherwise  = generate (vectorOf n arbitrary)++genQueries                      :: (Ord r, Arbitrary r)+                                => proxy r -> Int -> IO [r]+genQueries _ n | n <= 0     = error "genQueries: need n > 0"+               | otherwise  = generate (vectorOf n arbitrary)+++-- genQuerySetup     :: (Ord r, Arbitrary r)+--                   => proxy r -> Int -> IO (Int,IT.IntervalTree (I (Interval () r)) r, [r])+-- genQuerySetup p n = (\is qs -> (n, IT.fromIntervals . fmap I $ is, qs))+--                  <$> genIntervals p n+--                  <*> genQueries   p n+++-- | Benchmark building the interval tree+benchBuild    :: (Ord r, NFData r) => [Interval () r] -> Benchmark+benchBuild is = bgroup "build" [ bench (show n) $ nf IT.fromIntervals (take n is')+                               | n <- sizes is+                               ]+  where+    is' = I <$> is++benchQueryIT    :: (Ord r, Arbitrary r, NFData r) => [Interval () r] -> Benchmark+benchQueryIT is = bgroup "queries"+    [ env (setup' n) (\(t,qs) ->+                        bench ("queries on size" ++ show n) $ whnf (queryAll t) qs)+    | n <- sizes is+    ]+  where+    is'        = I <$> is+    r          = is^.to head.start.core+    setup' n  = traceShow "setup" $ setup n++    setup n    = (IT.fromIntervals (take n is'),) <$> genQueries (I r) 100000+    queryAll t = map (flip IT.search t)+++-- benchQueryIT          :: Ord r+--                       => (Int, IT.IntervalTree (I (Interval () r)) r, [r]) -> Benchmark+-- benchQueryIT (n,t,qs) = bgroup "queries" [ bench "query" $ whnf (flip IT.search t) q+--                                          | q <- qs+--                                          ]
+ benchmark/Data/Geometry/Vector/VectorFamily6.hs view
@@ -0,0 +1,258 @@+{-# LANGUAGE ScopedTypeVariables  #-}+{-# LANGUAGE UndecidableInstances #-}+module Data.Geometry.Vector.VectorFamily6 where++import           Control.Applicative (liftA2)+import           Control.DeepSeq+import           Control.Lens hiding (element)+-- import           Data.Aeson (ToJSON(..),FromJSON(..))+import qualified Data.Foldable as F+import qualified Data.Geometry.Vector.VectorFixed as FV+import           Data.Maybe (fromMaybe)+import           Data.Proxy+import           Data.Semigroup+import           Data.Traversable (foldMapDefault,fmapDefault)+import qualified Data.Vector.Fixed as V+import           Data.Vector.Fixed.Cont (Peano(..), PeanoNum(..), Fun(..))+import           GHC.TypeLits+import           Linear.Affine (Affine(..))+import           Linear.Metric+import qualified Linear.V2 as L2+import qualified Linear.V3 as L3+import qualified Linear.V4 as L4+import           Linear.Vector++--------------------------------------------------------------------------------+-- * d dimensional Vectors+++type One = S Z+type Two = S One+type Three = S Two+type Four = S Three+type Many d = S (S (S (S (S d))))+++type family FromPeano (d :: PeanoNum) :: Nat where+  FromPeano Z     = 0+  FromPeano (S d) = 1 + FromPeano d+++data SingPeano (d :: PeanoNum) where+  SZ :: SingPeano Z+  SS :: !(SingPeano d) -> SingPeano (S d)++class ImplicitPeano (d :: PeanoNum) where+  implicitPeano :: SingPeano d+instance ImplicitPeano Z where+  implicitPeano = SZ+instance ImplicitPeano d => ImplicitPeano (S d) where+  implicitPeano = SS implicitPeano++-- | Mapping between the implementation type, and the actual implementation.+type family VectorFamilyF (d :: PeanoNum) :: * -> * where+  VectorFamilyF Z        = Const ()+  VectorFamilyF One      = Identity+  VectorFamilyF Two      = L2.V2+  VectorFamilyF Three    = L3.V3+  VectorFamilyF Four     = L4.V4+  VectorFamilyF (Many d) = FV.Vector (FromPeano (Many d))+++-- | Datatype representing d dimensional vectors. The default implementation is+-- based n VectorFixed. However, for small vectors we automatically select a+-- more efficient representation.+newtype VectorFamily (d :: PeanoNum) (r :: *) =+  VectorFamily { _unVF :: VectorFamilyF d r }++type ImplicitArity d = (ImplicitPeano d, V.Arity (FromPeano d))++++instance (Eq r, ImplicitArity d) => Eq (VectorFamily d r) where+  (VectorFamily u) == (VectorFamily v) = case (implicitPeano :: SingPeano d) of+        SZ                         -> u == v+        (SS SZ)                    -> u == v+        (SS (SS SZ))               -> u == v+        (SS (SS (SS SZ)))          -> u == v+        (SS (SS (SS (SS SZ))))     -> u == v+        (SS (SS (SS (SS (SS _))))) -> u == v+  {-# INLINE (==) #-}++instance (Ord r, ImplicitArity d) => Ord (VectorFamily d r) where+  (VectorFamily u) `compare` (VectorFamily v) = case (implicitPeano :: SingPeano d) of+        SZ                         -> u `compare` v+        (SS SZ)                    -> u `compare` v+        (SS (SS SZ))               -> u `compare` v+        (SS (SS (SS SZ)))          -> u `compare` v+        (SS (SS (SS (SS SZ))))     -> u `compare` v+        (SS (SS (SS (SS (SS _))))) -> u `compare` v+  {-# INLINE compare #-}+++instance ImplicitArity d => Functor (VectorFamily d) where+  fmap f = VectorFamily . g f . _unVF+    where g = case (implicitPeano :: SingPeano d) of+                SZ                         -> fmap+                (SS SZ)                    -> fmap+                (SS (SS SZ))               -> fmap+                (SS (SS (SS SZ)))          -> fmap+                (SS (SS (SS (SS SZ))))     -> fmap+                (SS (SS (SS (SS (SS _))))) -> fmap+  {-# INLINE fmap #-}+++instance ImplicitArity d => Foldable (VectorFamily d) where+  foldMap f = g f . _unVF+    where g = case (implicitPeano :: SingPeano d) of+                SZ                         -> foldMap+                (SS SZ)                    -> foldMap+                (SS (SS SZ))               -> foldMap+                (SS (SS (SS SZ)))          -> foldMap+                (SS (SS (SS (SS SZ))))     -> foldMap+                (SS (SS (SS (SS (SS _))))) -> foldMap+  {-# INLINE foldMap #-}++instance ImplicitArity d => Traversable (VectorFamily d) where+  traverse f = fmap VectorFamily . g f . _unVF+    where g = case (implicitPeano :: SingPeano d) of+                SZ                         -> traverse+                (SS SZ)                    -> traverse+                (SS (SS SZ))               -> traverse+                (SS (SS (SS SZ)))          -> traverse+                (SS (SS (SS (SS SZ))))     -> traverse+                (SS (SS (SS (SS (SS _))))) -> traverse+  {-# INLINE traverse #-}++instance ImplicitArity d => Applicative (VectorFamily d) where+  pure = VectorFamily . case (implicitPeano :: SingPeano d) of+                SZ                         -> pure+                (SS SZ)                    -> pure+                (SS (SS SZ))               -> pure+                (SS (SS (SS SZ)))          -> pure+                (SS (SS (SS (SS SZ))))     -> pure+                (SS (SS (SS (SS (SS _))))) -> pure+  {-# INLINE pure #-}+  liftA2 f (VectorFamily u) (VectorFamily v) = VectorFamily $+      case (implicitPeano :: SingPeano d) of+                SZ                         -> liftA2 f u v+                (SS SZ)                    -> liftA2 f u v+                (SS (SS SZ))               -> liftA2 f u v+                (SS (SS (SS SZ)))          -> liftA2 f u v+                (SS (SS (SS (SS SZ))))     -> liftA2 f u v+                (SS (SS (SS (SS (SS _))))) -> liftA2 f u v+  {-# INLINE liftA2 #-}+++++type instance V.Dim (VectorFamily d)  = FromPeano d+++++instance ImplicitArity d => V.Vector (VectorFamily d) r where+  construct = fmap VectorFamily $ case (implicitPeano :: SingPeano d) of+                SZ                         -> Fun $ Const ()+                (SS SZ)                    -> V.construct+                (SS (SS SZ))               -> Fun L2.V2+                (SS (SS (SS SZ)))          -> Fun L3.V3+                (SS (SS (SS (SS SZ))))     -> Fun L4.V4+                (SS (SS (SS (SS (SS _))))) -> V.construct+  {-# INLINE construct #-}+  inspect (VectorFamily v) ff@(Fun f) = case (implicitPeano :: SingPeano d) of+                SZ                         -> f+                (SS SZ)                    -> V.inspect v ff+                (SS (SS SZ))               -> let (L2.V2 x y) = v     in f x y+                (SS (SS (SS SZ)))          -> let (L3.V3 x y z) = v   in f x y z+                (SS (SS (SS (SS SZ))))     -> let (L4.V4 x y z w) = v in f x y z w+                (SS (SS (SS (SS (SS _))))) -> V.inspect v ff+  {-# INLINE inspect #-}+  -- basicIndex (VectorFamily v) i = case (implicitPeano :: SingPeano d) of+  --               SZ                         -> err+  --               (SS SZ)                    -> if i == 0 then runIdentity v else err+  --               (SS (SS SZ))               -> let (L2.V2 x y) = v     in f x y+  --               (SS (SS (SS SZ)))          -> let (L3.V3 x y z) = v   in f x y z+  --               (SS (SS (SS (SS SZ))))     -> let (L4.V4 x y z w) = v in f x y z w+  --               (SS (SS (SS (SS (SS _))))) -> V.basicIndex v i+  --   where+  --     err = error "VectorFamily: basicIndex out of range"+  -- {-# INLINE basicIndex #-}+++instance (ImplicitArity d, Show r) => Show (VectorFamily d r) where+  show v = mconcat [ "Vector", show $ F.length v , " "+                   , show $ F.toList v ]++deriving instance (NFData (VectorFamilyF d r)) => NFData (VectorFamily d r)+++type instance Index   (VectorFamily d r) = Int+type instance IxValue (VectorFamily d r) = r++--------------------------------------------------------------------------------+++newtype Vector (d :: Nat) (r :: *) = MKVector { _unV :: VectorFamily (Peano d) r }++type instance V.Dim (Vector d)  = d+++type instance Index   (Vector d r) = Int+type instance IxValue (Vector d r) = r++type Arity d = ImplicitArity (Peano d)++deriving instance (Eq r,  Arity d) => Eq  (Vector d r)+deriving instance (Ord r, Arity d) => Ord (Vector d r)++deriving instance Arity d => Functor     (Vector d)+deriving instance Arity d => Foldable    (Vector d)+deriving instance Arity d => Traversable (Vector d)++instance (Arity d, Show r) => Show (Vector d r) where+  show v = mconcat [ "Vector", show $ F.length v , " "+                   , show $ F.toList v ]+++deriving instance (NFData (VectorFamily (Peano d) r)) => NFData (Vector d r)+++++--------------------------------------------------------------------------------+-- * Convenience "constructors"++pattern Vector   :: VectorFamilyF (Peano d) r -> Vector d r+pattern Vector v = MKVector (VectorFamily v)++pattern Vector1   :: r -> Vector 1 r+pattern Vector1 x = (Vector (Identity x))++pattern Vector2     :: r -> r -> Vector 2 r+pattern Vector2 x y = (Vector (L2.V2 x y))++pattern Vector3        :: r -> r -> r -> Vector 3 r+pattern Vector3 x y z  = (Vector (L3.V3 x y z))++pattern Vector4         :: r -> r -> r -> r -> Vector 4 r+pattern Vector4 x y z w = (Vector (L4.V4 x y z w))++--------------------------------------------------------------------------------++-- -- destruct            :: (Vec d r, Vec (d + 1) r, 1 <= (d + 1))+-- --                     => Vector (d + 1) r -> (r, Vector d r)+-- -- destruct (Vector v) = (V.head v, Vector $ V.tail v)+++-- -- -- vectorFromList :: Arity d => [a] -> Maybe (Vector d a)+-- -- vectorFromList = fmap Vector . V.fromListM++-- -- vectorFromListUnsafe :: V.Arity d => [a] -> Vector d a+-- -- vectorFromListUnsafe = Vector . V.fromList++ --------------------------------------------------------------------------------++-- | Cross product of two three-dimensional vectors+cross       :: Num r => Vector 3 r -> Vector 3 r -> Vector 3 r+(Vector u) `cross` (Vector v) = Vector $ u `L3.cross` v
+ benchmark/WSPDBench.hs view
@@ -0,0 +1,26 @@+{-# LANGUAGE PartialTypeSignatures #-}+module WSPDBench where++import Control.DeepSeq+import Control.Lens+import Criterion.Main+import Data.Ext+import Data.Geometry.Point+import Demo.ExpectedPairwiseDistance+++readInput'     :: FilePath -> Int -> IO [Point 2 Double :+ _]+readInput' fp k = take k <$> readInput fp+++benchWSPD :: Benchmark+benchWSPD = bgroup "Well-Separated Pair Decomposition"+    [ env (readInput' "pco.9420_convert.txt" 200) $ \pts -> bgroup "pco"+        [ bench "exact"     $ nf pairwiseDist                  pts+        , bench "wspd 0.05" $ nf (approxPairwiseDistance 0.05) pts+        , bench "wspd 0.10" $ nf (approxPairwiseDistance 0.10) pts+        , bench "wspd 0.20" $ nf (approxPairwiseDistance 0.20) pts+        ]+    ]++-- main = defaultMain [ benchWSPD ]
+ changelog.md view
@@ -0,0 +1,60 @@+#### 0.7 ###++- Compatibility with GHC 8.0-8.4+- Implemented more Algorithms and Data Structures. This includes+  * Polygon triangulation+- A new implementation of PlanarSubdivision that now also supports disconnected+  subdivsions.+- Performance improvements by changing to a different Vector+  implementation. For low dimensional vectors (of dimension at most four) we+  now essentially use the types from+  [linear](https://hackage.haskell.org/package/linear), this gives significant+  speedups on several small benchmarks.+- bugfixes.++#### 0.6 ###++- Implemented more Algorithms and Data Structures. This includes+  * Bentley-Ottmannn line-segment intersection,+  * Well-Separated Pair decompositions,+  * extremal point/tangents for Convex hulls,+  * Minkowski sum for convex polygons,+  * one dimensional segment trees,+  * one dimensional interval trees, and a+  * KD-tree.+- Several bug fixes, including a very stupid bug in Box+- Separate ConvexPolygon type.+- More thorough testing for some of the algorithms.+- Started work on a proper representation for planar subdivsions. This includes+  a representation of planar graphs that support querying if two vertices are+  connected by an edge in $O(1)$ time.+- Dropped support for GHC 7.8++#### 0.5 ###++- Implemented several algorithms, including Delaunay Triangulation, EMST, and+Douglas Peucker.+- Revamped the data types for Intersections++#### 0.4 ###++- Major rewrite from scratch, providing much stronger type-level+  guarantees. Incompatible with older versions.+- Convex Hull and Smallest enclosing disk algorithms.+- HGeometry now includes some very experimental and preliminary support for+  reading and writing Ipe7 files.++#### 0.2 & 0.3 ###++- Internal releases.++### 0.1.1 ###++- Fixed a bug in point on n the line segment test+- Generalized the types of inCircle, inDisc, onCircle, onDisc etc. We now need+  only that the type representing precision model implements the typeclass+  `Num` instead of `Floating'.++### 0.1 ###++- Initial release.
examples/BAPC2014/Armybase.lhs view
@@ -60,7 +60,7 @@   -> triangArea :: Triangle p Int -> Half+> triangArea :: Triangle 2 p Int -> Half > triangArea = Half . doubleArea  @@ -193,7 +193,7 @@   > findLargestTriang        :: Point 2 Int -> Point 2 Int->                          -> Unimodal (Array Int) (Point 2 Int) -> Triangle () Int+>                          -> Unimodal (Array Int) (Point 2 Int) -> Triangle 2 () Int > findLargestTriang p q us = triang . ternarySearchArray area' $ us >   where >     triang v = Triangle (ext p) (ext q) (ext v)
examples/Demo/Delaunay.hs view
@@ -4,7 +4,6 @@ import           Algorithms.Geometry.DelaunayTriangulation.DivideAndConqueror import           Algorithms.Geometry.DelaunayTriangulation.Types import           Algorithms.Geometry.EuclideanMST.EuclideanMST-import           Control.Applicative import           Control.Lens import           Data.Data import           Data.Ext@@ -12,7 +11,6 @@ import           Data.Geometry.Ipe import qualified Data.List.NonEmpty as NonEmpty import           Data.Semigroup-import           Data.Traversable import           Options.Applicative  
examples/Demo/ExpectedPairwiseDistance.hs view
@@ -20,7 +20,7 @@ import           Data.Data import           Data.Semigroup import qualified Data.Set as Set-import           GHC.TypeLits (natVal,KnownNat)+import           GHC.TypeLits import           Options.Applicative hiding ((<>))  @@ -56,7 +56,7 @@ -- -- running time: $O(n(1/eps)^d + n\log n)$, where $n$ is the number of points approxExpectedPairwiseDistance          :: (Floating r, Ord r-                                           , AlwaysTrueWSPD d, Index' 0 d+                                           , Arity d, Arity (d+1), 1 <= d                                          , Show r, Show p)                                          => r -> Int -> [Point d r :+ p] -> r approxExpectedPairwiseDistance eps k pts =@@ -73,7 +73,7 @@ -- | $(1+\eps)$-approximation of the sum of the pairwise distances. -- -- running time: $O(n(1/eps)^d + n\log n)$, where $n$ is the number of points-approxPairwiseDistance         :: (Floating r, Ord r, AlwaysTrueWSPD d, Index' 0 d+approxPairwiseDistance         :: (Floating r, Ord r, Arity d, Arity (d+1), 1 <= d                                   , Show r, Show p)                                => r -> [Point d r :+ p] -> r approxPairwiseDistance _   []  = 0@@ -179,7 +179,7 @@   -- | Computes all pairs of points that are uncovered by the WSPD with separation s-uncovered         :: (Floating r, Ord r, AlwaysTrueWSPD d, Ord p)+uncovered         :: (Floating r, Ord r, Arity d, Arity (d+1), Ord p)                   => [Point d r :+ p] -> r -> SplitTree d p r a -> [(Point d r :+ p, Point d r :+ p)] uncovered pts s t = Set.toList $ allPairs `Set.difference` covered   where
examples/Demo/GPXParser.hs view
@@ -85,7 +85,7 @@ extract = (\(Text s) -> s) . head . eChildren  readTime' :: String -> UTCTime-readTime' = readTime defaultTimeLocale "%0C%y-%m-%dT%TZ"+readTime' = parseTimeOrError True defaultTimeLocale "%0C%y-%m-%dT%TZ"  -- instance ReadGPX Position where --   parseGPX x@(Element "Position" _ _) = (\l l' -> Position $ point2 l l') <$> lat <*> lon
+ examples/Demo/TriangulateWorld.hs view
@@ -0,0 +1,106 @@+{-# LANGUAGE ScopedTypeVariables #-}+module Demo.TriangulateWorld where++import Algorithms.Geometry.LineSegmentIntersection (hasSelfIntersections)+import Algorithms.Geometry.PolygonTriangulation.Triangulate (triangulate)+import Algorithms.Geometry.PolygonTriangulation.MakeMonotone (makeMonotone)+import Data.Maybe(mapMaybe)+import Control.Lens+import Data.Data+import Data.Ext+import Data.Geometry.Ipe+import Data.Geometry.Polygon+import Data.Geometry.PlanarSubdivision+import Data.Semigroup+import Options.Applicative+import qualified Data.Foldable as F+++--------------------------------------------------------------------------------++data Options = Options { _inPath    :: FilePath+                       , _outFile   :: FilePath+                       }+               deriving Data++options :: ParserInfo Options+options = info (helper <*> parser)+               (  progDesc "Triangulate all polygons in the input file."+               <> header   "trianguldateWorld"+               )+  where+    parser = Options+          <$> strOption (help "Input file (in ipe7 xml format)"+                         <> short 'i'+                        )+          <*> strOption (help "Output File (in ipe7 xml format)"+                         <> short 'o'+                        )++++-- runExcept'   :: (Show e) => ExceptT e IO () -> IO ()+-- runExcept' m = runExceptT m >>= \case+--                 Left e   -> print e+--                 Right () -> pure ()++-- mainWith                          :: Options -> IO ()+-- mainWith (Options inFile outFile) = runExcept' $ do+--     (page :: IpePage Rational) <- readSinglePageFile inFile+--     let polies = page^..content.traverse._withAttrs _IpePath _asSimplePolygon+--     let out = undefinedL+--     lift $  writeIpeFile outFile . singlePageFromContent $ out++data PX = PX++mainWith                          :: Options -> IO ()+mainWith (Options inFile outFile) = do+    ePage <- readSinglePageFile inFile+    case ePage of+      Left err                         -> print err+      Right (page :: IpePage Rational) -> runPage page+  where+    runPage page = do+      let polies  = page^..content.to flattenGroups.traverse._withAttrs _IpePath _asSimplePolygon+          polies' = filter (not . hasSelfIntersections . (^.core)) polies+          subdivs = map (\(pg :+ _) -> triangulate (Identity PX) pg) polies'+          yMonotones = tail . mapMaybe (^?_2.core._Left)+                     . concatMap (F.toList.rawFacePolygons) $ subdivs+          ofs = map (\s -> rawFaceBoundary (outerFaceId s) s) subdivs+          segs    = map (^._2.core) . concatMap (F.toList . edgeSegments) $ subdivs+          out     = [ asIpeObject pg a+                    | pg :+ a <- polies+                    ] <>+                    [ asIpeObject s mempty+                    | s <- segs+                    ] <>+                    [ asIpeObject pg mempty+                    | pg <- yMonotones ]+      mapM_ print . map (\pg -> pg^.core.to polygonVertices.to length) $ polies'+      writeIpeFile outFile . singlePageFromContent $ out+++-- mainWith                          :: Options -> IO ()+-- mainWith (Options inFile outFile) = do+--     ePage <- readSinglePageFile inFile+--     case ePage of+--       Left err                         -> print err+--       Right (page :: IpePage Rational) -> runPage page+--   where+--     runPage page = do+--       let orig = page^.content+--           all' = page^.content.to flattenGroups+--       writeIpeFile outFile . singlePageFromContent $ orig <> all'+++-- type ValT = EitherT IO++-- flattenGroups :: [IpeObject r] -> [IpeObject r]+-- flattenGroups = concatMap flattenGroups'++-- flattenGroups'                              :: IpeObject r -> [IpeObject r]+-- flattenGroups' (IpeGroup (Group gs :+ ats)) =+--       map (applyAts ats) . concatMap flattenGroups' $ gs+--     where+--       applyAts ats = id+-- flattenGroups' o                            = [o]
examples/Main.hs view
@@ -12,6 +12,7 @@ import qualified Demo.MinDisk as MinDisk import qualified Demo.Delaunay as Delaunay import qualified Demo.ExpectedPairwiseDistance as ExpPWD+import qualified Demo.TriangulateWorld as TriangulateWorld   @@ -24,6 +25,7 @@              | MinDisk                   MinDisk.Options              | Delaunay                  Delaunay.Options              | ExpectedPairwiseDistance  ExpPWD.Options+             | TriangulateWorld          TriangulateWorld.Options              deriving Data  parser :: Parser Options@@ -33,6 +35,7 @@     <> command' MinDisk                        MinDisk.options     <> command' Delaunay                       Delaunay.options     <> command' ExpectedPairwiseDistance       ExpPWD.options+    <> command' TriangulateWorld               TriangulateWorld.options     )  @@ -44,6 +47,7 @@   MinDisk opts                        -> MinDisk.mainWith opts   Delaunay opts                       -> Delaunay.mainWith opts   ExpectedPairwiseDistance opts       -> ExpPWD.mainWith opts+  TriangulateWorld opts               -> TriangulateWorld.mainWith opts  -------------------------------------------------------------------------------- 
hgeometry.cabal view
@@ -2,7 +2,7 @@ -- documentation, see http://haskell.org/cabal/users-guide/  name:                hgeometry-version:             0.6.0.0+version:             0.7.0.0 synopsis:            Geometric Algorithms, Data structures, and Data types. description:   HGeometry provides some basic geometry types, and geometric algorithms and@@ -17,17 +17,20 @@ maintainer:          frank@fstaals.net -- copyright: -tested-with:         GHC >= 7.10.2+tested-with:         GHC >= 8.2  category:            Geometry build-type:          Simple -extra-source-files:  README.md-                     resources/basic.isy+data-files:          resources/basic.isy+                     test/Algorithms/Geometry/LineSegmentIntersection/manual.ipe+                     test/Algorithms/Geometry/LineSegmentIntersection/selfIntersections.ipe+                     test/Algorithms/Geometry/LowerEnvelope/manual.ipe+                     test/Algorithms/Geometry/PolygonTriangulation/monotone.ipe+                     test/Algorithms/Geometry/PolygonTriangulation/simplepolygon6.ipe+                     test/Algorithms/Geometry/SmallestEnclosingDisk/manual.ipe                      test/Data/Geometry/pointInPolygon.ipe                      test/Data/Geometry/Polygon/Convex/convexTests.ipe-                     test/Algorithms/Geometry/SmallestEnclosingDisk/manual.ipe-                     test/Algorithms/Geometry/LineSegmentIntersection/manual.ipe                      examples/BAPC2014/sample.in                      examples/BAPC2014/sample.out                      examples/BAPC2014/testdata.in@@ -38,7 +41,11 @@                      examples/BAPC2012/sampleG.out  -cabal-version:       >=1.10++extra-source-files:  README.md+                     changelog.md++cabal-version:       2.0 source-repository head   type:     git   location: https://github.com/noinia/hgeometry@@ -49,8 +56,18 @@   default:     False   manual:      True +flag with-quickcheck+  description: Include QuickCheck instances+  default:     True+  manual:      False++flag interactive+  description: Build  interactive parts+  default:     False+  manual:      True+ library-  ghc-options: -Wall -fno-warn-unticked-promoted-constructors -fno-warn-type-defaults+  ghc-options: -O2 -Wall -fno-warn-unticked-promoted-constructors -fno-warn-type-defaults    exposed-modules:                     -- * Generic Geometry@@ -63,6 +80,9 @@                     -- * Basic Geometry Types                     Data.Geometry.Vector                     Data.Geometry.Vector.VectorFixed+                    Data.Geometry.Vector.VectorFamily+                    Data.Geometry.Vector.VectorFamilyPeano+                     -- Data.Geometry.Vector.Vinyl                     Data.Geometry.Interval                     Data.Geometry.Interval.Util@@ -89,6 +109,8 @@                      Data.Geometry.KDTree                     Data.Geometry.PlanarSubdivision+                    Data.Geometry.PlanarSubdivision.Basic+                    Data.Geometry.PlanarSubdivision.Draw                      -- * Algorithms                     Algorithms.Util@@ -97,6 +119,8 @@                     Algorithms.Geometry.ConvexHull.GrahamScan                     Algorithms.Geometry.ConvexHull.DivideAndConqueror +                    Algorithms.Geometry.LowerEnvelope.DualCH+                     Algorithms.Geometry.SmallestEnclosingBall.Types                     Algorithms.Geometry.SmallestEnclosingBall.RandomizedIncrementalConstruction                     Algorithms.Geometry.SmallestEnclosingBall.Naive@@ -114,6 +138,14 @@                      Algorithms.Geometry.Diameter +                    Algorithms.Geometry.Sweep++                    Algorithms.Geometry.PolygonTriangulation.Types+                    Algorithms.Geometry.PolygonTriangulation.Triangulate+                    Algorithms.Geometry.PolygonTriangulation.MakeMonotone+                    Algorithms.Geometry.PolygonTriangulation.TriangulateMonotone++                    Algorithms.Geometry.LineSegmentIntersection                     Algorithms.Geometry.LineSegmentIntersection.Naive                     Algorithms.Geometry.LineSegmentIntersection.BentleyOttmann                     Algorithms.Geometry.LineSegmentIntersection.Types@@ -146,16 +178,20 @@                      Data.CircularList.Util                     Data.BalBST+                    Data.OrdSeq+                    Data.SlowSeq                     Data.Util                      -- * Planar Graphs                     Data.Permutation                     Data.PlanarGraph                     Data.PlaneGraph+                    Data.PlaneGraph.Draw                      -- * Other                     System.Random.Shuffle                     Control.Monad.State.Persistent+                    Data.Yaml.Util   @@ -167,12 +203,11 @@    -- other-extensions:   build-depends:--                  Frames           >= 0.1.3.0-                , base             >= 4.8       &&     < 5+                  base             >= 4.9       &&     < 5                 , bifunctors       >= 4.1                 , bytestring       >= 0.10                 , containers       >= 0.5.5+                , dlist            >= 0.7                 , contravariant    >= 1.4                 , lens             >= 4.2                 , linear           >= 1.10@@ -180,8 +215,11 @@                 , semigroups       >= 0.18                 , singletons       >= 2.0                 , text             >= 1.1.1.0-                , vinyl            >= 0.5       &&     < 0.6+                , vinyl            >= 0.6                 , deepseq          >= 1.1+                , fingertree       >= 0.1+                , colour           >= 2.3.3+                , reflection       >= 2.1                 -- , validation       >= 0.4 @@ -189,18 +227,22 @@                -- , tranformers      > 0.3                 , vector           >= 0.11-               , fixed-vector     >= 0.6.4.0+               , fixed-vector     >= 1.0                , data-clist       >= 0.0.7.2                 , hexpat           >= 0.20.9+               , aeson            >= 1.0+               , yaml             >= 0.8++                , mtl                , random                , template-haskell --               , time-               , directory-               , optparse-applicative+  if flag(with-quickcheck)+    build-depends: QuickCheck              >= 2.5+                 , quickcheck-instances    >= 0.3+    exposed-modules: Test.QuickCheck.HGeometryInstances     hs-source-dirs: src@@ -235,6 +277,80 @@                     , FlexibleContexts                     , MultiParamTypeClasses +executable hgeometry-viewer+  if !flag(interactive)+    buildable: False+  main-is: Viewer.hs++  if flag(interactive)+    build-depends: base+                 , hgeometry+                 , lens+                 , containers+                 , vinyl+                 , semigroups+                 , optparse-applicative   >= 0.13.0.0+                 , text+                 , hexpat+                 , bytestring+                 , directory+                 , time+                 , random+                 , vector+                 , colour+                 , cairo-canvas           >= 0.1.0.0+                 -- , sdl2                   >= 2.2.0+                 , gi-gtk                 >= 3.0.15+                 , reactive-banana-gi-gtk >= 0.2.0.0+                 , cairo                  >= 0.13.3.1+                 -- , gi-glib+                 , gi-cairo+                 , gi-gdk+                 -- , gi-gdkpixbuf+                 , gi-gtk+                 , transformers+                 , linear+                 , haskell-gi-base+                 , reactive-banana        >= 1.1.0.1++++  hs-source-dirs: interactive++  other-modules: RenderCanvas+                 RenderUtil+                 -- ConvexHull++  default-language: Haskell2010++  default-extensions: TypeFamilies+                    , GADTs+                    , KindSignatures+                    , DataKinds+                    , TypeOperators+                    , ConstraintKinds+                    , PolyKinds+                    , RankNTypes++                    , PatternSynonyms+                    , ViewPatterns++                    , StandaloneDeriving+                    , GeneralizedNewtypeDeriving+                    , DeriveFunctor+                    , DeriveFoldable+                    , DeriveTraversable++                    , DeriveDataTypeable+                    , AutoDeriveTypeable++                    , FlexibleInstances+                    , FlexibleContexts+                    , MultiParamTypeClasses++++ executable hgeometry-examples   if !flag(examples)     buildable: False@@ -246,7 +362,6 @@                  , lens                  , containers                  , vinyl-                 , Frames                  , semigroups                  , optparse-applicative   >= 0.13.0.0                  , text@@ -255,7 +370,7 @@                  , directory                  , time                  , random-+                 , QuickCheck    hs-source-dirs: examples @@ -264,7 +379,7 @@                  Demo.MinDisk                  Demo.Delaunay                  Demo.ExpectedPairwiseDistance-+                 Demo.TriangulateWorld                  Demo.GPXParser    default-language: Haskell2010@@ -300,7 +415,8 @@   type:          exitcode-stdio-1.0   ghc-options:   -threaded   main-is:       doctests.hs-  build-depends: base, doctest >= 0.8+  build-depends: base+               , doctest >= 0.8    default-language:    Haskell2010 @@ -311,32 +427,43 @@   main-is:              Spec.hs   ghc-options:   -O2 -fno-warn-unticked-promoted-constructors +  build-tool-depends: hspec-discover:hspec-discover++   other-modules: Data.RangeSpec                  Data.EdgeOracleSpec                  Data.PlanarGraphSpec+                 Data.OrdSeqSpec                  Data.Geometry.Ipe.ReaderSpec                  Data.Geometry.PolygonSpec+                 Data.Geometry.LineSegmentSpec                  Data.Geometry.PointSpec                  Data.Geometry.Polygon.Convex.ConvexSpec                  Data.Geometry.KDTreeSpec                  Data.Geometry.IntervalSpec                  Data.Geometry.BoxSpec-+                 Data.Geometry.LineSpec+                 Data.Geometry.SubLineSpec+                 Data.Geometry.PlanarSubdivisionSpec                   Algorithms.Geometry.SmallestEnclosingDisk.RISpec                  Algorithms.Geometry.DelaunayTriangulation.DTSpec                  Algorithms.Geometry.WellSeparatedPairDecomposition.WSPDSpec                  Algorithms.Geometry.LineSegmentIntersection.BentleyOttmannSpec+                 Algorithms.Geometry.PolygonTriangulation.MakeMonotoneSpec+                 Algorithms.Geometry.PolygonTriangulation.TriangulateMonotoneSpec+                 Algorithms.Geometry.LowerEnvelope.LowerEnvSpec+                 Algorithms.Geometry.ConvexHull.ConvexHullSpec -                 QuickCheck.Instances                  Util     build-depends:        base-                      , hspec        >= 2.1-                      , QuickCheck   >= 2.5+                      , hspec                >= 2.1+                      , QuickCheck           >= 2.5+                      , quickcheck-instances    >= 0.3+                      , approximate-equality >= 1.1.0.2                       , hgeometry-                      , Frames                       , lens                       , data-clist                       , linear@@ -346,6 +473,8 @@                       , vector                       , containers                       , random+                      , singletons+                      , colour    default-extensions: TypeFamilies                     , GADTs@@ -405,23 +534,38 @@  benchmark benchmarks -  hs-source-dirs: benchmark test+  hs-source-dirs: benchmark test examples    main-is: Benchmarks.hs   type: exitcode-stdio-1.0 -  other-modules:+  other-modules: Benchmark.Util+                 Algorithms.Geometry.ConvexHull.Bench+                 Algorithms.Geometry.ConvexHull.GrahamV2+                 Algorithms.Geometry.ConvexHull.GrahamFam+                 Algorithms.Geometry.ConvexHull.GrahamFamPeano+                 Algorithms.Geometry.ConvexHull.GrahamFixed+                 Data.Geometry.Vector.VectorFamily6+                 Algorithms.Geometry.ConvexHull.GrahamFam6+                 Data.Geometry.IntervalTreeBench+                 Demo.ExpectedPairwiseDistance+                 Demo.TriangulateWorld+                 WSPDBench    build-depends:                 base-              , criterion >= 1.1.4.0 && < 1.2+              , criterion >= 1.1.4.0+              , fixed-vector+              , linear               , semigroups               , deepseq               , deepseq-generics               , hgeometry-              , Frames               , lens               , QuickCheck+              , bytestring+              , containers+              , optparse-applicative    ghc-options: -Wall -O2 -rtsopts -fno-warn-unticked-promoted-constructors 
+ interactive/RenderCanvas.hs view
@@ -0,0 +1,177 @@+{-# LANGUAGE ScopedTypeVariables #-}+module RenderCanvas where++import           Control.Lens+import           Data.Colour.SRGB(RGB(..), toSRGB24)+import           Data.Colour.Names(readColourName)+import           Data.Ext+import           Data.Geometry+import           Data.Geometry.Box+import           Data.Geometry.Ipe.Attributes+import           Data.Geometry.Ipe.Types hiding (ipeObject', width)+import qualified Data.Geometry.Ipe.Attributes as A+import           Data.Proxy+import           Data.Vinyl+import           Linear.V4 (V4(..))+import           Graphics.Rendering.Cairo.Canvas (Canvas)+import qualified Graphics.Rendering.Cairo.Canvas as Canvas+import qualified Data.Text as T+++rectangle    :: (Real r, Ord r, Num r) => Rectangle p r -> Canvas ()+rectangle r' = let r                       = bimap id realToFrac r'+                   (Point2 x y :+ _,_,_,_) = corners r+               in Canvas.rect $ Canvas.D x y (width r) (height r)++polygon     :: Real r => SimplePolygon p r -> Canvas ()+polygon pg' = let pg = bimap id realToFrac pg'+              in Canvas.polygon $ pg^..outerBoundary.traverse.core.vector.to toV2++lineSegment    :: Real r => LineSegment 2 p r -> Canvas ()+lineSegment s' = let s = bimap id realToFrac s'+                 in Canvas.line (s^.start.core.vector.to toV2) (s^.end.core.vector.to toV2)++polyLine    :: Real r => PolyLine 2 p r -> Canvas ()+polyLine p' = let p = bimap id realToFrac p'+              in Canvas.shape Canvas.ShapeLines $ p^..points.traverse.core.vector.to toV2++-- | draw a point as a small disk+point   :: Real r => Point 2 r -> Canvas ()+point p = Canvas.circle' (realToFrac <$> (p^.vector.to toV2)) 5++-- | draw as a point+point'   :: Real r => Point 2 r -> Canvas ()+point' p = Canvas.point . fmap realToFrac $ p^.vector.to toV2++pathSegment                     :: Real r => PathSegment r -> Canvas ()+pathSegment (PolyLineSegment p) = polyLine p+pathSegment (PolygonPath p)     = polygon p+pathSegment _                   = error "pathSegment: Not implemented yet"+++ipeUse              :: Real r => IpeSymbol r -> Canvas ()+ipeUse (Symbol p _) = Canvas.circle' (realToFrac <$> p^.vector.to toV2) 10++ipePath          :: Real r => Path r -> Canvas ()+ipePath (Path p) = mapM_ pathSegment p++ipeGroup :: RealFrac r => Group r -> Canvas ()+ipeGroup = mapM_ ipeObject . _groupItems++ipeObject'              :: forall g r. (RealFrac r, AllSatisfy ApplyAttr (AttributesOf g))+                        => (g r -> Canvas ())+                        -> g r :+ IpeAttributes g r+                        -> Canvas ()+ipeObject' f (i :+ ats) = do+                            Canvas.pushMatrix+                            applyAttributes (Proxy :: Proxy g) ats+                            f i+                            Canvas.popMatrix++ipeObject                  :: RealFrac r+                           => IpeObject r -> Canvas ()+ipeObject (IpeGroup g)     = ipeObject' ipeGroup g+ipeObject (IpeImage _)     = undefined+ipeObject (IpeTextLabel _) = undefined+ipeObject (IpeMiniPage _)  = undefined+ipeObject (IpeUse p)       = ipeObject' ipeUse  p+ipeObject (IpePath p)      = ipeObject' ipePath p+++applyAttributes               :: (RealFrac r, AllSatisfy ApplyAttr (AttributesOf g))+                              => proxy g -> IpeAttributes g r -> Canvas ()+applyAttributes _ (Attrs ats) = applyAttributes' ats++applyAttributes'            :: (RealFrac r, AllSatisfy ApplyAttr rs)+                            => Rec (Attr (AttrMapSym1 r)) rs+                            -> Canvas ()+applyAttributes' RNil       = pure ()+applyAttributes' (a :& ats) = applyAttribute a >> applyAttributes' ats+++newtype CanvasM = CanvasM { unCanvasM :: Canvas () }+instance Monoid CanvasM where+  mempty = CanvasM $ pure ()+  (CanvasM a) `mappend` (CanvasM b) = CanvasM $ a >> b+++applyAttribute' :: (RealFrac r, ApplyAttr label)+                => Attr (AttrMapSym1 r) label -> CanvasM+applyAttribute' = CanvasM . applyAttribute+++class ApplyAttr (label :: AttributeUniverse) where+  applyAttribute :: RealFrac r => Attr (AttrMapSym1 r) label -> Canvas ()+++instance ApplyAttr Stroke where+  applyAttribute NoAttr   = pure ()+  applyAttribute (Attr c) = maybe (pure ()) Canvas.stroke $ toCanvasColor c++instance ApplyAttr Fill where+  applyAttribute NoAttr   = pure ()+  applyAttribute (Attr c) = maybe (pure ()) Canvas.fill $ toCanvasColor c++instance ApplyAttr Pen where+  applyAttribute NoAttr            = pure ()+  applyAttribute (Attr (IpePen p)) = case p of+      Named _  -> pure () -- TODO+      Valued v -> Canvas.strokeWeight (realToFrac v)++instance ApplyAttr Clip where+  applyAttribute _ = pure ()++instance ApplyAttr Size where+  applyAttribute _ = pure ()++instance ApplyAttr Dash where+  applyAttribute _ = pure ()+++instance ApplyAttr Layer where+  applyAttribute _ = pure ()++instance ApplyAttr LineCap where+  applyAttribute _ = pure ()++instance ApplyAttr LineJoin where+  applyAttribute _ = pure ()++instance ApplyAttr A.Matrix where+  applyAttribute _ = pure ()++instance ApplyAttr Pin where+  applyAttribute _ = pure ()++instance ApplyAttr FillRule where+  applyAttribute _ = pure ()++instance ApplyAttr Arrow where+  applyAttribute _ = pure ()++instance ApplyAttr RArrow where+  applyAttribute _ = pure ()++instance ApplyAttr Opacity where+  applyAttribute _ = pure ()++instance ApplyAttr Tiling where+  applyAttribute _ = pure ()++instance ApplyAttr Gradient where+  applyAttribute _ = pure ()++instance ApplyAttr Transformations where+  applyAttribute _ = pure ()+++++-- | Looks up the colorname in the SVG colors if it is a name.+toCanvasColor :: RealFrac r => IpeColor r -> Maybe Canvas.Color+toCanvasColor (IpeColor c) = case c of+    Named t            -> h . toSRGB24 <$> readColourName (T.unpack $ T.toLower t)+    Valued v           -> Just $ f v+  where+    f (RGB r g b) = floor <$> V4 (255 *r) (255*g) (255*b) 255+    h (RGB r g b) = V4 r g b 255
+ interactive/RenderUtil.hs view
@@ -0,0 +1,81 @@+{-# LANGUAGE OverloadedLabels #-}+module RenderUtil where++import           Control.Monad.IO.Class (MonadIO)+import           Control.Monad.Trans.Reader (runReaderT)+import           Data.GI.Base+import           Data.GI.Base.Signals (SignalInfo, HaskellCallbackType)+import           Data.IORef+import qualified Data.Text as T+import           Foreign.Ptr (castPtr)+import qualified GI.Cairo as GI.Cairo+import qualified GI.Gtk as Gtk+import           Graphics.Rendering.Cairo+import           Graphics.Rendering.Cairo.Canvas (Canvas)+import qualified Graphics.Rendering.Cairo.Canvas as Canvas+import qualified Graphics.Rendering.Cairo.Internal as Cairo.Internal+import           Graphics.Rendering.Cairo.Types (Cairo(Cairo))+import           Linear.V2 (V2(..))+import           Reactive.Banana+import           Reactive.Banana.Frameworks+import           Reactive.Banana.GI.Gtk+++++-- | This function bridges gi-cairo with the hand-written cairo+-- package. It takes a `GI.Cairo.Context` (as it appears in gi-cairo),+-- and a `Render` action (as in the cairo lib), and renders the+-- `Render` action into the given context.+renderWithContext      :: MonadIO m => GI.Cairo.Context -> Render a -> m a+renderWithContext ct r = liftIO $ withManagedPtr ct $ \p ->+                         runReaderT (Cairo.Internal.runRender r) (Cairo (castPtr p))+++renderCanvas           :: MonadIO m => GI.Cairo.Context -> V2 Double -> Canvas a -> m a+renderCanvas ct size c = liftIO $ Canvas.withRenderer (renderWithContext ct) size c+++showT :: Show a => a -> T.Text+showT = T.pack . show++-- | Get an 'Reactive.Banana.Event' from+-- a 'Data.GI.Base.Signals.SignalProxy' that produces one argument.+signalE1'+    ::+        ( HaskellCallbackType info ~ (a -> IO Bool)+        , SignalInfo info+        , Gtk.GObject self+        )+    => self+    -> SignalProxy self info+    -> (a -> IO b) -- ^ function to transform the Event with+    -> MomentIO (Event b)+signalE1' self signal h = signalEN self signal f >>= mapEventIO h+  where+    f g = \a -> g a >> return True -- we return True because the event has been+                                   -- handled, don't want to propagate it+                                   -- further+++draw                :: Gtk.DrawingArea -> Behavior (Canvas ()) -> MomentIO ()+draw drawingArea bc = do+    canvasRef <- liftIO . newIORef =<< valueB bc -- gets the initial canvas++    -- set up reactive-banana to update the canvasRef on changes, and triger a+    -- redraw+    c <- valueBLater bc+    liftIOLater $ writeIORef canvasRef c+    e <- changes bc+    reactimate' $ (fmap $ \c' -> do liftIO $ writeIORef canvasRef c'+                                    #queueDraw drawingArea+                  ) <$> e++    -- registers drawing event handler+    _ <- on drawingArea #draw $ \context -> do+        w <- realToFrac . fromIntegral <$> #getAllocatedWidth  drawingArea+        h <- realToFrac . fromIntegral <$> #getAllocatedHeight drawingArea+        canvas <- readIORef canvasRef+        renderCanvas context (V2 w h) canvas+        pure True+    pure ()
+ interactive/Viewer.hs view
@@ -0,0 +1,172 @@+{-# LANGUAGE OverloadedLabels #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE ScopedTypeVariables #-}+module Main where++import           Control.Exception (catch)+import           Control.Lens+import           Control.Monad (forM_)+import           Data.Ext+import           Data.GI.Base+import qualified Data.List.NonEmpty as NonEmpty+import qualified Data.Text as T+import qualified GI.Gdk as Gdk+import qualified GI.Gtk as Gtk+import           Graphics.Rendering.Cairo.Canvas (Canvas)+import qualified Graphics.Rendering.Cairo.Canvas as Canvas+import           Linear.Affine ((.-.),(.+^))+import           Linear.V2+import           Linear.Vector ((*^))+import           Reactive.Banana+import           Reactive.Banana.Frameworks+import           Reactive.Banana.GI.Gtk+import qualified RenderCanvas as Render+import           RenderUtil++main :: IO ()+main = runGtk `catch` (\(e::Gtk.GError) -> Gtk.gerrorMessage e >>= putStrLn . T.unpack)+  where+    runGtk = do+      _ <- Gtk.init Nothing+      compile networkDescription >>= actuate+      Gtk.main++data ArrowKey = UpKey | DownKey | LeftKey | RightKey deriving (Show,Read,Eq,Bounded,Enum)++toArrowKey         :: T.Text -> Maybe ArrowKey+toArrowKey "Up"    = Just UpKey+toArrowKey "Down"  = Just DownKey+toArrowKey "Left"  = Just LeftKey+toArrowKey "Right" = Just RightKey+toArrowKey _       = Nothing+++++toDirection          :: Num a => ArrowKey -> V2 a+toDirection UpKey    = V2 0    1+toDirection DownKey  = V2 0    (-1)+toDirection LeftKey  = V2 (-1) 0+toDirection RightKey = V2 1    0+++networkDescription :: MomentIO ()+networkDescription = do+    b <- Gtk.builderNew+    _ <- Gtk.builderAddFromFile b "interactive/viewport.glade"++    window   <- castB b "window" Gtk.Window+    destroyE <- signalE0 window #destroy+    reactimate $ Gtk.mainQuit <$ destroyE++    -- mouseLabel <- castB b "mouseLabel" Gtk.Label++    drawingArea  <- castB b "canvas" Gtk.DrawingArea+    drawingAreaH <- realToFrac . fromIntegral . snd <$> #getPreferredHeight drawingArea+    drawingAreaW <- realToFrac . fromIntegral . snd <$> #getPreferredWidth  drawingArea++    Gtk.widgetAddEvents drawingArea (gflagsToWord [ Gdk.EventMaskPointerMotionMask+                                                  , Gdk.EventMaskButtonPressMask+                                                  , Gdk.EventMaskSmoothScrollMask+                                                  , Gdk.EventMaskKeyPressMask+                                                  ])++    -- scroll Events+    scrollE <- signalE1' drawingArea #scrollEvent $ \e ->+                     Gdk.getEventScrollDeltaY e++    -- events when we press a key+    keyPressedE <- signalE1' drawingArea #keyPressEvent $ \e -> do+                     v  <- Gdk.getEventKeyKeyval e+                     Gdk.keyvalName v+    -- events where we press an arrow key+    let arrowKeyE = filterJust . fmap (>>= toArrowKey) $ keyPressedE++    -- handle mouse clicks+    mousePressedE <- signalE1' drawingArea #buttonPressEvent $ \e -> do+                      x <- Gdk.getEventButtonX e+                      y <- Gdk.getEventButtonY e+                      return $! V2 x ((-1*y) + drawingAreaH)++    lastMousePressB <- stepper undefined mousePressedE++    -- mouse release+    -- mouseReleasedE <- signalE1' drawingArea #buttonReleaseEvent $ \e -> do+    --                     x <- Gdk.getEventButtonX e+    --                     y <- Gdk.getEventButtonY e+    --                     return $! V2 x ((-1*y) + drawingAreaH)++    -- mouse coordinates+    mouseMotionE <- signalE1' drawingArea #motionNotifyEvent $ \e -> do+                      x  <- Gdk.getEventMotionX e+                      y  <- Gdk.getEventMotionY e+                      st <- Gdk.getEventMotionState e+                      let !p = V2 x ((-1*y) + drawingAreaH)+                      return (p,st)+    mouseMotionB  <- stepper undefined mouseMotionE++    -- difference between the current mouse position and where we clicked last+    let dragOffsetB = (\p (q,_) -> p .-. q) <$> lastMousePressB <*> mouseMotionB++        -- sample the displacement vector whenever we are have a move event+        -- and the moude button is still on+        dragOffsetE = dragOffsetB+                   <@ filterE ((Gdk.ModifierTypeButton1Mask `elem`) . snd) mouseMotionE+++    zoomLevelB <- accumB 1 $ (\dy -> (+0.1*dy)) <$> scrollE+++    let lastPosE = unions [ (\k -> (.+^ 2 *^ toDirection k)) <$> arrowKeyE   -- key event+                          , (\v -> (.+^ v))                  <$> dragOffsetE -- drag event+                          ]+    viewPortPosB <- accumB (V2 (drawingAreaW/2) (drawingAreaH/2)) $ lastPosE++    let viewPortB = ViewPort <$> pure drawWorld'+                             <*> pure (V2 drawingAreaW drawingAreaH)+                             <*> viewPortPosB+                             <*> zoomLevelB+                             <*> pure 0++    -- draw everything+    draw drawingArea (mirrored drawingAreaH render <$> viewPortB)+    #showAll window++data ViewPort a = ViewPort { drawWorld             :: Canvas a+                           , screenSize            :: V2 Double+                           , clippwingWindowCenter :: V2 Double+                           , zoomLevel             :: Double+                           , rotation              :: Double+                           }++clippingWindow :: ViewPort a -> Canvas.Dim+clippingWindow (ViewPort _ (V2 w h) (V2 cx cy) z _) = let x = cx - z*w/2+                                                          y = cy - z*h/2+                                                      in Canvas.D x y (z*w) (z*h)++-- some drawing+drawWorld' :: Canvas ()+drawWorld' = do+    Canvas.background $ Canvas.gray 255+    Canvas.stroke $ Canvas.gray 0+    forM_ [1..20] $ \i ->+      forM_ [1..16] $ \j -> do+        Canvas.rect (Canvas.D (100*i) (100*j) 20 20)++-- | Mirror the canvas s.t. the bottom-left corner is the origin+mirrored       :: Double -> (a -> Canvas ()) -> a -> Canvas ()+mirrored h d x = do Canvas.scale     $ V2 1 (-1)+                    Canvas.translate $ V2 0 (-1*h)+                    d x++-- | Render the view+render    :: ViewPort a -> Canvas a+render vp = do+    let (Canvas.D x y _ _) = clippingWindow vp++    Canvas.scale $ V2 (1/zoomLevel vp) (1/zoomLevel vp) -- scale everything s.t. the+                                                        -- cippingWindow equals+                                                        -- the window size+    Canvas.translate $ V2 (-1*x) (-1*y) -- move screen to the origin+    drawWorld vp
src/Algorithms/Geometry/ConvexHull/DivideAndConqueror.hs view
@@ -12,7 +12,8 @@ import           Data.Semigroup import           Data.Semigroup.Foldable --- | \(O(n \log n)\) time ConvexHull using divide and conqueror.+-- | \(O(n \log n)\) time ConvexHull using divide and conqueror. The resulting polygon is+-- given in clockwise order. convexHull :: (Ord r, Num r)            => NonEmpty.NonEmpty (Point 2 r :+ p) -> ConvexPolygon p r convexHull = unMerge
src/Algorithms/Geometry/ConvexHull/GrahamScan.hs view
@@ -49,8 +49,8 @@ hull'          :: (Ord r, Num r) => [Point 2 r :+ p] -> NonEmpty (Point 2 r :+ p) hull' (a:b:ps) = NonEmpty.fromList $ hull'' [b,a] ps   where-    hull'' h  []    = h-    hull'' h (p:ps) = hull'' (cleanMiddle (p:h)) ps+    hull'' h []      = h+    hull'' h (p:ps') = hull'' (cleanMiddle (p:h)) ps'      cleanMiddle h@[_,_]                         = h     cleanMiddle h@(z:y:x:rest)
src/Algorithms/Geometry/DelaunayTriangulation/Types.hs view
@@ -11,9 +11,11 @@ import qualified Data.IntMap.Strict as IM import qualified Data.Map as M import qualified Data.Map.Strict as SM-import           Data.PlaneGraph+import qualified Data.PlaneGraph  as PG+import qualified Data.PlanarGraph as PPG import qualified Data.Vector as V + --------------------------------------------------------------------------------  -- We store all adjacency lists in clockwise order@@ -80,47 +82,18 @@  -- | convert the triangulation into a planarsubdivision ----- running time: \(O(n\log n)\).-toPlanarSubdivision :: proxy s -> Triangulation p r -> PlanarSubdivision s p () () r-toPlanarSubdivision px tr = PlanarSubdivision g-  where-    g = toPlaneGraph px tr & vertexData.traverse  %~ (\(v :+ e) -> VertexData v e)-                           & dartData.traverse._2 %~ EdgeData Visible-                           & faceData.traverse    %~ FaceData []+-- running time: \(O(n)\).+toPlanarSubdivision    :: (Ord r, Fractional r)+                       => proxy s -> Triangulation p r -> PlanarSubdivision s p () () r+toPlanarSubdivision px = fromPlaneGraph . toPlaneGraph px  -- | convert the triangulation into a plane graph ----- running time: \(O(n\log n)\).+-- running time: \(O(n)\). toPlaneGraph    :: forall proxy s p r.-                   proxy s -> Triangulation p r -> PlaneGraph s Primal_ p () () r-toPlaneGraph _ tr = g & vertexData .~ tr^.positions+                   proxy s -> Triangulation p r -> PG.PlaneGraph s p () () r+toPlaneGraph _ tr = PG.PlaneGraph $ g&PPG.vertexData .~ vtxData   where-    g       = fromAdjacencyLists . V.toList . V.imap f $ tr^.neighbours+    g       = PG.fromAdjacencyLists . V.toList . V.imap f $ tr^.neighbours     f i adj = (VertexId i, VertexId <$> adj)---  -- (planarGraph' . P.toCycleRep n $ perm)&vertexData .~ tr^.positions-  -- where-  --   neighs    = C.rightElements <$> tr^.neighbours-  --   n         = sum . fmap length $ neighs--  --   vtxIDs = [0..]-  --   perm = trd' . foldr toOrbit (ST mempty 0 mempty) $ zip vtxIDs (V.toList neighs)--  --   -- | Given a vertex with its adjacent vertices (u,vs) (in CCW order) convert this-  --   -- vertex with its adjacent vertices into an Orbit-  --   toOrbit                     :: (VertexID,[VertexID]) -> ST' [[Dart s]]-  --                               -> ST' [[Dart s]]-  --   toOrbit (u,vs) (ST m a dss) =-  --     let (ST m' a' ds') = foldr (toDart . (u,)) (ST m a mempty) vs-  --     in ST m' a' (ds':dss)---  --   -- | Given an edge (u,v) and a triplet (m,a,ds) we construct a new dart-  --   -- representing this edge.-  --   toDart                   :: (VertexID,VertexID) -> ST' [Dart s] -> ST' [Dart s]-  --   toDart (u,v) (ST m a ds) = let dir = if u < v then Positive else Negative-  --                                  t'  = (min u v, max u v)-  --                              in case M.lookup t' m of-  --     Just a' -> ST m                  a     (Dart (Arc a') dir : ds)-  --     Nothing -> ST (SM.insert t' a m) (a+1) (Dart (Arc a)  dir : ds)+    vtxData = (\(loc :+ p) -> VertexData loc p) <$> tr^.positions
src/Algorithms/Geometry/EuclideanMST/EuclideanMST.hs view
@@ -25,14 +25,14 @@ -- running time: \(O(n \log n)\) euclideanMST     :: (Ord r, Fractional r)                  => NonEmpty.NonEmpty (Point 2 r :+ p) -> Tree (Point 2 r :+ p)-euclideanMST pts = (\v -> g^.vDataOf v) <$> t+euclideanMST pts = (\v -> g^.locationOf v :+ g^.dataOf v) <$> t   where     -- since we care only about the relative order of the edges we can use the     -- squared Euclidean distance rather than the Euclidean distance, thus     -- avoiding the Floating constraint     g = withEdgeDistances squaredEuclideanDist . toPlaneGraph (Proxy :: Proxy MSTW)       . delaunayTriangulation $ pts-    t = mst g+    t = mst $ g^.graph   data MSTW
+ src/Algorithms/Geometry/LineSegmentIntersection.hs view
@@ -0,0 +1,16 @@+module Algorithms.Geometry.LineSegmentIntersection where++import qualified Algorithms.Geometry.LineSegmentIntersection.BentleyOttmann as BO+import           Data.Geometry.LineSegment+import           Data.Geometry.Polygon++-- Tests if there are any interior intersections.+--+-- | \(O(n \log n)\)+hasInteriorIntersections :: (Ord r, Fractional r)+                         => [LineSegment 2 p r] -> Bool+hasInteriorIntersections = not . null . BO.interiorIntersections++-- | \(O(n \log n)\)+hasSelfIntersections :: (Ord r, Fractional r) => Polygon t p r -> Bool+hasSelfIntersections = hasInteriorIntersections . listEdges
src/Algorithms/Geometry/LineSegmentIntersection/BentleyOttmann.hs view
@@ -1,12 +1,11 @@+{-# LANGUAGE ScopedTypeVariables #-} module Algorithms.Geometry.LineSegmentIntersection.BentleyOttmann where  import           Algorithms.Geometry.LineSegmentIntersection.Types import           Control.Lens hiding (contains)-import qualified Data.BalBST as SS -- status struct import           Data.Ext-import           Data.Function (on)+import qualified Data.Foldable as F import           Data.Geometry.Interval-import           Data.Geometry.Line import           Data.Geometry.LineSegment import           Data.Geometry.Point import           Data.Geometry.Properties@@ -16,12 +15,12 @@ import qualified Data.Map as M import           Data.Maybe import           Data.Ord (Down(..), comparing)+import           Data.OrdSeq (Compare)+import qualified Data.OrdSeq as SS -- status struct import           Data.Semigroup import qualified Data.Set as EQ -- event queue import           Data.Vinyl-import           Frames.CoRec--import           Debug.Trace+import           Data.Vinyl.CoRec  -------------------------------------------------------------------------------- @@ -30,12 +29,23 @@ -- \(O((n+k)\log n)\), where \(k\) is the number of intersections. intersections    :: (Ord r, Fractional r)                  => [LineSegment 2 p r] -> Intersections p r-intersections ss = merge $ sweep pts (SS.empty $ ordAtNav undefined)+intersections ss = merge $ sweep pts mempty   where-    pts = EQ.fromAscList . groupStarts . L.sort . concatMap f $ ss-    f s = let [p,q] = L.sortBy ordPoints [s^.start.core,s^.end.core]-          in [Event p (Start $ s :| []), Event q (End s)]+    pts = EQ.fromAscList . groupStarts . L.sort . concatMap asEventPts $ ss +-- | Computes all intersection points p s.t. p lies in the interior of at least+-- one of the segments.+--+--  \(O((n+k)\log n)\), where \(k\) is the number of intersections.+interiorIntersections :: (Ord r, Fractional r)+                       => [LineSegment 2 p r] -> Intersections p r+interiorIntersections = M.filter (not . isEndPointIntersection) . intersections++-- | Computes the event points for a given line segment+asEventPts   :: Ord r => LineSegment 2 p r -> [Event p r]+asEventPts s = let [p,q] = L.sortBy ordPoints [s^.start.core,s^.end.core]+               in [Event p (Start $ s :| []), Event q (End s)]+ -- | Group the segments with the intersection points merge :: Ord r =>  [IntersectionPoint p r] -> Intersections p r merge = foldr (\(IntersectionPoint p a) -> M.insertWith (<>) p a) M.empty@@ -47,14 +57,12 @@ groupStarts (Event p (Start s) : es) = Event p (Start ss) : groupStarts rest   where     (ss',rest) = L.span sameStart es-     -- sort the segs on lower endpoint     ss         = let (x:|xs) = s in x :| (xs ++ concatMap startSegs ss')      sameStart (Event q (Start _)) = p == q     sameStart _                   = False-groupStarts (e : es)           = e : groupStarts es-+groupStarts (e : es)                 = e : groupStarts es  -------------------------------------------------------------------------------- -- * Data type for Events@@ -89,7 +97,6 @@ ordPoints     :: Ord r => Point 2 r -> Point 2 r -> Ordering ordPoints a b = let f p = (Down $ p^.yCoord, p^.xCoord) in comparing f a b - -- | Get the segments that start at the given event point startSegs   :: Event p r -> [LineSegment 2 p r] startSegs e = case eventType e of@@ -98,24 +105,30 @@  -------------------------------------------------------------------------------- --- | The navigator that we use that orders the segments that intersect at a--- horizontal line (from left to right)-ordAtNav   :: (Ord r, Fractional r) => r -> SS.TreeNavigator r (LineSegment 2 p r)-ordAtNav y = SS.Nav (\s x -> h s <= x) (min `on` h)-  where-    h s = match (s `intersect` horizontalLine y) $-         (H $ \NoIntersection -> error "ordAtNav: No intersection")-      :& (H $ \p              -> p^.xCoord)-      :& (H $ \_              -> rightEndpoint s) -- the intersection is s itself-      :& RNil+-- | Compare based on the x-coordinate of the intersection with the horizontal+-- line through y+ordAt   :: (Fractional r, Ord r) => r -> Compare (LineSegment 2 p r)+ordAt y = comparing (xCoordAt y) +-- | Given a y coord and a line segment that intersects the horizontal line+-- through y, compute the x-coordinate of this intersection point.+--+-- note that we will pretend that the line segment is closed, even if it is not+xCoordAt             :: (Fractional r, Ord r) => r -> LineSegment 2 p r -> r+xCoordAt y (LineSegment' (Point2 px py :+ _) (Point2 qx qy :+ _))+      | py == qy     = px `max` qx  -- s is horizontal, and since it by the+                                    -- precondition it intersects the sweep+                                    -- line, we return the x-coord of the+                                    -- rightmost endpoint.+      | otherwise    = px + alpha * (qx - px)+  where+    alpha = (y - py) / (qy - py)  -------------------------------------------------------------------------------- -- * The Main Sweep -type EventQueue p r = EQ.Set (Event p r)--type StatusStructure p r = SS.BalBST r (LineSegment 2 p r)+type EventQueue      p r = EQ.Set (Event p r)+type StatusStructure p r = SS.OrdSeq (LineSegment 2 p r)  -- | Run the sweep handling all events sweep       :: (Ord r, Fractional r)@@ -124,8 +137,13 @@     Nothing      -> []     Just (e,eq') -> handle e eq' ss +isClosedStart                     :: Eq r => Point 2 r -> LineSegment 2 p r -> Bool+isClosedStart p (LineSegment s e)+  | p == s^.unEndPoint.core       = isClosed s+  | otherwise                     = isClosed e+ -- | Handle an event point-handle                           :: (Ord r, Fractional r)+handle                           :: forall r p. (Ord r, Fractional r)                                  => Event p r -> EventQueue p r -> StatusStructure p r                                  -> [IntersectionPoint p r] handle e@(eventPoint -> p) eq ss = toReport <> sweep eq' ss'@@ -133,22 +151,20 @@     starts                   = startSegs e     (before,contains',after) = extractContains p ss     (ends,contains)          = L.partition (endsAt p) contains'---    toReport = case starts ++ contains' of-                 (_:_:_) -> [IntersectionPoint p $ associated (starts <> ends) contains]+    -- starting segments, exluding those that have an open starting point+    starts'  = filter (isClosedStart p) starts+    toReport = case starts' ++ contains' of+                 (_:_:_) -> [IntersectionPoint p $ associated (starts' <> ends) contains]                  _       -> []      -- new status structure-    ss' = before `SS.join` newSegs `SS.join` after-+    ss' = before <> newSegs <> after     newSegs = toStatusStruct p $ starts ++ contains      -- the new eeventqueue     eq' = foldr EQ.insert eq es-     -- the new events:-    es | SS.null newSegs = maybeToList $ app (findNewEvent p) sl sr+    es | F.null newSegs  = maybeToList $ app (findNewEvent p) sl sr        | otherwise       = let s'  = fst <$> SS.minView newSegs                                s'' = fst <$> SS.maxView newSegs                            in catMaybes [ app (findNewEvent p) sl  s'@@ -164,24 +180,22 @@ extractContains      :: (Fractional r, Ord r)                      => Point 2 r -> StatusStructure p r                      -> (StatusStructure p r, [LineSegment 2 p r], StatusStructure p r)-extractContains p ss = (before, mid1 ++ mid2, after)+extractContains p ss = (before, F.toList $ mid1 <> mid2, after)   where-    n = ordAtNav (p^.yCoord)-    SS.Split before (mid1,mid2) after = SS.splitExtract pred' sel $ ss { SS.nav = n}--    pred' s = not $ SS.goLeft n s (p^.xCoord)-    sel   s = p `onSegment` s-+    (before, mid1, after') = SS.splitOn (xCoordAt $ p^.yCoord) (p^.xCoord) ss+    -- Make sure to also select the horizontal segments containing p+    (mid2, after) = SS.splitMonotonic (\s -> not $ p `onSegment` s) after'  -- | Given a point and the linesegements that contain it. Create a piece of -- status structure for it. toStatusStruct      :: (Fractional r, Ord r)                     => Point 2 r -> [LineSegment 2 p r] -> StatusStructure p r-toStatusStruct p xs = ss { SS.nav = ordAtNav $ p^.yCoord } `SS.join` hors+toStatusStruct p xs = ss <> hors+  -- ss { SS.nav = ordAtNav $ p^.yCoord } `SS.join` hors   where     (hors',rest) = L.partition isHorizontal xs-    ss           = SS.fromList (ordAtNav $ maxY xs) rest-    hors         = SS.fromList (SS.ordNavBy rightEndpoint) hors'+    ss           = SS.fromListBy (ordAt $ maxY xs) rest+    hors         = SS.fromListBy (comparing rightEndpoint) hors'      isHorizontal s  = s^.start.core.yCoord == s^.end.core.yCoord 
src/Algorithms/Geometry/LineSegmentIntersection/Naive.hs view
@@ -11,7 +11,7 @@ import qualified Data.Map as M import           Data.Semigroup import           Data.Vinyl-import           Frames.CoRec+import           Data.Vinyl.CoRec   -- | Compute all intersections (naively)
src/Algorithms/Geometry/LineSegmentIntersection/Types.hs view
@@ -26,6 +26,7 @@                                  , _interiorTo        :: Set' (LineSegment 2 p r)                                  } deriving (Show) + instance (Eq p, Eq r) => Eq (Associated p r) where   (Associated es is) == (Associated es' is') = f es es' && f is is'     where@@ -65,6 +66,13 @@                     } deriving (Show,Eq) makeLenses ''IntersectionPoint ++-- | reports true if there is at least one segment for which this intersection+-- point is interior.+--+-- \(O(1)\)+isEndPointIntersection :: Associated p r -> Bool+isEndPointIntersection = Map.null . _interiorTo   -- newtype E a b = E (a -> b)
+ src/Algorithms/Geometry/LowerEnvelope/DualCH.hs view
@@ -0,0 +1,49 @@+{-# LANGUAGE ScopedTypeVariables #-}+module Algorithms.Geometry.LowerEnvelope.DualCH where++import Data.Maybe(fromJust)+import Control.Lens((^.))+import Data.Ext+import Data.Geometry+import Algorithms.Geometry.ConvexHull.GrahamScan+import Data.List.NonEmpty(NonEmpty(..))+import qualified Data.List.NonEmpty as NonEmpty+import Data.Geometry.Duality+import Data.Proxy+import Data.Vinyl.CoRec++type Envelope a r = NonEmpty (Line 2 r :+ a)++-- | Given a list of non-vertical lines, computes the lower envelope using+-- duality.+--+-- \(O(n\log n)\)+lowerEnvelope :: (Ord r, Fractional r) => NonEmpty (Line 2 r :+ a) -> Envelope a r+lowerEnvelope = lowerEnvelopeWith upperHull+++type UpperHullAlgorithm a r = NonEmpty (Point 2 r :+ a) -> NonEmpty (Point 2 r :+ a)++-- | Given a list of non-vertical lines, computes the lower envelope by computing+-- the upper convex hull. It uses the given algorithm to do so+--+-- running time: O(time required by the given upper hull algorithm)+lowerEnvelopeWith        :: (Fractional r, Eq r)+                         => UpperHullAlgorithm (Line 2 r :+ a) r+                         -> NonEmpty (Line 2 r :+ a) -> Envelope a r+lowerEnvelopeWith chAlgo = fromPts . chAlgo . toPts+  where+    toPts   = fmap (\l -> dualPoint' (l^.core) :+ l)+    fromPts = fmap (^.extra)++-- | Computes the vertices of the envelope, in left to right order+vertices   :: (Ord r, Fractional r) => Envelope a r -> [Point 2 r :+ (a,a)]+vertices e = zipWith intersect' (NonEmpty.toList e) (NonEmpty.tail e)+++-- | Given two non-parallel lines, compute the intersection point and+-- return the pair of a's associated with the lines+intersect'                     :: forall r a. (Ord r, Fractional r)+                               => Line 2 r :+ a -> Line 2 r :+ a -> Point 2 r :+ (a,a)+intersect' (l :+ le) (r :+ re) = (:+ (le,re)) . fromJust+                               . asA (Proxy :: Proxy (Point 2 r)) $ l `intersect` r
+ src/Algorithms/Geometry/PolygonTriangulation/MakeMonotone.hs view
@@ -0,0 +1,310 @@+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE ScopedTypeVariables #-}+module Algorithms.Geometry.PolygonTriangulation.MakeMonotone where++import           Algorithms.Geometry.LineSegmentIntersection.BentleyOttmann ( xCoordAt+                                                                            , ordAt)+import           Algorithms.Geometry.PolygonTriangulation.Types+import           Control.Lens+import           Control.Monad (forM_, when)+import           Control.Monad.Reader+import           Control.Monad.State.Strict+import           Control.Monad.Writer (WriterT, execWriterT,tell)+import           Data.Bifunctor+import           Data.CircularSeq (rotateL, rotateR, zip3LWith)+import qualified Data.DList as DList+import           Data.Ext+import qualified Data.Foldable as F+import           Data.Geometry.LineSegment+import           Data.Geometry.PlanarSubdivision.Basic+import           Data.Geometry.Point+import           Data.Geometry.Polygon+import qualified Data.IntMap as IntMap+import qualified Data.List.NonEmpty as NonEmpty+import           Data.Ord (comparing, Down(..))+import           Data.OrdSeq (OrdSeq)+import qualified Data.OrdSeq as SS+import           Data.Semigroup+import           Data.Util+import qualified Data.Vector as V+import qualified Data.Vector.Mutable as MV+++----------------------------------------------------------------------------------++data VertexType = Start | Merge | Split | End | Regular deriving (Show,Read,Eq)+++-- How about the hole vertices?++-- | assigns a vertex type to each vertex+--+-- pre: the polygon is given in CCW order+--+-- running time: \(O(n)\).+classifyVertices                     :: (Num r, Ord r)+                                     => Polygon t p r+                                     -> Polygon t (p :+ VertexType) r+classifyVertices p@(SimplePolygon _) = classifyVertices' p+classifyVertices (MultiPolygon vs h) = MultiPolygon vs' h'+  where+    (SimplePolygon vs') = classifyVertices' $ SimplePolygon vs+    h' = map (first (&extra %~ onHole) . classifyVertices') h++    -- the roles on hole vertices are slightly different+    onHole Start   = Split+    onHole Merge   = End+    onHole Split   = Start+    onHole End     = Merge+    onHole Regular = Regular++-- | assigns a vertex type to each vertex+--+-- pre: the polygon is given in CCW order+--+-- running time: \(O(n)\).+classifyVertices'                    :: (Num r, Ord r)+                                     => SimplePolygon p r+                                     -> SimplePolygon (p :+ VertexType) r+classifyVertices' (SimplePolygon vs) =+    SimplePolygon $ zip3LWith f (rotateL vs) vs (rotateR vs)+  where+    -- is the angle larger than > 180 degrees+    largeInteriorAngle p c n = case ccw (p^.core) (c^.core) (n^.core) of+           CCW -> False+           CW  -> True+           _   -> error "classifyVertices -> largeInteriorAngle: colinear points"++    f p c n = c&extra %~ (:+ vt)+      where+        vt = case (p `cmpSweep` c, n `cmpSweep` c, largeInteriorAngle p c n) of+               (LT, LT, False) -> Start+               (LT, LT, True)  -> Split+               (GT, GT, False) -> End+               (GT, GT, True)  -> Merge+               _               -> Regular++++-- | p < q = p.y < q.y || p.y == q.y && p.x > q.y+cmpSweep :: Ord r => Point 2 r :+ e -> Point 2 r :+ e -> Ordering+p `cmpSweep` q =+  comparing (^.core.yCoord) p q <> comparing (Down . (^.core.xCoord)) p q+++--------------------------------------------------------------------------------++type Event r = Point 2 r :+ (Two (LineSegment 2 Int r))++data StatusStruct r = SS { _statusStruct :: !(SS.OrdSeq (LineSegment 2 Int r))+                         , _helper       :: !(IntMap.IntMap Int)+                         -- ^ for every e_i, the id of the helper vertex+                         } deriving (Show)+makeLenses ''StatusStruct++ix'   :: Int -> Lens' (V.Vector a) a+ix' i = singular (ix i)++-- | Given a polygon, find a set of non-intersecting diagonals that partition+-- the polygon into y-monotone pieces.+--+-- running time: \(O(n\log n)\)+computeDiagonals    :: forall t r p. (Fractional r, Ord r)+                    => Polygon t p r -> [LineSegment 2 p r]+computeDiagonals p' = map f . sweep+                    . NonEmpty.sortBy (flip cmpSweep)+                    . polygonVertices . withIncidentEdges+                    . first (^._1) $ pg+  where+    -- remaps to get the p value rather than the vertexId+    f = first (\i -> vertexInfo^.ix' i._2)++    pg :: Polygon t (SP Int (p :+ VertexType)) r+    pg = numberVertices . classifyVertices . toCounterClockWiseOrder $ p'+    vertexInfo :: V.Vector (STR (Point 2 r) p VertexType)+    vertexInfo = let vs = polygonVertices pg+                     n  = F.length vs+                 in V.create $ do+                   v <- MV.new n+                   forM_ vs $ \(pt :+ SP i (p :+ vt)) ->+                     MV.write v i (STR pt p vt)+                   return v++    initialSS = SS mempty mempty++    sweep  es = flip runReader vertexInfo $ evalStateT (sweep' es) initialSS+    sweep' es = DList.toList <$> execWriterT (sweep'' es)++    sweep'' :: NonEmpty.NonEmpty (Event r) -> Sweep p r ()+    sweep'' = mapM_ handle++-- | Computes a set of diagionals that decompose the polygon into y-monotone+-- pieces.+--+-- running time: \(O(n\log n)\)+makeMonotone      :: (Fractional r, Ord r)+                  => proxy s -> Polygon t p r+                  -> PlanarSubdivision s p PolygonEdgeType PolygonFaceData r+makeMonotone px pg = let (e:es) = listEdges pg+                     in constructSubdivision px e es (computeDiagonals pg)++type Sweep p r = WriterT (DList.DList (LineSegment 2 Int r))+                   (StateT (StatusStruct r)+                     (Reader (V.Vector (VertexInfo p r))))++type VertexInfo p r = STR (Point 2 r) p VertexType+++tell' :: LineSegment 2 Int r -> Sweep p r ()+tell' = tell . DList.singleton++getIdx :: Event r -> Int+getIdx = view (extra._1.end.extra)++getVertexType   :: Int -> Sweep p r VertexType+getVertexType v = asks (^.ix' v._3)++getEventType :: Event r -> Sweep p r VertexType+getEventType = getVertexType . getIdx++handle   :: (Fractional r, Ord r) => Event r -> Sweep p r ()+handle e = let i = getIdx e in getEventType e >>= \case+    Start   -> handleStart   i e+    End     -> handleEnd     i e+    Split   -> handleSplit   i e+    Merge   -> handleMerge   i e+    Regular | isLeftVertex i e -> handleRegularL i e+            | otherwise        -> handleRegularR i e+++insertAt   :: (Ord r, Fractional r) => Point 2 r -> LineSegment 2 q r+           -> OrdSeq (LineSegment 2 q r) -> OrdSeq (LineSegment 2 q r)+insertAt v = SS.insertBy (ordAt $ v^.yCoord)++deleteAt   :: (Fractional r, Ord r) => Point 2 r -> LineSegment 2 p r+           -> OrdSeq (LineSegment 2 p r) -> OrdSeq (LineSegment 2 p r)+deleteAt v = SS.deleteAllBy (ordAt $ v^.yCoord)+++handleStart              :: (Fractional r, Ord r)+                         => Int -> Event r -> Sweep p r ()+handleStart i (v :+ adj) = modify $ \(SS t h) ->+                                SS (insertAt v (adj^._2) t)+                                   (IntMap.insert i i h)++handleEnd              :: (Fractional r, Ord r)+                       => Int -> Event r -> Sweep p r ()+handleEnd i (v :+ adj) = do let iPred = adj^._1.start.extra  -- i-1+                            -- lookup p's helper; if it is a merge vertex+                            -- we insert a new segment+                            tellIfMerge i v iPred+                            -- delete e_{i-1} from the status struct+                            modify $ \ss ->+                              ss&statusStruct %~ deleteAt v (adj^._1)++-- | Adds edge (i,j) if e_j's helper is a merge vertex+tellIfMerge       :: Int -> Point 2 r -> Int -> Sweep p r ()+tellIfMerge i v j = do SP u ut <- getHelper j+                       when (ut == Merge) (tell' $ ClosedLineSegment (v :+ i) u)++-- | Get the helper of edge i, and its vertex type+getHelper   :: Int -> Sweep p r (SP (Point 2 r :+ Int) VertexType)+getHelper i = do Just ui    <- gets (^.helper.at i)+                 STR u _ ut <- asks (^.ix' ui)+                 pure $ SP (u :+ ui) ut+++lookupLE     :: (Ord r, Fractional r)+             => Point 2 r -> OrdSeq (LineSegment 2 Int r)+             -> Maybe (LineSegment 2 Int r)+lookupLE v s = let (l,m,_) = SS.splitOn (xCoordAt $ v^.yCoord) (v^.xCoord) s+               in SS.lookupMax (l <> m)+++handleSplit              :: (Fractional r, Ord r) => Int -> Event r -> Sweep p r ()+handleSplit i (v :+ adj) = do Just ej <- gets $ \ss -> ss^.statusStruct.to (lookupLE v)+                              let j = ej^.start.extra+                              SP u _ <- getHelper j+                              -- update the status struct:+                              -- insert the new edge into the status Struct and+                              -- set the helper of e_j to be v_i+                              modify $ \(SS t h) ->+                                SS (insertAt v (adj^._2) t)+                                   (IntMap.insert i i . IntMap.insert j i $ h)+                              -- return the diagonal+                              tell' $ ClosedLineSegment (v :+ i) u++handleMerge              :: (Fractional r, Ord r) => Int -> Event r -> Sweep p r ()+handleMerge i (v :+ adj) = do let ePred = adj^._1.start.extra -- i-1+                              tellIfMerge i v ePred+                              -- delete e_{i-1} from the status struct+                              modify $ \ss -> ss&statusStruct %~ deleteAt v (adj^._1)+                              connectToLeft i v++-- | finds the edge j to the left of v_i, and connect v_i to it if the helper+-- of j is a merge vertex+connectToLeft     :: (Fractional r, Ord r) => Int -> Point 2 r -> Sweep p r ()+connectToLeft i v = do Just ej <- gets $ \ss -> ss^.statusStruct.to (lookupLE v)+                       let j = ej^.start.extra+                       tellIfMerge i v j+                       modify $ \ss -> ss&helper %~ IntMap.insert j i++-- | returns True if v the interior of the polygon is to the right of v+isLeftVertex              :: Ord r => Int -> Event r -> Bool+isLeftVertex i (v :+ adj) = case (adj^._1.start) `cmpSweep` (v :+ i) of+                              GT -> True+                              _  -> False+  -- if the predecessor occurs before the sweep, this must be a left vertex++handleRegularL              :: (Fractional r, Ord r) => Int -> Event r -> Sweep p r ()+handleRegularL i (v :+ adj) = do let ePred = adj^._1.start.extra -- i-1+                                 tellIfMerge i v ePred+                                 -- delete e_{i-1} from the status struct+                                 modify $ \ss ->+                                   ss&statusStruct %~ deleteAt v (adj^._1)+                                 -- insert a e_i in the status struct, and set its helper+                                 -- to be v_i+                                 modify $ \(SS t h) ->+                                     SS (insertAt v (adj^._2) t)+                                        (IntMap.insert i i h)++handleRegularR            :: (Fractional r, Ord r) => Int -> Event r -> Sweep p r ()+handleRegularR i (v :+ _) = connectToLeft i v+++++--------------------------------------------------------------------------------+++-- testPolygon :: SimplePolygon Int Rational+-- testPolygon = fromPoints [ point2 20 20 :+ 1+--                          , point2 18 19 :+ 2+--                          , point2 16 25 :+ 3+--                          , point2 13 23 :+ 4+--                          , point2 10 24 :+ 5+--                          , point2 6  22 :+ 6+--                          , point2 8  21 :+ 7+--                          , point2 7  18 :+ 8+--                          , point2 2  19 :+ 9+--                          , point2 1  10 :+ 10+--                          , point2 3  5  :+ 11+--                          , point2 11 7  :+ 12+--                          , point2 15 1  :+ 13+--                          , point2 12 15 :+ 14+--                          , point2 15 12 :+ 15+--                          ]++-- vertexTypes = [Start,Merge,Start,Merge,Start,Regular,Regular,Merge,Start,Regular,End,Split,End,Split,End]+++-- loadT = do pgs <- readAllFrom "/Users/frank/tmp/testPoly.ipe"+--                         :: IO [SimplePolygon () Rational :+ IpeAttributes Path Rational]+--            mapM_ print pgs+--            let diags = map (computeDiagonals . (^.core)) pgs+--                f = asIpeGroup . map (asIpeObject' mempty)+--                out = [ asIpeGroup $ map (\(pg :+ a) -> asIpeObject pg a) pgs+--                      , asIpeGroup $ map f diags+--                      ]+--                outFile = "/Users/frank/tmp/out.ipe"+--            writeIpeFile outFile . singlePageFromContent $ out
+ src/Algorithms/Geometry/PolygonTriangulation/Triangulate.hs view
@@ -0,0 +1,70 @@+module Algorithms.Geometry.PolygonTriangulation.Triangulate where+++import qualified Algorithms.Geometry.PolygonTriangulation.MakeMonotone as MM+import qualified Algorithms.Geometry.PolygonTriangulation.TriangulateMonotone as TM+import           Algorithms.Geometry.PolygonTriangulation.Types+import           Control.Lens+import           Data.Either (lefts)+import           Data.Ext+import qualified Data.Foldable as F+import           Data.Geometry.LineSegment+import           Data.Geometry.PlanarSubdivision.Basic+import           Data.Geometry.Polygon+import           Data.PlaneGraph (PlaneGraph)+import           Data.Semigroup++-- | Triangulates a polygon of \(n\) vertices+--+-- running time: \(O(n \log n)\)+triangulate        :: (Ord r, Fractional r)+                   => proxy s -> Polygon t p r+                   -> PlanarSubdivision s p PolygonEdgeType PolygonFaceData r+triangulate px pg' = constructSubdivision px e es diags+  where+    (pg, diags)   = computeDiagonals' pg'+    (e:es)        = listEdges pg+++-- | Triangulates a polygon of \(n\) vertices+--+-- running time: \(O(n \log n)\)+triangulate'        :: (Ord r, Fractional r)+                   => proxy s -> Polygon t p r+                   -> PlaneGraph s p PolygonEdgeType PolygonFaceData r+triangulate' px pg' = constructGraph px e es diags+  where+    (pg, diags)   = computeDiagonals' pg'+    (e:es)        = listEdges pg+++-- | Computes a set of diagaonals that together triangulate the input polygon+-- of \(n\) vertices.+--+-- running time: \(O(n \log n)\)+computeDiagonals :: (Ord r, Fractional r) => Polygon t p r -> [LineSegment 2 p r]+computeDiagonals = snd . computeDiagonals'++-- | Computes a set of diagaonals that together triangulate the input polygon+-- of \(n\) vertices. Returns a copy of the input polygon, whose boundaries are+-- oriented in counter clockwise order, as well.+--+-- running time: \(O(n \log n)\)+computeDiagonals'     :: (Ord r, Fractional r)+                      => Polygon t p r -> (Polygon t p r, [LineSegment 2 p r])+computeDiagonals' pg' = (pg, monotoneDiags <> extraDiags)+  where+    pg            = toCounterClockWiseOrder pg'+    monotoneP     = MM.makeMonotone (Identity pg') pg -- use some arbitrary proxy type+    -- outerFaceId'  = outerFaceId monotoneP++    monotoneDiags = map (^._2.core) . filter (\e' -> e'^._2.extra == Diagonal)+                  . F.toList . edgeSegments $ monotoneP+    extraDiags    = concatMap (TM.computeDiagonals . toCounterClockWiseOrder')+                  . lefts . map (^._2.core)+                  -- . filter (\f -> f^._1 /= outerFaceId')+                  . F.toList . rawFacePolygons $ monotoneP++    -- we alredy know we get the polgyons in *clockwise* order, so skip the+    -- check if it is counter clockwise+    toCounterClockWiseOrder' = reverseOuterBoundary
+ src/Algorithms/Geometry/PolygonTriangulation/TriangulateMonotone.hs view
@@ -0,0 +1,178 @@+module Algorithms.Geometry.PolygonTriangulation.TriangulateMonotone where++import           Control.Lens+import           Data.Bifunctor+import qualified Data.CircularSeq as C+import           Data.Ext+import qualified Data.Foldable as F+import           Data.Geometry.LineSegment+import           Data.Geometry.Point+import           Data.Geometry.Polygon+import qualified Data.List as L+import           Data.Ord (comparing, Down(..))+import           Data.Semigroup+import           Data.Util+import           Algorithms.Geometry.PolygonTriangulation.Types+import           Data.PlaneGraph (PlaneGraph)+import           Data.Geometry.PlanarSubdivision.Basic(PolygonFaceData, PlanarSubdivision)++--------------------------------------------------------------------------------++--+type MonotonePolygon p r = SimplePolygon p r++data LR = L | R deriving (Show,Eq)++-- | Triangulates a polygon of \(n\) vertices+--+-- running time: \(O(n \log n)\)+triangulate        :: (Ord r, Fractional r)+                   => proxy s -> MonotonePolygon p r+                   -> PlanarSubdivision s p PolygonEdgeType PolygonFaceData r+triangulate px pg' = constructSubdivision px e es (computeDiagonals pg)+  where+    pg     = toCounterClockWiseOrder pg'+    (e:es) = listEdges pg+  -- TODO: Find a way to construct the graph in O(n) time.++-- | Triangulates a polygon of \(n\) vertices+--+-- running time: \(O(n \log n)\)+triangulate'        :: (Ord r, Fractional r)+                    => proxy s -> MonotonePolygon p r+                    -> PlaneGraph s p PolygonEdgeType PolygonFaceData r+triangulate' px pg' = constructGraph px e es (computeDiagonals pg)+  where+    pg     = toCounterClockWiseOrder pg'+    (e:es) = listEdges pg+  -- TODO: Find a way to construct the graph in O(n) time.+++-- | Given a y-monotone polygon in counter clockwise order computes the diagonals+-- to add to triangulate the polygon+--+-- pre: the input polygon is y-monotone and has \(n \geq 3\) vertices+--+-- running time: \(O(n)\)+computeDiagonals    :: (Ord r, Num r)+                    => MonotonePolygon p r -> [LineSegment 2 p r]+computeDiagonals pg = diags'' <> diags'+  where+    -- | run the stack computation+    SP (_:stack') diags' = L.foldl' (\(SP stack acc) v' -> (<> acc) <$> process v' stack)+                                    (SP [v,u] []) vs'+    -- add vertices from the last guy w to all 'middle' guys of the final stack+    diags'' = map (seg w) $ init stack'+    -- extract the last vertex+    Just (vs',w) = unsnoc vs+    -- merge the two lists into one list for procerssing+    (u:v:vs) = uncurry (mergeBy $ comparing (\(Point2 x y :+ _) -> (Down y, x)))+             $ splitPolygon pg+++type P p r = Point 2 r :+ (LR :+ p)++type Stack a = [a]+++++-- type Scan p r = State (Stack (P p r))++chainOf :: P p r -> LR+chainOf = (^.extra.core)++toVtx :: P p r -> Point 2 r :+ p+toVtx = (&extra %~ (^.extra))++seg     :: P p r -> P p r -> LineSegment 2 p r+seg u v = ClosedLineSegment (toVtx u) (toVtx v)++process                    :: (Ord r, Num r)+                           => P p r -> Stack (P p r)+                           -> SP (Stack (P p r)) [LineSegment 2 p r]+process _ []               = error "TriangulateMonotone.process: absurd. empty stack"+process v stack@(u:ws)+  | chainOf v /= chainOf u = SP [v,u]      (map (seg v) . init $ stack)+  | otherwise              = SP (v:w:rest) (map (seg v) popped)+      where+        (popped,rest) = bimap (map fst) (map fst) . L.span (isInside v) $ zip ws stack+        w             = last $ u:popped+++-- | test if m does not block the line segment from v to u+isInside          :: (Ord r, Num r) => P p r -> (P p r, P p r) -> Bool+isInside v (u, m) = case ccw' v m u of+                     CoLinear -> False+                     CCW      -> chainOf v == R+                     CW       -> chainOf v == L++-- | given a comparison function, merge the two ordered lists+mergeBy     :: (a -> a -> Ordering) -> [a] -> [a] -> [a]+mergeBy cmp = go+  where+    go []     ys     = ys+    go xs     []     = xs+    go (x:xs) (y:ys) = case x `cmp` y of+                         GT -> y : go (x:xs) ys+                         _  -> x : go xs     (y:ys)+++-- | When the polygon is in counter clockwise order we return (leftChain,rightChain)+-- ordered from the top-down.+--+-- if there are multiple points with the maximum yCoord we pick the rightmost one,+-- if there are multiple point with the minimum yCoord we pick the leftmost one.+--+-- running time: \(O(n)\)+splitPolygon    :: Ord r => MonotonePolygon p r+                -> ([Point 2 r :+ (LR :+ p)], [Point 2 r :+ (LR :+ p)])+splitPolygon pg = bimap (f L) (f R)+                . second reverse+                . L.break (\v -> v^.core == vMinY)+                . F.toList . C.rightElements $ vs'+  where+    f x = map (&extra %~ (x :+))+    -- rotates the list to the vtx with max ycoord+    Just vs' = C.findRotateTo (\v -> v^.core == vMaxY)+             $ pg^.outerBoundary+    vMaxY = getY F.maximumBy+    vMinY = getY F.minimumBy+    swap' (Point2 x y) = Point2 y x+    getY ff = let p = ff (comparing (^.core.to swap')) $ pg^.outerBoundary+              in p^.core++++--------------------------------------------------------------------------------++-- testPolygon = fromPoints . map ext $ [ point2 10 10+--                                      , point2 5 20+--                                      , point2 3 14+--                                      , point2 1 1+--                                      , point2 8 8 ]+++++++testPoly5 :: SimplePolygon () Rational+testPoly5 = toCounterClockWiseOrder . fromPoints $ map ext $ [ Point2 176 736+                                                             , Point2 240 688+                                                             , Point2 240 608+                                                             , Point2 128 576+                                                             , Point2 64 640+                                                             , Point2 80 720+                                                             , Point2 128 752+                                                             ]+++-- testPoly5 :: SimplePolygon () Rational+-- testPoly5 = toCounterClockWiseOrder . fromPoints $ map ext $ [ Point2 320 320+--                                                              , Point2 256 320+--                                                              , Point2 224 320+--                                                              , Point2 128 240+--                                                              , Point2 64 224+--                                                              , Point2 256 192+--                                                              ]
+ src/Algorithms/Geometry/PolygonTriangulation/Types.hs view
@@ -0,0 +1,138 @@+{-# LANGUAGE ScopedTypeVariables #-}+module Algorithms.Geometry.PolygonTriangulation.Types where++import           Control.Lens+import           Control.Monad (forM_)+import           Data.Ext+import qualified Data.Foldable as F+import           Data.Geometry.LineSegment+import           Data.Geometry.PlanarSubdivision.Basic+import qualified Data.List.NonEmpty as NonEmpty+import           Data.List.NonEmpty (NonEmpty(..))+import qualified Data.PlaneGraph as PG+import           Data.Semigroup+import qualified Data.Vector as V+import qualified Data.Vector.Mutable as MV+--------------------------------------------------------------------------------++data PolygonEdgeType = Original | Diagonal+                     deriving (Show,Read,Eq)++-- | Given a list of original edges and a list of diagonals, creates a+-- planar-subdivision+--+--+-- running time: \(O(n\log n)\)+constructSubdivision                  :: forall proxy r s p. (Fractional r, Ord r)+                                      => proxy s+                                      -> LineSegment 2 p r -- ^ A counter-clockwise+                                                         -- edge along the outer+                                                         -- boundary+                                      -> [LineSegment 2 p r] -- ^ remaining original edges+                                      -> [LineSegment 2 p r] -- ^ diagonals+                                      -> PlanarSubdivision s+                                            p PolygonEdgeType PolygonFaceData r+constructSubdivision px e origs diags = fromPlaneGraph $ constructGraph px e origs diags++-- constructSubdivision px e origs diags =+--     subdiv & rawVertexData.traverse.dataVal  %~ NonEmpty.head+--            & rawFaceData                     %~ V.zipWith zipF faceData'+--            & rawDartData.traverse.dataVal    %~ snd+--   where+--     subdiv :: PlanarSubdivision s (NonEmpty p) (Bool,PolygonEdgeType) () r+--     subdiv = fromConnectedSegments px $ e' : origs' <> diags'++--     diags' = (:+ (True, Diagonal)) <$> diags+--     origs' = (:+ (False,Original)) <$> origs+--     e'     = e :+ (True, Original)++--     -- the darts incident to internal faces+--     queryDarts = concatMap shouldQuery . F.toList . edges' $ subdiv+--     shouldQuery d = case subdiv^.dataOf d of+--                       (True, Original) -> [d]+--                       (True, Diagonal) -> [d, twin d]+--                       _                -> []++--     -- the interior faces+--     intFaces = flip leftFace subdiv <$> queryDarts+--     faceData' = V.create $ do+--                   v' <- MV.replicate (numFaces subdiv) Outside+--                   forM_ intFaces $ \(PG.FaceId (PG.VertexId f)) ->+--                     MV.write v' f Inside+--                   pure v'++--     -- set the inside/outside data value+--     zipF x rfd = rfd&dataVal .~ x+-- -- TODO: Idea: generalize the face data assignment into a function+-- -- that does something like: [(Dart, fLeft, fRight] -> FaceData+++-- | Given a list of original edges and a list of diagonals, creates a+-- planar-subdivision+--+--+-- running time: \(O(n\log n)\)+constructGraph                  :: forall proxy r s p. (Fractional r, Ord r)+                                      => proxy s+                                      -> LineSegment 2 p r -- ^ A counter-clockwise+                                                         -- edge along the outer+                                                         -- boundary+                                      -> [LineSegment 2 p r] -- ^ remaining original edges+                                      -> [LineSegment 2 p r] -- ^ diagonals+                                      -> PG.PlaneGraph s+                                            p PolygonEdgeType PolygonFaceData r+constructGraph px e origs diags =+    subdiv & PG.vertexData.traverse  %~ NonEmpty.head+           & PG.faceData             .~ faceData'+           & PG.rawDartData.traverse  %~ snd+  where+    subdiv :: PG.PlaneGraph s (NonEmpty p) (Bool,PolygonEdgeType) () r+    subdiv = PG.fromConnectedSegments px $ e' : origs' <> diags'++    diags' = (:+ (True, Diagonal)) <$> diags+    origs' = (:+ (False,Original)) <$> origs+    e'     = e :+ (True, Original)++    -- the darts incident to internal faces+    queryDarts = concatMap shouldQuery . F.toList . PG.edges' $ subdiv+    shouldQuery d = case subdiv^.dataOf d of+                      (True, Original) -> [d]+                      (True, Diagonal) -> [d, twin d]+                      _                -> []++    -- the interior faces+    intFaces = flip PG.leftFace subdiv <$> queryDarts+    faceData' :: V.Vector PolygonFaceData+    faceData' = V.create $ do+                  v' <- MV.replicate (PG.numFaces subdiv) Outside+                  forM_ intFaces $ \(PG.FaceId (PG.VertexId f)) ->+                    MV.write v' f Inside+                  pure v'++-- -constructSubdivision px e origs diags =+-- -    subdiv & planeGraph.PG.vertexData.traverse        %~ NonEmpty.head+-- -           & planeGraph.PG.faceData                   .~ faceData'+-- -           & planeGraph.PG.rawDartData.traverse.eData %~ snd+-- -  where+-- -    subdiv = fromConnectedSegments px $ e' : origs' <> diags'+-- -+-- -    diags' = (:+ EdgeData Visible (True, Diagonal)) <$> diags+-- -    origs' = (:+ EdgeData Visible (False,Original)) <$> origs+-- -    e'     = e :+ EdgeData Visible (True, Original)+-- -+-- -    g = subdiv^.planeGraph+-- -+-- -    -- the darts incident to internal faces+-- -    queryDarts = concatMap shouldQuery . F.toList . PG.edges' $ g+-- -    shouldQuery d = case g^.dataOf d.eData of+-- -                      (True, Original) -> [d]+-- -                      (True, Diagonal) -> [d, twin d]+-- -                      _                -> []+-- -+-- -    -- the interior faces+-- -    intFaces = flip PG.leftFace g <$> queryDarts+-- -    faceData' = V.create $ do+-- -                  v' <- MV.replicate (PG.numFaces g) (FaceData [] Outside)+-- -                  forM_ intFaces $ \(PG.FaceId (PG.VertexId f)) ->+-- -                    MV.write v' f (FaceData [] Inside)+-- -                  pure v'
+ src/Algorithms/Geometry/Sweep.hs view
@@ -0,0 +1,151 @@+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE UndecidableInstances #-}+module Algorithms.Geometry.Sweep where++import qualified Data.Map as Map+import           Data.Map (Map)+import           Data.Proxy+import           Data.Reflection+import           Unsafe.Coerce++++newtype Tagged (s :: *) a = Tagged { unTag :: a} deriving (Show,Eq,Ord)++tag   :: proxy s -> a -> Tagged s a+tag _ = Tagged++newtype Timed s t a = Timed {atTime :: (Tagged s t) -> a }+++instance (Reifies s t, Ord k) => Ord (Timed s t k) where+  compare = compare_++instance (Reifies s t, Ord k) => Eq (Timed s t k) where+  a == b = a `compare` b == EQ++compare_                       :: forall s t k. (Ord k, Reifies s t)+                               => Timed s t k -> Timed s t k+                               -> Ordering+(Timed f) `compare_` (Timed g) = let t = reflect (Proxy :: Proxy s)+                                 in f (Tagged t) `compare` g (Tagged t)+++coerceTo :: proxy s -> f (Timed s' t k) v -> f (Timed s t k) v+coerceTo _ = unsafeCoerce++unTagged :: f (Timed s t k) v -> f (Timed () t k) v+unTagged = coerceTo (Proxy :: Proxy ())+++-- | Runs a computation at a given time.+runAt       :: forall s0 t k r f v. Ord k+            => t+            -> f (Timed s0 t k) v+            -> (forall s. Reifies s t => f (Timed s t k) v -> r)+            -> r+runAt t m f = reify t $ \prx -> f (coerceTo prx m)++getTime :: Timed s Int Int+getTime = Timed unTag++constT   :: proxy s -> Int -> Timed s Int Int+constT _ i = Timed (const i)+++test1 i = reify 5 $ \prx -> getTime < constT prx i++++++test2M   :: Reifies s Int => proxy s -> Map (Timed s Int Int) String+test2M p = Map.fromList [ (constT p 10, "ten")+                        , (getTime, "timed")+                        ]+++query :: forall s v. Ord (Timed s Int Int)+      => Map (Timed s Int Int) v -> Maybe v+query = fmap snd . Map.lookupGE (constT (Proxy :: Proxy s) 4)+++test2   :: Int -> Maybe String+test2 t = runAt t m query+  where+    m :: Map (Timed () Int Int) String+    m = reify 0 $ \p -> unTagged $ test2M p++++++-- test2 = reify 0 $ \p0 ->+--                     let m = unTagged $ test2M p0+--                     in runAt 10 m Map.lookup++++-- newtype Key s a b = Key { getKey :: a -> b }++-- instance (Eq b, Reifies s a) => Eq (Key s a b) where+--   (Key f) == (Key g) = let x = reflect (Proxy :: Proxy s)+--                        in f x == g x++-- instance (Ord b, Reifies s a) => Ord (Key s a b) where+--   Key f `compare` Key g = let x = reflect (Proxy :: Proxy s)+--                           in f x `compare` g x+++-- -- | Query the sweep+-- queryAt       :: a+--               -> (forall (s :: *). Reifies s a => Map (Key s a b) v -> res)+--               -> Map (a -> b) v -> res+-- queryAt x f m = reify x (\p -> f . coerceKeys p $ m)++-- updateAt      :: a+--               -> (forall (s :: *). Reifies s a =>+--                    Map (Key s a b) v -> Map (Key s a b) v')+--               -> Map (a -> b) v+--               -> Map (a -> b) v'+-- updateAt x f m = reify x (\p -> uncoerceKeys . f . coerceKeys p $ m)+++-- combineAt            :: a+--                      -> (forall (s :: *). Reifies s a =>+--                            Map (Key s a b) v -> Map (Key s a b) v+--                            -> Map (Key s a b) v)+--                      -> Map (a -> b) v+--                      -> Map (a -> b) v+--                      -> Map (a -> b) v+-- combineAt x uF m1 m2 = reify x (\p -> uncoerceKeys $+--                                         coerceKeys p m1 `uF` coerceKeys p m2)+++-- splitLookupAt       :: Ord b+--                     => a+--                     -> (a -> b)+--                     -> Map (a -> b) v+--                     -> (Map (a -> b) v, Maybe v, Map (a -> b) v)+-- splitLookupAt x k m = reify x (\p -> let (l,mv,r) = Map.splitLookup (Key k)+--                                                   $ coerceKeys p m+--                                    in (uncoerceKeys l, mv, uncoerceKeys r))+++-- --------------------------------------------------------------------------------++-- coerceKeys   :: proxy s -> Map (a -> b) v -> Map (Key s a b) v+-- coerceKeys _ = unsafeCoerce++-- uncoerceKeys :: Map (Key s a b) v -> Map (a -> b) v+-- uncoerceKeys = unsafeCoerce+++-- --------------------------------------------------------------------------------+++-- data Node a = Node2 a a+--             | Node3 a a a++-- data FT a = Single a+--           | Deep (FT (Node a)) a (FT (Node a))
src/Algorithms/Geometry/WellSeparatedPairDecomposition/Types.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE UndecidableInstances  #-} module Algorithms.Geometry.WellSeparatedPairDecomposition.Types where  import           Control.Lens hiding (Level)
src/Algorithms/Geometry/WellSeparatedPairDecomposition/WSPD.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE TemplateHaskell  #-} {-# LANGUAGE LambdaCase  #-} module Algorithms.Geometry.WellSeparatedPairDecomposition.WSPD where @@ -36,10 +35,8 @@ -- | Construct a split tree -- -- running time: \(O(n \log n)\)-fairSplitTree     :: (Fractional r, Ord r, Arity d, Index' 0 d,-                      KnownNat d-                        , Show r, Show p-+fairSplitTree     :: (Fractional r, Ord r, Arity d, 1 <= d+                     , Show r, Show p                      )                   => NonEmpty.NonEmpty (Point d r :+ p) -> SplitTree d p r () fairSplitTree pts = foldUp node' Leaf $ fairSplitTree' n pts'@@ -62,7 +59,7 @@ -- | Given a split tree, generate the Well separated pairs -- -- running time: \(O(s^d n)\)-wellSeparatedPairs   :: (Floating r, Ord r, AlwaysTrueWSPD d)+wellSeparatedPairs   :: (Floating r, Ord r, Arity d, Arity (d + 1))                      => r -> SplitTree d p r a -> [WSP d p r a] wellSeparatedPairs s = f   where@@ -107,7 +104,7 @@ -- (PointSeq))'s. Since we have the level assignment, we can compute these -- lists by traversing each original input list (i.e. one for every dimension) -- once, and partition the points based on their level assignment.-fairSplitTree'       :: (Fractional r, Ord r, Arity d, Index' 0 d, KnownNat d+fairSplitTree'       :: (Fractional r, Ord r, Arity d, 1 <= d                         , Show r, Show p                         )                      => Int -> GV.Vector d (PointSeq d (Idx :+ p) r)@@ -187,7 +184,7 @@ -- time. -- -- so, basically, run reIndex points in ST as well.-reIndexPoints      :: (Arity d, Index' 0 d)+reIndexPoints      :: (Arity d, 1 <= d)                    => GV.Vector d (PointSeq d (Idx :+ p) r)                    -> GV.Vector d (PointSeq d (Idx :+ p) r) reIndexPoints ptsV = fmap reIndex ptsV@@ -357,10 +354,10 @@ -------------------------------------------------------------------------------- -- * Finding Well Separated Pairs -type AlwaysTrueWSPD d = ( Arity d, KnownNat d-                        , AlwaysTruePFT d, AlwaysTrueTransformation d)+-- type AlwaysTrueWSPD d = ( Arity d, KnownNat d+--                         , AlwaysTruePFT d, AlwaysTrueTransformation d) -findPairs                     :: (Floating r, Ord r, AlwaysTrueWSPD d)+findPairs                     :: (Floating r, Ord r, Arity d, Arity (d + 1))                               => r -> SplitTree d p r a -> SplitTree d p r a                               -> [WSP d p r a] findPairs s l r@@ -370,7 +367,7 @@   -- | Test if the two sets are well separated with param s-areWellSeparated                     :: ( AlwaysTrueWSPD d, Fractional r, Ord r)+areWellSeparated                     :: (Arity d, Arity (d + 1), Fractional r, Ord r)                                      => r -- ^ separation factor                                      -> SplitTree d p r a                                      -> SplitTree d p r a -> Bool@@ -392,7 +389,7 @@ --     b' = translateBy v . scaleUniformlyBy s . translateBy ((-1) *^ v) $ b  -- | Test if the two boxes are sufficiently far appart-boxBox         :: (Fractional r, Ord r, AlwaysTruePFT d, AlwaysTrueTransformation d)+boxBox         :: (Fractional r, Ord r, Arity d, Arity (d + 1))                => r -> Box d p r -> Box d p r -> Bool boxBox s lb rb = boxBox' lb rb && boxBox' rb lb   where
src/Control/Monad/State/Persistent.hs view
@@ -13,7 +13,7 @@  -- | A State monad that can store earlier versions of the state. newtype PersistentStateT s m a =-  PersistentStateT { runPersistentStateT' :: StateT (NonEmpty s) m a }+  PersistentStateT (StateT (NonEmpty s) m a)   deriving (Functor,Applicative,Monad)            -- We store all the versions in reverse order 
src/Data/BalBST.hs view
@@ -1,6 +1,7 @@ {-# LANGUAGE RecordWildCards #-} module Data.BalBST where +import           Control.Applicative((<|>)) import           Data.Bifunctor import           Data.Function (on) import           Data.Functor.Contravariant@@ -93,8 +94,16 @@ member   :: Eq a => a -> BalBST k a -> Bool member x = isJust . lookup x --+-- | Search for the Predecessor+-- \(O(\log n)\)+lookupLE :: Ord k => k -> BalBST k a -> Maybe a+lookupLE kx (BalBST n@Nav{..} t) = lookup' t+  where+    lookup' Empty            = Nothing+    lookup' (Leaf y)         = if goLeft y kx then Just y else Nothing+    lookup' (Node _ _ l k r)+      | kx <= k              = lookup' l+      | otherwise            = lookup' r <|> lookupMax (BalBST n l)   -- | Insert an element in the BST.@@ -115,8 +124,15 @@  -- delete = undefined --- delete                        :: Eq a => a -> BalBST k a -> BalBST k a--- delete x (BalBST n@Nav{..} t) = delete' t+-- | Delete (one occurance of) an element.+-- \(O(\log n)\)+delete                        :: Eq a => a -> BalBST k a -> BalBST k a+delete x t = let Split l _ r = split x t+                 n           = nav t+             in BalBST n $ joinWith n l r+++-- (BalBST n@Nav{..} t) = delete' t --   where --     delete' Empty      = Empty --     delete' l@(Leaf y) = if x == y then Empty else l@@ -136,6 +152,9 @@     minView' (Leaf x)         = Just (x,Empty)     minView' (Node _ _ l _ r) = fmap (flip (joinWith n) r) <$> minView' l +lookupMin :: BalBST k b -> Maybe b+lookupMin = fmap fst . maxView+ -- | Extract the maximum from the tree -- \(O(\log n)\) maxView              :: BalBST k a -> Maybe (a, Tree k a)@@ -144,6 +163,10 @@     maxView' Empty            = Nothing     maxView' (Leaf x)         = Just (x,Empty)     maxView' (Node _ _ l _ r) = fmap (joinWith n l) <$> maxView' r++lookupMax :: BalBST k b -> Maybe b+lookupMax = fmap fst . maxView+  -- | Joins two BSTs. Assumes that the ranges are disjoint. It takes the left Tree nav --
src/Data/CircularSeq.hs view
@@ -32,17 +32,19 @@                        , isShiftOf                        ) where +import           Control.DeepSeq import           Control.Lens (lens, Lens', bimap) import qualified Data.Foldable as F import qualified Data.List as L import qualified Data.List.NonEmpty as NonEmpty import           Data.Maybe (listToMaybe) import           Data.Semigroup-import           Data.Semigroup.Foldable+import           Data.Semigroup.Foldable hiding (toNonEmpty) import           Data.Sequence ((|>),(<|),ViewL(..),ViewR(..),Seq) import qualified Data.Sequence as S import qualified Data.Traversable as T import           Data.Tuple (swap)+import           GHC.Generics (Generic)  -------------------------------------------------------------------------------- @@ -52,7 +54,10 @@  -- | Nonempty circular sequence data CSeq a = CSeq !(Seq a) !a !(Seq a)+  deriving (Generic)                      -- we keep the seq balanced, i.e. size left >= size right++instance NFData a => NFData (CSeq a)  instance Eq a => Eq (CSeq a) where   a == b = asSeq a == asSeq b
src/Data/Ext.hs view
@@ -1,7 +1,14 @@ {-# LANGUAGE DeriveAnyClass  #-}+{-# LANGUAGE OverloadedStrings  #-}+{-|+Module    : Data.Ext+Description: A pair-like data type to represent a 'core' type that has extra information as well.+Copyright : (c) Frank Staals+License : See LICENCE file+-} module Data.Ext where -import Control.Lens+import Control.Lens hiding ((.=)) import Data.Biapplicative import Data.Bifoldable import Data.Bifunctor.Apply@@ -12,9 +19,12 @@ import Data.Semigroup.Bitraversable import GHC.Generics (Generic) import Control.DeepSeq-+import Data.Aeson+import Data.Aeson.Types(typeMismatch) -------------------------------------------------------------------------------- +-- | Our Ext type that represents the core datatype core extended with extra+-- information of type 'extra'. data core :+ extra = core :+ extra deriving (Show,Read,Eq,Ord,Bounded,Generic,NFData) infixr 1 :+ @@ -43,6 +53,17 @@ instance (Semigroup core, Semigroup extra) => Semigroup (core :+ extra) where   (c :+ e) <> (c' :+ e') = c <> c' :+ e <> e' ++instance (ToJSON core, ToJSON extra) => ToJSON (core :+ extra) where+  -- toJSON     (c :+ e) = toJSON     (c,e)+  -- toEncoding (c :+ e) = toEncoding (c,e)+  toJSON     (c :+ e) = object ["core" .= c, "extra" .= e]+  toEncoding (c :+ e) = pairs  ("core" .= c <> "extra" .= e)++instance (FromJSON core, FromJSON extra) => FromJSON (core :+ extra) where+  -- parseJSON = fmap (\(c,e) -> c :+ e) . parseJSON+  parseJSON (Object v) = (:+) <$> v .: "core" <*> v .: "extra"+  parseJSON invalid    = typeMismatch "Ext (:+)" invalid  _core :: (core :+ extra) -> core _core (c :+ _) = c
src/Data/Geometry.hs view
@@ -7,16 +7,16 @@ module Data.Geometry( module Data.Geometry.Properties                     , module Data.Geometry.Transformation                     , module Data.Geometry.Point-                    , module Data.Geometry.Vector+                    , module V                     , module Data.Geometry.Line                     , module Data.Geometry.LineSegment                     , module Data.Geometry.PolyLine                     , module Data.Geometry.Polygon-                    , module Linear.Affine-                    , module Linear.Vector+                    -- , module Linear.Affine+                    -- , module Linear.Vector                     ) where -+import Data.Geometry.Vector as V hiding (last) import Data.Geometry.Line import Data.Geometry.LineSegment import Data.Geometry.Point@@ -24,6 +24,5 @@ import Data.Geometry.Polygon hiding (fromPoints) import Data.Geometry.Properties import Data.Geometry.Transformation-import Data.Geometry.Vector-import Linear.Affine hiding (Point, Vector, origin)-import Linear.Vector+-- import Linear.Affine hiding (Point, Vector, origin)+-- import Linear.Vector
src/Data/Geometry/Ball.hs view
@@ -1,5 +1,11 @@ {-# LANGUAGE TemplateHaskell  #-} {-# LANGUAGE UndecidableInstances #-}+{-|+Module    : Data.Geometry.Ball+Description: \(d\)-dimensional Balls and Spheres+Copyright : (c) Frank Staals+License : See LICENCE file+-} module Data.Geometry.Ball where  import           Control.DeepSeq@@ -16,7 +22,7 @@ import qualified Data.List as L import qualified Data.Traversable as T import           Data.Vinyl-import           Frames.CoRec+import           Data.Vinyl.CoRec import           GHC.Generics (Generic) import           Linear.Matrix import           Linear.V3 (V3(..))@@ -36,7 +42,7 @@   deriving instance (Show r, Show p, Arity d)     => Show (Ball d p r)--- deriving instance (NFData p, NFData r, Arity d) => NFData (Ball d p r)+instance (NFData p, NFData r, Arity d) => NFData (Ball d p r) deriving instance (Eq r, Eq p, Arity d)         => Eq (Ball d p r)  type instance NumType   (Ball d p r) = r@@ -111,6 +117,7 @@  pattern Sphere     :: Point d r :+ p -> r -> Sphere d p r pattern Sphere c r = Boundary (Ball c r)+{-# COMPLETE Sphere #-}   @@ -122,12 +129,14 @@  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  pattern Circle     :: Point 2 r :+ p ->  r -> Circle p r pattern Circle c r = Sphere c r+{-# COMPLETE Circle #-}  -- | Given three points, get the disk through the three points. If the three -- input points are colinear we return Nothing
src/Data/Geometry/Boundary.hs view
@@ -7,8 +7,8 @@  -- | The boundary of a geometric object. newtype Boundary g = Boundary g-                   deriving (Show,Eq,Ord,Read,IsTransformable)-+                   deriving (Show,Eq,Ord,Read,IsTransformable+                            ,Functor,Foldable,Traversable)  type instance NumType (Boundary g)   = NumType g type instance Dimension (Boundary g) = Dimension g
src/Data/Geometry/Box.hs view
@@ -1,7 +1,14 @@ {-# LANGUAGE TemplateHaskell  #-} {-# LANGUAGE ScopedTypeVariables  #-}+{-# LANGUAGE UndecidableInstances  #-} {-# LANGUAGE DeriveAnyClass  #-} {-# OPTIONS_GHC -fno-warn-orphans #-}+{-|+Module    : Data.Geometry.Box+Description: Orthogonal \(d\)-dimensiontal boxes (e.g. rectangles)+Copyright : (c) Frank Staals+License : See LICENCE file+-} module Data.Geometry.Box( module Data.Geometry.Box.Internal                         , topSide, leftSide, bottomSide, rightSide                         , sides, sides'
src/Data/Geometry/Box/Internal.hs view
@@ -1,16 +1,17 @@ {-# LANGUAGE TemplateHaskell  #-} {-# LANGUAGE ScopedTypeVariables  #-}+{-# LANGUAGE UndecidableInstances  #-}+{-# LANGUAGE InstanceSigs  #-} module Data.Geometry.Box.Internal where  import           Control.DeepSeq import           Control.Lens import           Data.Bifunctor import           Data.Ext-import           Frames.CoRec (asA) import           Data.Geometry.Point import           Data.Geometry.Properties import           Data.Geometry.Transformation-import           Data.Geometry.Vector (Vector, Arity, Index',C(..))+import           Data.Geometry.Vector (Vector, Arity, C(..)) import qualified Data.Geometry.Vector as V import qualified Data.List.NonEmpty as NE import           Data.Proxy@@ -18,8 +19,9 @@ import           Data.Semigroup import qualified Data.Semigroup.Foldable as F import qualified Data.Vector.Fixed as FV-import           GHC.TypeLits+import           Data.Vinyl.CoRec (asA) import           GHC.Generics (Generic)+import           GHC.TypeLits   --------------------------------------------------------------------------------@@ -61,6 +63,12 @@                     (CWMax (Point $ fmap (^.R.upper.R.unEndPoint) rs) :+ mempty)  +-- | Given a center point and a vector specifying the box width's, construct a box.+fromCenter      :: (Arity d, Fractional r) => Point d r -> Vector d r -> Box d () r+fromCenter c ws = let f x r = R.ClosedRange (x-r) (x+r)+                  in fromExtent $ FV.zipWith f (toVec c) ((/2) <$> ws)++ -- | Center of the box centerPoint   :: (Arity d, Fractional r) => Box d p r -> Point d r centerPoint b = Point $ w V.^/ 2@@ -85,7 +93,12 @@       f = maybe (coRec NoIntersection) (coRec . fromExtent)       r `intersect'` s = asA (Proxy :: Proxy (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)+    where+      g' :: Functor g => g (Point d r) -> g (Point d s)+      g' = fmap (fmap 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@@ -119,7 +132,8 @@   pmap f (Box mi ma) = Box (first (fmap f) mi) (first (fmap f) ma)  -instance (Num r, AlwaysTruePFT d) => IsTransformable (Box d p r) where+instance (Fractional r, Arity d, Arity (d + 1))+         => IsTransformable (Box d p r) where   -- Note that this does not guarantee the box is still a proper box Only use   -- this to do translations and scalings. Other transformations may produce   -- unexpected results.@@ -171,7 +185,8 @@ -- 1 -- >>> widthIn (C :: C 3) (boundingBoxList' [origin, point3 1 2 3] :: Box 3 () Int) -- 3-widthIn   :: forall proxy p i d r. (Arity d, Num r, Index' (i-1) d) => proxy i -> Box d p r -> r+widthIn   :: forall proxy p i d r. (Arity d, Arity (i - 1), Num r, ((i-1)+1) <= d)+          => proxy i -> Box d p r -> r widthIn _ = view (V.element (C :: C (i - 1))) . size  
src/Data/Geometry/HalfLine.hs view
@@ -4,6 +4,7 @@ module Data.Geometry.HalfLine where  +import           Control.DeepSeq import           Control.Lens import           Data.Ext import qualified Data.Foldable as F@@ -18,7 +19,7 @@ import qualified Data.Traversable as T import           Data.UnBounded import           GHC.Generics (Generic)-import           Control.DeepSeq+import           GHC.TypeLits  -------------------------------------------------------------------------------- -- * d-dimensional Half-Lines@@ -50,7 +51,7 @@   supportingLine ~(HalfLine p v) = Line p v  -- Half-Lines are transformable-instance (Num r, AlwaysTruePFT d) => IsTransformable (HalfLine d r) where+instance (Fractional r, Arity d, Arity (d + 1)) => IsTransformable (HalfLine d r) where   transformBy t = toHalfLine . transformPointFunctor t . toLineSegment'     where       toLineSegment' :: (Num r, Arity d) => HalfLine d r -> LineSegment d () r
src/Data/Geometry/Interval.hs view
@@ -27,7 +27,7 @@ import           Data.Semigroup import qualified Data.Traversable as T import           Data.Vinyl-import           Frames.CoRec+import           Data.Vinyl.CoRec import           GHC.Generics (Generic)  --------------------------------------------------------------------------------@@ -74,7 +74,7 @@  pattern Interval     :: EndPoint (r :+ a) -> EndPoint (r :+ a) -> Interval a r pattern Interval l u = GInterval (Range l u)-+{-# COMPLETE Interval #-}  -------------------------------------------------------------------------------- 
src/Data/Geometry/Ipe.hs view
@@ -1,3 +1,9 @@+{-|+Module    : Data.Geometry.Ipe+Description: Reexports the functionality for reading and writing Ipe files.+Copyright : (c) Frank Staals+License : See LICENCE file+-} module Data.Geometry.Ipe( module Data.Geometry.Ipe.Types                         , module Data.Geometry.Ipe.Writer                         , module Data.Geometry.Ipe.Reader
src/Data/Geometry/Ipe/Attributes.hs view
@@ -5,15 +5,16 @@ {-# LANGUAGE UndecidableInstances #-} module Data.Geometry.Ipe.Attributes where -import           Control.Lens hiding (rmap, Const)-import           Data.Semigroup-import           Data.Singletons-import           Data.Singletons.TH-import           Data.Text(Text)-import           Data.Vinyl-import           Data.Vinyl.Functor-import           Data.Vinyl.TypeLevel-import           GHC.Exts+import Control.Lens hiding (rmap, Const)+import Data.Colour.SRGB+import Data.Semigroup+import Data.Singletons+import Data.Singletons.TH+import Data.Text (Text)+import Data.Vinyl+import Data.Vinyl.Functor+import Data.Vinyl.TypeLevel+import GHC.Exts  -------------------------------------------------------------------------------- @@ -68,15 +69,20 @@  makeLenses ''Attr +pattern Attr   :: Apply f label -> Attr f label pattern Attr x = GAttr (Just x)++pattern NoAttr :: Attr f label pattern NoAttr = GAttr Nothing  -- | Give pref. to the *RIGHT*-instance Monoid (Attr f l) where-  mempty                 = NoAttr-  _ `mappend` b@(Attr _) = b-  a `mappend` _          = a+instance Semigroup (Attr f l) where+  _ <> b@(Attr _) = b+  a <> _          = a +instance Monoid (Attr f l) where+  mempty  = NoAttr+  mappend = (<>)  newtype Attributes (f :: TyFun u * -> *) (ats :: [u]) =   Attrs { _unAttrs :: Rec (Attr f) ats }@@ -187,16 +193,19 @@   -- | Many types either consist of a symbolc value, or a value of type v-data IpeValue v = Named Text | Valued v deriving (Show,Eq,Ord)+data IpeValue v = Named Text | Valued v deriving (Show,Eq,Ord,Functor,Foldable,Traversable)  instance IsString (IpeValue v) where   fromString = Named . fromString -type Colour = Text -- TODO: Make this a Colour.Colour+newtype IpeSize  r = IpeSize  (IpeValue r)          deriving (Show,Eq,Ord)+newtype IpePen   r = IpePen   (IpeValue r)          deriving (Show,Eq,Ord)+newtype IpeColor r = IpeColor (IpeValue (RGB r))    deriving (Show,Eq) -newtype IpeSize r = IpeSize  (IpeValue r)      deriving (Show,Eq,Ord)-newtype IpePen  r = IpePen   (IpeValue r)      deriving (Show,Eq,Ord)-newtype IpeColor  = IpeColor (IpeValue Colour) deriving (Show,Eq,Ord)+instance Ord r => Ord (IpeColor r) where+  (IpeColor c) `compare` (IpeColor c') = fmap f c `compare` fmap f c'+    where+      f (RGB r g b) = (r,g,b)   -- -- | And the corresponding types@@ -317,26 +326,6 @@ -- GroupAttributeUniverse instance IpeAttrName Clip     where attrName _ = "clip" ---- | Wrap up a value with a capability given by its type-data GDict (c :: k -> Constraint) (a :: k) where-  GDict :: c a => Proxy a -> GDict c a---- -- | Sometimes we may know something for /all/ fields of a record, but when--- -- you expect to be able to /each/ of the fields, you are then out of luck.--- -- Surely given @∀x:u.φ(x)@ we should be able to recover @x:u ⊢ φ(x)@! Sadly,--- -- the constraint solver is not quite smart enough to realize this and we must--- -- make it patently obvious by reifying the constraint pointwise with proof.--- gReifyConstraint---   :: RecAll f rs c---   => proxy c---   -> Rec f rs---   -> Rec (GDict c :. f) rs--- gReifyConstraint prx RNil      = RNil--- gReifyConstraint prx (x :& xs) = Compose (mkDict x) :& reifyConstraint prx xs---   where---     mkDict   :: f l -> (GDict c l)---     mkDict _ = GDict (Proxy :: Proxy l)  -- | Function that states that all elements in xs satisfy a given constraint c type family AllSatisfy (c :: k -> Constraint) (xs :: [k]) :: Constraint where
src/Data/Geometry/Ipe/FromIpe.hs view
@@ -1,49 +1,146 @@+{-# LANGUAGE OverloadedStrings #-} module Data.Geometry.Ipe.FromIpe where -import           Control.Lens+import           Control.Lens hiding (Simple) import           Data.Ext+import           Data.Geometry.Ipe.Reader import           Data.Geometry.Ipe.Types-import           Data.Geometry.Line import           Data.Geometry.LineSegment import qualified Data.Geometry.PolyLine as PolyLine import           Data.Geometry.Polygon+import           Data.Geometry.Properties import qualified Data.Seq2 as S2-import qualified Data.Traversable as Tr+import qualified Data.List.NonEmpty as NonEmpty +--------------------------------------------------------------------------------+-- $setup+-- >>> :{+-- import           Data.Geometry.Ipe.Attributes+--+-- let testPath :: Path Int+--     testPath = Path . S2.l1Singleton  . PolyLineSegment . PolyLine.fromPoints . map ext+--              $ [ origin, point2 10 10, point2 200 100 ]+--+--     testPathAttrs :: IpeAttributes Path Int+--     testPathAttrs = attr SStroke (IpeColor (Named "red")) +--     testObject :: IpeObject Int+--     testObject = IpePath (testPath :+ testPathAttrs)+-- :}++ -- | Try to convert a path into a line segment, fails if the path is not a line -- segment or a polyline with more than two points.+--+-- _asLineSegment :: Prism' (Path r) (LineSegment 2 () r) _asLineSegment = prism' seg2path path2seg   where     seg2path   = review _asPolyLine . PolyLine.fromLineSegment     path2seg p = PolyLine.asLineSegment' =<< preview _asPolyLine p - -- | Convert to a polyline. Ignores all non-polyline parts+--+-- >>> testPath ^? _asPolyLine+-- Just (PolyLine {_points = Seq2 (Point2 [0,0] :+ ()) (fromList [Point2 [10,10] :+ ()]) (Point2 [200,100] :+ ())}) _asPolyLine :: Prism' (Path r) (PolyLine.PolyLine 2 () r) _asPolyLine = prism' poly2path path2poly   where     poly2path = Path . S2.l1Singleton  . PolyLineSegment-    path2poly = preview (pathSegments.Tr.traverse._PolyLineSegment)+    path2poly = preview (pathSegments.traverse._PolyLineSegment)     -- TODO: Check that the path actually is a polyline, rather     -- than ignoring everything that does not fit --- | Convert to a simple polygon: simply takes the first closed path-_asSimplePolygon :: Prism' (Path r) (SimplePolygon () r)-_asSimplePolygon = prism' poly2path path2poly+-- | Convert to a simple polygon+_asSimplePolygon :: Prism' (Path r) (Polygon Simple () r)+_asSimplePolygon = prism' polygonToPath path2poly   where-    poly2path = Path . S2.l1Singleton . PolygonPath-    path2poly = preview (pathSegments.Tr.traverse._PolygonPath)-    -- TODO: Check that the path actually is a simple polygon, rather-    -- than ignoring everything that does not fit+    path2poly p = pathToPolygon p >>= either pure (const Nothing) +-- | Convert to a multipolygon+_asMultiPolygon :: Prism' (Path r) (MultiPolygon () r)+_asMultiPolygon = prism' polygonToPath path2poly+  where+    path2poly p = pathToPolygon p >>= either (const Nothing) pure++polygonToPath                      :: Polygon t () r -> Path r+polygonToPath pg@(SimplePolygon _) = Path . S2.l1Singleton . PolygonPath $ pg+polygonToPath (MultiPolygon vs hs) = Path . S2.viewL1FromNonEmpty . fmap PolygonPath+                                   $ SimplePolygon vs NonEmpty.:| hs+++pathToPolygon   :: Path r -> Maybe (Either (SimplePolygon () r) (MultiPolygon () r))+pathToPolygon p = case p^..pathSegments.traverse._PolygonPath of+                    []                   -> Nothing+                    [pg]                 -> Just . Left  $ pg+                    SimplePolygon vs: hs -> Just . Right $ MultiPolygon vs hs+++ -- | use the first prism to select the ipe object to depicle with, and the second -- how to select the geometry object from there on. Then we can select the geometry -- object, directly with its attributes here.+--+-- >>> testObject ^? _withAttrs _IpePath _asPolyLine+-- Just (PolyLine {_points = Seq2 (Point2 [0,0] :+ ()) (fromList [Point2 [10,10] :+ ()]) (Point2 [200,100] :+ ())} :+ Attrs {_unAttrs = {GAttr {_getAttr = Nothing}, GAttr {_getAttr = Nothing}, GAttr {_getAttr = Nothing}, GAttr {_getAttr = Nothing}, GAttr {_getAttr = Just (IpeColor (Named "red"))}, GAttr {_getAttr = Nothing}, GAttr {_getAttr = Nothing}, GAttr {_getAttr = Nothing}, GAttr {_getAttr = Nothing}, GAttr {_getAttr = Nothing}, GAttr {_getAttr = Nothing}, GAttr {_getAttr = Nothing}, GAttr {_getAttr = Nothing}, GAttr {_getAttr = Nothing}, GAttr {_getAttr = Nothing}, GAttr {_getAttr = Nothing}}}) _withAttrs       :: Prism' (IpeObject r) (i r :+ IpeAttributes i r) -> Prism' (i r) g                  -> Prism' (IpeObject r) (g :+ IpeAttributes i r) _withAttrs po pg = prism' g2o o2g   where     g2o    = review po . over core (review pg)     o2g o  = preview po o >>= \(i :+ ats) -> (:+ ats) <$> preview pg i++++++-- instance HasDefaultIpeObject Path where+--   defaultIpeObject' = _IpePath+++-- class HasDefaultFromIpe g where+--   type DefaultFromIpe g :: * -> *+--   defaultIpeObject :: proxy g -> Prism' (IpeObject r) (DefaultFromIpe g r :+ IpeAttributes (DefaultFromIpe g) r)+--   defaultFromIpe   :: proxy g -> Prism' (DefaultFromIpe g (NumType g)) g+++class HasDefaultFromIpe g where+  type DefaultFromIpe g :: * -> *+  defaultFromIpe :: (r ~ NumType g)+                 => Prism' (IpeObject r) (g :+ IpeAttributes (DefaultFromIpe g) r)++-- instance HasDefaultFromIpe (Point 2 r) where+--   type DefaultFromIpe (Point 2 r) = IpeSymbol+--   defaultFromIpe = _withAttrs _IpeUse symbolPoint+++instance HasDefaultFromIpe (LineSegment 2 () r) where+  type DefaultFromIpe (LineSegment 2 () r) = Path+  defaultFromIpe = _withAttrs _IpePath _asLineSegment++instance HasDefaultFromIpe (PolyLine.PolyLine 2 () r) where+  type DefaultFromIpe (PolyLine.PolyLine 2 () r) = Path+  defaultFromIpe = _withAttrs _IpePath _asPolyLine+++instance HasDefaultFromIpe (SimplePolygon () r) where+  type DefaultFromIpe (SimplePolygon () r) = Path+  defaultFromIpe = _withAttrs _IpePath _asSimplePolygon++instance HasDefaultFromIpe (MultiPolygon () r) where+  type DefaultFromIpe (MultiPolygon () r) = Path+  defaultFromIpe = _withAttrs _IpePath _asMultiPolygon+++-- | Read all g's from some ipe page(s).+readAll :: (HasDefaultFromIpe g, r ~ NumType g, Foldable f)+        => f (IpePage r) -> [g :+ IpeAttributes (DefaultFromIpe g) r]+readAll = foldMap (^..content.traverse.defaultFromIpe)+++-- | Convenience function from reading all g's from an ipe file. If there+-- is an error reading or parsing the file the error is "thrown away".+readAllFrom    :: (HasDefaultFromIpe g, r ~ NumType g, Coordinate r, Eq r)+               => FilePath -> IO [g :+ IpeAttributes (DefaultFromIpe g) r]+readAllFrom fp = readAll <$> readSinglePageFile fp+
src/Data/Geometry/Ipe/IpeOut.hs view
@@ -1,14 +1,17 @@ {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE ScopedTypeVariables #-} module Data.Geometry.Ipe.IpeOut where -import           Control.Lens+import           Control.Lens hiding (Simple) import           Data.Bifunctor import           Data.Ext import           Data.Geometry.Ball import           Data.Geometry.Boundary import           Data.Geometry.Box import           Data.Geometry.Ipe.Attributes+import           Data.Geometry.Ipe.FromIpe import           Data.Geometry.Ipe.Types+import           Data.Geometry.Line import           Data.Geometry.LineSegment import           Data.Geometry.Point import           Data.Geometry.PolyLine@@ -16,9 +19,12 @@ import           Data.Geometry.Polygon.Convex import           Data.Geometry.Properties import           Data.Geometry.Transformation+import           Data.Maybe (fromMaybe)+import           Data.Proxy import           Data.Semigroup import qualified Data.Seq2 as S2 import           Data.Text (Text)+import           Data.Vinyl.CoRec  -------------------------------------------------------------------------------- @@ -44,7 +50,8 @@ -- ipe geometry object, the geometry object, and a record with its attributes, -- construct an ipe Object representing it. asIpeObjectWith          :: (ToObject i, NumType g ~ r)-                      => IpeOut g (IpeObject' i r) -> g -> IpeAttributes i r -> IpeObject r+                         => IpeOut g (IpeObject' i r) -> g -> IpeAttributes i r+                         -> IpeObject r asIpeObjectWith io g ats = asIpe (ipeObject io ats) g  @@ -83,6 +90,10 @@   --                  => IpeOut g (IpeObject (NumType g))   -- defaultIpeObject = IpeOut $ flip asIpeObject mempty +-- instance HasDefaultIpeOut g => HasDefaultIpeOut [g] where+--   type DefaultIpeOut [g] = Group+--   defaultIpeOut = IpeOut $ asIpeGroup . map (asIpeObject' mempty)+ instance HasDefaultIpeOut (Point 2 r) where   type DefaultIpeOut (Point 2 r) = IpeSymbol   defaultIpeOut = ipeDiskMark@@ -99,11 +110,15 @@   type DefaultIpeOut (PolyLine 2 p r) = Path   defaultIpeOut = noAttrs ipePolyLine -instance HasDefaultIpeOut (SimplePolygon p r) where-  type DefaultIpeOut (SimplePolygon p r) = Path-  defaultIpeOut = flip addAttributes ipeSimplePolygon $-                    mempty <> attr SFill (IpeColor "red")+instance HasDefaultIpeOut (Polygon t p r) where+  type DefaultIpeOut (Polygon t p r) = Path+  defaultIpeOut = flip addAttributes ipePolygon $+                    mempty <> attr SFill (IpeColor "0.722 0.145 0.137") +instance HasDefaultIpeOut (SomePolygon p r) where+  type DefaultIpeOut (SomePolygon p r) = Path+  defaultIpeOut = IpeOut $ either (asIpe defaultIpeOut) (asIpe defaultIpeOut)+ instance HasDefaultIpeOut (ConvexPolygon p r) where   type DefaultIpeOut (ConvexPolygon p r) = Path   defaultIpeOut = IpeOut $ asIpe defaultIpeOut . view simplePolygon@@ -132,15 +147,22 @@ defaultClipRectangle = boundingBox (point2 (-200) (-200)) <>                        boundingBox (point2 1000 1000) --- -- | An ipe out to draw a line, by clipping it to stay within a rectangle of--- -- default size.--- line :: IpeOut (Line 2 r) (IpeObject' Path r)--- line = line' defaultClipRectangle---- -- | An ipe out to draw a line, by clipping it to stay within the rectangle--- line'   :: Rectangle p r -> IpeOut (Line 2 r) (IpeObject' Path r)--- line' r = IpeOut $ \l -> error "not implemented yet"+-- | An ipe out to draw a line, by clipping it to stay within a rectangle of+-- default size.+line :: (Fractional r, Ord r) => IpeOut (Line 2 r) (IpeObject' Path r)+line = lineWith defaultClipRectangle +-- | An ipe out to draw a line, by clipping it to stay within the rectangle.+--+-- pre: intersection of the line and the rectangle is a line segment+-- (otherwise it arbitrarily inserts the bottom of the rectangle as the path)+lineWith   :: forall p r. (Ord r, Fractional r)+              => Rectangle p r -> IpeOut (Line 2 r) (IpeObject' Path r)+lineWith r = IpeOut (asIpe defaultIpeOut . clip)+  where+    def    = bimap (const ()) id $ bottomSide r+    clip l = fromMaybe def . asA (Proxy :: Proxy (LineSegment 2 () r))+           $ l `intersect` r  ipeLineSegment :: IpeOut (LineSegment 2 p r) (IpeObject' Path r) ipeLineSegment = noAttrs $ fromPathSegment ipeLineSegment'@@ -175,11 +197,17 @@ fromPathSegment    :: IpeOut g (PathSegment r) -> IpeOut g (Path r) fromPathSegment io = IpeOut $ Path . S2.l1Singleton . asIpe io -ipeSimplePolygon :: IpeOut (SimplePolygon p r) (Path r)-ipeSimplePolygon = fromPathSegment . IpeOut $ PolygonPath . dropExt++ipePolygon :: IpeOut (Polygon t p r) (Path r)+ipePolygon = IpeOut $ io . first (const ())   where-    dropExt                    :: SimplePolygon p r -> SimplePolygon () r-    dropExt (SimplePolygon vs) = SimplePolygon $ fmap (&extra .~ ()) vs+    io                       :: forall t r. Polygon t () r -> Path r+    io pg@(SimplePolygon _)  = pg^.re _asSimplePolygon+    io pg@(MultiPolygon _ _) = pg^.re _asMultiPolygon++++   
src/Data/Geometry/Ipe/ParserPrimitives.hs view
@@ -2,7 +2,8 @@ {-# Language OverloadedStrings  #-} module Data.Geometry.Ipe.ParserPrimitives( runP, runP'                                          , pMany, pMany1, pChoice-                                         , pChar, pSpace, pWhiteSpace, pInteger, pNatural+                                         , pChar, pSpace, pWhiteSpace, pInteger+                                         , pNatural, pPaddedNatural                                          , (<*><>) , (<*><)                                          , (<***>) , (<***) , (***>)                                          , pMaybe , pCount , pSepBy@@ -43,6 +44,11 @@  pNatural :: Parser Integer pNatural = read <$> pMany1 digit++-- | parses an integer with a prefix of zeros. Returns the total length of the+-- string parced (i.e. number of digits) and the resulting antural number.+pPaddedNatural :: Parser (Int, Integer)+pPaddedNatural = (\s -> (length s, read s)) <$> pMany1 digit  pInteger :: Parser Integer pInteger = pNatural
src/Data/Geometry/Ipe/PathParser.hs view
@@ -1,4 +1,5 @@ {-# Language OverloadedStrings #-}+{-# Language DefaultSignatures #-} module Data.Geometry.Ipe.PathParser where  import           Data.Bifunctor@@ -14,29 +15,31 @@ import           Data.Semigroup import           Data.Text (Text) import qualified Data.Text as T-import           Numeric import           Text.Parsec.Error (messageString, errorMessages)   ----------------------------------------------------------------------- -- | Represent stuff that can be used as a coordinate in ipe. (similar to show/read) -class Num r => Coordinate r where-    fromSeq :: Integer -> Maybe Integer -> r--defaultFromSeq :: (Ord r, Fractional r) => Integer -> Maybe Integer -> r-defaultFromSeq x Nothing  = fromInteger x-defaultFromSeq x (Just y) = let x'        = fromInteger x-                                y'        = fromInteger y-                                asDecimal = head . dropWhile (>= 1) . iterate (* 0.1)-                            in signum x' * (abs x' + asDecimal y')+class Fractional r => Coordinate r where+    -- reads a coordinate. The input is an integer representing the+    -- part before the decimal point, and a length and an integer+    -- representing the part after the decimal point+    fromSeq :: Integer -> Maybe (Int, Integer) -> r+    default fromSeq :: (Ord r, Fractional r) => Integer -> Maybe (Int, Integer) -> r+    fromSeq = defaultFromSeq -instance Coordinate Double where-  fromSeq = defaultFromSeq+defaultFromSeq                :: (Ord r, Fractional r)+                              => Integer -> Maybe (Int, Integer) -> r+defaultFromSeq x Nothing      = fromInteger x+defaultFromSeq x (Just (l,y)) = let x'          = fromInteger x+                                    y'          = fromInteger y+                                    asDecimal a =  a * (0.1 ^ l)+                                    z           = if x' < 0 then (-1) else 1+                                in z * (abs x' + asDecimal y') -instance Coordinate (Ratio Integer) where-    fromSeq x  Nothing = fromInteger x-    fromSeq x (Just y) = fst . head $ readSigned readFloat (show x ++ "." ++ show y)+instance Coordinate Double+instance Coordinate (Ratio Integer)  ----------------------------------------------------------------------- -- | Running the parsers@@ -52,13 +55,16 @@  -- Collect errors data Either' l r = Left' l | Right' r deriving (Show,Eq)++instance (Semigroup l, Semigroup r) => Semigroup (Either' l r) where+  (Left' l)  <> (Left' l')  = Left' $ l <> l'+  (Left' l)  <> _           = Left' l+  _          <> (Left' l')  = Left' l'+  (Right' r) <> (Right' r') = Right' $ r <> r'+ instance (Semigroup l, Semigroup r, Monoid r) => Monoid (Either' l r) where   mempty = Right' mempty-  (Left' l)  `mappend` (Left' l')  = Left' $ l <> l'-  (Left' l)  `mappend` _           = Left' l-  _          `mappend` (Left' l')  = Left' l'-  (Right' r) `mappend` (Right' r') = Right' $ r <> r'-+  mappend = (<>) either' :: (l -> a) -> (r -> a) -> Either' l r -> a either' lf _  (Left' l)  = lf l either' _  rf (Right' r) = rf r@@ -130,8 +136,9 @@ pCoordinate :: Coordinate r => Parser r pCoordinate = fromSeq <$> pInteger <*> pDecimal               where-                pDecimal = pMaybe (pChar '.' *> pInteger)+                pDecimal  = pMaybe (pChar '.' *> pPaddedNatural) + pRectangle :: Coordinate r => Parser (Rectangle () r) pRectangle = (\p q -> box (ext p) (ext q)) <$> pPoint                                            <*  pWhiteSpace@@ -144,9 +151,9 @@  -- | Generate a matrix from a list of 6 coordinates. mkMatrix               :: Coordinate r => [r] -> Matrix 3 3 r-mkMatrix [a,b,c,d,e,f] = Matrix $ v3 (v3 a c e)-                                     (v3 b d f)-                                     (v3 0 0 1)+mkMatrix [a,b,c,d,e,f] = Matrix $ Vector3 (Vector3 a c e)+                                          (Vector3 b d f)+                                          (Vector3 0 0 1)                            -- We need the matrix in the following order:                          -- 012                          -- 345
src/Data/Geometry/Ipe/Reader.hs view
@@ -22,15 +22,19 @@                                , ipeReadObject                                , ipeReadAttrs                                , ipeReadRec++                               , Coordinate(..)                                ) where +import           Control.Applicative((<|>)) import           Control.Lens hiding (Const, rmap) import qualified Data.ByteString as B+import           Data.Colour.SRGB (RGB(..)) import           Data.Either (rights) import           Data.Ext import           Data.Geometry.Box import           Data.Geometry.Ipe.Attributes-import           Data.Geometry.Ipe.ParserPrimitives (pInteger)+import           Data.Geometry.Ipe.ParserPrimitives (pInteger, pWhiteSpace) import           Data.Geometry.Ipe.PathParser import           Data.Geometry.Ipe.Types import           Data.Geometry.Point@@ -40,14 +44,14 @@ import qualified Data.List as L import qualified Data.List.NonEmpty as NE import           Data.Maybe (fromMaybe, mapMaybe)-import           Data.Monoid import           Data.Proxy import qualified Data.Seq2 as S2+import           Data.Semigroup ((<>)) import           Data.Singletons-import qualified Data.Text as T import           Data.Text (Text)+import qualified Data.Text as T import qualified Data.Traversable as Tr-import           Data.Vinyl+import           Data.Vinyl hiding (Label) import           Data.Vinyl.Functor import           Data.Vinyl.TypeLevel import           Text.XML.Expat.Tree@@ -59,19 +63,22 @@   -- | Given a file path, tries to read an ipe file-readRawIpeFile :: Coordinate r => FilePath -> IO (Either ConversionError (IpeFile r))+readRawIpeFile :: (Coordinate r, Eq r)+               => FilePath -> IO (Either ConversionError (IpeFile r)) readRawIpeFile = fmap fromIpeXML . B.readFile   -- | Given a file path, tries to read an ipe file. This function applies all -- matrices to objects.-readIpeFile :: Coordinate r => FilePath -> IO (Either ConversionError (IpeFile r))+readIpeFile :: (Coordinate r, Eq r)+            => FilePath -> IO (Either ConversionError (IpeFile r)) readIpeFile = fmap (bimap id applyMatrices) . readRawIpeFile   -- | Since most Ipe file contain only one page, we provide a shortcut for that -- as well. This function applies all matrices.-readSinglePageFile :: Coordinate r => FilePath -> IO (Either ConversionError (IpePage r))+readSinglePageFile :: (Coordinate r, Eq r)+                   => FilePath -> IO (Either ConversionError (IpePage r)) readSinglePageFile = fmap f . readIpeFile   where     f (Left e)  = Left e@@ -151,9 +158,17 @@ instance Coordinate r => IpeReadText (Rectangle () r) where   ipeReadText = readRectangle -instance IpeReadText IpeColor where-  ipeReadText = fmap IpeColor . ipeReadTextWith Right+instance Coordinate r => IpeReadText (RGB r) where+  ipeReadText = runParser (pRGB <|> pGrey)+    where+      pGrey = (\c -> RGB c c c) <$> pCoordinate+      pRGB  = RGB <$> pCoordinate <* pWhiteSpace+                  <*> pCoordinate <* pWhiteSpace+                  <*> pCoordinate +instance Coordinate r => IpeReadText (IpeColor r) where+  ipeReadText = fmap IpeColor . ipeReadTextWith ipeReadText+ instance Coordinate r => IpeReadText (IpePen r) where   ipeReadText = fmap IpePen . ipeReadTextWith readCoordinate @@ -164,7 +179,7 @@ instance Coordinate r => IpeReadText [Operation r] where   ipeReadText = readPathOperations -instance Coordinate r => IpeReadText (NE.NonEmpty (PathSegment r)) where+instance (Coordinate r, Eq r) => IpeReadText (NE.NonEmpty (PathSegment r)) where   ipeReadText t = ipeReadText t >>= fromOpsN     where       fromOpsN xs = case fromOps xs of@@ -179,7 +194,7 @@       fromOps' _ []             = Left "Found only a MoveTo operation"       fromOps' s (LineTo q:ops) = let (ls,xs) = span' _LineTo ops                                       pts  = map ext $ s:q:mapMaybe (^?_LineTo) ls-                                      poly = Polygon.fromPoints pts+                                      poly = Polygon.fromPoints . dropRepeats $ pts                                       pl   = fromPoints pts                                   in case xs of                                        (ClosePath : xs') -> PolygonPath poly   <<| xs'@@ -190,7 +205,11 @@        x <<| xs = (x:) <$> fromOps xs -instance Coordinate r => IpeReadText (Path r) where++dropRepeats :: Eq a => [a] -> [a]+dropRepeats = map head . L.group++instance (Coordinate r, Eq r) => IpeReadText (Path r) where   ipeReadText = fmap (Path . S2.viewL1FromNonEmpty) . ipeReadText  --------------------------------------------------------------------------------@@ -253,17 +272,17 @@ ipeReadAttrs _ _ = fmap Attrs . ipeReadRec (Proxy :: Proxy f) (Proxy :: Proxy ats)  -testSym :: B.ByteString-testSym = "<use name=\"mark/disk(sx)\" pos=\"320 736\" size=\"normal\" stroke=\"black\"/>"+-- testSym :: B.ByteString+-- testSym = "<use name=\"mark/disk(sx)\" pos=\"320 736\" size=\"normal\" stroke=\"black\"/>"     -- readAttrsFromXML :: B.ByteString -> Either -readSymAttrs :: Either ConversionError (IpeAttributes IpeSymbol Double)-readSymAttrs = readXML testSym-               >>= ipeReadAttrs (Proxy :: Proxy IpeSymbol) (Proxy :: Proxy Double)+-- readSymAttrs :: Either ConversionError (IpeAttributes IpeSymbol Double)+-- readSymAttrs = readXML testSym+--                >>= ipeReadAttrs (Proxy :: Proxy IpeSymbol) (Proxy :: Proxy Double)   @@ -301,7 +320,7 @@     unT (Text t) = Right t     unT _        = Left "allText: Expected Text, found an Element" -instance Coordinate r => IpeRead (Path r) where+instance (Coordinate r, Eq r) => IpeRead (Path r) where   ipeRead (Element "path" _ chs) = allText chs >>= ipeReadText   ipeRead _                      = Left "path: expected element, found text" @@ -333,7 +352,7 @@   ipeRead (Element "image" ats _) = Image () <$> (lookup' "rect" ats >>= ipeReadText)   ipeRead _                       = Left "Image: Element expected, text found" -instance Coordinate r => IpeRead (IpeObject r) where+instance (Coordinate r, Eq r) => IpeRead (IpeObject r) where   ipeRead x = firstRight [ IpeUse       <$> ipeReadObject (Proxy :: Proxy IpeSymbol) r x                          , IpePath      <$> ipeReadObject (Proxy :: Proxy Path)      r x                          , IpeGroup     <$> ipeReadObject (Proxy :: Proxy Group)     r x@@ -348,8 +367,8 @@ firstRight = maybe (Left "No matching object") Right . firstOf (traverse._Right)  -instance Coordinate r => IpeRead (Group r) where-  ipeRead (Element "group" _ chs) = Group <$> mapM ipeRead chs+instance (Coordinate r, Eq r) => IpeRead (Group r) where+  ipeRead (Element "group" _ chs) = Right . Group . rights . map ipeRead $ chs   ipeRead _                       = Left "ipeRead Group: expected Element, found Text"  @@ -366,7 +385,7 @@  -- TODO: this instance throws away all of our error collecting (and is pretty -- slow/stupid since it tries parsing all children with all parsers)-instance Coordinate r => IpeRead (IpePage r) where+instance (Coordinate r, Eq r) => IpeRead (IpePage r) where   ipeRead (Element "page" _ chs) = Right $ IpePage (readAll chs) (readAll chs) (readAll chs)   ipeRead _                      = Left "page: Element expected, text found"       -- withDef   :: b -> Either a b -> Either c b@@ -381,7 +400,7 @@ readAll   = rights . map ipeRead  -instance Coordinate r => IpeRead (IpeFile r) where+instance (Coordinate r, Eq r) => IpeRead (IpeFile r) where   ipeRead (Element "ipe" _ chs) = case readAll chs of                                     []  -> Left "Ipe: no pages found"                                     pgs -> Right $ IpeFile Nothing [] (NE.fromList pgs)@@ -389,59 +408,6 @@   -testz :: Either ConversionError (IpeObject Double)-testz = (bimap (T.pack . show) id $ parse' defaultParseOptions testSym)-               >>= ipeRead -- Object (Proxy :: Proxy IpeSymbol) (Proxy :: Proxy Double)---------------  -- ipeReadAttrs (Element _ ats _) =--instance Coordinate r => IpeReadText (PolyLine 2 () r) where-  ipeReadText t = readPathOperations t >>= fromOps-    where-      fromOps (MoveTo p:LineTo q:ops) = (\ps -> fromPoints' $ [p,q] ++ ps)-                                     <$> validateAll "Expected LineTo p" _LineTo ops-      fromOps _                       = Left "Expected MoveTo p:LineTo q:... "--validateAll         :: ConversionError -> Prism' (Operation r) (Point 2 r) -> [Operation r]-                    -> Either ConversionError [Point 2 r]-validateAll err fld = bimap T.unlines id . validateAll' err fld---validateAll' :: err -> Prism' (Operation r) (Point 2 r) -> [Operation r]-               -> Either [err] [Point 2 r]-validateAll' err field = toEither . foldr (\op' res -> f op' <> res) (Right' [])-  where-    f op' = maybe (Left' [err]) (\p -> Right' [p]) $ op' ^? field-    toEither = either' Left Right---- This is a bit of a hack-instance Coordinate r => IpeRead (PolyLine 2 () r) where-  ipeRead (Element "path" _ ts) = ipeReadText . T.unlines . map unText $ ts-                                    -- apparently hexpat already splits the text into lines-  ipeRead _                     = Left "iperead: no polyline."--unText          :: Node t t1 -> t1-unText (Text t) = t-unText _        = error "unText: element found, text expected"--instance Coordinate r => IpeRead (PathSegment r) where-  ipeRead = fmap PolyLineSegment . ipeRead--testP :: B.ByteString-testP = "<path stroke=\"black\">\n128 656 m\n224 768 l\n304 624 l\n432 752 l\n</path>"   --------------------------------------------------------------------------------
src/Data/Geometry/Ipe/Types.hs view
@@ -8,7 +8,7 @@  import           Control.Lens import           Data.Proxy-import           Data.Vinyl+import           Data.Vinyl hiding (Label)  import           Data.Ext import           Data.Geometry.Box(Rectangle)@@ -50,7 +50,7 @@ type instance NumType   (Image r) = r type instance Dimension (Image r) = 2 -instance Num r => IsTransformable (Image r) where+instance Fractional r => IsTransformable (Image r) where   transformBy t = over rect (transformBy t)  --------------------------------------------------------------------------------@@ -68,10 +68,10 @@ type instance NumType   (MiniPage r) = r type instance Dimension (MiniPage r) = 2 -instance Num r => IsTransformable (TextLabel r) where+instance Fractional r => IsTransformable (TextLabel r) where   transformBy t (Label txt p) = Label txt (transformBy t p) -instance Num r => IsTransformable (MiniPage r) where+instance Fractional r => IsTransformable (MiniPage r) where   transformBy t (MiniPage txt p w) = MiniPage txt (transformBy t p) w  width                  :: MiniPage t -> t@@ -90,7 +90,7 @@ type instance NumType   (IpeSymbol r) = r type instance Dimension (IpeSymbol r) = 2 -instance Num r => IsTransformable (IpeSymbol r) where+instance Fractional r => IsTransformable (IpeSymbol r) where   transformBy t = over symbolPoint (transformBy t)  @@ -118,7 +118,7 @@ type instance NumType   (PathSegment r) = r type instance Dimension (PathSegment r) = 2 -instance Num r => IsTransformable (PathSegment r) where+instance Fractional r => IsTransformable (PathSegment r) where   transformBy t (PolyLineSegment p) = PolyLineSegment $ transformBy t p   transformBy t (PolygonPath p)     = PolygonPath $ transformBy t p   transformBy _ _                   = error "transformBy: not implemented yet"@@ -132,7 +132,7 @@ type instance NumType   (Path r) = r type instance Dimension (Path r) = 2 -instance Num r => IsTransformable (Path r) where+instance Fractional r => IsTransformable (Path r) where   transformBy t (Path s) = Path $ fmap (transformBy t) s  -- | type that represents a path in ipe.@@ -161,9 +161,9 @@   AttrMap r Pin             = PinType   AttrMap r Transformations = TransformationTypes -  AttrMap r Stroke = IpeColor+  AttrMap r Stroke = IpeColor r   AttrMap r Pen    = IpePen r-  AttrMap r Fill   = IpeColor+  AttrMap r Fill   = IpeColor r   AttrMap r Size   = IpeSize r    AttrMap r Dash     = IpeDash r@@ -203,7 +203,7 @@ type instance NumType   (Group r) = r type instance Dimension (Group r) = 2 -instance Num r => IsTransformable (Group r) where+instance Fractional r => IsTransformable (Group r) where   transformBy t (Group s) = Group $ fmap (transformBy t) s  @@ -256,7 +256,7 @@ instance ToObject IpeSymbol  where ipeObject' s a = IpeUse       (s :+ a) instance ToObject Path       where ipeObject' p a = IpePath      (p :+ a) -instance Num r => IsTransformable (IpeObject r) where+instance Fractional r => IsTransformable (IpeObject r) where   transformBy t (IpeGroup i)     = IpeGroup     $ i&core %~ transformBy t   transformBy t (IpeImage i)     = IpeImage     $ i&core %~ transformBy t   transformBy t (IpeTextLabel i) = IpeTextLabel $ i&core %~ transformBy t@@ -288,6 +288,17 @@     s (IpeUse i)       a = IpeUse       $ i&select .~ a     s (IpePath i)      a = IpePath      $ i&select .~ a +-- | collect all non-group objects+flattenGroups :: [IpeObject r] -> [IpeObject r]+flattenGroups = concatMap flattenGroups'+  where+    flattenGroups'                              :: IpeObject r -> [IpeObject r]+    flattenGroups' (IpeGroup (Group gs :+ ats)) =+      map (applyAts ats) . concatMap flattenGroups' $ gs+        where+          applyAts _ = id+    flattenGroups' o                            = [o]+ --------------------------------------------------------------------------------  @@ -372,7 +383,7 @@     (mm,ats') = takeAttr (Proxy :: Proxy AT.Matrix) ats  -- | Applies the matrix to an ipe object if it has one.-applyMatrix                  :: Num r => IpeObject r -> IpeObject r+applyMatrix                  :: Fractional r => IpeObject r -> IpeObject r applyMatrix (IpeGroup i)     = IpeGroup . applyMatrix'                              $ i&core.groupItems.traverse %~ applyMatrix                              -- note that for a group we first (recursively)@@ -384,10 +395,10 @@ applyMatrix (IpeUse i)       = IpeUse       $ applyMatrix' i applyMatrix (IpePath i)      = IpePath      $ applyMatrix' i -applyMatrices   :: Num r => IpeFile r -> IpeFile r+applyMatrices   :: Fractional r => IpeFile r -> IpeFile r applyMatrices f = f&pages.traverse %~ applyMatricesPage -applyMatricesPage   :: Num r => IpePage r -> IpePage r+applyMatricesPage   :: Fractional r => IpePage r -> IpePage r applyMatricesPage p = p&content.traverse %~ applyMatrix  
src/Data/Geometry/Ipe/Writer.hs view
@@ -6,6 +6,7 @@ import           Control.Lens ((^.),(^..),(.~),(&), to) import qualified Data.ByteString as B import qualified Data.ByteString.Char8 as C+import           Data.Colour.SRGB (RGB(..)) import           Data.Ext import           Data.Fixed import qualified Data.Foldable as F@@ -13,11 +14,10 @@ import           Data.Geometry.Ipe.Attributes import qualified Data.Geometry.Ipe.Attributes as IA import           Data.Geometry.Ipe.Types-import qualified Data.Geometry.Ipe.Types as IT import           Data.Geometry.LineSegment import           Data.Geometry.Point import           Data.Geometry.PolyLine-import           Data.Geometry.Polygon (SimplePolygon, outerBoundary)+import           Data.Geometry.Polygon (Polygon, outerBoundary, holeList, asSimplePolygon) import qualified Data.Geometry.Transformation as GT import           Data.Geometry.Vector import           Data.Maybe (catMaybes, mapMaybe, fromMaybe)@@ -26,17 +26,15 @@ import           Data.Semigroup import qualified Data.Seq2 as S2 import           Data.Singletons+import           Data.Text (Text) import qualified Data.Text as T import qualified Data.Text as Text-import           Data.Text (Text)-import qualified Data.Traversable as Tr-import           Data.Vinyl+import           Data.Vinyl hiding (Label) import           Data.Vinyl.Functor import           Data.Vinyl.TypeLevel import           System.IO (hPutStrLn,stderr) import           Text.XML.Expat.Format (format') import           Text.XML.Expat.Tree- --------------------------------------------------------------------------------  -- | Given a prism to convert something of type g into an ipe file, a file path,@@ -92,10 +90,16 @@ class IpeWrite t where   ipeWrite :: t -> Maybe (Node Text Text) +instance (IpeWrite l, IpeWrite r) => IpeWrite (Either l r) where+  ipeWrite = either ipeWrite ipeWrite  instance IpeWriteText (Apply f at) => IpeWriteText (Attr f at) where   ipeWriteText att = _getAttr att >>= ipeWriteText +instance (IpeWriteText l, IpeWriteText r) => IpeWriteText (Either l r) where+  ipeWriteText = either ipeWriteText ipeWriteText++ -- | Functon to write all attributes in a Rec ipeWriteAttrs           :: ( AllSatisfy IpeAttrName rs                            , RecAll (Attr f) rs IpeWriteText@@ -175,16 +179,19 @@   ipeWriteText Horizontal = Just "h"   ipeWriteText Vertical   = Just "v" +instance IpeWriteText r => IpeWriteText (RGB r) where+  ipeWriteText (RGB r g b) = unwords' . map ipeWriteText $ [r,g,b]+ deriving instance IpeWriteText r => IpeWriteText (IpeSize  r) deriving instance IpeWriteText r => IpeWriteText (IpePen   r)-deriving instance IpeWriteText IpeColor+deriving instance IpeWriteText r => IpeWriteText (IpeColor r)  instance IpeWriteText r => IpeWriteText (IpeDash r) where   ipeWriteText (DashNamed t) = Just t   ipeWriteText (DashPattern xs x) = (\ts t -> mconcat [ "["                                                       , Text.intercalate " " ts                                                       , "] ", t ])-                                    <$> Tr.mapM ipeWriteText xs+                                    <$> mapM ipeWriteText xs                                     <*> ipeWriteText x  instance IpeWriteText FillType where@@ -196,7 +203,7 @@                                                             <*> ipeWriteText s  instance IpeWriteText r => IpeWriteText (Path r) where-  ipeWriteText = fmap concat' . Tr.sequence . fmap ipeWriteText . _pathSegments+  ipeWriteText = fmap concat' . sequence . fmap ipeWriteText . _pathSegments     where       concat' = F.foldr1 (\t t' -> t <> "\n" <> t') @@ -227,28 +234,37 @@   instance IpeWriteText r => IpeWriteText (Operation r) where-  ipeWriteText (MoveTo p)      = unwords' [ ipeWriteText p, Just "m"]-  ipeWriteText (LineTo p)      = unwords' [ ipeWriteText p, Just "l"]-  ipeWriteText (CurveTo p q r) = unwords' [ ipeWriteText p-                                          , ipeWriteText q-                                          , ipeWriteText r, Just "m"]-  ipeWriteText (Ellipse m)     = unwords' [ ipeWriteText m, Just "e"]-  -- TODO: The rest-  ipeWriteText ClosePath       = Just "h"+  ipeWriteText (MoveTo p)         = unwords' [ ipeWriteText p, Just "m"]+  ipeWriteText (LineTo p)         = unwords' [ ipeWriteText p, Just "l"]+  ipeWriteText (CurveTo p q r)    = unwords' [ ipeWriteText p+                                             , ipeWriteText q+                                             , ipeWriteText r, Just "c"]+  ipeWriteText (QCurveTo p q)     = unwords' [ ipeWriteText p+                                             , ipeWriteText q, Just "q"]+  ipeWriteText (Ellipse m)        = unwords' [ ipeWriteText m, Just "e"]+  ipeWriteText (ArcTo m p)        = unwords' [ ipeWriteText m+                                             , ipeWriteText p, Just "a"]+  ipeWriteText (Spline pts)       = unlines' $ map ipeWriteText pts <> [Just "s"]+  ipeWriteText (ClosedSpline pts) = unlines' $ map ipeWriteText pts <> [Just "u"]+  ipeWriteText ClosePath          = Just "h"   instance IpeWriteText r => IpeWriteText (PolyLine 2 () r) where-  ipeWriteText pl = case pl^..points.Tr.traverse.core of+  ipeWriteText pl = case pl^..points.traverse.core of     (p : rest) -> unlines' . map ipeWriteText $ MoveTo p : map LineTo rest     -- the polyline type guarantees that there is at least one point -instance IpeWriteText r => IpeWriteText (SimplePolygon () r) where-  ipeWriteText pg = case pg^..outerBoundary.to F.toList.Tr.traverse.core of-    (p : rest) -> unlines' . map ipeWriteText $ MoveTo p : map LineTo rest ++ [ClosePath]-    _          -> Nothing+instance IpeWriteText r => IpeWriteText (Polygon t () r) where+  ipeWriteText pg = fmap mconcat . traverse f $ asSimplePolygon pg : holeList pg+    where+      f pg' = case pg'^..outerBoundary.traverse.core of+        (p : rest) -> unlines' . map ipeWriteText+                    $ MoveTo p : map LineTo rest ++ [ClosePath]+        _          -> Nothing     -- TODO: We are not really guaranteed that there is at least one point, it would     -- be nice if the type could guarantee that. + instance IpeWriteText r => IpeWriteText (PathSegment r) where   ipeWriteText (PolyLineSegment p) = ipeWriteText p   ipeWriteText (PolygonPath     p) = ipeWriteText p@@ -369,7 +385,7 @@ instance (IpeWriteText r, IpeWrite p) => IpeWrite (PolyLine 2 p r) where   ipeWrite p = ipeWrite path     where-      path = fromPolyLine $ p & points.Tr.traverse.extra .~ ()+      path = fromPolyLine $ p & points.traverse.extra .~ ()       -- TODO: Do something with the p's  fromPolyLine :: PolyLine 2 () r -> Path r
src/Data/Geometry/KDTree.hs view
@@ -1,9 +1,10 @@+{-# LANGUAGE UndecidableInstances  #-} {-# LANGUAGE ScopedTypeVariables #-} module Data.Geometry.KDTree where  import           Control.Lens hiding (imap, element, Empty, (:<)) import           Data.BinaryTree-import           Data.Coerce+import           Unsafe.Coerce(unsafeCoerce) import           Data.Ext import qualified Data.Foldable as F import           Data.Geometry.Box@@ -70,11 +71,11 @@ -- | Expects the input to be a set, i.e. no duplicates -- -- running time: \(O(n \log n)\)-buildKDTree :: (Arity d, KnownNat d, Index' 0 d, Ord r)+buildKDTree :: (Arity d, 1 <= d, Ord r)             => [Point d r :+ p] -> KDTree d p r buildKDTree = maybe Empty (Tree . buildKDTree') . NonEmpty.nonEmpty -buildKDTree' :: (Arity d, KnownNat d, Index' 0 d, Ord r)+buildKDTree' :: (Arity d, 1 <= d, Ord r)              => NonEmpty.NonEmpty (Point d r :+ p) -> KDTree' d p r buildKDTree' = KDT . addBoxes . build (Coord 1) . toPointSet . Seq.fromNonEmpty   where     -- compute one tree with bounding boxes, then merge them together@@ -102,7 +103,7 @@                   in (f p, p^.core) `compare` (f q, q^.core)  -build      :: (Index' 0 d, Arity d, KnownNat d, Ord r)+build      :: (1 <= d, Arity d, Ord r)            => Coord d            -> PointSet (LSeq 1) d p r            -> BinLeafTree (Split' d r) (Point d r :+ p)@@ -179,8 +180,8 @@     unzip' = bimap vectorFromListUnsafe vectorFromListUnsafe . unzip . F.toList  -asSingleton   :: (Index' 0 d, Arity d) => PointSet (LSeq 1) d p r+asSingleton   :: (1 <= d, Arity d) => PointSet (LSeq 1) d p r               -> Either (Point d r :+ p) (PointSet (LSeq 2) d p r) asSingleton v = case Seq.viewl $ v^.element (C :: C 0) of-                  _ :< _ Seq.:<< _ -> Right $ coerce v+                  _ :< _ Seq.:<< _ -> Right $ unsafeCoerce v                   p :< _           -> Left p -- only one element
src/Data/Geometry/Line.hs view
@@ -1,18 +1,34 @@ {-# OPTIONS_GHC -fno-warn-orphans #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE UnicodeSyntax #-} module Data.Geometry.Line( module Data.Geometry.Line.Internal                          ) where -import Data.Geometry.Line.Internal-import Data.Geometry.LineSegment-import Data.Geometry.Box-import Data.Geometry.Properties-import Data.Geometry.Point-import Data.Geometry.Boundary-import Data.Geometry.Transformation-import Data.Geometry.Vector+import           Control.Lens ((^.), re, bimap)+import           Data.Ext+import           Data.Geometry.Boundary+import           Data.Geometry.Box+import           Data.Geometry.Line.Internal+import           Data.Geometry.LineSegment+import           Data.Geometry.Point+import           Data.Geometry.Properties+import           Data.Geometry.SubLine+import           Data.Geometry.Transformation+import           Data.Geometry.Vector+import qualified Data.List as L+import           Data.Maybe (mapMaybe)+import           Data.Proxy+import           Data.UnBounded+import           Data.Vinyl.CoRec+import           Data.Vinyl.Core+import           Data.Vinyl.Lens+import           GHC.TypeLits +--------------------------------------------------------------------------------+ -- | Lines are transformable, via line segments-instance (Num r, AlwaysTruePFT d) => IsTransformable (Line d r) where+instance (Fractional r, Arity d, Arity (d + 1)) => IsTransformable (Line d r) where   transformBy t = supportingLine . transformPointFunctor t . toLineSegment'     where       toLineSegment' :: (Num r, Arity d) => Line d r -> LineSegment d () r@@ -23,17 +39,50 @@   [ NoIntersection, Point 2 r, (Point 2 r, Point 2 r) , LineSegment 2 () r]  --- instance (Eq r, Fractional r)---          => (Line 2 r) `IsIntersectableWith` (Boundary (Rectangle p r)) where---   nonEmptyIntersection = defaultNonEmptyIntersection+instance (Ord r, Fractional r)+         => (Line 2 r) `IsIntersectableWith` (Boundary (Rectangle p r)) where+  nonEmptyIntersection = defaultNonEmptyIntersection ---   _    `intersect` (Boundary Empty) = coRec NoIntersection---   line `intersect` (Boundary rect)  = error "TODO"---     where---       (t,r,b,l) = sides' rect+  line' `intersect` (Boundary rect)  = case asA' segP of+      [sl'] -> coRec . bimap id unVal $ sl'^.re _SubLine+      []    -> case nub' . map (fmap unVal) $ asA' pointP of+        [p]   -> coRec p+        [p,q] -> coRec (p,q)+        _     -> coRec NoIntersection+      _     -> error "intersect; ine x boundary rect; absurd"+    where+      (t,r,b,l) = sides' rect+      ints = map (\s -> sl `intersect` toSL s) [t,r,b,l] ---       ints = map (line `intersect`) [t,r,b,l]+      nub' = map head . L.group . L.sort +      sl = fromLine line'+      -- wrap a segment into an potentially unbounded subline+      toSL s = bimap (const ()) Val $ s^._SubLine +      unVal (Val x) = x+      unVal _       = error "intersect; line x boundary rect: unVal Unbounded"++      asA'    :: (t ∈ IntersectionOf (SubLine 2 () (UnBounded r))+                                     (SubLine 2 () (UnBounded r)))+              => proxy t -> [t]+      asA' px = mapMaybe (asA px) ints++      segP   = Proxy :: Proxy (SubLine 2 () (UnBounded r))+      pointP = Proxy :: Proxy (Point 2      (UnBounded r))++ type instance IntersectionOf (Line 2 r) (Rectangle p r) =   [ NoIntersection, Point 2 r, LineSegment 2 () r]+++instance (Ord r, Fractional r)+         => (Line 2 r) `IsIntersectableWith` (Rectangle p r) where+  nonEmptyIntersection = defaultNonEmptyIntersection++  line' `intersect` rect  = match (line' `intersect` (Boundary rect)) $+       (H $ \NoIntersection -> coRec NoIntersection)+    :& (H $ \p@(Point2 _ _) -> coRec p)+    :& (H $ \(p,q)          -> coRec $ ClosedLineSegment (ext p) (ext q))+    :& (H $ \s              -> coRec s)+    :& RNil
src/Data/Geometry/Line/Internal.hs view
@@ -13,7 +13,7 @@ import           Data.Ord (comparing) import qualified Data.Traversable as T import           Data.Vinyl-import           Frames.CoRec+import           Data.Vinyl.CoRec import           GHC.Generics (Generic)  @@ -46,14 +46,14 @@ lineThrough p q = Line p (q .-. p)  verticalLine   :: Num r => r -> Line 2 r-verticalLine x = Line (point2 x 0) (v2 0 1)+verticalLine x = Line (point2 x 0) (Vector2 0 1)  horizontalLine   :: Num r => r -> Line 2 r-horizontalLine y = Line (point2 0 y) (v2 1 0)+horizontalLine y = Line (point2 0 y) (Vector2 1 0)  -- | Given a line l with anchor point p, get the line perpendicular to l that also goes through p. perpendicularTo                           :: Num r => Line 2 r -> Line 2 r-perpendicularTo (Line p ~(Vector2 vx vy)) = Line p (v2 (-vy) vx)+perpendicularTo (Line p ~(Vector2 vx vy)) = Line p (Vector2 (-vy) vx)   @@ -89,6 +89,11 @@ p `onLine` (Line q v) = p == q || (p .-. q) `isScalarMultipleOf` v  +-- | Specific 2d version of testing if apoint lies on a line.+onLine2 :: (Ord r, Num r) => Point 2 r -> Line 2 r -> Bool+p `onLine2` (Line q v) = ccw p q (q .+^ v) == CoLinear++ -- | The intersection of two lines is either: NoIntersection, a point or a line. type instance IntersectionOf (Line 2 r) (Line 2 r) = [ NoIntersection                                                      , Point 2 r@@ -146,7 +151,7 @@  -- | Create a line from the linear function ax + b fromLinearFunction     :: Num r => r -> r -> Line 2 r-fromLinearFunction a b = Line (point2 0 b) (v2 1 a)+fromLinearFunction a b = Line (point2 0 b) (Vector2 1 a)  -- | get values a,b s.t. the input line is described by y = ax + b. -- returns Nothing if the line is vertical@@ -194,3 +199,25 @@ bisector p q = let v = q .-. p                    h = p .+^ (v ^/ 2)                in perpendicularTo (Line h v)+++-- | Compares the lines on slope. Vertical lines are considered larger than+-- anything else.+--+-- >>> (Line origin (Vector2 5 1)) `cmpSlope` (Line origin (Vector2 3 3))+-- LT+-- >>> (Line origin (Vector2 5 1)) `cmpSlope` (Line origin (Vector2 (-3) 3))+-- GT+-- >>> (Line origin (Vector2 5 1)) `cmpSlope` (Line origin (Vector2 0 1))+-- LT+cmpSlope :: (Num r, Ord r) => Line 2 r -> Line 2 r -> Ordering+(Line _ u) `cmpSlope` (Line _ v) = case ccw origin (f u) (f v) of+                                     CCW      -> LT+                                     CW       -> GT+                                     CoLinear -> EQ+  where+    f w@(Vector2 x y) = Point $ case (x `compare` 0, y >= 0) of+                                  (GT,_)    -> w+                                  (EQ,True) -> w+                                  _         -> (-1) *^ w+                                  -- x < 0, or (x==0 and y <0 ; i.e. a vertical line)
src/Data/Geometry/LineSegment.hs view
@@ -1,5 +1,11 @@ {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE UndecidableInstances #-}+{-|+Module    : Data.Geometry.LineSegment+Description: Line segment data type and some basic functions on line segments+Copyright : (c) Frank Staals+License : See LICENCE file+-} module Data.Geometry.LineSegment( LineSegment                                 , pattern LineSegment                                 , pattern LineSegment'@@ -17,24 +23,25 @@                                 , flipSegment                                 ) where -import           Data.Ord(comparing)-import           Control.Arrow((&&&))+import           Control.Arrow ((&&&)) import           Control.Lens import           Data.Bifunctor-import           Data.Semigroup import           Data.Ext+import qualified Data.Foldable as F import           Data.Geometry.Box.Internal-import           Data.Geometry.Interval+import           Data.Geometry.Interval hiding (width, midPoint) import           Data.Geometry.Line.Internal import           Data.Geometry.Point import           Data.Geometry.Properties import           Data.Geometry.SubLine import           Data.Geometry.Transformation import           Data.Geometry.Vector-import           Data.Vinyl+import           Data.Ord (comparing)+import           Data.Semigroup import           Data.UnBounded-import           Frames.CoRec-import qualified Data.Foldable as F+import           Data.Vinyl+import           Data.Vinyl.CoRec+import           GHC.TypeLits  -------------------------------------------------------------------------------- -- * d-dimensional LineSegments@@ -43,32 +50,33 @@ -- | Line segments. LineSegments have a start and end point, both of which may -- contain additional data of type p. We can think of a Line-Segment being defined as -----  data LineSegment d p r = LineSegment (EndPoint (Point d r :+ p))---                                       (EndPoint (Point d r :+ p))+--+-- >>>  data LineSegment d p r = LineSegment (EndPoint (Point d r :+ p)) (EndPoint (Point d r :+ p)) newtype LineSegment d p r = GLineSegment { _unLineSeg :: Interval p (Point d r)}  makeLenses ''LineSegment  -- | Pattern that essentially models the line segment as a: ----- data LineSegment d p r = LineSegment (EndPoint (Point d r :+ p))---                                      (EndPoint (Point d r :+ p))+-- >>> data LineSegment d p r = LineSegment (EndPoint (Point d r :+ p)) (EndPoint (Point d r :+ p)) pattern LineSegment           :: EndPoint (Point d r :+ p)                               -> EndPoint (Point d r :+ p)                               -> LineSegment d p r pattern LineSegment       s t = GLineSegment (Interval s t)+{-# COMPLETE LineSegment #-}  -- | Gets the start and end point, but forgetting if they are open or closed. pattern LineSegment'          :: Point d r :+ p                               -> Point d r :+ p                               -> LineSegment d p r pattern 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 s t = GLineSegment (ClosedInterval s t)+{-# COMPLETE ClosedLineSegment #-}  type instance Dimension (LineSegment d p r) = d type instance NumType   (LineSegment d p r) = r@@ -86,6 +94,7 @@  _SubLine :: (Fractional r, Eq r, Arity d) => Iso' (LineSegment d p r) (SubLine d p r) _SubLine = iso segment2SubLine subLineToSegment+{-# INLINE _SubLine #-}  segment2SubLine    :: (Fractional r, Eq r, Arity d)                    => LineSegment d p r -> SubLine d p r@@ -107,6 +116,7 @@ instance (Num r, Arity d) => HasSupportingLine (LineSegment d p r) where   supportingLine s = lineThrough (s^.start.core) (s^.end.core) + instance (Show r, Show p, Arity d) => Show (LineSegment d p r) where   show ~(LineSegment p q) = concat ["LineSegment (", show p, ") (", show q, ")"] @@ -121,7 +131,7 @@ instance Arity d => IsBoxable (LineSegment d p r) where   boundingBox l = boundingBox (l^.start.core) <> boundingBox (l^.end.core) -instance (Num r, AlwaysTruePFT d) => IsTransformable (LineSegment d p r) where+instance (Fractional r, Arity d, Arity (d + 1)) => IsTransformable (LineSegment d p r) where   transformBy = transformPointFunctor  instance Arity d => Bifunctor (LineSegment d) where@@ -207,7 +217,10 @@ p `onSegment` l = let s          = l^.start.core                       t          = l^.end.core                       inRange' x = 0 <= x && x <= 1-                  in maybe False inRange' $ scalarMultiple (p .-. s) (t .-. s)+                  in+                  if s == t -- zero length segment+                  then p == s+                  else maybe False inRange' $ scalarMultiple (p .-. s) (t .-. s)   -- | The left and right end point (or left below right if they have equal x-coords)
src/Data/Geometry/PlanarSubdivision.hs view
@@ -1,132 +1,107 @@ {-# LANGUAGE TemplateHaskell #-}-module Data.Geometry.PlanarSubdivision where+{-# LANGUAGE PartialTypeSignatures #-}+{-# LANGUAGE ScopedTypeVariables #-}+module Data.Geometry.PlanarSubdivision( module Data.Geometry.PlanarSubdivision.Basic+                                      , fromPolygon, fromPolygons+                                      ) where -import           Control.Lens-import qualified Data.BalBST as SS-import           Data.Bifunctor.Apply-import qualified Data.CircularSeq as C+-- import           Algorithms.Geometry.PolygonTriangulation.Triangulate+import           Control.Lens hiding (holes, holesOf, (.=))+import qualified Data.CircularSeq as CSeq import           Data.Ext import qualified Data.Foldable as F-import           Data.Geometry.Interval-import           Data.Geometry.LineSegment-import           Data.Geometry.Point+import           Data.Geometry.Box+import           Data.Geometry.PlanarSubdivision.Basic import           Data.Geometry.Polygon-import           Data.Geometry.Properties-import qualified Data.Map as M-import           Data.PlanarGraph-import           Data.PlaneGraph-import           Data.Semigroup-import           Data.Util+import           Data.Geometry.Vector+import qualified Data.Geometry.Vector as Vec+import           Data.List.NonEmpty (NonEmpty(..)) import qualified Data.Vector as V+import qualified Data.PlaneGraph as PG+import Data.Proxy  --- | Note that the functor instance is in v-data VertexData r v = VertexData { _location :: !(Point 2 r)-                                 , _vData    :: !v-                                 } deriving (Show,Eq,Ord,Functor,Foldable,Traversable)-makeLenses ''VertexData+-- | Construct a planar subdivision from a polygon. Since our PlanarSubdivision+-- models only connected planar subdivisions, this may add dummy/invisible+-- edges.+--+-- running time: \(O(n)\) for a simple polygon, \(O(n\log n)\) for a polygon+-- with holes.+fromPolygon                              :: forall proxy t p f r s.+                                            (Ord r, Fractional r) => proxy s+                                         -> Polygon t p r+                                         -> f -- ^ data inside+                                         -> f -- ^ data outside the polygon+                                         -> PlanarSubdivision s p () f r+fromPolygon p pg@(SimplePolygon _) iD oD = fromSimplePolygon p pg iD oD+fromPolygon _ (MultiPolygon vs hs) iD oD = PlanarSubdivision cs vd dd fd+  where+    wp = Proxy :: Proxy (Wrap s) -instance Bifunctor VertexData where-  bimap f g (VertexData p v) = VertexData (fmap f p) (g v)+    -- the components+    cs = undefined+    cs' = PG.fromSimplePolygon wp (SimplePolygon vs) iD oD+        : map (\h -> PG.fromSimplePolygon wp h oD iD) hs +    vd = undefined+    dd = undefined+    fd = undefined -data EdgeType = Visible | Invisible deriving (Show,Read,Eq,Ord) -data EdgeData e = EdgeData { _edgeType :: !EdgeType-                           , _eData    :: !e-                           } deriving (Show,Eq,Ord,Functor,Foldable,Traversable)-makeLenses ''EdgeData  --- | The Face data consists of the data itself and a list of holes-data FaceData h f = FaceData { _holes :: [h]-                             , _fData :: !f-                             } deriving (Show,Eq,Ord,Functor,Foldable,Traversable)-makeLenses ''FaceData---newtype PlanarSubdivision s v e f r = PlanarSubdivision { _graph ::-    PlanarGraph s Primal_ (VertexData r v) (EdgeData e) (FaceData (Dart s) f) }-      deriving (Show,Eq)-makeLenses ''PlanarSubdivision--instance Functor (PlanarSubdivision s v e f) where-  fmap f s = s&graph.vertexData.traverse.location %~ fmap f+-- | Given a list of *disjoint* polygons, construct a planarsubdivsion+-- representing them. This may create dummy vertices which have no vertex data,+-- hence the 'Maybe p' data type for the vertices.+--+-- running time: \(O(n\log n)\)+fromPolygons           :: (Ord r, Fractional r)+                       => proxy s+                       -> NonEmpty (SimplePolygon p r :+ f)+                       -> f -- ^ data outside the polygons+                       -> PlanarSubdivision s (Maybe p) () f r+fromPolygons px pgs oD = undefined+  -- subd&planeGraph.faceData .~ faceData'+  --                            &planeGraph.vertexData.traverse %~ getP+  -- where+  --   faceData' = fmap (\(fi, FaceData hs _) -> FaceData hs (getFData fi)) . faces $ subd +  --   -- given a faceId lookup the+  --   getFData fi = let v = boundaryVertices fi subd V.! 0+  --                 in subd^.dataOf v.to holeData ---------------------------------------------------------------------------------+  --   -- note that we intentionally reverse the order of iDd and oD in the call below,+  --   -- as our holes are now outside+  --   subd = fromPolygon px (MultiPolygon (CSeq.fromList [a,b,c,d]) holes') (Just oD) Nothing --- | Construct a planar subdivision from a polygon------ running time: \(O(n)\).-fromPolygon                            :: proxy s-                                       -> SimplePolygon p r-                                       -> f -- ^ data inside-                                       -> f -- ^ data outside the polygon-                                       -> PlanarSubdivision s p () f r-fromPolygon p (SimplePolygon vs) iD oD = PlanarSubdivision g'-  where-    g      = fromVertices p vs-    fData' = V.fromList [FaceData [] iD, FaceData [] oD]+  --   -- for every polygon, construct a hole.+  --   holes' = map withF . F.toList $ pgs+  --   -- add the facedata to the vertex data+  --   withF (pg :+ f) = bimap (\p -> Hole f p) id pg -    g'     = g & faceData .~ fData'-               & dartData.traverse._2 .~ EdgeData Visible ()--- The following does not really work anymore--- frompolygon p (MultiPolygon vs hs) iD oD = PlanarSubdivision g'---   where---     g      = fromVertices p vs---     hs'    = map (\h -> fromPolygon p h oD iD) hs---            -- note that oD and iD are exchanged---     fData' = V.fromList [FaceData iD hs', FaceData oD []]+  --   -- corners of the slightly enlarged boundingbox+  --   (a,b,c,d) = corners . bimap (const $ Outer oD) id+  --             . grow 1 . boundingBoxList . fmap (^.core) $ pgs +    --TODO: We need to mark the edges of the outer square as invisible. -fromVertices      :: proxy s-                  -> C.CSeq (Point 2 r :+ p)-                  -> PlanarGraph s Primal_ (VertexData r p) () ()-fromVertices _ vs = g&vertexData .~ vData'-  where-    n = length vs-    g = planarGraph [ [ (Dart (Arc i)               Positive, ())-                      , (Dart (Arc $ (i+1) `mod` n) Negative, ())-                      ]-                    | i <- [0..(n-1)]]-    vData' = V.fromList . map (\(p :+ e) -> VertexData p e) . F.toList $ vs+    -- Main Idea: Assign the vertices the hole-number on which they occur. For+    -- each face we then find an incident vertex to find the data corresponding+    -- to that face. +data HoleData f p = Outer !f | Hole !f !p deriving (Show,Eq) --- | Constructs a connected planar subdivision.------ pre: the segments form a single connected component--- running time: \(O(n\log n)\)-fromConnectedSegments       :: (Foldable f, Ord r, Num r)-                            => proxy s-                            -> f (LineSegment 2 p r :+ EdgeData e)-                            -> PlanarSubdivision s [p] e () r-fromConnectedSegments px ss = PlanarSubdivision $-    fromConnectedSegments' px ss & faceData.traverse %~ FaceData []+holeData            :: HoleData f p -> f+holeData (Outer f)  = f+holeData (Hole f _) = f --- | Constructs a planar graph------ pre: The segments form a single connected component------ running time: \(O(n\log n)\)-fromConnectedSegments'      :: (Foldable f, Ord r, Num r)-                            => proxy s-                            -> f (LineSegment 2 p r :+ e)-                            -> PlanarGraph s Primal_ (VertexData r [p]) e ()-fromConnectedSegments' _ ss = planarGraph dts & vertexData .~ vxData-  where-    pts         = M.fromListWith (<>) . concatMap f . zipWith g [0..] . F.toList $ ss-    f (s :+ e)  = [ ( s^.start.core-                    , SP [s^.start.extra] [(s^.end.core)   :+ h Positive e])-                  , ( s^.end.core-                    , SP [s^.end.extra]   [(s^.start.core) :+ h Negative e])-                  ]-    g i (s :+ e) = s :+ (Arc i :+ e)-    h d (a :+ e) = (Dart a d, e)+getP            :: HoleData f p -> Maybe p+getP (Outer _)  = Nothing+getP (Hole _ p) = Just p -    vts    = map (\(p,sp) -> (p,map (^.extra) . sortArround (ext p) <$> sp))-           . M.assocs $ pts-    -- vertex Data-    vxData = V.fromList . map (\(p,sp) -> VertexData p (sp^._1)) $ vts-    -- The darts-    dts    = map (^._2._2) vts+-- | grows the box by x on all sides+grow     :: (Num r, Arity d) => r -> Box d p r -> Box d p r+grow x b = let mi = minPoint b+               ma = maxPoint b+               v  = Vec.replicate x+           in box (mi&core %~ (.+^ ((-1) *^ v))) (ma&core %~ (.+^ v))
+ src/Data/Geometry/PlanarSubdivision/Basic.hs view
@@ -0,0 +1,598 @@+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE PartialTypeSignatures #-}+{-# LANGUAGE ScopedTypeVariables #-}+module Data.Geometry.PlanarSubdivision.Basic( VertexId', FaceId'+                                           , VertexData(VertexData), PG.vData, PG.location++                                           , FaceData(FaceData), holes, fData++                                           , PlanarSubdivision(PlanarSubdivision)+                                           , Wrap++                                           , Component, ComponentId++                                           , PolygonFaceData(..)+                                           , PlanarGraph+                                           , PlaneGraph+                                           , fromSimplePolygon+                                           , fromConnectedSegments+                                           , fromPlaneGraph, fromPlaneGraph'++                                           , numVertices, numEdges, numFaces, numDarts+                                           , dual++                                           , components, component+                                           , vertices', vertices+                                           , edges', edges+                                           , faces', faces, internalFaces+                                           , darts'++                                           , headOf, tailOf, twin, endPoints++                                           , incidentEdges, incomingEdges, outgoingEdges+                                           , nextIncidentEdge+                                           , neighboursOf++                                           , leftFace, rightFace+                                           , outerBoundaryDarts, boundaryVertices, holesOf+                                           , outerFaceId+                                           , boundary'++                                           , locationOf+                                           , HasDataOf(..)++                                           , endPointsOf, endPointData++                                           , edgeSegment, edgeSegments+                                           , rawFacePolygon, rawFaceBoundary+                                           , rawFacePolygons++                                           , VertexId(..), FaceId(..), Dart, World(..)+++                                           , rawVertexData, rawDartData, rawFaceData+                                           , dataVal++                                           , dartMapping, Raw(..)+                                           ) where++import           Control.Lens hiding (holes, holesOf, (.=))+import           Data.Aeson+import           Data.Coerce+import           Data.Ext+import qualified Data.Foldable as F+import           Data.Geometry.Box+import           Data.Geometry.LineSegment+import           Data.Geometry.Point+import           Data.Geometry.Polygon+import           Data.Geometry.Properties+import qualified Data.List as L+import           Data.List.NonEmpty (NonEmpty(..))+import qualified Data.List.NonEmpty as NonEmpty+import           Data.Permutation (ix')+import           Data.PlanarGraph (toAdjacencyLists,buildFromJSON, isPositive, allDarts)+import qualified Data.PlaneGraph as PG+import           Data.PlaneGraph( PlaneGraph, PlanarGraph, dual+                                , Dart, VertexId(..), FaceId(..), twin+                                , World(..)+                                , VertexId', FaceId'+                                , VertexData, location, vData+                                , HasDataOf(..)+                                )+import qualified Data.Sequence as Seq+import qualified Data.Vector as V+import qualified Data.Vector.Mutable as MV+import           GHC.Generics (Generic)++--------------------------------------------------------------------------------++-- | The Face data consists of the data itself and a list of holes+data FaceData h f = FaceData { _holes :: (Seq.Seq h)+                             , _fData :: !f+                             } deriving (Show,Eq,Ord,Functor,Foldable,Traversable,Generic)+makeLenses ''FaceData++instance Bifunctor FaceData where+  bimap f g (FaceData hs x) = FaceData (fmap f hs) (g x)+++instance (FromJSON h, FromJSON f) => FromJSON (FaceData h f)+instance (ToJSON h, ToJSON f)     => ToJSON (FaceData h f) where+  toEncoding = genericToEncoding defaultOptions+++--------------------------------------------------------------------------------+++data Wrap' s+type family Wrap (s :: k) :: k where+  Wrap s = Wrap' s++newtype ComponentId s = ComponentId { unCI :: Int }+  deriving (Show,Eq,Ord,Generic,Bounded,Enum)+++data Raw s ia a = Raw { _compId  :: {-# UNPACK #-} !(ComponentId s)+                      , _idxVal  :: {-# UNPACK #-} !ia+                      , _dataVal :: !a+                      } deriving (Eq,Show,Functor,Foldable,Traversable)+makeLenses ''Raw++++--------------------------------------------------------------------------------++-- | A connected component.+--+-- For every face f, and every hole in this face, the facedata points to a dart+-- d on the hole s.t. this dart has the face f on its left. i.e.+-- leftFace d = f+type Component s r = PlaneGraph (Wrap s)+                                (VertexId' s) (Dart s) (FaceData (Dart s) (FaceId' s))+                                r+++-- | A planarsubdivision is essentially a bunch of plane-graphs; one for every+-- connected component. These graphs store the global ID's (darts, vertexId's, faceId's)+-- in their data values. This essentially gives us a mapping between the two.+--+-- note that a face may actually occur in multiple graphs, hence when we store+-- the edges to the the holes, we store the global edgeId's rather than the+-- 'local' edgeId (dart)'s.+--+-- invariant: the outerface has faceId 0+data PlanarSubdivision s v e f r =+  PlanarSubdivision { _components    :: V.Vector (Component s r)+                    , _rawVertexData :: V.Vector (Raw s (VertexId' (Wrap s)) v)+                    , _rawDartData   :: V.Vector (Raw s (Dart      (Wrap s)) e)+                    , _rawFaceData   :: V.Vector (Raw s (FaceId'   (Wrap s)) f)+                    } deriving (Show,Eq,Functor)+makeLenses ''PlanarSubdivision+++type instance NumType   (PlanarSubdivision s v e f r) = r+type instance Dimension (PlanarSubdivision s v e f r) = 2++instance IsBoxable (PlanarSubdivision s v e f r) where+  boundingBox = boundingBoxList' . V.toList . _components+++component    :: ComponentId s -> Lens' (PlanarSubdivision s v e f r)+                                       (Component s r)+component ci = components.ix' (unCI ci)++--------------------------------------------------------------------------------++-- | Constructs a planarsubdivision from a PlaneGraph+--+-- runningTime: \(O(n)\)+fromPlaneGraph   :: forall s v e f r. (Ord r, Fractional r)+                      => PlaneGraph s v e f r -> PlanarSubdivision s v e f r+fromPlaneGraph g = fromPlaneGraph' g (PG.outerFaceDart g)++-- | Given a (connected) PlaneGraph and a dart that has the outerface on its left+-- | Constructs a planarsubdivision+--+-- runningTime: \(O(n)\)+fromPlaneGraph'        :: forall s v e f r. PlaneGraph s v e f r -> Dart s+                       -> PlanarSubdivision s v e f r+fromPlaneGraph' g ofD = PlanarSubdivision (V.singleton . coerce $ g') vd ed fd+  where+    c = ComponentId 0+    vd = V.imap    (\i v   -> Raw c (VertexId i) v)             $ g^.PG.vertexData+    ed = V.zipWith (\d dd  -> Raw c d            dd) allDarts'' $ g^.PG.rawDartData+    fd = V.imap (\i f      -> Raw c (mkFaceId i) f) . swapOf    $ g^.PG.faceData++    g' :: PlaneGraph s (VertexId' s) (Dart s) (FaceData (Dart s) (FaceId' s)) r+    g' = g&PG.faceData    %~ V.imap (\i _ -> mkFaceData i)+          &PG.vertexData  %~ V.imap (\i _ -> VertexId i)+          &PG.rawDartData .~ allDarts''++    allDarts'' :: forall s'. V.Vector (Dart s')+    allDarts'' = allDarts' (PG.numDarts g)++    -- make sure the outerFaceId is 0+    (FaceId (VertexId of')) = PG.leftFace ofD g++    -- at index i we are storing the outerface+    mkFaceData i | i == of'  = faceData (Seq.singleton ofD) 0+                 | i == 0    = faceData mempty of'+                 | otherwise = faceData mempty i+    faceData xs i = FaceData xs (FaceId . VertexId $ i)+++    mkFaceId :: forall s'. Int -> FaceId' s'+    mkFaceId = FaceId . VertexId . mkFaceId'+    mkFaceId' i | i == 0    = of'+                | i == of'  = 0+                | otherwise = i+    swapOf = V.modify (\v -> MV.swap v 0 of')++++++-- | Construct a planar subdivision from a simple polygon+--+-- running time: \(O(n)\).+fromSimplePolygon            :: (Ord r, Fractional r)+                             => proxy s+                             -> SimplePolygon p r+                             -> f -- ^ data inside+                             -> f -- ^ data outside the polygon+                             -> PlanarSubdivision s p () f r+fromSimplePolygon p pg iD oD =+  fromPlaneGraph (PG.fromSimplePolygon p pg iD oD)++-- | Constructs a connected planar subdivision.+--+-- pre: the segments form a single connected component+-- running time: \(O(n\log n)\)+fromConnectedSegments    :: (Foldable f, Ord r, Fractional r)+                         => proxy s+                         -> f (LineSegment 2 p r :+ e)+                         -> PlanarSubdivision s (NonEmpty p) e () r+fromConnectedSegments px = fromPlaneGraph . PG.fromConnectedSegments px++--------------------------------------------------------------------------------++-- | Data type that expresses whether or not we are inside or outside the+-- polygon.+data PolygonFaceData = Inside | Outside deriving (Show,Read,Eq)+++--------------------------------------------------------------------------------+-- * Basic Graph information++-- | Get the number of vertices+--+-- >>> numVertices myGraph+-- 4+numVertices :: PlanarSubdivision s v e f r  -> Int+numVertices = V.length . _rawVertexData++-- | Get the number of Darts+--+-- >>> numDarts myGraph+-- 12+numDarts :: PlanarSubdivision s v e f r  -> Int+numDarts = V.length . _rawDartData++-- | Get the number of Edges+--+-- >>> numEdges myGraph+-- 6+numEdges :: PlanarSubdivision s v e f r  -> Int+numEdges = (`div` 2) . V.length . _rawDartData++-- | Get the number of faces+--+-- >>> numFaces myGraph+-- 4+numFaces :: PlanarSubdivision s v e f r  -> Int+numFaces = V.length . _rawFaceData++-- | Enumerate all vertices+--+-- >>> vertices' myGraph+-- [VertexId 0,VertexId 1,VertexId 2,VertexId 3]+vertices'   :: PlanarSubdivision s v e f r  -> V.Vector (VertexId' s)+vertices' ps = let n = numVertices ps+               in V.fromList $ map VertexId [0..n-1]++-- | Enumerate all vertices, together with their vertex data++-- >>> vertices myGraph+-- [(VertexId 0,()),(VertexId 1,()),(VertexId 2,()),(VertexId 3,())]+vertices    :: PlanarSubdivision s v e f r  -> V.Vector (VertexId' s, VertexData r v)+vertices ps = (\vi -> (vi,ps^.vertexDataOf vi)) <$> vertices' ps++-- | Enumerate all darts+darts' :: PlanarSubdivision s v e f r  -> V.Vector (Dart s)+darts' = allDarts' . numDarts++allDarts'   :: forall s'. Int -> V.Vector (Dart s')+allDarts' n = V.fromList $ take n allDarts+++-- | Enumerate all edges. We report only the Positive darts+edges' :: PlanarSubdivision s v e f r  -> V.Vector (Dart s)+edges' = V.filter isPositive . darts'++-- | Enumerate all edges with their edge data. We report only the Positive+-- darts.+--+-- >>> mapM_ print $ edges myGraph+-- (Dart (Arc 2) +1,"c+")+-- (Dart (Arc 1) +1,"b+")+-- (Dart (Arc 0) +1,"a+")+-- (Dart (Arc 5) +1,"g+")+-- (Dart (Arc 4) +1,"e+")+-- (Dart (Arc 3) +1,"d+")+edges    :: PlanarSubdivision s v e f r  -> V.Vector (Dart s, e)+edges ps = (\e -> (e,ps^.dataOf e)) <$> edges' ps+++faces'    :: PlanarSubdivision s v e f r -> V.Vector (FaceId' s)+faces' ps = let n = numFaces ps+            in V.fromList $ map (FaceId . VertexId) [0..n-1]++faces    :: PlanarSubdivision s v e f r -> V.Vector (FaceId' s, FaceData (Dart s) f)+faces ps = (\fi -> (fi,ps^.faceDataOf fi)) <$> faces' ps++-- | Enumerates all faces with their face data exlcluding  the outer face+internalFaces    :: (Ord r, Fractional r)+                 => PlanarSubdivision s v e f r+                 -> V.Vector (FaceId' s, FaceData (Dart s) f)+internalFaces ps = let i = outerFaceId ps+                   in V.filter (\(j,_) -> i /= j) $ faces ps+++-- -- | lens to access the Dart Data+-- dartData :: Lens (PlanarSubdivision s v e f r) (PlanarSubdivision s v e' f r)+--                  (V.Vector (Dart s, e)) (V.Vector (Dart s, e'))+-- dartData = graph.PG.dartData++++++-- | The tail of a dart, i.e. the vertex this dart is leaving from+--+-- running time: \(O(1)\)+tailOf      :: Dart s -> PlanarSubdivision s v e f r  -> VertexId' s+tailOf d ps = let (_,d',g) = asLocalD d ps+              in g^.dataOf (PG.tailOf d' g)+++-- | The vertex this dart is heading in to+--+-- running time: \(O(1)\)+headOf       :: Dart s -> PlanarSubdivision s v e f r  -> VertexId' s+headOf d ps = let (_,d',g) = asLocalD d ps+              in g^.dataOf (PG.headOf d' g)+++-- | endPoints d g = (tailOf d g, headOf d g)+--+-- running time: \(O(1)\)+endPoints      :: Dart s -> PlanarSubdivision s v e f r+               -> (VertexId' s, VertexId' s)+endPoints d ps = (tailOf d ps, headOf d ps)+++-- | All edges incident to vertex v, in counterclockwise order around v.+--+-- running time: \(O(k)\), where \(k\) is the number of edges reported.+incidentEdges                 :: VertexId' s -> PlanarSubdivision s v e f r+                              -> V.Vector (Dart s)+incidentEdges v ps=  let (_,v',g) = asLocalV v ps+                         ds       = PG.incidentEdges v' g+                     in (\d -> g^.dataOf d) <$> ds+++-- | Given a dart d that points into some vertex v, report the next+-- dart e in the cyclic order around v.+--+-- running time: \(O(1)\)+nextIncidentEdge      :: Dart s -> PlanarSubdivision s v e f r -> Dart s+nextIncidentEdge d ps = let (_,d',g) = asLocalD d ps+                            d''      = PG.nextIncidentEdge d' g+                        in g^.dataOf d''++-- | All incoming edges incident to vertex v, in counterclockwise order around v.+incomingEdges      :: VertexId' s -> PlanarSubdivision s v e f r -> V.Vector (Dart s)+incomingEdges v ps = V.filter (not . isPositive) $ incidentEdges v ps++-- | All outgoing edges incident to vertex v, in counterclockwise order around v.+outgoingEdges      :: VertexId' s -> PlanarSubdivision s v e f r  -> V.Vector (Dart s)+outgoingEdges v ps = V.filter isPositive $ incidentEdges v ps+++-- | Gets the neighbours of a particular vertex, in counterclockwise order+-- around the vertex.+--+-- 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+++-- | The face to the left of the dart+--+-- running time: \(O(1)\).+leftFace      :: Dart s -> PlanarSubdivision s v e f r  -> FaceId' s+leftFace d ps = let (_,d',g) = asLocalD d ps+                    fi       = PG.leftFace d' g+                in g^.dataOf fi.fData++-- | The face to the right of the dart+--+-- running time: \(O(1)\).+rightFace      :: Dart s -> PlanarSubdivision s v e f r  -> FaceId' s+rightFace d ps = let (_,d',g) = asLocalD d ps+                     fi       = PG.rightFace d' g+                in g^.dataOf fi.fData++-- | The darts on the outer boundary of the face, for internal faces in+-- clockwise order, for the outer face in counter clockwise order.+--+--+-- running time: \(O(k)\), where \(k\) is the output size.+outerBoundaryDarts      :: FaceId' s -> PlanarSubdivision s v e f r  -> V.Vector (Dart s)+outerBoundaryDarts f ps = let (_,f',g) = asLocalF f ps+                              ds       = PG.boundary f' g+                          in (\d -> g^.dataOf d) <$> ds++++-- | The vertices of the outer boundary of the face, for internal faces in+-- clockwise order, for the outer face in counter clockwise order.+--+--+-- running time: \(O(k)\), where \(k\) is the output size.+boundaryVertices      :: FaceId' s -> PlanarSubdivision s v e f r+                      -> V.Vector (VertexId' s)+boundaryVertices f ps = (\d -> headOf d ps) <$> outerBoundaryDarts f ps+++-- | Lists the holes in this face, given as a list of darts to arbitrary darts+-- on those faces.+--+-- running time: \(O(k)\), where \(k\) is the number of darts returned.+holesOf      :: FaceId' s -> PlanarSubdivision s v e f r -> Seq.Seq (Dart s)+holesOf f ps = ps^.faceDataOf f.holes+++--------------------------------------------------------------------------------+-- * Access data++++asLocalD      :: Dart s -> PlanarSubdivision s v e f r+              -> (ComponentId s, Dart (Wrap s), Component s r)+asLocalD d ps = let (Raw ci d' _) = ps^.rawDartData.ix' (fromEnum d)+                in (ci,d',ps^.component ci)+++++asLocalV                 :: VertexId' s -> PlanarSubdivision s v e f r+                         -> (ComponentId s, VertexId' (Wrap s), Component s r)+asLocalV (VertexId v) ps = let (Raw ci v' _) = ps^.rawVertexData.ix' v+                           in (ci,v',ps^.component ci)++asLocalF                          :: FaceId' s -> PlanarSubdivision s v e f r+                                  -> (ComponentId s, FaceId' (Wrap s), Component s r)+asLocalF (FaceId (VertexId f)) ps = let (Raw ci f' _) = ps^.rawFaceData.ix' f+                                    in (ci,f',ps^.component ci)++++-- | Note that using the setting part of this lens may be very expensive!!+vertexDataOf               :: VertexId' s+                           -> Lens' (PlanarSubdivision s v e f r ) (VertexData r v)+vertexDataOf (VertexId vi) = lens get' set''+  where+    get' ps = let (Raw ci wvdi x) = ps^.rawVertexData.ix' vi+                  vd              = ps^.component ci.PG.vertexDataOf wvdi+              in vd&vData .~ x+    set'' ps x = let (Raw ci wvdi _)  = ps^.rawVertexData.ix' vi+                 in ps&rawVertexData.ix' vi.dataVal               .~ (x^.vData)+                      &component ci.PG.vertexDataOf wvdi.location .~ (x^.location)++locationOf   :: VertexId' s -> Lens' (PlanarSubdivision s v e f r ) (Point 2 r)+locationOf v = vertexDataOf v.location+++faceDataOf    :: FaceId' s -> Lens' (PlanarSubdivision s v e f r)+                                    (FaceData (Dart s) f)+faceDataOf fi = lens getF setF+  where+    (FaceId (VertexId i)) = fi+    getF ps = let (Raw ci wfi x) = ps^.rawFaceData.ix' i+                  fd             = ps^.component ci.dataOf wfi+              in fd&fData .~ x++    setF ps fd = let (Raw ci wfi _) = ps^.rawFaceData.ix' i+                     fd'            = fd&fData .~ fi+                     x              = fd^.fData+                 in ps&component ci.dataOf wfi   .~ fd'+                      &rawFaceData.ix' i.dataVal .~ x++instance HasDataOf (PlanarSubdivision s v e f r) (VertexId' s) where+  type DataOf (PlanarSubdivision s v e f r) (VertexId' s) = v+  dataOf v = vertexDataOf v.vData++instance HasDataOf (PlanarSubdivision s v e f r) (Dart s) where+  type DataOf (PlanarSubdivision s v e f r) (Dart s) = e+  dataOf d = rawDartData.ix' (fromEnum d).dataVal++instance HasDataOf (PlanarSubdivision s v e f r) (FaceId' s) where+  type DataOf (PlanarSubdivision s v e f r) (FaceId' s) = f+  dataOf f = faceDataOf f.fData++++-- | Getter for the data at the endpoints of a dart+--+-- running time: \(O(1)\)+endPointsOf   :: Dart s -> Getter (PlanarSubdivision s v e f r )+                                  (VertexData r v, VertexData r v)+endPointsOf d = to (endPointData d)++-- | data corresponding to the endpoints of the dart+--+-- running time: \(O(1)\)+endPointData      :: Dart s -> PlanarSubdivision s v e f r+                  ->  (VertexData r v, VertexData r v)+endPointData d ps = let (u,v) = endPoints d ps+                    in (ps^.vertexDataOf u, ps^.vertexDataOf v)+++--------------------------------------------------------------------------------++-- | gets the id of the outer face+--+-- running time: \(O(1)\)+outerFaceId :: PlanarSubdivision s v e f r -> FaceId' s+outerFaceId = const . FaceId . VertexId $ 0+  -- our invariant tells us the outerface is always at faceId 0++--------------------------------------------------------------------------------++-- | Reports all edges as line segments+edgeSegments    :: PlanarSubdivision s v e f r -> V.Vector (Dart s, LineSegment 2 v r :+ e)+edgeSegments ps = (\d -> (d,edgeSegment d ps)) <$> edges' ps+++-- | Given a dart and the subdivision constructs the line segment representing it+--+-- \(O(1)\)+edgeSegment      :: Dart s -> PlanarSubdivision s v e f r -> LineSegment 2 v r :+ e+edgeSegment d ps = let (p,q) = bimap PG.vtxDataToExt PG.vtxDataToExt $ ps^.endPointsOf d+                   in ClosedLineSegment p q :+ ps^.dataOf d+++-- | Generates the darts incident to a face, starting with the given dart.+--+--+-- \(O(k)\), where \(k\) is the number of darts reported+boundary'     :: Dart s -> PlanarSubdivision s v e f r -> V.Vector (Dart s)+boundary' d ps = let (_,d',g) = asLocalD d ps+                 in (\d'' -> g^.dataOf d'') <$> PG.boundary' d' g+++-- | Constructs the outer boundary of the face+--+-- \(O(k)\), where \(k\) is the complexity of the outer boundary of the face+rawFaceBoundary      :: FaceId' s -> PlanarSubdivision s v e f r -> SimplePolygon v r :+ f+rawFaceBoundary i ps = fromPoints pts :+ (ps^.dataOf i)+  where+    d   = V.head $ outerBoundaryDarts i ps+    pts = (\d' -> PG.vtxDataToExt $ ps^.vertexDataOf (headOf d' ps))+       <$> V.toList (boundary' d ps)+++-- | Constructs the boundary of the given face+--+-- \(O(k)\), where \(k\) is the complexity of the face+rawFacePolygon :: FaceId' s -> PlanarSubdivision s v e f r+                    -> SomePolygon v r :+ f+rawFacePolygon i ps = case F.toList $ holesOf i ps of+                        [] -> Left  res                               :+ x+                        hs -> Right (MultiPolygon vs $ map toHole hs) :+ x+  where+    res@(SimplePolygon vs) :+ x = rawFaceBoundary i ps+    toHole d = (rawFaceBoundary (leftFace d ps) ps)^.core++-- | Lists all faces of the planar subdivision.+rawFacePolygons    :: PlanarSubdivision s v e f r+                   -> V.Vector (FaceId' s, SomePolygon v r :+ f)+rawFacePolygons ps = fmap (\i -> (i,rawFacePolygon i ps)) . faces' $ ps++++dartMapping ps = ps^.component (ComponentId 0).PG.dartData
+ src/Data/Geometry/PlanarSubdivision/Draw.hs view
@@ -0,0 +1,17 @@+module Data.Geometry.PlanarSubdivision.Draw where++import           Data.Geometry.Ipe+import           Data.Ext+import           Control.Lens+import qualified Data.Vector as V+import Data.Geometry.PlanarSubdivision++drawPlanarSubdivision :: forall s v e f r. IpeOut (PlanarSubdivision s v e f r) (IpeObject r)+drawPlanarSubdivision = IpeOut draw+  where+    draw   :: PlanarSubdivision s v e f r -> IpeObject r+    draw g = asIpeGroup $ concatMap V.toList [vs, es, fs]+      where+        vs = (\(_,VertexData p _) -> asIpeObject p mempty) <$> vertices g+        es = (\(_,s :+ _) -> asIpeObject s mempty) <$> edgeSegments g+        fs = (\(_,f :+ _) -> asIpeObject f mempty) <$> rawFacePolygons g
src/Data/Geometry/Point.hs view
@@ -1,9 +1,16 @@ {-# LANGUAGE ScopedTypeVariables  #-} {-# LANGUAGE UndecidableInstances #-}+{-|+Module    : Data.Geometry.Point+Description: \(d\)-dimensional points+Copyright : (c) Frank Staals+License : See LICENCE file+-} module Data.Geometry.Point 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@@ -13,8 +20,6 @@ import qualified Data.Geometry.Vector as Vec import qualified Data.List as L import           Data.Proxy-import qualified Data.Traversable as T-import qualified Data.Vector.Fixed as FV import           GHC.Generics (Generic) import           GHC.TypeLits --------------------------------------------------------------------------------@@ -23,7 +28,7 @@ -- $setup -- >>> :{ -- let myVector :: Vector 3 Int---     myVector = v3 1 2 3+--     myVector = Vector3 1 2 3 --     myPoint = Point myVector -- :} @@ -35,20 +40,17 @@ newtype Point d r = Point { toVec :: Vector d r } deriving (Generic)  instance (Show r, Arity d) => Show (Point d r) where-  show (Point (Vector v)) = mconcat [ "Point", show $ FV.length v , " "-                                    , show $ F.toList v-                                    ]--+  show (Point v) = mconcat [ "Point", show $ F.length v , " "+                           , show $ F.toList v+                           ]  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             => F.Foldable (Point d)-deriving instance Arity d             => T.Traversable (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) - type instance NumType (Point d r) = r type instance Dimension (Point d r) = d @@ -58,7 +60,13 @@   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@@ -73,7 +81,7 @@ -- -- >>> (point3 1 2 3) ^. vector -- Vector3 [1,2,3]--- >>> origin & vector .~ v3 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)@@ -86,7 +94,7 @@ -- >>> point3 1 2 3 ^. unsafeCoord 2 -- 2 unsafeCoord   :: Arity d => Int -> Lens' (Point d r) r-unsafeCoord i = vector . FV.element (i-1)+unsafeCoord i = vector . singular (ix (i-1))                 -- Points are 1 indexed, vectors are 0 indexed  -- | Get the coordinate in a given dimension@@ -97,9 +105,18 @@ -- Point3 [10,2,3] -- >>> point3 1 2 3 & coord (C :: C 3) %~ (+1) -- Point3 [1,2,4]-coord   :: forall proxy i d r. (Index' (i-1) d, Arity d) => proxy i -> Lens' (Point d r) r+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)@@ -108,6 +125,10 @@ 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 @@ -128,6 +149,7 @@ pattern Point2 x y   <- (_point2 -> (x,y))   where     Point2 x y = point2 x y+{-# COMPLETE Point2 #-}  -- | Similarly, we can write: --@@ -142,47 +164,48 @@ pattern Point3 x y z <- (_point3 -> (x,y,z))   where     Point3 x y z = point3 x y z+{-# COMPLETE Point3 #-}  -- | Construct a 2 dimensional point -- -- >>> point2 1 2 -- Point2 [1,2] point2     :: r -> r -> Point 2 r-point2 x y = Point $ v2 x y+point2 x y = Point $ Vector2 x y  -- | Destruct a 2 dimensional point -- -- >>> _point2 $ point2 1 2 -- (1,2)-_point2   :: Point 2 r -> (r,r)-_point2 p = (p^.xCoord, p^.yCoord)+_point2 :: Point 2 r -> (r,r)+_point2 = (\(Vector2 x y) -> (x,y)) . toVec  + -- | Construct a 3 dimensional point -- -- >>> point3 1 2 3 -- Point3 [1,2,3] point3       :: r -> r -> r -> Point 3 r-point3 x y z = Point $ v3 x y z+point3 x y z = Point $ Vector3 x y z  -- | Destruct a 3 dimensional point -- -- >>> _point3 $ point3 1 2 3 -- (1,2,3)-_point3   :: Point 3 r -> (r,r,r)-_point3 p = (p^.xCoord, p^.yCoord, p^.zCoord)+_point3 :: Point 3 r -> (r,r,r)+_point3 = (\(Vector3 x y z) -> (x,y,z)) . toVec  -type i <=. d = (Index' (i-1) d, Arity d)- -- | 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) => Lens' (Point d r) r+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 --@@ -190,8 +213,9 @@ -- 2 -- >>> point3 1 2 3 & yCoord %~ (+1) -- Point3 [1,3,3]-yCoord :: (2 <=. d) => Lens' (Point d r) r+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 --@@ -199,9 +223,9 @@ -- 3 -- >>> point3 1 2 3 & zCoord %~ (+1) -- Point3 [1,2,4]-zCoord :: (3 <=. d) => Lens' (Point d r) r+zCoord :: (3 <= d, Arity d) => Lens' (Point d r) r zCoord = coord (C :: C 3)-+{-# INLINABLE zCoord #-}   --------------------------------------------------------------------------------@@ -235,6 +259,10 @@        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.@@ -251,7 +279,7 @@ -- | 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)+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@@ -266,7 +294,7 @@                                    (LT, GT) -> BottomRight  -- | Quadrants with respect to the origin-quadrant :: (Ord r, Num r, 1 <=. d, 2 <=. d) => Point d r :+ p -> Quadrant+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@@ -274,7 +302,7 @@ -- 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)+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]
src/Data/Geometry/PolyLine.hs view
@@ -16,6 +16,7 @@ import           Data.Semigroup import qualified Data.Seq2 as S2 import qualified Data.Sequence as Seq+import           GHC.TypeLits  -------------------------------------------------------------------------------- -- * d-dimensional Polygonal Lines (PolyLines)@@ -40,7 +41,7 @@ instance Arity d => IsBoxable (PolyLine d p r) where   boundingBox = boundingBoxList . NE.fromList . toListOf (points.traverse.core) -instance (Num r, AlwaysTruePFT d) => IsTransformable (PolyLine d p r) where+instance (Fractional r, Arity d, Arity (d + 1)) => IsTransformable (PolyLine d p r) where   transformBy = transformPointFunctor  instance PointFunctor (PolyLine d p) where@@ -77,3 +78,7 @@ asLineSegment' (PolyLine (S2.Seq2 p m q))   | Seq.null m                            = Just $ ClosedLineSegment p q   | otherwise                             = Nothing+++-- polylineEdges :: Polyline d p r -> NonEmpty.NonEmpty (LineSegment d p r)+-- polylineEdges (Polyline )
src/Data/Geometry/Polygon.hs view
@@ -1,11 +1,19 @@ {-# LANGUAGE ScopedTypeVariables  #-}+{-|+Module    : Data.Geometry.Polygon+Description: A Polygon data type and some basic functions to interact with them.+Copyright : (c) Frank Staals+License : See LICENCE file+-} module Data.Geometry.Polygon where +import           Control.DeepSeq import           Control.Lens hiding (Simple)+import           Data.Bifoldable import           Data.Bifunctor+import           Data.Bitraversable import qualified Data.CircularSeq as C import           Data.Ext-import qualified Data.List.NonEmpty as NonEmpty import qualified Data.Foldable as F import           Data.Geometry.Boundary import           Data.Geometry.Box@@ -15,12 +23,13 @@ import           Data.Geometry.Properties import           Data.Geometry.Transformation import           Data.Geometry.Vector+import qualified Data.List.NonEmpty as NonEmpty import           Data.Maybe (mapMaybe) import           Data.Proxy import           Data.Semigroup+import qualified Data.Sequence as Seq import           Data.Util-import           Frames.CoRec (asA)-+import           Data.Vinyl.CoRec (asA)  -------------------------------------------------------------------------------- -- * Polygons@@ -44,10 +53,36 @@   SimplePolygon :: C.CSeq (Point 2 r :+ p)                         -> Polygon Simple p r   MultiPolygon  :: C.CSeq (Point 2 r :+ p) -> [Polygon Simple p r] -> Polygon Multi  p r +instance Bifunctor (Polygon t) where+  bimap = bimapDefault++instance Bifoldable (Polygon t) where+  bifoldMap = bifoldMapDefault++instance Bitraversable (Polygon t) where+  bitraverse f g p = case p of+    SimplePolygon vs   -> SimplePolygon <$> bitraverseVertices f g vs+    MultiPolygon vs hs -> MultiPolygon  <$> bitraverseVertices f g vs+                                        <*> traverse (bitraverse f g) hs++instance (NFData p, NFData r) => NFData (Polygon t p r) where+  rnf (SimplePolygon vs)   = rnf vs+  rnf (MultiPolygon vs hs) = rnf (vs,hs)++bitraverseVertices     :: (Applicative f, Traversable t) => (p -> f q) -> (r -> f s)+                  -> t (Point 2 r :+ p) -> f (t (Point 2 s :+ q))+bitraverseVertices f g = traverse (bitraverse (traverse g) f)+ type SimplePolygon = Polygon Simple  type MultiPolygon  = Polygon Multi +-- | Either a simple or multipolygon+type SomePolygon p r = Either (Polygon Simple p r) (Polygon Multi p r)++type instance Dimension (SomePolygon p r) = 2+type instance NumType   (SomePolygon p r) = r+ -- | Polygons are per definition 2 dimensional type instance Dimension (Polygon t p r) = 2 type instance NumType   (Polygon t p r) = r@@ -64,12 +99,30 @@   pmap f (SimplePolygon vs)   = SimplePolygon (fmap (first f) vs)   pmap f (MultiPolygon vs hs) = MultiPolygon  (fmap (first f) vs) (map (pmap f) hs) -instance Num r => IsTransformable (Polygon t p r) where+instance Fractional r => IsTransformable (Polygon t p r) where   transformBy = transformPointFunctor  instance IsBoxable (Polygon t p r) where   boundingBox = boundingBoxList' . toListOf (outerBoundary.traverse.core) +type instance IntersectionOf (Line 2 r) (Boundary (Polygon t p r)) =+  '[Seq.Seq (Either (Point 2 r) (LineSegment 2 () r))]++-- instance IsIntersectableWith (Line 2 r) (Boundary (Polygon t p r)) where+--   nonEmptyIntersection _ _ (CoRec xs) = null xs+--   l `intersect` (Boundary (SimplePolygon vs)) =+--     undefined+  -- l `intersect` (Boundary (MultiPolygon vs hs)) = coRec .+  --    Seq.sortBy f . Seq.fromList+  --     . concatMap (unpack . (l `intersect`) . Boundary)+  --     $ SimplePolygon vs : hs+  --   where+  --     unpack (CoRec x) = x+  --     f = undefined++++ -- * Functions on Polygons  outerBoundary :: forall t p r. Lens' (Polygon t p r) (C.CSeq (Point 2 r :+ p))@@ -84,8 +137,8 @@     s (SimplePolygon _)      vs = SimplePolygon vs     s (MultiPolygon  _   hs) vs = MultiPolygon vs hs -holes :: forall p r. Lens' (Polygon Multi p r) [Polygon Simple p r]-holes = lens g s+polygonHoles :: forall p r. Lens' (Polygon Multi p r) [Polygon Simple p r]+polygonHoles = lens g s   where     g                     :: Polygon Multi p r -> [Polygon Simple p r]     g (MultiPolygon _ hs) = hs@@ -120,15 +173,47 @@   sconcat $ C.toNonEmpty vs NonEmpty.:| map polygonVertices hs  -+-- | Creates a simple polygon from the given list of vertices.+--+-- pre: the input list constains no repeated vertices. fromPoints :: [Point 2 r :+ p] -> SimplePolygon p r fromPoints = SimplePolygon . C.fromList + -- | The edges along the outer boundary of the polygon. The edges are half open.+--+-- running time: \(O(n)\) outerBoundaryEdges :: Polygon t p r -> C.CSeq (LineSegment 2 p r) outerBoundaryEdges = toEdges . (^.outerBoundary) +-- | Lists all edges. The edges on the outer boundary are given before the ones+-- on the holes. However, no other guarantees are given on the order.+--+-- running time: \(O(n)\)+listEdges    :: Polygon t p r -> [LineSegment 2 p r]+listEdges pg = let f = F.toList . outerBoundaryEdges+               in  f pg <> concatMap f (holeList pg) +-- | Pairs every vertex with its incident edges. The first one is its+-- predecessor edge, the second one its successor edge.+--+-- >>> 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] :+ ()))+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)+withIncidentEdges (MultiPolygon vs hs) = MultiPolygon vs' hs'+  where+    (SimplePolygon vs') = withIncidentEdges $ SimplePolygon vs+    hs' = map withIncidentEdges hs+ -- -- | Gets the i^th edge on the outer boundary of the polygon, that is the edge ---- with vertices i and i+1 with respect to the current focus. All indices -- -- modulo n.@@ -284,25 +369,29 @@ -- | Test if the outer boundary of the polygon is in clockwise or counter -- clockwise order. ----- running time: \(O(1)\)+-- running time: \(O(n)\) -- isCounterClockwise :: (Eq r, Fractional r) => Polygon t p r -> Bool isCounterClockwise = (\x -> x == abs x) . signedArea-                   . fromPoints . take 3 . F.toList . (^.outerBoundary)+                   . fromPoints . F.toList . (^.outerBoundary)   -- | Orient the outer boundary to clockwise order toClockwiseOrder         :: (Eq r, Fractional r) => Polygon t p r -> Polygon t p r toClockwiseOrder p-  | isCounterClockwise p = p&outerBoundary %~ C.reverseDirection+  | isCounterClockwise p = reverseOuterBoundary p   | otherwise            = p  -- | Orient the outer boundary to counter clockwise order toCounterClockWiseOrder    :: (Eq r, Fractional r) => Polygon t p r -> Polygon t p r toCounterClockWiseOrder p-  | not $ isCounterClockwise p = p&outerBoundary %~ C.reverseDirection+  | not $ isCounterClockwise p = reverseOuterBoundary p   | otherwise                  = p +reverseOuterBoundary   :: Polygon t p r -> Polygon t p r+reverseOuterBoundary p = p&outerBoundary %~ C.reverseDirection++ -- | Convert a Polygon to a simple polygon by forgetting about any holes. asSimplePolygon                        :: Polygon t p r -> SimplePolygon p r asSimplePolygon poly@(SimplePolygon _) = poly@@ -324,3 +413,14 @@ extremesLinear u p = let vs = p^.outerBoundary                          f  = cmpExtreme u                      in (F.minimumBy f vs, F.maximumBy f vs)+++-- | assigns unique integer numbers to all vertices. Numbers start from 0, and+-- are increasing along the outer boundary. The vertices of holes+-- will be numbered last, in the same order.+--+-- >>> numberVertices simplePoly+-- SimplePolygon 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 ()]+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/Polygon/Convex.hs view
@@ -20,35 +20,42 @@                                    , bottomMost                                    ) where +import           Control.DeepSeq import           Control.Lens hiding ((:<), (:>)) import           Data.CircularSeq (focus,CSeq) import qualified Data.CircularSeq as C import           Data.Ext import qualified Data.Foldable as F import           Data.Function (on, )-import           Data.Geometry import           Data.Geometry.Box (IsBoxable(..))-import           Data.Geometry.Polygon (fromPoints, cmpExtreme)+import           Data.Geometry.LineSegment+import           Data.Geometry.Point+import           Data.Geometry.Polygon (fromPoints, SimplePolygon, cmpExtreme, outerBoundary) import           Data.Geometry.Properties+import           Data.Geometry.Transformation+import           Data.Geometry.Vector import           Data.Maybe (fromJust) import           Data.Ord (comparing) import           Data.Sequence (viewl,viewr, ViewL(..), ViewR(..)) import qualified Data.Sequence as S  -- import           Data.Geometry.Ipe-import           Debug.Trace+-- import           Debug.Trace --------------------------------------------------------------------------------  newtype ConvexPolygon p r = ConvexPolygon {_simplePolygon :: SimplePolygon p r }-                          deriving (Show,Eq,PointFunctor)+                          deriving (Show,Eq,NFData) makeLenses ''ConvexPolygon +instance PointFunctor (ConvexPolygon p) where+  pmap f (ConvexPolygon p) = ConvexPolygon $ pmap f p+ -- | Polygons are per definition 2 dimensional type instance Dimension (ConvexPolygon p r) = 2 type instance NumType   (ConvexPolygon p r) = r  -instance Num r => IsTransformable (ConvexPolygon p r) where+instance Fractional r => IsTransformable (ConvexPolygon p r) where   transformBy = transformPointFunctor  instance IsBoxable (ConvexPolygon p r) where@@ -349,14 +356,14 @@ --                   nxt = focus' xs' --               in if p cur nxt then go xs' else xs -test1 :: Num r => ConvexPolygon () r-test1 = ConvexPolygon . fromPoints . map ext . reverse $ [origin, point2 1 4, point2 5 6, point2 10 3]+-- test1 :: Num r => ConvexPolygon () r+-- test1 = ConvexPolygon . fromPoints . map ext . reverse $ [origin, point2 1 4, point2 5 6, point2 10 3] -test2 :: Num r => ConvexPolygon () r-test2 = ConvexPolygon . fromPoints . map ext . reverse $ [point2 11 6, point2 10 10, point2 15 18, point2 12 5]+-- test2 :: Num r => ConvexPolygon () r+-- test2 = ConvexPolygon . fromPoints . map ext . reverse $ [point2 11 6, point2 10 10, point2 15 18, point2 12 5] -testA :: Num r => ConvexPolygon () r-testA = ConvexPolygon . fromPoints . map ext $ [origin, point2 5 1, point2 2 2]+-- testA :: Num r => ConvexPolygon () r+-- testA = ConvexPolygon . fromPoints . map ext $ [origin, point2 5 1, point2 2 2] -testB :: Num r => ConvexPolygon () r-testB = ConvexPolygon . fromPoints . map ext $ [origin, point2 5 3, point2 (-2) 2, point2 (-2) 1]+-- testB :: Num r => ConvexPolygon () r+-- testB = ConvexPolygon . fromPoints . map ext $ [origin, point2 5 3, point2 (-2) 2, point2 (-2) 1]
src/Data/Geometry/Properties.hs view
@@ -2,19 +2,23 @@ {-# LANGUAGE ImpredicativeTypes #-} {-# LANGUAGE UnicodeSyntax #-} {-# LANGUAGE DefaultSignatures #-}+{-|+Module    : Data.Geometry.Properties+Description: Defines some generic geometric properties e.g. Dimensions, NumType, and Intersection types.+Copyright : (c) Frank Staals+License : See LICENCE file+-} module Data.Geometry.Properties where -import           Data.Maybe(isNothing)-import           Data.Proxy-import           Data.Vinyl.Core-import           Data.Vinyl.Functor-import           Data.Vinyl.Lens-import           Frames.CoRec-import           GHC.TypeLits--+import Data.Maybe (isNothing)+import Data.Proxy+import Data.Vinyl.CoRec+import Data.Vinyl.Core+import Data.Vinyl.Functor+import Data.Vinyl.Lens+import GHC.TypeLits ---------------------------------------------------------------------------------+-------------------------------------------------------------------------------  -- | A type family for types that are associated with a dimension. The -- dimension is the dimension of the geometry they are embedded in.@@ -35,7 +39,7 @@  -- | Helper to produce a corec coRec :: (a ∈ as) => a -> CoRec Identity as-coRec = Col . Identity+coRec = CoRec . Identity   class IsIntersectableWith g h where@@ -51,7 +55,7 @@    -- | Helper to implement `intersects`.   nonEmptyIntersection :: proxy g -> proxy h -> Intersection g h -> Bool-  {-# MINIMAL intersect , nonEmptyIntersection #-}+  {-# MINIMAL intersect, nonEmptyIntersection #-}    default nonEmptyIntersection :: ( NoIntersection ∈ IntersectionOf g h                                   , RecApplicative (IntersectionOf g h)
src/Data/Geometry/SegmentTree/Generic.hs view
@@ -21,13 +21,11 @@ import           Data.BinaryTree import           Data.Ext import           Data.Geometry.Interval-import           Data.Geometry.Interval.Util import           Data.Geometry.IntervalTree (IntervalLike(..)) import           Data.Geometry.Properties import qualified Data.List as List import           Data.List.NonEmpty (NonEmpty) import qualified Data.List.NonEmpty as NonEmpty-import           Data.Range import           Data.Semigroup import           GHC.Generics (Generic) 
src/Data/Geometry/Slab.hs view
@@ -2,7 +2,7 @@ {-# Language TemplateHaskell #-} module Data.Geometry.Slab where -import           Control.Lens (makeLenses, (^.),(%~),(.~),(&), both)+import           Control.Lens (makeLenses, (^.),(%~),(.~),(&), both, from) import           Data.Bifunctor import           Data.Ext import qualified Data.Foldable as F@@ -15,7 +15,7 @@ import           Data.Geometry.SubLine import qualified Data.Traversable as T import           Data.Vinyl-import           Frames.CoRec+import           Data.Vinyl.CoRec  -------------------------------------------------------------------------------- @@ -141,6 +141,21 @@     where       dropExtra sub = sub&subRange %~ bimap (const ()) id       singleton p = let x = ext $ toOffset p l in SubLine l (ClosedInterval x x)+++type instance IntersectionOf (LineSegment 2 p r) (Slab o a r) =+  [NoIntersection, LineSegment 2 () r]++instance (Fractional r, Ord r, HasBoundingLines o) =>+         LineSegment 2 a r `IsIntersectableWith` (Slab o a r) where+  nonEmptyIntersection = defaultNonEmptyIntersection++  seg `intersect` slab = match ((seg^._SubLine) `intersect` slab) $+       (H $ \NoIntersection -> coRec   NoIntersection)+    :& (H $ \sl             -> coRec $ sl^. from _SubLine)+    :& RNil++   test :: SubLine 2 () Double
src/Data/Geometry/SubLine.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE TemplateHaskell  #-}+{-# LANGUAGE UndecidableInstances  #-} module Data.Geometry.SubLine where  import           Control.Lens@@ -12,11 +13,11 @@ import qualified Data.Traversable as T import           Data.UnBounded import           Data.Vinyl-import           Frames.CoRec+import           Data.Vinyl.CoRec  -------------------------------------------------------------------------------- --- | Part of a line. The interval is ranged based on the unit-vector of the+-- | Part of a line. The interval is ranged based on the vector of the -- line l, and s.t.t zero is the anchorPoint of l. data SubLine d p r = SubLine { _line     :: Line d r                              , _subRange :: Interval p r@@ -34,12 +35,17 @@ deriving instance Arity d                   => F.Foldable (SubLine d p) deriving instance Arity d                   => T.Traversable (SubLine d p) +instance Arity d => Bifunctor (SubLine d) where+  bimap f g (SubLine l r) = SubLine (g <$> l) (bimap f g r) + -- | Get the point at the given position along line, where 0 corresponds to the -- anchorPoint of the line, and 1 to the point anchorPoint .+^ directionVector pointAt              :: (Num r, Arity d) => r -> Line d r -> Point d r pointAt a (Line p v) = p .+^ (a *^ v) ++ -- | Annotate the subRange with the actual ending points fixEndPoints    :: (Num r, Arity d) => SubLine d p r -> SubLine d (Point d r :+ p) r fixEndPoints sl = sl&subRange %~ f@@ -63,31 +69,52 @@                                                                , SubLine 2 p r                                                                ] +-- | given point p, and a Subline l r such that p lies on line l, test if it+-- lies on the subline, i.e. in the interval r+onSubLine                 :: (Ord r, Fractional r, Arity d)+                          => Point d r -> SubLine d p r -> Bool+onSubLine p (SubLine l r) = toOffset p l `inInterval` r +-- | given point p, and a Subline l r such that p lies on line l, test if it+-- lies on the subline, i.e. in the interval r+onSubLine2        :: (Ord r, Num r) => Point 2 r -> SubLine 2 p r -> Bool+p `onSubLine2` sl = d `inInterval` r+  where+    -- get the endpoints (a,b) of the subline+    SubLine _ (Interval s e) = fixEndPoints sl+    a = s^.unEndPoint.extra.core+    b = e^.unEndPoint.extra.core+    d = (p .-. a) `dot` (b .-. a)+    -- map to an interval corresponding to the length of the segment+    r = Interval (s&unEndPoint.core .~ 0) (e&unEndPoint.core .~ squaredEuclideanDist b a)+      -- note that we take the dist between b and a, so if these are infinity+      -- we get maxInfinity as well+ instance (Ord r, Fractional r) =>          (SubLine 2 p r) `IsIntersectableWith` (SubLine 2 p r) where    nonEmptyIntersection = defaultNonEmptyIntersection -  (SubLine l r) `intersect` (SubLine m s) = match (l `intersect` m) $+  sl@(SubLine l r) `intersect` sm@(SubLine m _) = match (l `intersect` m) $          (H $ \NoIntersection -> coRec NoIntersection)-      :& (H $ \p@(Point _)    -> if (toOffset p l) `inInterval` r-                                    &&-                                    (toOffset p m) `inInterval` s+      :& (H $ \p@(Point _)    -> if onSubLine2 p sl && onSubLine2 p sm                                  then coRec p                                  else coRec NoIntersection)-      :& (H $ \_             -> match (r `intersect` s') $+      :& (H $ \_             -> match (r `intersect` s'') $                                       (H $ \NoIntersection -> coRec NoIntersection)                                    :& (H $ \i              -> coRec $ SubLine l i)                                    :& RNil            )       :& RNil     where-      s' = shiftLeft' (toOffset (m^.anchorPoint) l) s-+      -- s' = shiftLeft' (toOffset (m^.anchorPoint) l) $ s+      s'  = (fixEndPoints sm)^.subRange+      s'' = bimap (^.extra) id+          $ s'&start.core .~ toOffset (s'^.start.extra.core) l+              &end.core   .~ toOffset (s'^.end.extra.core)   l  fromLine   :: Arity d => Line d r -> SubLine d () (UnBounded r)-fromLine l = SubLine (fmap Val l) (OpenInterval (ext MinInfinity) (ext MaxInfinity))+fromLine l = SubLine (fmap Val l) (ClosedInterval (ext MinInfinity) (ext MaxInfinity))   -- testL :: SubLine 2 () (UnBounded Rational)
src/Data/Geometry/Transformation.hs view
@@ -38,21 +38,21 @@ -- * Transformations  -- | A type representing a Transformation for d dimensional objects-newtype Transformation d r = Transformation { _transformationMatrix :: Matrix (1 + d) (1 + d) r }+newtype Transformation d r = Transformation { _transformationMatrix :: Matrix (d + 1) (d + 1) r } -transformationMatrix :: Lens' (Transformation d r) (Matrix (1 + d) (1 + d) r)+transformationMatrix :: Lens' (Transformation d r) (Matrix (d + 1) (d + 1) r) transformationMatrix = lens _transformationMatrix (const Transformation) -deriving instance (Show r, Arity (1 + d)) => Show (Transformation d r)-deriving instance (Eq r, Arity (1 + d))   => Eq (Transformation d r)-deriving instance (Ord r, Arity (1 + d))  => Ord (Transformation d r)-deriving instance Arity (1 + d)           => Functor (Transformation d)+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)  type instance NumType (Transformation d r) = r   -- | Compose transformations (right to left)-(|.|) :: (Num r, Arity (1 + d)) => Transformation d r -> Transformation d r -> Transformation d r+(|.|) :: (Num r, Arity (d + 1)) => Transformation d r -> Transformation d r -> Transformation d r (Transformation f) |.| (Transformation g) = Transformation $ f `multM` g  --------------------------------------------------------------------------------@@ -67,55 +67,55 @@ transformAllBy t = fmap (transformBy t)  -type AlwaysTruePFT d = AlwaysTrueDestruct d  (1 + d)---transformPointFunctor   :: ( PointFunctor g, Num r, d ~ Dimension (g r)-                           , AlwaysTruePFT d+transformPointFunctor   :: ( PointFunctor g, Fractional r, d ~ Dimension (g r)+                           , Arity d, Arity (d + 1)                            ) => Transformation d r -> g r -> g r transformPointFunctor t = pmap (transformBy t) -instance ( Num r-         , Arity d, AlwaysTrueDestruct d (1 + d)-         ) => IsTransformable (Point d r) where-  transformBy (Transformation m) (Point v) = Point . V.init $ m `mult` v'+instance (Fractional r, Arity d, Arity (d + 1))+         => IsTransformable (Point d r) where+  transformBy t = Point . transformBy t . toVec++instance (Fractional r, Arity d, Arity (d + 1))+         => IsTransformable (Vector d r) where+  transformBy (Transformation m) v = f $ m `mult` snoc v 1     where-      v'    = snoc v 1+      f u   = (/ V.last u) <$> V.init u   -------------------------------------------------------------------------------- -- * Common transformations -translation   :: ( Num r, Arity (1 + d)-                 , AlwaysTrueSnoc d, Arity d, Index' (1+d-1) (1+d))+translation   :: (Num r, Arity d, Arity (d + 1))               => Vector d r -> Transformation d r translation v = Transformation . Matrix $ V.imap transRow (snoc v 1)  -scaling   :: (Num r, Arity (1 + d), AlwaysTrueSnoc d, Arity d) => Vector d r -> Transformation d r+scaling   :: (Num r, Arity d, Arity (d + 1))+          => Vector d r -> Transformation d r scaling v = Transformation . Matrix $ V.imap mkRow (snoc v 1) -uniformScaling :: (Num r, Arity (1 + d), AlwaysTrueSnoc d, Arity d) => r -> Transformation d r+uniformScaling :: (Num r, Arity d, Arity (d + 1)) => r -> Transformation d r uniformScaling = scaling . pure  -------------------------------------------------------------------------------- -- * Functions that execute transformations -type AlwaysTrueTransformation d = (Arity (1 + d), AlwaysTrueSnoc d, Arity d, Index' (1+d-1) (1+d))+-- type AlwaysTrueTransformation d = (Arity (1 + d), AlwaysTrueSnoc d, Arity d, Index' (1+d-1) (1+d))  translateBy :: ( IsTransformable g, Num (NumType g)-               , AlwaysTrueTransformation (Dimension g)+               , Arity (Dimension g), Arity (Dimension g + 1)                ) => Vector (Dimension g) (NumType g) -> g -> g translateBy = transformBy . translation  scaleBy :: ( IsTransformable g, Num (NumType g)-           , AlwaysTrueTransformation (Dimension g)+           , Arity (Dimension g), Arity (Dimension g + 1)            ) => Vector (Dimension g) (NumType g) -> g -> g scaleBy = transformBy . scaling   scaleUniformlyBy :: ( IsTransformable g, Num (NumType g)-                    , AlwaysTrueTransformation (Dimension g)+                    , Arity (Dimension g), Arity (Dimension g + 1)                     ) => NumType g -> g -> g scaleUniformlyBy = transformBy  . uniformScaling @@ -129,5 +129,10 @@ mkRow i x = set (FV.element i) x zero  -- | Row in a translation matrix-transRow     :: forall n r. (Arity n, Index' (n-1) n, Num r) => Int -> r -> Vector n r-transRow i x = set (V.element (Proxy :: Proxy (n-1))) x $ mkRow i 1+-- transRow     :: forall n r. ( Arity n, Arity (n- 1), ((n - 1) + 1) ~ n+--                             , Num r) => Int -> r -> Vector n r+-- transRow i x = set (V.element (Proxy :: Proxy (n-1))) x $ mkRow i 1++transRow     :: forall n r. (Arity n, Arity (n + 1), Num r)+             => Int -> r -> Vector (n + 1) r+transRow i x = set (V.element (Proxy :: Proxy n)) x $ mkRow i 1
src/Data/Geometry/Triangle.hs view
@@ -1,39 +1,43 @@ {-# LANGUAGE DeriveFunctor #-}+{-# LANGUAGE UndecidableInstances #-} module Data.Geometry.Triangle where  import Data.Bifunctor import Control.Lens import Data.Ext import Data.Geometry.Point+import Data.Geometry.Vector import Data.Geometry.Ball import Data.Geometry.Properties import Data.Geometry.Transformation+import GHC.TypeLits -data Triangle p r = Triangle (Point 2 r :+ p)-                             (Point 2 r :+ p)-                             (Point 2 r :+ p)-                    deriving (Show,Eq)+data Triangle d p r = Triangle (Point d r :+ p)+                               (Point d r :+ p)+                               (Point d r :+ p) -instance Functor (Triangle p) where+deriving instance (Arity d, Show r, Show p) => Show (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)  -type instance NumType   (Triangle p r) = r-type instance Dimension (Triangle p r) = 2+type instance NumType   (Triangle d p r) = r+type instance Dimension (Triangle d p r) = d -instance PointFunctor (Triangle p) where+instance PointFunctor (Triangle d p) where   pmap f (Triangle p q r) = Triangle (p&core %~ f) (q&core %~ f) (r&core %~ f) -instance Num r => IsTransformable (Triangle d r) where+instance (Fractional r, Arity d, Arity (d + 1)) => IsTransformable (Triangle d p r) where   transformBy = transformPointFunctor   -- | Compute the area of a triangle-area   :: Fractional r => Triangle p r -> r+area   :: Fractional r => Triangle 2 p r -> r area t = doubleArea t / 2  -- | 2*the area of a triangle.-doubleArea                  :: Num r => Triangle p r -> r+doubleArea                  :: Num r => Triangle 2 p r -> r doubleArea (Triangle a b c) = abs $ ax*by - ax*cy                                   + bx*cy - bx*ay                                   + cx*ay - cx*by@@ -46,5 +50,6 @@  -- | get the inscribed disk. Returns Nothing if the triangle is degenerate, -- i.e. if the points are colinear.-inscribedDisk                  :: (Eq r, Fractional r) => Triangle p r -> Maybe (Disk () r)+inscribedDisk                  :: (Eq r, Fractional r)+                               => Triangle 2 p r -> Maybe (Disk () r) inscribedDisk (Triangle p q r) = disk (p^.core) (q^.core) (r^.core)
src/Data/Geometry/Vector.hs view
@@ -1,46 +1,55 @@-module Data.Geometry.Vector( module Data.Geometry.Vector.VectorFixed+module Data.Geometry.Vector( module Data.Geometry.Vector.VectorFamily                            , module LV+                           , C(..)                            , Affine(..)                            , qdA, distanceA-                           , dot, norm+                           , dot, norm, signorm                            , isScalarMultipleOf                            , scalarMultiple+                           -- reexports+                           , FV.replicate+                           , FV.imap,                            ) where +import           Control.Applicative (liftA2) import qualified Data.Foldable as F-import           Data.Geometry.Vector.VectorFixed-import           Data.Geometry.Vector.VectorFixed as GV+import           Data.Geometry.Properties+import           Data.Geometry.Vector.VectorFamily+import           Data.Geometry.Vector.VectorFixed(C(..)) import           Data.Maybe+import           Data.Semigroup import qualified Data.Vector.Fixed as FV import           Linear.Affine (Affine(..), qdA, distanceA)-import           Linear.Metric (dot,norm)+import           Linear.Metric (dot,norm,signorm) import           Linear.Vector as LV  -------------------------------------------------------------------------------- +type instance Dimension (Vector d r) = d+type instance NumType (Vector d r) =r  -- | Test if v is a scalar multiple of u. ----- >>> v2 1 1 `isScalarMultipleOf` v2 10 10+-- >>> Vector2 1 1 `isScalarMultipleOf` Vector2 10 10 -- True--- >>> v2 1 1 `isScalarMultipleOf` v2 10 1+-- >>> Vector2 1 1 `isScalarMultipleOf` Vector2 10 1 -- False--- >>> v2 1 1 `isScalarMultipleOf` v2 11.1 11.1+-- >>> Vector2 1 1 `isScalarMultipleOf` Vector2 11.1 11.1 -- True--- >>> v2 1 1 `isScalarMultipleOf` v2 11.1 11.2+-- >>> Vector2 1 1 `isScalarMultipleOf` Vector2 11.1 11.2 -- False--- >>> v2 2 1 `isScalarMultipleOf` v2 11.1 11.2+-- >>> Vector2 2 1 `isScalarMultipleOf` Vector2 11.1 11.2 -- False--- >>> v2 2 1 `isScalarMultipleOf` v2 4 2+-- >>> Vector2 2 1 `isScalarMultipleOf` Vector2 4 2 -- True--- >>> v2 2 1 `isScalarMultipleOf` v2 4 0+-- >>> Vector2 2 1 `isScalarMultipleOf` Vector2 4 0 -- False-isScalarMultipleOf       :: (Eq r, Fractional r, GV.Arity d)+isScalarMultipleOf       :: (Eq r, Fractional r, Arity d)                          => Vector d r -> Vector d r -> Bool u `isScalarMultipleOf` v = isJust $ scalarMultiple u v  -- | Get the scalar labmda s.t. v = lambda * u (if it exists)-scalarMultiple     :: (Eq r, Fractional r, GV.Arity d)+scalarMultiple     :: (Eq r, Fractional r, Arity d)                    => Vector d r -> Vector d r -> Maybe r scalarMultiple u v       | allZero u || allZero v = Just 0@@ -60,27 +69,30 @@ --     allLambda (_, myLambda) (b,Just lambda) = (myLambda == lambda && b, Just lambda)  -allZero :: (GV.Arity d, Eq r, Num r) => Vector d r -> Bool+allZero :: (Arity d, Eq r, Num r) => Vector d r -> Bool allZero = F.all (== 0)   data ScalarMultiple r = No | Maybe | Yes r deriving (Eq,Show) -instance Eq r => Monoid (ScalarMultiple r) where-  mempty = Maybe--  No      `mappend` _       = No-  _       `mappend` No      = No-  Maybe   `mappend` x       = x-  x       `mappend` Maybe   = x-  (Yes x) `mappend` (Yes y)+instance Eq r => Semigroup (ScalarMultiple r) where+  No      <> _       = No+  _       <> No      = No+  Maybe   <> x       = x+  x       <> Maybe   = x+  (Yes x) <> (Yes y)      | x == y               = Yes x      | otherwise            = No  -scalarMultiple'      :: (Eq r, Fractional r, GV.Arity d)+instance Eq r => Monoid (ScalarMultiple r) where+  mempty = Maybe+  mappend = (<>)++-- | Actual implementation of scalarMultiple+scalarMultiple'      :: (Eq r, Fractional r, Arity d)                      => Vector d r -> Vector d r -> Maybe r-scalarMultiple' u v = g . F.foldr mappend mempty $ FV.zipWith f u v+scalarMultiple' u v = g . F.foldr mappend mempty $ liftA2 f u v   where     f 0  0  = Maybe -- we don't know lambda yet, but it may still be a scalar mult.     f _  0  = No      -- Not a scalar multiple
+ src/Data/Geometry/Vector/VectorFamily.hs view
@@ -0,0 +1,156 @@+{-# LANGUAGE ScopedTypeVariables  #-}+{-# LANGUAGE UndecidableInstances #-}+module Data.Geometry.Vector.VectorFamily where++import           Control.DeepSeq+import           Control.Lens hiding (element)+import           Data.Aeson+-- import           Data.Aeson (ToJSON(..),FromJSON(..))+import qualified Data.Foldable as F+import qualified Data.List as L+import           Data.Geometry.Vector.VectorFixed (C(..))+import qualified Data.Geometry.Vector.VectorFamilyPeano as Fam+import           Data.Geometry.Vector.VectorFamilyPeano ( VectorFamily(..)+                                                        , VectorFamilyF+                                                        , ImplicitArity+                                                        )+import           Data.Semigroup+import qualified Data.Vector.Fixed as V+import           Data.Vector.Fixed.Cont (Peano)+import           GHC.TypeLits+import           Linear.Affine (Affine(..))+import           Linear.Metric+import qualified Linear.V2 as L2+import qualified Linear.V3 as L3+import qualified Linear.V4 as L4+import           Linear.Vector+++--------------------------------------------------------------------------------+-- * d dimensional Vectors+++-- | Datatype representing d dimensional vectors. The default implementation is+-- based n VectorFixed. However, for small vectors we automatically select a+-- more efficient representation.+newtype Vector (d :: Nat) (r :: *) = MKVector { _unV :: VectorFamily (Peano d) r }++type instance V.Dim   (Vector d)   = Fam.FromPeano (Peano d)+-- the above definition is a bit convoluted, but it allows us to make Vector an instance of+-- V.Vector having only an Arity constraint rather than an Arity2 constraint.+type instance Index   (Vector d r) = Int+type instance IxValue (Vector d r) = r++unV :: Lens (Vector d r) (Vector d s) (VectorFamily (Peano d) r) (VectorFamily (Peano d) s)+unV = lens _unV (const MKVector)+{-# INLINE unV #-}++type Arity d = (ImplicitArity (Peano d), KnownNat d)++deriving instance (Eq r,  Arity d) => Eq  (Vector d r)+deriving instance (Ord r, Arity d) => Ord (Vector d r)++deriving instance Arity d => Functor     (Vector d)+deriving instance Arity d => Foldable    (Vector d)+deriving instance Arity d => Traversable (Vector d)+deriving instance Arity d => Applicative (Vector d)++deriving instance Arity d => Additive (Vector d)+deriving instance Arity d => Metric (Vector d)+deriving instance Arity d => Affine (Vector d)++instance Arity d => Ixed (Vector d r) where+  ix = element'++instance Arity d => V.Vector (Vector d) r where+  construct  = MKVector <$> V.construct+  inspect    = V.inspect . _unV+  basicIndex = V.basicIndex . _unV++instance (Arity d, Show r) => Show (Vector d r) where+  show v = mconcat [ "Vector", show $ F.length v , " "+                   , show $ F.toList v ]++deriving instance (FromJSON r, Arity d) => FromJSON (Vector d r)+instance (ToJSON r, Arity d) => ToJSON (Vector d r) where+  toJSON     = toJSON . _unV+  toEncoding = toEncoding . _unV++deriving instance (NFData r, Arity d) => NFData (Vector d r)++--------------------------------------------------------------------------------+-- * Convenience "constructors"++pattern Vector   :: VectorFamilyF (Peano d) r -> Vector d r+pattern Vector v = MKVector (VectorFamily v)++pattern Vector1   :: r -> Vector 1 r+pattern Vector1 x = (Vector (Identity x))++pattern Vector2     :: r -> r -> Vector 2 r+pattern Vector2 x y = (Vector (L2.V2 x y))++pattern Vector3        :: r -> r -> r -> Vector 3 r+pattern Vector3 x y z  = (Vector (L3.V3 x y z))++pattern Vector4         :: r -> r -> r -> r -> Vector 4 r+pattern Vector4 x y z w = (Vector (L4.V4 x y z w))++--------------------------------------------------------------------------------++vectorFromList :: Arity d => [r] -> Maybe (Vector d r)+vectorFromList = V.fromListM++vectorFromListUnsafe :: Arity d => [r] -> Vector d r+vectorFromListUnsafe = V.fromList++destruct   :: (Arity d, Arity (d + 1))+           => Vector (d + 1) r -> (r, Vector d r)+destruct v = (head $ F.toList v, vectorFromListUnsafe . tail $ F.toList v)+  -- FIXME: this implementaion of tail is not particularly nice++--------------------------------------------------------------------------------+-- * Indexing vectors++-- | Lens into the i th element+element   :: forall proxy i d r. (Arity d, KnownNat i, (i + 1) <= d)+          => proxy i -> Lens' (Vector d r) r+element _ = singular . element' . fromInteger $ natVal (C :: C i)+{-# INLINE element #-}+++-- | Similar to 'element' above. Except that we don't have a static guarantee+-- that the index is in bounds. Hence, we can only return a Traversal+element' :: forall d r. Arity d => Int -> Traversal' (Vector d r) r+element' i = unV.(e (C :: C d) i)+  where+    e  :: Arity d => proxy d -> Int -> Traversal' (VectorFamily (Peano d) r) r+    e _ = Fam.element'+{-# INLINE element' #-}++--------------------------------------------------------------------------------+-- * Snoccing and consindg++-- | Add an element at the back of the vector+snoc     :: (Arity (d + 1), Arity d) => Vector d r -> r -> Vector (d + 1) r+snoc v x = vectorFromListUnsafe . (++ [x]) $ F.toList v+  -- FIXME: horrible implementation here as well++-- | Get a vector of the first d - 1 elements.+init :: (Arity d, Arity (d + 1)) => Vector (d + 1) r -> Vector d r+init = vectorFromListUnsafe . L.init . F.toList++last :: forall d r. (KnownNat d, Arity (d + 1)) => Vector (d + 1) r -> r+last = view $ element (C :: C d)++-- | Get a prefix of i elements of a vector+prefix :: forall i d r. (Arity d, Arity i, i <= d)+       => Vector d r -> Vector i r+prefix = let i = fromInteger . natVal $ (C :: C i)+         in vectorFromListUnsafe . take i . F.toList++--------------------------------------------------------------------------------+-- * Specific on 3-dimensional vectors+-- | Cross product of two three-dimensional vectors+cross       :: Num r => Vector 3 r -> Vector 3 r -> Vector 3 r+(Vector u) `cross` (Vector v) = Vector $ u `L3.cross` v
+ src/Data/Geometry/Vector/VectorFamilyPeano.hs view
@@ -0,0 +1,291 @@+{-# LANGUAGE ScopedTypeVariables  #-}+{-# LANGUAGE UndecidableInstances #-}+module Data.Geometry.Vector.VectorFamilyPeano where++import           Control.Applicative (liftA2)+import           Control.DeepSeq+import           Control.Lens hiding (element)+import           Data.Aeson(FromJSON(..),ToJSON(..))+-- import           Data.Aeson (ToJSON(..),FromJSON(..))+import qualified Data.Foldable as F+import qualified Data.Geometry.Vector.VectorFixed as FV+import           Data.Maybe (fromMaybe)+import           Data.Proxy+import           Data.Semigroup+import           Data.Traversable (foldMapDefault,fmapDefault)+import qualified Data.Vector.Fixed as V+import qualified Data.Vector.Fixed.Cont as Cont+import           Data.Vector.Fixed.Cont (Peano(..), PeanoNum(..), Fun(..))+import           GHC.TypeLits+import           Linear.Affine (Affine(..))+import           Linear.Metric+import qualified Linear.V2 as L2+import qualified Linear.V3 as L3+import qualified Linear.V4 as L4+import           Linear.Vector++--------------------------------------------------------------------------------+-- * Natural number stuff++type One = S Z+type Two = S One+type Three = S Two+type Four = S Three+type Many d = S (S (S (S (S d))))+++type family FromPeano (d :: PeanoNum) :: Nat where+  FromPeano Z     = 0+  FromPeano (S d) = 1 + FromPeano d+++data SingPeano (d :: PeanoNum) where+  SZ :: SingPeano Z+  SS :: !(SingPeano d) -> SingPeano (S d)++class ImplicitPeano (d :: PeanoNum) where+  implicitPeano :: SingPeano d+instance ImplicitPeano Z where+  implicitPeano = SZ+instance ImplicitPeano d => ImplicitPeano (S d) where+  implicitPeano = SS implicitPeano++--------------------------------------------------------------------------------+-- * d dimensional Vectors++-- | Datatype representing d dimensional vectors. The default implementation is+-- based n VectorFixed. However, for small vectors we automatically select a+-- more efficient representation.+newtype VectorFamily (d :: PeanoNum) (r :: *) =+  VectorFamily { _unVF :: VectorFamilyF d r }++-- | Mapping between the implementation type, and the actual implementation.+type family VectorFamilyF (d :: PeanoNum) :: * -> * where+  VectorFamilyF Z        = Const ()+  VectorFamilyF One      = Identity+  VectorFamilyF Two      = L2.V2+  VectorFamilyF Three    = L3.V3+  VectorFamilyF Four     = L4.V4+  VectorFamilyF (Many d) = FV.Vector (FromPeano (Many d))++type instance V.Dim (VectorFamily d)  = FromPeano d+type instance Index   (VectorFamily d r) = Int+type instance IxValue (VectorFamily d r) = r++type instance V.Dim L2.V2 = 2+type instance V.Dim L3.V3 = 3+type instance V.Dim L4.V4 = 4++unVF :: Lens (VectorFamily  d r) (VectorFamily d t)+             (VectorFamilyF d r) (VectorFamilyF d t)+unVF = lens _unVF (const VectorFamily)+{-# INLINE unVF #-}++type ImplicitArity d = (ImplicitPeano d, V.Arity (FromPeano d))++instance (Eq r, ImplicitArity d) => Eq (VectorFamily d r) where+  (VectorFamily u) == (VectorFamily v) = case (implicitPeano :: SingPeano d) of+        SZ                         -> u == v+        (SS SZ)                    -> u == v+        (SS (SS SZ))               -> u == v+        (SS (SS (SS SZ)))          -> u == v+        (SS (SS (SS (SS SZ))))     -> u == v+        (SS (SS (SS (SS (SS _))))) -> u == v+  {-# INLINE (==) #-}++instance (Ord r, ImplicitArity d) => Ord (VectorFamily d r) where+  (VectorFamily u) `compare` (VectorFamily v) = case (implicitPeano :: SingPeano d) of+        SZ                         -> u `compare` v+        (SS SZ)                    -> u `compare` v+        (SS (SS SZ))               -> u `compare` v+        (SS (SS (SS SZ)))          -> u `compare` v+        (SS (SS (SS (SS SZ))))     -> u `compare` v+        (SS (SS (SS (SS (SS _))))) -> u `compare` v+  {-# INLINE compare #-}+++instance ImplicitArity d => Functor (VectorFamily d) where+  fmap f = VectorFamily . g f . _unVF+    where g = case (implicitPeano :: SingPeano d) of+                SZ                         -> fmap+                (SS SZ)                    -> fmap+                (SS (SS SZ))               -> fmap+                (SS (SS (SS SZ)))          -> fmap+                (SS (SS (SS (SS SZ))))     -> fmap+                (SS (SS (SS (SS (SS _))))) -> fmap+  {-# INLINE fmap #-}+++instance ImplicitArity d => Foldable (VectorFamily d) where+  foldMap f = g f . _unVF+    where g = case (implicitPeano :: SingPeano d) of+                SZ                         -> foldMap+                (SS SZ)                    -> foldMap+                (SS (SS SZ))               -> foldMap+                (SS (SS (SS SZ)))          -> foldMap+                (SS (SS (SS (SS SZ))))     -> foldMap+                (SS (SS (SS (SS (SS _))))) -> foldMap+  {-# INLINE foldMap #-}++instance ImplicitArity d => Traversable (VectorFamily d) where+  traverse f = fmap VectorFamily . g f . _unVF+    where g = case (implicitPeano :: SingPeano d) of+                SZ                         -> traverse+                (SS SZ)                    -> traverse+                (SS (SS SZ))               -> traverse+                (SS (SS (SS SZ)))          -> traverse+                (SS (SS (SS (SS SZ))))     -> traverse+                (SS (SS (SS (SS (SS _))))) -> traverse+  {-# INLINE traverse #-}++instance ImplicitArity d => Applicative (VectorFamily d) where+  pure = VectorFamily . case (implicitPeano :: SingPeano d) of+                SZ                         -> pure+                (SS SZ)                    -> pure+                (SS (SS SZ))               -> pure+                (SS (SS (SS SZ)))          -> pure+                (SS (SS (SS (SS SZ))))     -> pure+                (SS (SS (SS (SS (SS _))))) -> pure+  {-# INLINE pure #-}+  liftA2 f (VectorFamily u) (VectorFamily v) = VectorFamily $+      case (implicitPeano :: SingPeano d) of+                SZ                         -> liftA2 f u v+                (SS SZ)                    -> liftA2 f u v+                (SS (SS SZ))               -> liftA2 f u v+                (SS (SS (SS SZ)))          -> liftA2 f u v+                (SS (SS (SS (SS SZ))))     -> liftA2 f u v+                (SS (SS (SS (SS (SS _))))) -> liftA2 f u v+  {-# INLINE liftA2 #-}+++instance ImplicitArity d => V.Vector (VectorFamily d) r where+  construct = fmap VectorFamily $ case (implicitPeano :: SingPeano d) of+                SZ                         -> Fun $ Const ()+                (SS SZ)                    -> V.construct+                (SS (SS SZ))               -> Fun L2.V2+                (SS (SS (SS SZ)))          -> Fun L3.V3+                (SS (SS (SS (SS SZ))))     -> Fun L4.V4+                (SS (SS (SS (SS (SS _))))) -> V.construct+  {-# INLINE construct #-}+  inspect (VectorFamily v) ff@(Fun f) = case (implicitPeano :: SingPeano d) of+                SZ                         -> f+                (SS SZ)                    -> V.inspect v ff+                (SS (SS SZ))               -> let (L2.V2 x y) = v     in f x y+                (SS (SS (SS SZ)))          -> let (L3.V3 x y z) = v   in f x y z+                (SS (SS (SS (SS SZ))))     -> let (L4.V4 x y z w) = v in f x y z w+                (SS (SS (SS (SS (SS _))))) -> V.inspect v ff+  {-# INLINE inspect #-}+  basicIndex v i = v^.singular (element' i)+  {-# INLINE basicIndex #-}++instance (ImplicitArity d, Show r) => Show (VectorFamily d r) where+  show v = mconcat [ "Vector", show $ F.length v , " "+                   , show $ F.toList v ]++instance (NFData r, ImplicitArity d) => NFData (VectorFamily d r) where+  rnf (VectorFamily v) = case (implicitPeano :: SingPeano d) of+                           SZ                         -> rnf v+                           (SS SZ)                    -> rnf v+                           (SS (SS SZ))               -> rnf v+                           (SS (SS (SS SZ)))          -> rnf v+                           (SS (SS (SS (SS SZ))))     -> rnf v+                           (SS (SS (SS (SS (SS _))))) -> rnf v+  {-# INLINE rnf #-}++instance ImplicitArity d => Ixed (VectorFamily d r) where+  ix = element'++element' :: forall d r. ImplicitArity d => Int -> Traversal' (VectorFamily d r) r+element' = case (implicitPeano :: SingPeano d) of+               SZ                         -> elem0+               (SS SZ)                    -> elem1+               (SS (SS SZ))               -> elem2+               (SS (SS (SS SZ)))          -> elem3+               (SS (SS (SS (SS SZ))))     -> elem4+               (SS (SS (SS (SS (SS _))))) -> elemD+{-# INLINE element' #-}++elem0   :: Int -> Traversal' (VectorFamily Z r) r+elem0 _ = \_ v -> pure v+{-# INLINE elem0 #-}+-- zero length vectors don't store any elements++elem1 :: Int -> Traversal' (VectorFamily One r) r+elem1 = \case+           0 -> unVF.(lens runIdentity (\_ -> Identity))+           _ -> \_ v -> pure v+{-# INLINE elem1 #-}++elem2 :: Int -> Traversal' (VectorFamily Two r) r+elem2 = \case+          0 -> unVF.L2._x+          1 -> unVF.L2._y+          _ -> \_ v -> pure v+{-# INLINE elem2 #-}++elem3 :: Int -> Traversal' (VectorFamily Three r) r+elem3 = \case+          0 -> unVF.L3._x+          1 -> unVF.L3._y+          2 -> unVF.L3._z+          _ -> \_ v -> pure v+{-# INLINE elem3 #-}++elem4 :: Int -> Traversal' (VectorFamily Four r) r+elem4 = \case+          0 -> unVF.L4._x+          1 -> unVF.L4._y+          2 -> unVF.L4._z+          3 -> unVF.L4._w+          _ -> \_ v -> pure v+{-# INLINE elem4 #-}++elemD   :: V.Arity (FromPeano (Many d)) => Int -> Traversal' (VectorFamily (Many d) r) r+elemD i = unVF.FV.element' i+{-# INLINE elemD #-}+++instance ImplicitArity d => Metric (VectorFamily d)++instance ImplicitArity d => Additive (VectorFamily d) where+  zero = pure 0+  u ^+^ v = liftA2 (+) u v++instance ImplicitArity d => Affine (VectorFamily d) where+  type Diff (VectorFamily d) = VectorFamily d++  u .-. v = u ^-^ v+  p .+^ v = p ^+^ v++instance (FromJSON r, ImplicitArity d)  => FromJSON (VectorFamily d r) where+  parseJSON y = parseJSON y >>= \xs -> case vectorFromList xs of+                  Nothing -> fail . mconcat $+                    [ "FromJSON (Vector d a), wrong number of elements. Expected "+                    , show $ natVal (Proxy :: Proxy (FromPeano d))+                    , " elements but found "+                    , show $ length xs+                    , "."+                    ]+                  Just v -> pure v++instance (ToJSON r, ImplicitArity d) => ToJSON (VectorFamily d r) where+  toJSON     = toJSON     . F.toList+  toEncoding = toEncoding . F.toList++--------------------------------------------------------------------------------++vectorFromList :: ImplicitArity d => [r] -> Maybe (VectorFamily d r)+vectorFromList = V.fromListM++vectorFromListUnsafe :: ImplicitArity d => [r] -> VectorFamily d r+vectorFromListUnsafe = V.fromList++-- | Get the head and tail of a vector+destruct   :: (ImplicitArity d, ImplicitArity (S d))+           => VectorFamily (S d) r -> (r, VectorFamily d r)+destruct v = (head $ F.toList v, vectorFromListUnsafe . tail $ F.toList v)+  -- FIXME: this implementaion of tail is not particularly nice++snoc     :: (ImplicitArity d, ImplicitArity (S d), (1 + FromPeano d) ~ (FromPeano d + 1))+         => VectorFamily d r -> r -> VectorFamily (S d) r+snoc = flip V.snoc
src/Data/Geometry/Vector/VectorFixed.hs view
@@ -3,15 +3,19 @@ module Data.Geometry.Vector.VectorFixed where  import           Control.DeepSeq-import           Control.Lens+import           Control.Lens hiding (element)+import           Data.Aeson import qualified Data.Foldable as F+import           Data.Proxy import qualified Data.Vector.Fixed as V+import           Data.Vector.Fixed (Arity) import           Data.Vector.Fixed.Boxed-import           Data.Vector.Fixed.Cont (Z, S, ToPeano)+import           Data.Vector.Fixed.Cont (Peano, PeanoNum(..)) import           GHC.Generics (Generic) import           GHC.TypeLits import           Linear.Affine (Affine(..)) import           Linear.Metric+import qualified Linear.V2 as L2 import qualified Linear.V3 as L3 import           Linear.Vector @@ -25,25 +29,22 @@  -- | Datatype representing d dimensional vectors. Our implementation wraps the -- implementation provided by fixed-vector.-newtype Vector (d :: Nat)  (r :: *) = Vector { _unV :: Vec (ToPeano d) r }+newtype Vector (d :: Nat)  (r :: *) = Vector { _unV :: Vec d r }                                     deriving (Generic) -unV :: Lens' (Vector d r) (Vec (ToPeano d) r)+unV :: Lens' (Vector d r) (Vec d r) unV = lens _unV (const Vector)  -----------------------------------------type Arity  (n :: Nat)  = V.Arity (ToPeano n) -type Index' i d = V.Index (ToPeano i) (ToPeano d)-- -- | Lens into the i th element-element   :: forall proxy i d r. (Arity d, Index' i d) => proxy i -> Lens' (Vector d r) r-element _ = V.elementTy (undefined :: (ToPeano i))+element   :: forall proxy i d r. (Arity d, Arity i, (i + 1) <= d)+          => proxy i -> Lens' (Vector d r) r+element _ = V.elementTy (Proxy :: Proxy i)  -- | Similar to 'element' above. Except that we don't have a static guarantee -- that the index is in bounds. Hence, we can only return a Traversal-element'   :: forall d r. (KnownNat d, Arity d) => Int -> Traversal' (Vector d r) r+element'   :: forall d r. Arity d => Int -> Traversal' (Vector d r) r element' i f v   | 0 <= i && i < fromInteger (natVal (C :: C d)) = f (v V.! i)                                                  <&> \a -> (v&V.element i .~ a)@@ -65,8 +66,12 @@  deriving instance (Eq r, Arity d)   => Eq (Vector d r) deriving instance (Ord r, Arity d)  => Ord (Vector d r)-deriving instance Arity d  => Functor (Vector d)+-- deriving instance Arity d  => Functor (Vector d) +-- for some weird reason, implemeting this myself yields is faster code+instance Arity d  => Functor (Vector d) where+  fmap f (Vector v) = Vector $ fmap f v+ deriving instance Arity d  => Foldable (Vector d) deriving instance Arity d  => Applicative (Vector d) @@ -89,21 +94,33 @@  instance Arity d => Metric (Vector d) -type instance V.Dim (Vector d) = ToPeano d+type instance V.Dim (Vector d) = d  instance Arity d => V.Vector (Vector d) r where-  construct    = Vector <$> V.construct-  inspect    v = V.inspect (_unV v)-  basicIndex v = V.basicIndex (_unV v)+  construct  = Vector <$> V.construct+  inspect    = V.inspect . _unV+  basicIndex = V.basicIndex . _unV --- ----------------------------------------+instance (FromJSON r, Arity d, KnownNat d)  => FromJSON (Vector d r) where+  parseJSON y = parseJSON y >>= \xs -> case vectorFromList xs of+                  Nothing -> fail . mconcat $+                    [ "FromJSON (Vector d a), wrong number of elements. Expected "+                    , show $ natVal (Proxy :: Proxy d)+                    , " elements but found "+                    , show $ length xs+                    , "."+                    ]+                  Just v -> pure v -type AlwaysTrueDestruct pd d = (Arity pd, ToPeano d ~ S (ToPeano pd))+instance (ToJSON r, Arity d) => ToJSON (Vector d r) where+  toJSON     = toJSON     . F.toList+  toEncoding = toEncoding . F.toList +------------------------------------------  -- | Get the head and tail of a vector-destruct            :: AlwaysTrueDestruct predD d-                    => Vector d r -> (r, Vector predD r)+destruct            :: (Arity d, Arity (d + 1), 1 <= (d + 1))+                    => Vector (d + 1) r -> (r, Vector d r) destruct (Vector v) = (V.head v, Vector $ V.tail v)  @@ -114,6 +131,10 @@  -------------------------------------------------------------------------------- +-- | Vonversion to a Linear.V2+toV2                :: Vector 2 a -> L2.V2 a+toV2 ~(Vector2 a b) = L2.V2 a b+ -- | Conversion to a Linear.V3 toV3                  :: Vector 3 a -> L3.V3 a toV3 ~(Vector3 a b c) = L3.V3 a b c@@ -124,34 +145,22 @@  ---------------------------------------------------------------------------------- --type AlwaysTrueSnoc d = ToPeano (1 + d) ~ S (ToPeano d)- -- | Add an element at the back of the vector-snoc :: (AlwaysTrueSnoc d, Arity d) => Vector d r -> r -> Vector (1 + d) r+snoc :: (Arity (d + 1), Arity d) => Vector d r -> r -> Vector (d + 1) r snoc = flip V.snoc  -- | Get a vector of the first d - 1 elements.-init :: AlwaysTrueDestruct predD d => Vector d r -> Vector predD r+init :: (Arity d, Arity (d + 1)) => Vector (d + 1) r -> Vector d r init = Vector . V.reverse . V.tail . V.reverse . _unV --- | Get a prefix of i elements of a vector-prefix :: (Prefix (ToPeano i) (ToPeano d)) => Vector d r -> Vector i r-prefix (Vector v) = Vector $ prefix' v--class Prefix i d where-  prefix' :: Vec d r -> Vec i r--instance Prefix Z d where-  prefix' _ = V.vector V.empty--instance (V.Arity i, V.Arity d, Prefix i d) => Prefix (S i) (S d) where-  prefix' v = V.vector $ V.head v `V.cons` (prefix' $ V.tail v)-+last :: forall d r. (Arity d, Arity (d + 1)) => Vector (d + 1) r -> r+last = view $ element (Proxy :: Proxy d) --- | Map with indices-imap :: Arity d => (Int -> r -> s ) -> Vector d r -> Vector d s-imap = V.imap+-- | Get a prefix of i elements of a vector+prefix :: forall i d r. (Arity d, Arity i, i <= d)+       => Vector d r -> Vector i r+prefix = let i = fromInteger . natVal $ (Proxy :: Proxy i)+         in V.fromList . take i . V.toList  -------------------------------------------------------------------------------- -- * Functions specific to two and three dimensional vectors.@@ -164,7 +173,6 @@ v3      :: r -> r -> r -> Vector 3 r v3 a b c = Vector $ V.mk3 a b c - -- | Destruct a 2 dim vector into a pair _unV2 :: Vector 2 r -> (r,r) _unV2 v = let [x,y] = V.toList v in (x,y)@@ -172,10 +180,22 @@ _unV3 :: Vector 3 r -> (r,r,r) _unV3 v = let [x,y,z] = V.toList v in (x,y,z) - -- | Pattern synonym for two and three dim vectors pattern Vector2       :: r -> r -> Vector 2 r pattern Vector2 x y   <- (_unV2 -> (x,y))+  where+    Vector2 x y = v2 x y+{-# COMPLETE Vector2 #-}  pattern Vector3       :: r -> r -> r -> Vector 3 r pattern Vector3 x y z <- (_unV3 -> (x,y,z))+  where+    Vector3 x y z = v3 x y z+{-# COMPLETE Vector3 #-}+++pattern Vector4         :: r -> r -> r -> r -> Vector 4 r+pattern Vector4 x y z a <- (V.toList -> [x,y,z,a])+  where+    Vector4 x y z a = V.mk4 x y z a+{-# COMPLETE Vector4 #-}
+ src/Data/OrdSeq.hs view
@@ -0,0 +1,190 @@+module Data.OrdSeq where+++import           Control.Lens (bimap)+import qualified Data.FingerTree as FT+import           Data.FingerTree hiding (null, viewl, viewr)+import qualified Data.Foldable as F+import           Data.Maybe+import           Data.Semigroup++--------------------------------------------------------------------------------++data Key a = NoKey | Key { getKey :: !a } deriving (Show,Eq,Ord)++instance Semigroup (Key a) where+  k <> NoKey = k+  _ <> k     = k++instance Monoid (Key a) where+  mempty = NoKey+  k `mappend` k' = k <> k'++liftCmp                     :: (a -> a -> Ordering) -> Key a -> Key a -> Ordering+liftCmp _   NoKey   NoKey   = EQ+liftCmp _   NoKey   (Key _) = LT+liftCmp _   (Key _) NoKey   = GT+liftCmp cmp (Key x) (Key y) = x `cmp` y++++newtype Elem a = Elem { getElem :: a } deriving (Eq,Ord,Traversable,Foldable,Functor)++instance Show a => Show (Elem a) where+  show (Elem x) = "Elem " <> show x+++newtype OrdSeq a = OrdSeq { _asFingerTree :: FingerTree (Key a) (Elem a) }+                   deriving (Show,Eq)++instance Semigroup (OrdSeq a) where+  (OrdSeq s) <> (OrdSeq t) = OrdSeq $ s `mappend` t++instance Monoid (OrdSeq a) where+  mempty = OrdSeq mempty+  mappend = (<>)++instance Foldable OrdSeq where+  foldMap f = foldMap (foldMap f) . _asFingerTree+  null      = null . _asFingerTree+  length    = length . _asFingerTree+  minimum   = fromJust . lookupMin+  maximum   = fromJust . lookupMax++instance Measured (Key a) (Elem a) where+  measure (Elem x) = Key x+++type Compare a = a -> a -> Ordering++-- | Insert into a monotone OrdSeq.+--+-- pre: the comparator maintains monotonicity+--+-- \(O(\log n)\)+insertBy                  :: Compare a -> a -> OrdSeq a -> OrdSeq a+insertBy cmp x (OrdSeq s) = OrdSeq $ l `mappend` (Elem x <| r)+  where+    (l,r) = split (\v -> liftCmp cmp v (Key x) `elem` [EQ, GT]) s++-- | Insert into a sorted OrdSeq+--+-- \(O(\log n)\)+insert :: Ord a => a -> OrdSeq a -> OrdSeq a+insert = insertBy compare++deleteAllBy         :: Compare a -> a -> OrdSeq a -> OrdSeq a+deleteAllBy cmp x s = l <> r+  where+    (l,_,r) = splitBy cmp x s++    -- (l,m) = split (\v -> liftCmp cmp v (Key x) `elem` [EQ,GT]) s+    -- (_,r) = split (\v -> liftCmp cmp v (Key x) == GT) m+++-- | \(O(\log n)\)+splitBy                  :: Compare a -> a -> OrdSeq a -> (OrdSeq a, OrdSeq a, OrdSeq a)+splitBy cmp x (OrdSeq s) = (OrdSeq l, OrdSeq m', OrdSeq r)+  where+    (l, m) = split (\v -> liftCmp cmp v (Key x) `elem` [EQ,GT]) s+    (m',r) = split (\v -> liftCmp cmp v (Key x) == GT) m+++-- | Given a monotonic function f that maps a to b, split the sequence s+-- depending on the b values. I.e. the result (l,m,r) is such that+-- * all (< x) . fmap f $ l+-- * all (== x) . fmap f $ m+-- * all (> x) . fmap f $ r+--+-- >>> splitOn id 3 $ fromAscList' [1..5]+-- (OrdSeq {_asFingerTree = fromList [Elem 1,Elem 2]},OrdSeq {_asFingerTree = fromList [Elem 3]},OrdSeq {_asFingerTree = fromList [Elem 4,Elem 5]})+-- >>> splitOn fst 2 $ fromAscList' [(0,"-"),(1,"A"),(2,"B"),(2,"C"),(3,"D"),(4,"E")]+-- (OrdSeq {_asFingerTree = fromList [Elem (0,"-"),Elem (1,"A")]},OrdSeq {_asFingerTree = fromList [Elem (2,"B"),Elem (2,"C")]},OrdSeq {_asFingerTree = fromList [Elem (3,"D"),Elem (4,"E")]})+--+-- \(O(\log n)\)+splitOn :: Ord b => (a -> b) -> b -> OrdSeq a -> (OrdSeq a, OrdSeq a, OrdSeq a)+splitOn f x (OrdSeq s) = (OrdSeq l, OrdSeq m', OrdSeq r)+  where+    (l, m) = split (\(Key v) -> compare (f v) x `elem` [EQ,GT]) s+    (m',r) = split (\(Key v) -> compare (f v) x ==     GT)      m++-- | Given a monotonic predicate p, splits the sequence s into two sequences+--  (as,bs) such that all (not p) as and all p bs+--+-- \(O(\log n)\)+splitMonotonic  :: (a -> Bool) -> OrdSeq a -> (OrdSeq a, OrdSeq a)+splitMonotonic p = bimap OrdSeq OrdSeq . split (p . getKey) . _asFingerTree+++-- Deletes all elements from the OrdDeq+--+-- \(O(n\log n)\)+deleteAll :: Ord a => a -> OrdSeq a -> OrdSeq a+deleteAll = deleteAllBy compare+++-- | inserts all eleements in order+-- \(O(n\log n)\)+fromListBy     :: Compare a -> [a] -> OrdSeq a+fromListBy cmp = foldr (insertBy cmp) mempty++-- | inserts all eleements in order+-- \(O(n\log n)\)+fromListByOrd :: Ord a => [a] -> OrdSeq a+fromListByOrd = fromListBy compare++-- | O(n)+fromAscList' :: [a] -> OrdSeq a+fromAscList' = OrdSeq . fromList . fmap Elem+++-- | \(O(\log n)\)+lookupBy         :: Compare a -> a -> OrdSeq a -> Maybe a+lookupBy cmp x s = let (_,m,_) = splitBy cmp x s in listToMaybe . F.toList $ m++memberBy        :: Compare a -> a -> OrdSeq a -> Bool+memberBy cmp x = isJust . lookupBy cmp x+++-- | Fmap, assumes the order does not change+-- O(n)+mapMonotonic   :: (a -> b) -> OrdSeq a -> OrdSeq b+mapMonotonic f = fromAscList' . map f . F.toList+++-- | Gets the first element from the sequence+-- \(O(1)\)+viewl :: OrdSeq a -> ViewL OrdSeq a+viewl = f . FT.viewl . _asFingerTree+  where+    f EmptyL         = EmptyL+    f (Elem x :< s)  = x :< OrdSeq s++-- Last element+-- \(O(1)\)+viewr :: OrdSeq a -> ViewR OrdSeq a+viewr = f . FT.viewr . _asFingerTree+  where+    f EmptyR         = EmptyR+    f (s :> Elem x)  = OrdSeq s :> x+++-- \(O(1)\)+minView   :: OrdSeq a -> Maybe (a, OrdSeq a)+minView s = case viewl s of+              EmptyL   -> Nothing+              (x :< t) -> Just (x,t)++-- \(O(1)\)+lookupMin :: OrdSeq a -> Maybe a+lookupMin = fmap fst . minView++-- \(O(1)\)+maxView   :: OrdSeq a -> Maybe (a, OrdSeq a)+maxView s = case viewr s of+              EmptyR   -> Nothing+              (t :> x) -> Just (x,t)++-- \(O(1)\)+lookupMax :: OrdSeq a -> Maybe a+lookupMax = fmap fst . maxView
src/Data/Permutation.hs view
@@ -52,6 +52,10 @@ next     :: GV.Vector v a => v a -> Int -> a next v i = let n = GV.length v in v GV.! ((i+1) `mod` n) +-- | Previous item in a cyclic permutation+previous     :: GV.Vector v a => v a -> Int -> a+previous v i = let n = GV.length v in v GV.! ((i-1) `mod` n)+ -- | Lookup the indices of an element, i.e. in which orbit the item is, and the -- index within the orbit. --
src/Data/PlanarGraph.hs view
@@ -1,5 +1,6 @@ {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE OverloadedStrings #-} module Data.PlanarGraph( Arc(..)                        , Direction(..), rev @@ -8,60 +9,68 @@                         , World(..) -                       , Dual+                       , DualOf -                       , VertexId(..)+                       , VertexId(..), VertexId'                         , PlanarGraph-                       , embedding, vertexData, dartData, faceData+                       , embedding, vertexData, dartData, faceData, rawDartData                        , edgeData                         , planarGraph, planarGraph', fromAdjacencyLists+                       , toAdjacencyLists+                       , buildFromJSON                         , numVertices, numDarts, numEdges, numFaces                        , darts', darts, edges', edges, vertices', vertices, faces', faces                         , tailOf, headOf, endPoints                        , incidentEdges, incomingEdges, outgoingEdges, neighboursOf--                       , vDataOf, eDataOf, fDataOf, endPointDataOf, endPointData+                       , nextIncidentEdge, prevIncidentEdge +                       , HasDataOf(..), endPointDataOf, endPointData                         , dual -                       , FaceId(..)-                       , leftFace, rightFace, boundary, boundaryVertices-+                       , FaceId(..), FaceId'+                       , leftFace, rightFace, boundary, boundary', boundaryVertices+                       , nextEdge, prevEdge                          , EdgeOracle                        , edgeOracle, buildEdgeOracle                        , findEdge-                       , hasEdge+                       , hasEdge, findDart++                       , allDarts                        ) where + import           Control.Applicative (Alternative(..))-import           Control.Lens-import           Control.Monad (forM_)+import           Control.Lens hiding ((.=)) import           Control.Monad.ST (ST) import           Control.Monad.State.Strict+import           Data.Aeson import           Data.Bifunctor import           Data.Bitraversable import           Data.Ext import qualified Data.Foldable as F-import           Data.Maybe (catMaybes, isJust)+import           Data.Maybe (catMaybes, isJust, fromJust, fromMaybe) import           Data.Permutation import           Data.Semigroup (Semigroup(..)) import           Data.Traversable (fmapDefault,foldMapDefault)-import           Data.Util+import           Data.Type.Equality (gcastWith, (:~:)(..)) import qualified Data.Vector as V import qualified Data.Vector.Generic as GV import qualified Data.Vector.Mutable as MV import qualified Data.Vector.Unboxed as UV import qualified Data.Vector.Unboxed.Mutable as UMV+import           Unsafe.Coerce (unsafeCoerce)  -import           Debug.Trace+-- import           Data.Yaml.Util+-- import           Debug.Trace+ --------------------------------------------------------------------------------  --------------------------------------------------------------------------------@@ -69,7 +78,7 @@ -- >>> :{ -- let dart i s = Dart (Arc i) (read s) --     (aA:aB:aC:aD:aE:aG:_) = take 6 [Arc 0..]---     myGraph :: PlanarGraph Test Primal_ () String ()+--     myGraph :: PlanarGraph Test Primal () String () --     myGraph = planarGraph [ [ (Dart aA Negative, "a-") --                             , (Dart aC Positive, "c+") --                             , (Dart aB Positive, "b+")@@ -89,8 +98,8 @@ --                           ] -- :} --- TODO: Add a fig. of the Graph-+-- This represents the following graph:+-- ![myGraph](docs/Data/PlanarGraph/testG.png)  -------------------------------------------------------------------------------- @@ -121,13 +130,14 @@ -- | A dart represents a bi-directed edge. I.e. a dart has a direction, however -- the dart of the oposite direction is always present in the planar graph as -- well.-data Dart s = Dart { _arc       :: !(Arc s)-                   , _direction :: !Direction+data Dart s = Dart { _arc       :: {-#UNPACK #-} !(Arc s)+                   , _direction :: {-#UNPACK #-} !Direction                    } deriving (Eq,Ord) makeLenses ''Dart   + instance Show (Dart s) where   show (Dart a d) = "Dart (" ++ show a ++ ") " ++ show d @@ -156,24 +166,39 @@                                 Negative -> 2*i + 1  +-- | Enumerates all darts such that+-- allDarts !! i = d   <=> i == fromEnum d+allDarts :: [Dart s]+allDarts = concatMap (\a -> [Dart a Positive, Dart a Negative]) [Arc 0..]+ -- | The world in which the graph lives-data World = Primal_ | Dual_ deriving (Show,Eq)+data World = Primal | Dual deriving (Show,Eq) -type family Dual (sp :: World) where-  Dual Primal_ = Dual_-  Dual Dual_   = Primal_+type family DualOf (sp :: World) where+  DualOf Primal = Dual+  DualOf Dual   = Primal +dualDualIdentity :: forall w. DualOf (DualOf w) :~: w+dualDualIdentity = unsafeCoerce Refl+          -- manual proof:+          --    DualOf (DualOf Primal) = Primal+          --    DualOf (DualOf Dual)   = Dual + -- | A vertex in a planar graph. A vertex is tied to a particular planar graph -- by the phantom type s, and to a particular world w.-newtype VertexId s (w :: World) = VertexId { _unVertexId :: Int } deriving (Eq,Ord,Enum)+newtype VertexId s (w :: World) = VertexId { _unVertexId :: Int }+                                deriving (Eq,Ord,Enum,ToJSON,FromJSON) -- VertexId's are in the range 0...|orbits|-1-makeLenses ''VertexId +type VertexId' s = VertexId s Primal++unVertexId :: Getter (VertexId s w) Int+unVertexId = to _unVertexId+ instance Show (VertexId s w) where   show (VertexId i) = "VertexId " ++ show i - -------------------------------------------------------------------------------- -- * The graph type itself @@ -184,27 +209,144 @@ -- The types v, e, and f are the are the types of the data associated with the -- vertices, edges, and faces, respectively. ----- The orbits in the embedding are assumed to be in counterclockwise order.-data PlanarGraph s (w :: World) v e f = PlanarGraph { _embedding  :: Permutation (Dart s)-                                                    , _vertexData :: V.Vector v+-- The orbits in the embedding are assumed to be in counterclockwise+-- order. Therefore, every dart directly bounds the face to its right.+data PlanarGraph s (w :: World) v e f = PlanarGraph { _embedding   :: Permutation (Dart s)+                                                    , _vertexData  :: V.Vector v                                                     , _rawDartData :: V.Vector e                                                     , _faceData    :: V.Vector f+                                                    , _dual        :: PlanarGraph s (DualOf w) f e v                                                     }-                                      deriving (Show,Eq)-makeLenses ''PlanarGraph +instance (Show v, Show e, Show f) => Show (PlanarGraph s w v e f) where+  show (PlanarGraph e v r f _) = unwords [ "PlanarGraph"+                                         , "embedding =", show e+                                         , ", vertexData =", show v+                                         , ", rawDartData =", show r+                                         , ", faceData =", show f+                                         ] +instance (Eq v, Eq e, Eq f) => Eq (PlanarGraph s w v e f) where+  (PlanarGraph e v r f _) == (PlanarGraph e' v' r' f' _) =  e == e' && v == v'+                                                         && r == r' && f == f'+++instance (ToJSON v, ToJSON e, ToJSON f)+         => ToJSON (PlanarGraph s w v e f) where+  toJSON     = object . encodeJSON+  toEncoding = pairs . mconcat . encodeJSON++encodeJSON   :: (ToJSON f, ToJSON e, ToJSON v, KeyValue t)+             => PlanarGraph s w v e f -> [t]+encodeJSON g = [ "vertices"    .= ((\(v,d) -> v :+ d)             <$> vertices g)+               , "darts"       .= ((\(e,d) -> endPoints e g :+ d) <$> darts g)+               , "faces"       .= ((\(f,d) -> f :+ d)             <$> faces g)+               , "adjacencies" .= toAdjacencyLists g+               ]+++instance (FromJSON v, FromJSON e, FromJSON f)+         => FromJSON (PlanarGraph s Primal v e f) where+  parseJSON = withObject "" $ \v -> buildFromJSON <$> v .: "vertices"+                                                  <*> v .: "darts"+                                                  <*> v .: "faces"+                                                  <*> v .: "adjacencies"+++-- | Helper function to build the graph from JSON data+--+-- running time: \(O(n)\)+buildFromJSON             :: V.Vector (VertexId' s :+ v)+                          -> V.Vector ((VertexId' s, VertexId' s) :+ e)+                          -> V.Vector (FaceId' s :+ f)+                          -> [(VertexId' s, V.Vector (VertexId' s))]+                          -> PlanarGraph s Primal v e f+buildFromJSON vs es fs as = g&vertexData .~ reorder vs _unVertexId+                             &dartData   .~ ds+                             &faceData   .~ reorder fs (_unVertexId._unFaceId)+  where+    g = fromAdjacencyLists as+    oracle = edgeOracle g+    findEdge' (u,v) = fromJust $ findDart u v oracle++    ds = es&traverse %~ \(e:+x) -> (findEdge' e,x)+    -- for the face data we don't really know enough to reconstruct them I think+    -- i.e. we may not have the guarnatee that the faceId's are the same in the+    -- old graph and the new one++    -- make sure we order the data values appropriately+    reorder v f = V.create $ do+                               v' <- MV.new (V.length v)+                               forM_ v $ \(i :+ x) ->+                                 MV.write v' (f i) x+                               pure v'+++++++-- ** lenses and getters++embedding :: Getter (PlanarGraph s w v e f) (Permutation (Dart s))+embedding = to _embedding++vertexData :: Lens (PlanarGraph s w v e f) (PlanarGraph s w v' e f)+                   (V.Vector v) (V.Vector v')+vertexData = lens _vertexData (\g vD -> updateData (const vD) id id g)++rawDartData :: Lens (PlanarGraph s w v e f) (PlanarGraph s w v e' f)+                    (V.Vector e) (V.Vector e')+rawDartData = lens _rawDartData (\g dD -> updateData id (const dD) id g)++faceData :: Lens (PlanarGraph s w v e f) (PlanarGraph s w v e f')+                 (V.Vector f) (V.Vector f')+faceData = lens _faceData (\g fD -> updateData id id (const fD) g)++dual :: Getter (PlanarGraph s w v e f) (PlanarGraph s (DualOf w) f e v)+dual = to _dual++ -- | lens to access the Dart Data dartData :: Lens (PlanarGraph s w v e f) (PlanarGraph s w v e' f)-                 (V.Vector (Dart s, e)) (V.Vector (Dart s, e'))-dartData = lens darts (\g xs -> g&rawDartData .~ reorderEdgeData xs)+                (V.Vector (Dart s, e)) (V.Vector (Dart s, e'))+dartData = lens darts (\g dD -> updateData id (const $ reorderEdgeData dD) id g)  -- | edgeData is just an alias for 'dartData' edgeData :: Lens (PlanarGraph s w v e f) (PlanarGraph s w v e' f)                  (V.Vector (Dart s, e)) (V.Vector (Dart s, e')) edgeData = dartData +-- | Helper function to update the data in a planar graph. Takes care to update+-- both the data in the original graph as well as in the dual.+updateData :: forall s w v e f v' e' f'+           .  (V.Vector v -> V.Vector v')+           -> (V.Vector e -> V.Vector e')+           -> (V.Vector f -> V.Vector f')+           -> PlanarGraph s w v  e  f+           -> PlanarGraph s w v' e' f'+updateData = gcastWith proof updateData'+  where+    proof :: DualOf (DualOf w) :~: w+    proof = dualDualIdentity +-- | The function that does the actual work for 'updateData'+updateData'  :: (DualOf (DualOf w) ~ w)+             => (V.Vector v -> V.Vector v')+             -> (V.Vector e -> V.Vector e')+             -> (V.Vector f -> V.Vector f')+             -> PlanarGraph s w v  e  f+             -> PlanarGraph s w v' e' f'+updateData' fv fe ff (PlanarGraph em vtxData dData fData dg) = g'+  where+    vtxData' = fv vtxData+    dData'   = fe dData+    fData'   = ff fData++    g'       = PlanarGraph em              vtxData' dData' fData'   dg'+    dg'      = PlanarGraph (dg^.embedding) fData'   dData' vtxData' g'++ -- | Reorders the edge data to be in the right order to set edgeData reorderEdgeData    :: Foldable f => f (Dart s, e) -> V.Vector e reorderEdgeData ds = V.create $ do@@ -213,27 +355,31 @@                                     MV.write v (fromEnum d) x                                   pure v +--------------------------------------------------------------------------------+-- ** Constructing a Planar graph  -- | Construct a planar graph+--+-- running time: \(O(n)\). planarGraph'      :: Permutation (Dart s) -> PlanarGraph s w () () ()-planarGraph' perm = PlanarGraph perm vData eData fData+planarGraph' perm = pg   where-    d = size perm-    e = d `div` 2-    v = V.length (perm^.orbits)-    f = e - v + 2+    pg = PlanarGraph perm vData eData fData (computeDual pg)+        -- note the lazy calculation of computeDual that refers to pg itself+    d  = size perm+    e  = d `div` 2+    v  = V.length (perm^.orbits)+    f  = e - v + 2      vData  = V.replicate v ()     eData  = V.replicate d ()     fData  = V.replicate f () -- -- | Construct a planar graph, given the darts in cyclic order around each -- vertex. -- -- running time: \(O(n)\).-planarGraph    :: [[(Dart s,e)]] -> PlanarGraph s Primal_ () e ()+planarGraph    :: [[(Dart s,e)]] -> PlanarGraph s Primal () e () planarGraph ds = (planarGraph' perm)&dartData .~ (V.fromList . concat $ ds)   where     n     = sum . map length $ ds@@ -244,9 +390,11 @@ -- | Construct a planar graph from a adjacency matrix. For every vertex, all -- vertices should be given in counter clockwise order. --+-- pre: No self-loops, and no multi-edges+-- -- running time: \(O(n)\).-fromAdjacencyLists      :: forall s w f. (Foldable f, Functor f)-                        => [(VertexId s w, f (VertexId s w))]+fromAdjacencyLists      :: forall s w h. (Foldable h, Functor h)+                        => [(VertexId s w, h (VertexId s w))]                         -> PlanarGraph s w () () () fromAdjacencyLists adjM = planarGraph' . toCycleRep n $ perm   where@@ -280,8 +428,17 @@     f   :: e -> State Int (Int :+ e)     f e = do i <- get ; put (i+1) ; pure (i :+ e) --+-- | Produces the adjacencylists for all vertices in the graph. For every vertex, the+-- adjacent vertices are given in counter clockwise order.+--+-- Note that in case a vertex u as a self loop, we have that this vertexId occurs+-- twice in the list of neighbours, i.e.: u : [...,u,..,u,...]. Similarly, if there are+-- multiple darts between a pair of edges they occur multiple times.+--+-- running time: \(O(n)\)+toAdjacencyLists    :: PlanarGraph s w v e f -> [(VertexId s w, V.Vector (VertexId s w))]+toAdjacencyLists pg = map (\u -> (u,neighboursOf u pg)) . V.toList . vertices' $ pg+-- TODO: something weird happens when we have self-loops here.  --     -- Go through all of the edges we find an edge (u,v), with u <= v, --     -- assign an ArcId to this edge (and increment the next available arcId).@@ -311,15 +468,15 @@ -- --            u < v, to arcId's. -- -- - a: the next available unused arcID -- -- - x: the data value we are interested in computing--- type STR' s b = STR (SM.Map (VertexId s Primal_,VertexId s Primal_) Int) Int b+-- type STR' s b = STR (SM.Map (VertexId s Primal,VertexId s Primal) Int) Int b  -- -- | Construct a planar graph from a adjacency matrix. For every vertex, all -- -- vertices should be given in counter clockwise order. -- -- -- -- running time: \(O(n \log n)\). -- fromAdjacencyLists      :: forall s.---                            [(VertexId s Primal_, C.CList (VertexId s Primal_))]---                         -> PlanarGraph s Primal_ () () ()+--                            [(VertexId s Primal, C.CList (VertexId s Primal))]+--                         -> PlanarGraph s Primal () () () -- fromAdjacencyLists adjM = planarGraph' . toCycleRep n $ perm --   where --     n    = sum . fmap length $ adjM@@ -328,7 +485,7 @@  --     -- | Given a vertex with its adjacent vertices (u,vs) (in CCW order) convert this --     -- vertex with its adjacent vertices into an Orbit---     toOrbit                     :: (VertexId s Primal_, C.CList (VertexId s Primal_))+--     toOrbit                     :: (VertexId s Primal, C.CList (VertexId s Primal)) --                                 -> STR' s [[Dart s]] --                                 -> STR' s [[Dart s]] --     toOrbit (u,vs) (STR m a dss) =@@ -338,7 +495,7 @@  --     -- | Given an edge (u,v) and a triplet (m,a,ds) we construct a new dart --     -- representing this edge.---     toDart                    :: (VertexId s Primal_,VertexId s Primal_)+--     toDart                    :: (VertexId s Primal,VertexId s Primal) --                               -> STR' s [Dart s] --                               -> STR' s [Dart s] --     toDart (u,v) (STR m a ds) = let dir = if u < v then Positive else Negative@@ -349,6 +506,7 @@   --------------------------------------------------------------------------------+-- ** Convenience functions  -- | Get the number of vertices --@@ -414,7 +572,7 @@ -- (Dart (Arc 2) -1,"c-") -- (Dart (Arc 5) -1,"g-") darts   :: PlanarGraph s w v e f -> V.Vector (Dart s, e)-darts g = (\d -> (d,g^.eDataOf d)) <$> darts' g+darts g = (\d -> (d,g^.dataOf d)) <$> darts' g  -- | Enumerate all edges. We report only the Positive darts edges' :: PlanarGraph s w v e f -> V.Vector (Dart s)@@ -457,12 +615,15 @@ endPoints d g = (tailOf d g, headOf d g)  ++ -- | All edges incident to vertex v, in counterclockwise order around v. -- -- running time: \(O(k)\), where \(k\) is the output size incidentEdges                :: VertexId s w -> PlanarGraph s w v e f                              -> V.Vector (Dart s) incidentEdges (VertexId v) g = g^.embedding.orbits.ix' v+  -- TODO: The Delaunay triang. stuff seems to produce these in clockwise order instead  -- | All incoming edges incident to vertex v, in counterclockwise order around v. incomingEdges     :: VertexId s w -> PlanarGraph s w v e f -> V.Vector (Dart s)@@ -482,36 +643,50 @@   where     otherVtx d = let u = tailOf d g in if u == v then headOf d g else u --- outgoingNeighbours :: VertexId s w -> PlanarGraph s w v e f -> V.Vector (VertexId s w)--- outgoingNeighbours = undefined+-- | Given a dart d that points into some vertex v, report the next dart in the+-- cyclic order around v.+--+-- running time: \(O(1)\)+nextIncidentEdge     :: Dart s -> PlanarGraph s w v e f -> Dart s+nextIncidentEdge d g = let perm  = g^.embedding+                           (i,j) = lookupIdx perm d+                       in next (perm^.orbits.ix' i) j --- incomingNeighbours :: VertexId s w -> PlanarGraph s w v e f -> V.Vector (VertexId s w)--- incomingNeighbours = undefined +-- | Given a dart d that points into some vertex v, report the next dart in the+-- cyclic order around v.+--+-- running time: \(O(1)\)+prevIncidentEdge     :: Dart s -> PlanarGraph s w v e f -> Dart s+prevIncidentEdge d g = let perm  = g^.embedding+                           (i,j) = lookupIdx perm d+                       in previous (perm^.orbits.ix' i) j + -------------------------------------------------------------------------------- -- * Access data --- | Get the vertex data associated with a node. Note that updating this data may be--- expensive!!------ running time: \(O(1)\)-vDataOf              :: VertexId s w -> Lens' (PlanarGraph s w v e f) v-vDataOf (VertexId i) = vertexData.ix' i --- | Edge data of a given dart------ running time: \(O(1)\)-eDataOf   :: Dart s -> Lens' (PlanarGraph s w v e f) e-eDataOf d = rawDartData.ix' (fromEnum d)+class HasDataOf g i where+  type DataOf g i+  -- | get the data associated with the value i.+  --+  -- running time: \(O(1)\) to read the data, \(O(n)\) to write it.+  dataOf :: i -> Lens' g (DataOf g i) --- | Data of a face of a given face------ running time: \(O(1)\)-fDataOf                       :: FaceId s w -> Lens' (PlanarGraph s w v e f) f-fDataOf (FaceId (VertexId i)) = faceData.ix' i+instance HasDataOf (PlanarGraph s w v e f) (VertexId s w) where+  type DataOf (PlanarGraph s w v e f) (VertexId s w) = v+  dataOf (VertexId i) = vertexData.ix' i +instance HasDataOf (PlanarGraph s w v e f) (Dart s) where+  type DataOf (PlanarGraph s w v e f) (Dart s) = e+  dataOf d = rawDartData.ix' (fromEnum d) +instance HasDataOf (PlanarGraph s w v e f) (FaceId s w) where+  type DataOf (PlanarGraph s w v e f) (FaceId s w) = f+  dataOf (FaceId (VertexId i)) = faceData.ix' i++ -- | Data corresponding to the endpoints of the dart endPointDataOf   :: Dart s -> Getter (PlanarGraph s w v e f) (v,v) endPointDataOf d = to $ endPointData d@@ -521,7 +696,7 @@ -- -- running time: \(O(1)\) endPointData     :: Dart s -> PlanarGraph s w v e f -> (v,v)-endPointData d g = let (u,v) = endPoints d g in (g^.vDataOf u, g^.vDataOf v)+endPointData d g = let (u,v) = endPoints d g in (g^.dataOf u, g^.dataOf v)  -------------------------------------------------------------------------------- -- * The Dual graph@@ -535,27 +710,42 @@ --                        , fromList [dart 1 "+1",dart 3 "-1",dart 2 "-1"] --                        , fromList [dart 4 "-1",dart 3 "+1",dart 5 "+1",dart 5 "-1"] --                        ]---  in (dual myGraph)^.embedding.orbits == answer+--  in (computeDual myGraph)^.embedding.orbits == answer -- :} -- True -- -- running time: \(O(n)\).-dual   :: PlanarGraph s w v e f -> PlanarGraph s (Dual w) f e v-dual g = let perm = g^.embedding-         in PlanarGraph (cycleRep (elems perm) (apply perm . twin))+computeDual :: forall s w v e f. PlanarGraph s w v e f -> PlanarGraph s (DualOf w) f e v+computeDual = gcastWith proof computeDual'+  where+    proof :: DualOf (DualOf w) :~: w+    proof = dualDualIdentity++-- | Does the actual work for dualGraph+computeDual'   :: (DualOf (DualOf w) ~ w)+               => PlanarGraph s w v e f -> PlanarGraph s (DualOf w) f e v+computeDual' g = dualG+  where+    perm  = g^.embedding+    dualG = PlanarGraph (cycleRep (elems perm) (apply perm . twin))                         (g^.faceData)                         (g^.rawDartData)                         (g^.vertexData)+                        g + -- | A face-newtype FaceId s w = FaceId { _unFaceId :: VertexId s (Dual w) } deriving (Eq,Ord)+newtype FaceId s w = FaceId { _unFaceId :: VertexId s (DualOf w) }+                   deriving (Eq,Ord,ToJSON,FromJSON) +type FaceId' s = FaceId s Primal+ instance Show (FaceId s w) where   show (FaceId (VertexId i)) = "FaceId " ++ show i  -- | Enumerate all faces in the planar graph faces' :: PlanarGraph s w v e f -> V.Vector (FaceId s w)-faces' = fmap FaceId . vertices' . dual+faces' = fmap FaceId . vertices' . _dual  -- | All faces with their face data. faces   :: PlanarGraph s w v e f -> V.Vector (FaceId s w, f)@@ -574,7 +764,7 @@ -- -- running time: \(O(1)\). leftFace     :: Dart s -> PlanarGraph s w v e f -> FaceId s w-leftFace d g = FaceId . headOf d $ dual g+leftFace d g = FaceId . headOf d $ _dual g   -- | The face to the right of the dart@@ -590,18 +780,44 @@ -- -- running time: \(O(1)\). rightFace     :: Dart s -> PlanarGraph s w v e f -> FaceId s w-rightFace d g = FaceId . tailOf d $ dual g+rightFace d g = FaceId . tailOf d $ _dual g  +-- | Get the next edge along the face+--+-- running time: \(O(1)\).+nextEdge   :: Dart s -> PlanarGraph s w v e f -> Dart s+nextEdge d = nextIncidentEdge d . _dual++-- | Get the previous edge along the face+--+-- running time: \(O(1)\).+prevEdge :: Dart s -> PlanarGraph s w v e f -> Dart s+prevEdge d = prevIncidentEdge d . _dual++ -- | The darts bounding this face, for internal faces in clockwise order, for -- the outer face in counter clockwise order. -- -- -- running time: \(O(k)\), where \(k\) is the output size. boundary              :: FaceId s w -> PlanarGraph s w v e f -> V.Vector (Dart s)-boundary (FaceId v) g = incidentEdges v $ dual g+boundary (FaceId v) g = incidentEdges v $ _dual g  +-- | Generates the darts incident to a face, starting with the given dart.+--+--+-- \(O(k)\), where \(k\) is the number of darts reported+boundary'     :: Dart s -> PlanarGraph s w v e f -> V.Vector (Dart s)+boundary' d g = fromMaybe (error "boundary'")  . rotateTo d $ boundary (rightFace d g) g+  where+    rotateTo     :: Eq a => a -> V.Vector a -> Maybe (V.Vector a)+    rotateTo x v = f <$> V.elemIndex x v+      where+        f i = let (a,b) = V.splitAt i v  in b <> a++ -- | The vertices bounding this face, for internal faces in clockwise order, for -- the outer face in counter clockwise order. --@@ -610,6 +826,10 @@ boundaryVertices     :: FaceId s w -> PlanarGraph s w v e f -> V.Vector (VertexId s w) boundaryVertices f g = fmap (flip tailOf g) $ boundary f g +-- -- | Gets the next dart along the face+-- nextDart     :: Dart s -> PlanarGraph s w v e f -> Dart s+-- nextDart d g = f rightFace e+ -------------------------------------------------------------------------------- -- Testing stuff @@ -635,41 +855,33 @@  data Test --- testG :: PlanarGraph Test Primal_ () String ()--- testG = planarGraph' [ [ (Dart aA Negative, "a-")---                        , (Dart aC Positive, "c+")---                        , (Dart aB Positive, "b+")---                        , (Dart aA Positive, "a+")---                        ]---                      , [ (Dart aE Negative, "e-")---                        , (Dart aB Negative, "b-")---                        , (Dart aD Negative, "d-")---                        , (Dart aG Positive, "g+")---                        ]---                      , [ (Dart aE Positive, "e+")---                        , (Dart aD Positive, "d+")---                        , (Dart aC Negative, "c-")---                        ]---                      , [ (Dart aG Negative, "g-")---                        ]---                      ]---   where---     (aA:aB:aC:aD:aE:aG:_) = take 6 [Arc 0..]+testG :: PlanarGraph Test Primal () String ()+testG = planarGraph [ [ (Dart aA Negative, "a-")+                      , (Dart aC Positive, "c+")+                      , (Dart aB Positive, "b+")+                      , (Dart aA Positive, "a+")+                      ]+                    , [ (Dart aE Negative, "e-")+                      , (Dart aB Negative, "b-")+                      , (Dart aD Negative, "d-")+                      , (Dart aG Positive, "g+")+                      ]+                    , [ (Dart aE Positive, "e+")+                      , (Dart aD Positive, "d+")+                      , (Dart aC Negative, "c-")+                      ]+                    , [ (Dart aG Negative, "g-")+                      ]+                    ]+  where+    (aA:aB:aC:aD:aE:aG:_) = take 6 [Arc 0..]  ---------------------------------------------------------------------------------   --- type ArcID = Int --- -- | ST' is a strict triple (m,a,x) containing:--- ----- -- - m: a Map, mapping edges, represented by a pair of vertexId's (u,v) with--- --            u < v, to arcId's.--- -- - a: the next available unused arcID--- -- - x: the data value we are interested in computing--- type ST' a = ST (SM.Map (VertexID,VertexID) ArcID) ArcID a+--------------------------------------------------------------------------------   --------------------------------------------------------------------------------@@ -700,11 +912,23 @@       g = traverse (bitraverse pure f)  -edgeOracle   :: PlanarGraph s w v e f -> EdgeOracle s w ()-edgeOracle g = buildEdgeOracle [ (v, ext <$> neighboursOf v g)+-- | Given a planar graph, construct an edge oracle. Given a pair of vertices+-- this allows us to efficiently find the dart representing this edge in the+-- graph.+--+-- pre: No self-loops and no multi-edges!!!+--+-- running time: \(O(n)\)+edgeOracle   :: PlanarGraph s w v e f -> EdgeOracle s w (Dart s)+edgeOracle g = buildEdgeOracle [ (v, mkAdjacency v <$> incidentEdges v g)                                | v <- F.toList $ vertices' g                                ]+  where+    mkAdjacency v d = otherVtx v d :+ d+    otherVtx v d = let u = tailOf d g in if u == v then headOf d g else u ++ -- | Builds an edge oracle that can be used to efficiently test if two vertices -- are connected by an edge. --@@ -780,14 +1004,24 @@   where     find' j i = fmap (^.extra) . F.find (\(VertexId k :+ _) -> j == k) $ os V.! i -+-- | Given a pair of vertices (u,v) returns the dart, oriented from u to v,+-- corresponding to these vertices.+--+-- running time: \(O(1)\)+findDart :: VertexId s w -> VertexId s w -> EdgeOracle s w (Dart s) -> Maybe (Dart s)+findDart (VertexId u) (VertexId v) (EdgeOracle os) = find' twin u v <|> find' id v u+    -- looks up j in the adjacencylist of i and applies f to the result+  where+    find' f j i = fmap (f . (^.extra)) . F.find (\(VertexId k :+ _) -> j == k) $ os V.! i  --------------------------------------------------------------------------------  data TestG -type Vertex = VertexId TestG Primal_ ++type Vertex = VertexId TestG Primal+ testEdges :: [(Vertex,[Vertex])] testEdges = map (\(i,vs) -> (VertexId i, map VertexId vs))             [ (0, [1])@@ -797,3 +1031,26 @@             , (4, [1,2,5])             , (5, [3,4])             ]+++myGraph :: PlanarGraph Test Primal () String ()+myGraph = planarGraph [ [ (Dart aA Negative, "a-")+                            , (Dart aC Positive, "c+")+                            , (Dart aB Positive, "b+")+                            , (Dart aA Positive, "a+")+                            ]+                          , [ (Dart aE Negative, "e-")+                            , (Dart aB Negative, "b-")+                            , (Dart aD Negative, "d-")+                            , (Dart aG Positive, "g+")+                            ]+                          , [ (Dart aE Positive, "e+")+                            , (Dart aD Positive, "d+")+                            , (Dart aC Negative, "c-")+                            ]+                          , [ (Dart aG Negative, "g-")+                            ]+                          ]+  where+    -- dart i s = Dart (Arc i) (read s)+    (aA:aB:aC:aD:aE:aG:_) = take 6 [Arc 0..]
src/Data/PlaneGraph.hs view
@@ -1,37 +1,548 @@-module Data.PlaneGraph( module Data.PlanarGraph-                      , PlaneGraph+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE OverloadedStrings #-}+module Data.PlaneGraph( PlaneGraph(PlaneGraph), graph+                      , PlanarGraph+                      , VertexData(VertexData), vData, location, vtxDataToExt+                      , fromSimplePolygon, fromConnectedSegments+                      , PG.fromAdjacencyLists +                      , numVertices, numEdges, numFaces, numDarts+                      , dual++                      , vertices', vertices+                      , edges', edges+                      , faces', faces, internalFaces, faces''+                      , darts'++                      , headOf, tailOf, twin, endPoints++                      , incidentEdges, incomingEdges, outgoingEdges+                      , neighboursOf+                      , nextIncidentEdge, prevIncidentEdge+++                      , leftFace, rightFace+                      , nextEdge, prevEdge+                      , boundary, boundary', boundaryVertices+                      , outerFaceId, outerFaceDart++                      , vertexDataOf, locationOf, HasDataOf(..)++                      , endPointsOf, endPointData+                      , vertexData, faceData, dartData, rawDartData++                      , edgeSegment, edgeSegments+                      , rawFacePolygon, rawFaceBoundary+                      , rawFacePolygons++                      , VertexId(..), FaceId(..), Dart, World(..), VertexId', FaceId'++                       , withEdgeDistances-                      , faceToSimplePolygon                       ) where -import Data.Ext-import Control.Lens-import Data.PlanarGraph-import Data.Geometry.Point-import Data.Geometry.Polygon(fromPoints, SimplePolygon)-import Data.Geometry.Properties++import           Control.Lens hiding (holes, holesOf, (.=))+import           Data.Aeson+import           Data.ByteString (ByteString)+import qualified Data.CircularSeq as C+import           Data.Ext+import qualified Data.Foldable as F+import           Data.Function (on)+import           Data.Geometry.Interval+import           Data.Geometry.Line (cmpSlope, supportingLine)+import           Data.Geometry.LineSegment+import           Data.Geometry.Box+import           Data.Geometry.Properties+import           Data.Geometry.Point+import           Data.Geometry.Polygon+import qualified Data.List.NonEmpty as NonEmpty+import qualified Data.Map as M+import           Data.Ord (comparing)+import qualified Data.PlanarGraph as PG+import           Data.PlanarGraph( PlanarGraph, planarGraph, dual+                                 , Dart(..), VertexId(..), FaceId(..), Arc(..)+                                 , Direction(..), twin+                                 , World(..)+                                 , FaceId', VertexId'+                                 , HasDataOf(..)+                                 )+import           Data.Semigroup+import           Data.Util import qualified Data.Vector as V+import           GHC.Generics (Generic)+import           Debug.Trace +-------------------------------------------------------------------------------- +-- | Note that the functor instance is in v+data VertexData r v = VertexData { _location :: !(Point 2 r)+                                 , _vData    :: !v+                                 } deriving (Show,Eq,Ord,Functor,Foldable,Traversable)+makeLenses ''VertexData++vtxDataToExt                  :: VertexData r v -> Point 2 r :+ v+vtxDataToExt (VertexData p v) = p :+ v++instance Bifunctor VertexData where+  bimap f g (VertexData p v) = VertexData (fmap f p) (g v)++instance (FromJSON r, FromJSON v) => FromJSON (VertexData r v) where+  parseJSON = fmap (\(l :+ d) -> VertexData l d) . parseJSON++instance (ToJSON r, ToJSON v) => ToJSON (VertexData r v) where+  toJSON     = toJSON     . vtxDataToExt+  toEncoding = toEncoding . vtxDataToExt+ -------------------------------------------------------------------------------- -type PlaneGraph s w v e f r = PlanarGraph s w (Point 2 r :+ v) e f+-- | Embedded, *connected*, planar graph+newtype PlaneGraph s v e f r =+    PlaneGraph { _graph :: PlanarGraph s Primal (VertexData r v) e f }+      deriving (Show,Eq,ToJSON,FromJSON)+makeLenses ''PlaneGraph -type instance NumType (PlaneGraph s w v e f r) = r+type instance NumType   (PlaneGraph s v e f r) = r+type instance Dimension (PlaneGraph s v e f r) = 2 +instance Functor (PlaneGraph s v e f) where+  fmap f pg = pg&graph.PG.vertexData.traverse.location %~ fmap f --- | Labels the edges of a plane graph with their distances, as specified by--- the distance function.-withEdgeDistances     :: (Point 2 r ->  Point 2 r -> a)-                      -> PlaneGraph s w p e f r -> PlaneGraph s w p (a :+ e) f r-withEdgeDistances f g = g&dartData %~ fmap (\(d,x) -> (d,len d :+ x))+instance IsBoxable (PlaneGraph s v e f r) where+  boundingBox = boundingBoxList' . F.toList . fmap (^._2.location) . vertices+++++--------------------------------------------------------------------------------+-- * Constructing a Plane Graph++-- | Construct a plane graph from a simple polygon. It is assumed that the+-- polygon is given in counterclockwise order.+--+-- the interior of the polygon will have faceId 0+--+-- pre: the input polygon is given in counterclockwise order+-- running time: \(O(n)\).+fromSimplePolygon                            :: proxy s+                                             -> SimplePolygon p r+                                             -> f -- ^ data inside+                                             -> f -- ^ data outside the polygon+                                             -> PlaneGraph s p () f r+fromSimplePolygon p (SimplePolygon vs) iD oD = PlaneGraph g'   where-    len d = uncurry f . over both (^.core) $ endPointData d g+    g      = fromVertices p vs+    fData' = V.fromList [iD, oD]+    g'     = g & PG.faceData .~ fData' +-- | Constructs a planar from the given vertices+fromVertices      :: proxy s+                  -> C.CSeq (Point 2 r :+ p)+                  -> PlanarGraph s Primal (VertexData r p) () ()+fromVertices _ vs = g&PG.vertexData .~ vData'+  where+    n = length vs+    g = planarGraph [ [ (Dart (Arc i)               Positive, ())+                      , (Dart (Arc $ (i+1) `mod` n) Negative, ())+                      ]+                    | i <- [0..(n-1)]]+    vData' = V.fromList . map (\(p :+ e) -> VertexData p e) . F.toList $ vs -faceToSimplePolygon      :: FaceId s w -> PlaneGraph s w p e f r-                         -> SimplePolygon p r :+ f-faceToSimplePolygon i gr = poly (boundaryVertices i gr) :+ gr^.fDataOf i+-- | Constructs a connected plane graph+--+-- pre: The segments form a single connected component+--+-- running time: \(O(n\log n)\)+fromConnectedSegments      :: (Foldable f, Ord r, Num r)+                           => proxy s+                           -> f (LineSegment 2 p r :+ e)+                           -> PlaneGraph s (NonEmpty.NonEmpty p) e () r+fromConnectedSegments _ ss = PlaneGraph $ planarGraph dts & PG.vertexData .~ vxData   where-    poly = fromPoints . V.toList . fmap (\j -> gr^.vDataOf j)+    pts         = M.fromListWith (<>) . concatMap f . zipWith g [0..] . F.toList $ ss+    f (s :+ e)  = [ ( s^.start.core+                    , SP (sing $ s^.start.extra) [(s^.end.core)   :+ h Positive e])+                  , ( s^.end.core+                    , SP (sing $ s^.end.extra)   [(s^.start.core) :+ h Negative e])+                  ]+    g i (s :+ e) = s :+ (Arc i :+ e)+    h d (a :+ e) = (Dart a d, e)++    sing x = x NonEmpty.:| []++    vts    = map (\(p,sp) -> (p,map (^.extra) . sortArround (ext p) <$> sp))+           . M.assocs $ pts+    -- vertex Data+    vxData = V.fromList . map (\(p,sp) -> VertexData p (sp^._1)) $ vts+    -- The darts+    dts    = map (^._2._2) vts++--------------------------------------------------------------------------------+-- * Basic Graph information++-- | Get the number of vertices+--+-- >>> numVertices myGraph+-- 4+numVertices :: PlaneGraph s v e f r  -> Int+numVertices = PG.numVertices . _graph++-- | Get the number of Darts+--+-- >>> numDarts myGraph+-- 12+numDarts :: PlaneGraph s v e f r  -> Int+numDarts = PG.numDarts . _graph++-- | Get the number of Edges+--+-- >>> numEdges myGraph+-- 6+numEdges :: PlaneGraph s v e f r  -> Int+numEdges = PG.numEdges . _graph++-- | Get the number of faces+--+-- >>> numFaces myGraph+-- 4+numFaces :: PlaneGraph s v e f r  -> Int+numFaces = PG.numFaces . _graph++-- | Enumerate all vertices+--+-- >>> vertices' myGraph+-- [VertexId 0,VertexId 1,VertexId 2,VertexId 3]+vertices'   :: PlaneGraph s v e f r  -> V.Vector (VertexId' s)+vertices' = PG.vertices' . _graph++-- | Enumerate all vertices, together with their vertex data++-- >>> vertices myGraph+-- [(VertexId 0,()),(VertexId 1,()),(VertexId 2,()),(VertexId 3,())]+vertices   :: PlaneGraph s v e f r  -> V.Vector (VertexId' s, VertexData r v)+vertices = PG.vertices . _graph++-- | Enumerate all darts+darts' :: PlaneGraph s v e f r  -> V.Vector (Dart s)+darts' = PG.darts' . _graph++-- | Enumerate all edges. We report only the Positive darts+edges' :: PlaneGraph s v e f r  -> V.Vector (Dart s)+edges' = PG.edges' . _graph++-- | Lens to access the raw dart data, use at your own risk+rawDartData :: Lens (PlaneGraph s v e f r) (PlaneGraph s v e' f r)+                    (V.Vector e) (V.Vector e')+rawDartData = graph.PG.rawDartData++-- | lens to access the Dart Data+dartData :: Lens (PlaneGraph s v e f r) (PlaneGraph s v e' f r)+                 (V.Vector (Dart s, e)) (V.Vector (Dart s, e'))+dartData = graph.PG.dartData++-- | Lens to access face data+faceData :: Lens (PlaneGraph s v e f r) (PlaneGraph s v e f' r)+                 (V.Vector f) (V.Vector f')+faceData = graph.PG.faceData++vertexData :: Lens (PlaneGraph s v e f r) (PlaneGraph s v' e f r)+                   (V.Vector v) (V.Vector v')+vertexData = lens get'' set''+  where+    get'' pg    = let v = pg^.graph.PG.vertexData in (^.vData) <$> v+    set'' pg v' = pg&graph.PG.vertexData %~ V.zipWith f v'+    f x (VertexData l _) = VertexData l x++-- | Enumerate all edges with their edge data. We report only the Positive+-- darts.+--+-- >>> mapM_ print $ edges myGraph+-- (Dart (Arc 2) +1,"c+")+-- (Dart (Arc 1) +1,"b+")+-- (Dart (Arc 0) +1,"a+")+-- (Dart (Arc 5) +1,"g+")+-- (Dart (Arc 4) +1,"e+")+-- (Dart (Arc 3) +1,"d+")+edges :: PlaneGraph s v e f r  -> V.Vector (Dart s, e)+edges = PG.edges . _graph++-- | Enumerate all faces in the plane graph+faces' :: PlaneGraph s v e f r  -> V.Vector (FaceId' s)+faces' = PG.faces' . _graph++-- | All faces with their face data.+faces :: PlaneGraph s v e f r  -> V.Vector (FaceId' s, f)+faces = PG.faces . _graph+++-- | Reports the outerface and all internal faces separately.+-- running time: \(O(n)\)+faces''   :: (Ord r, Fractional r)+          => PlaneGraph s v e f r -> ((FaceId' s, f), V.Vector (FaceId' s, f))+faces'' g = let i = outerFaceId g+            in ((i,g^.dataOf i), V.filter (\(j,_) -> i /= j) $ faces g)++-- | Reports all internal faces.+-- running time: \(O(n)\)+internalFaces :: (Ord r, Fractional r)+              => PlaneGraph s v e f r -> V.Vector (FaceId' s, f)+internalFaces = snd . faces''++-- | The tail of a dart, i.e. the vertex this dart is leaving from+--+-- running time: \(O(1)\)+tailOf   :: Dart s -> PlaneGraph s v e f r  -> VertexId' s+tailOf d = PG.tailOf d . _graph++-- | The vertex this dart is heading in to+--+-- running time: \(O(1)\)+headOf   :: Dart s -> PlaneGraph s v e f r  -> VertexId' s+headOf d = PG.headOf d . _graph++-- | endPoints d g = (tailOf d g, headOf d g)+--+-- running time: \(O(1)\)+endPoints   :: Dart s -> PlaneGraph s v e f r+            -> (VertexId' s, VertexId' s)+endPoints d = PG.endPoints d . _graph++-- | All edges incident to vertex v, in counterclockwise order around v.+--+-- running time: \(O(k)\), where \(k\) is the output size+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.+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.+outgoingEdges   :: VertexId' s -> PlaneGraph s v e f r  -> V.Vector (Dart s)+outgoingEdges v = PG.outgoingEdges v . _graph++-- | Gets the neighbours of a particular vertex, in counterclockwise order+-- around the vertex.+--+-- running time: \(O(k)\), where \(k\) is the output size+neighboursOf   :: VertexId' s -> PlaneGraph s v e f r+               -> V.Vector (VertexId' s)+neighboursOf v = PG.neighboursOf v . _graph++-- | Given a dart d that points into some vertex v, report the next dart in the+-- cyclic order around v.+--+-- running time: \(O(1)\)+nextIncidentEdge   :: Dart s -> PlaneGraph s v e f r -> Dart s+nextIncidentEdge d = PG.nextIncidentEdge d . _graph++-- | Given a dart d that points into some vertex v, report the next dart in the+-- cyclic order around v.+--+-- running time: \(O(1)\)+prevIncidentEdge   :: Dart s -> PlaneGraph s v e f r -> Dart s+prevIncidentEdge d = PG.prevIncidentEdge d . _graph+++-- | The face to the left of the dart+--+-- >>> leftFace (dart 1 "+1") myGraph+-- FaceId 1+-- >>> leftFace (dart 1 "-1") myGraph+-- FaceId 2+-- >>> leftFace (dart 2 "+1") myGraph+-- FaceId 2+-- >>> leftFace (dart 0 "+1") myGraph+-- FaceId 0+--+-- running time: \(O(1)\).+leftFace   :: Dart s -> PlaneGraph s v e f r  -> FaceId' s+leftFace d = PG.leftFace d . _graph++-- | The face to the right of the dart+--+-- >>> rightFace (dart 1 "+1") myGraph+-- FaceId 2+-- >>> rightFace (dart 1 "-1") myGraph+-- FaceId 1+-- >>> rightFace (dart 2 "+1") myGraph+-- FaceId 1+-- >>> rightFace (dart 0 "+1") myGraph+-- FaceId 1+--+-- running time: \(O(1)\).+rightFace   :: Dart s -> PlaneGraph s v e f r  -> FaceId' s+rightFace d = PG.rightFace d . _graph+++-- | Get the next edge along the face+--+--+-- running time: \(O(1)\).+nextEdge   :: Dart s -> PlaneGraph s v e f r -> Dart s+nextEdge d = PG.nextEdge d . _graph++-- | Get the previous edge along the face+--+--+-- running time: \(O(1)\).+prevEdge   :: Dart s -> PlaneGraph s v e f r -> Dart s+prevEdge d = PG.prevEdge d . _graph+++-- | The darts bounding this face, for internal faces in clockwise order, for+-- the outer face in counter clockwise order.+--+--+-- running time: \(O(k)\), where \(k\) is the output size.+boundary   :: FaceId' s -> PlaneGraph s v e f r  -> V.Vector (Dart s)+boundary f = PG.boundary f . _graph++-- | Generates the darts incident to a face, starting with the given dart.+--+--+-- \(O(k)\), where \(k\) is the number of darts reported+boundary'   :: Dart s -> PlaneGraph s v e f r -> V.Vector (Dart s)+boundary' d = PG.boundary' d . _graph+++-- | The vertices bounding this face, for internal faces in clockwise order, for+-- the outer face in counter clockwise order.+--+--+-- running time: \(O(k)\), where \(k\) is the output size.+boundaryVertices   :: FaceId' s -> PlaneGraph s v e f r+                   -> V.Vector (VertexId' s)+boundaryVertices f = PG.boundaryVertices f . _graph++--------------------------------------------------------------------------------+-- * Access data++vertexDataOf   :: VertexId' s -> Lens' (PlaneGraph s v e f r ) (VertexData r v)+vertexDataOf v = graph.PG.dataOf v++locationOf   :: VertexId' s -> Lens' (PlaneGraph s v e f r ) (Point 2 r)+locationOf v = vertexDataOf v.location+++instance HasDataOf (PlaneGraph s v e f r) (VertexId' s) where+  type DataOf (PlaneGraph s v e f r) (VertexId' s) = v+  dataOf v = graph.dataOf v.vData++instance HasDataOf (PlaneGraph s v e f r) (Dart s) where+  type DataOf (PlaneGraph s v e f r) (Dart s) = e+  dataOf d = graph.dataOf d++instance HasDataOf (PlaneGraph s v e f r) (FaceId' s) where+  type DataOf (PlaneGraph s v e f r) (FaceId' s) = f+  dataOf f = graph.dataOf f+++-- | Getter for the data at the endpoints of a dart+--+-- running time: \(O(1)\)+endPointsOf   :: Dart s -> Getter (PlaneGraph s v e f r )+                                  (VertexData r v, VertexData r v)+endPointsOf d = graph.PG.endPointDataOf d++-- | Data corresponding to the endpoints of the dart+--+-- running time: \(O(1)\)+endPointData   :: Dart s -> PlaneGraph s v e f r+               ->  (VertexData r v, VertexData r v)+endPointData d = PG.endPointData d . _graph++--------------------------------------------------------------------------------++-- | gets the id of the outer face+--+-- running time: \(O(n)\)+outerFaceId    :: (Ord r, Fractional r) => PlaneGraph s v e f r -> FaceId' s+outerFaceId ps = leftFace (outerFaceDart ps) ps+++-- | gets a dart incident to the outer face (in particular, that has the+-- outerface on its left)+--+-- running time: \(O(n)\)+outerFaceDart    :: (Ord r, Fractional r) => PlaneGraph s v e f r -> Dart s+outerFaceDart ps = d+  where+    (v,_)  = V.minimumBy (comparing (^._2.location.xCoord)) . vertices $ ps+    d :+ _ = V.maximumBy (cmpSlope `on` (^.extra))+           .  fmap (\d' -> d' :+ (edgeSegment d' ps)^.core.to supportingLine)+           $ incidentEdges v ps+    -- based on the approach sketched at https://cstheory.stackexchange.com/questions/27586/finding-outer-face-in-plane-graph-embedded-planar-graph+    -- basically: find the leftmost vertex, find the incident edge with the largest slope+    -- and take the face left of that edge. This is the outerface.+    -- note that this requires that the edges are straight line segments+    --++++--------------------------------------------------------------------------------++-- | Reports all edges as line segments+edgeSegments    :: PlaneGraph s v e f r -> V.Vector (Dart s, LineSegment 2 v r :+ e)+edgeSegments ps = fmap withSegment . edges $ ps+  where+    withSegment (d,e) = let (p,q) = bimap vtxDataToExt vtxDataToExt+                                  $ ps^.endPointsOf d+                            seg   = ClosedLineSegment p q+                        in (d, seg :+ e)++-- | Given a dart and the graph constructs the line segment representing the dart+--+-- \(O(1)\)+edgeSegment      :: Dart s -> PlaneGraph s v e f r -> LineSegment 2 v r :+ e+edgeSegment d ps = seg :+ ps^.dataOf d+  where+    seg = let (p,q) = bimap vtxDataToExt vtxDataToExt $ ps^.endPointsOf d+          in ClosedLineSegment p q++-- | The polygon describing the face+--+-- runningtime: \(O(k)\), where \(k\) is the size of the face.+rawFaceBoundary      :: FaceId' s -> PlaneGraph s v e f r+                    -> SimplePolygon v r :+ f+rawFaceBoundary i ps = pg :+ (ps^.dataOf i)+  where+    pg = fromPoints . F.toList . fmap (\j -> ps^.graph.dataOf j.to vtxDataToExt)+       . boundaryVertices i $ ps++-- | Alias for rawFace Boundary+--+-- runningtime: \(O(k)\), where \(k\) is the size of the face.+rawFacePolygon :: FaceId' s -> PlaneGraph s v e f r -> SimplePolygon v r :+ f+rawFacePolygon = rawFaceBoundary++-- | Lists all faces of the plane graph.+rawFacePolygons    :: PlaneGraph s v e f r+                   -> V.Vector (FaceId' s, SimplePolygon v r :+ f)+rawFacePolygons ps = fmap (\i -> (i,rawFacePolygon i ps)) . faces' $ ps+++--------------------------------------------------------------------------------+-- * Reading and Writing the Plane Graph++--+-- readPlaneGraph :: (FromJSON v, FromJSON e, FromJSON f, FromJSON r)+--                           => proxy s -> ByteString+--                          -> Either String (PlaneGraph s v e f r)+-- readPlaneGraph = undefined--  parseEither+++-- writePlaneGraph :: (ToJSON v, ToJSON e, ToJSON f, ToJSON r)+--                           => PlaneGraph s v e f r -> ByteString+-- writePlaneGraph = YamlP.encodePretty YamlP.defConfig++--------------------------------------------------------------------------------++-- | Labels the edges of a plane graph with their distances, as specified by+-- the distance function.+withEdgeDistances     :: (Point 2 r ->  Point 2 r -> a)+                      -> PlaneGraph s p e f r -> PlaneGraph s p (a :+ e) f r+withEdgeDistances f g = g&graph.PG.dartData %~ fmap (\(d,x) -> (d,len d :+ x))+  where+    len d = uncurry f . over both (^.location) $ endPointData d g
+ src/Data/PlaneGraph/Draw.hs view
@@ -0,0 +1,29 @@+{-# LANGUAGE ScopedTypeVariables #-}+module Data.PlaneGraph.Draw where++import Data.PlaneGraph+import           Data.Geometry.Ipe+import           Data.Ext+import           Control.Lens+import qualified Data.Vector as V++++drawPlaneGraph :: forall s v e f r. IpeOut (PlaneGraph s v e f r) (IpeObject r)+drawPlaneGraph = IpeOut draw+  where+    draw   :: PlaneGraph s v e f r -> IpeObject r+    draw g = asIpeGroup $ concatMap V.toList [vs, es, fs]+      where+        vs = (\(_,VertexData p _) -> asIpeObject p mempty) <$> vertices g+        es = (\(_,s :+ _) -> asIpeObject s mempty) <$> edgeSegments g+        fs = (\(_,f :+ _) -> asIpeObject f mempty) <$> rawFacePolygons g+++-- drawPlaneGraphWith :: (VertexId' s :+ v -> IpeObject r)+--                    -> (Dart s :+ e      -> IpeObject r)+--                    -> (FaceId' s :+ f   -> IpeObject r)+--                    -> IpeObject+-- drawPlaneGraphWith vertexF edgeF faceF g = asIpeGroup $ vs ++ es ++ fs+--   where+--     vs = map vertices ()
src/Data/Range.hs view
@@ -1,5 +1,11 @@ {-# LANGUAGE TemplateHaskell   #-} {-# LANGUAGE DeriveAnyClass  #-}+{-|+Module    : Data.Range+Description: Generic Ranges (Intervals)+Copyright : (c) Frank Staals+License : See LICENCE file+-} module Data.Range( EndPoint(..)                  , isOpen, isClosed                  , unEndPoint@@ -15,14 +21,14 @@  import Control.Lens import Data.Geometry.Properties-import Frames.CoRec+import Data.Vinyl.CoRec import Text.Printf(printf) import GHC.Generics (Generic) import Control.DeepSeq  -------------------------------------------------------------------------------- -+-- | Endpoints of a range may either be open or closed. data EndPoint a = Open   !a                 | Closed !a                 deriving (Show,Read,Eq,Functor,Foldable,Traversable,Generic,NFData)@@ -55,6 +61,7 @@  -------------------------------------------------------------------------------- +-- | Data type for representing ranges. data Range a = Range { _lower :: !(EndPoint a)                      , _upper :: !(EndPoint a)                      }@@ -72,9 +79,10 @@ pattern ClosedRange     :: a -> a -> Range a pattern ClosedRange l u = Range (Closed l) (Closed u) --- | A range from l to u, ignoring/forgetting the type of the enpoints+-- | A range from l to u, ignoring/forgetting the type of the endpoints pattern Range'     :: a -> a -> Range a pattern Range' l u <- ((\r -> (r^.lower.unEndPoint,r^.upper.unEndPoint) -> (l,u)))+{-# COMPLETE Range' #-}   prettyShow             :: Show a => Range a -> String
src/Data/Seq.hs view
@@ -34,12 +34,11 @@                , promise                ) where -import           Control.Lens ((%~), (&), (<&>), (^?), Lens', bimap)+import           Control.Lens ((%~), (&), (<&>), (^?), bimap) import           Control.Lens.At (Ixed(..), Index, IxValue) import qualified Data.Foldable as F import qualified Data.List.NonEmpty as NonEmpty import           Data.Maybe (fromJust)-import           Data.Proxy import           Data.Semigroup import qualified Data.Sequence as S import qualified Data.Traversable as Tr@@ -174,15 +173,17 @@  infixr 5 :<| --- pattern (:<|) :: a -> LSeq n a -> LSeq (1 + n) a+-- pattern (:<|)    :: a -> LSeq n a -> LSeq (1 + m) a pattern x :<| xs <- (viewl -> x :< xs)   where     x :<| xs = x <| xs  infixr 5 :<< +pattern (:<<)    :: a -> LSeq 0 a -> LSeq n a pattern x :<< xs <- (viewLSeq -> Just (x,xs)) +pattern EmptyL   :: LSeq n a pattern EmptyL   <- (viewLSeq -> Nothing)  viewLSeq          :: LSeq n a -> Maybe (a,LSeq 0 a)@@ -226,10 +227,10 @@  -------------------------------------------------------------------------------- -testL = (eval (Proxy :: Proxy 2) $ fromList [1..5])+-- testL = (eval (Proxy :: Proxy 2) $ fromList [1..5]) -testL' :: LSeq 2 Integer-testL' = fromJust testL+-- testL' :: LSeq 2 Integer+-- testL' = fromJust testL -test            :: Show a => LSeq (1 + n) a -> String-test (x :<| xs) = show x ++ show xs+-- test            :: Show a => LSeq (1 + n) a -> String+-- test (x :<| xs) = show x ++ show xs
src/Data/Sequence/Util.hs view
@@ -2,11 +2,12 @@  import Data.Sequence(Seq, ViewL(..),ViewR(..)) import qualified Data.Sequence as S+import qualified Data.Vector.Generic as V  -------------------------------------------------------------------------------- --- | Get the index h such that everything strictly smaller than h has: p i =--- False, and all i >= h, we have p h = True+-- | Given a monotonic predicate, Get the index h such that everything strictly+-- smaller than h has: p i = False, and all i >= h, we have p h = True -- -- returns Nothing if no element satisfies p --@@ -23,7 +24,24 @@     p' = p . S.index s     u  = S.length s - 1 +-- | Given a monotonic predicate, get the index h such that everything strictly+-- smaller than h has: p i = False, and all i >= h, we have p h = True+--+-- returns Nothing if no element satisfies p+--+-- running time: \(O(T*\log n)\), where \(T\) is the time to execute the+-- predicate.+binarySearchVec                             :: V.Vector v a+                                            => (a -> Bool) -> v a -> Maybe Int+binarySearchVec p' v | V.null v   = Nothing+                     | not $ p n' = Nothing+                     | otherwise  = Just $ if p 0 then 0+                                                  else binarySearch p 0 n'+  where+    n' = V.length v - 1+    p = p' . (v V.!) + -- | Partition the seq s given a monotone predicate p into (xs,ys) such that -- -- all elements in xs do *not* satisfy the predicate p@@ -49,6 +67,7 @@ -- -- running time: \(O(\log(u - l))\) {-# SPECIALIZE binarySearch :: (Int -> Bool) -> Int -> Int -> Int #-}+{-# SPECIALIZE binarySearch :: (Word -> Bool) -> Word -> Word -> Word #-} binarySearch       :: Integral a => (a -> Bool) -> a -> a -> a binarySearch p l u = let d = u - l                          m = l + (d `div` 2)
+ src/Data/SlowSeq.hs view
@@ -0,0 +1,206 @@+module Data.SlowSeq where+++import           Control.Lens (bimap)+-- import qualified Data.FingerTree as FT+-- import           Data.FingerTree hiding (null, viewl, viewr)+import           Data.FingerTree(ViewL(..),ViewR(..))+import qualified Data.Foldable as F+import           Data.Maybe+import           Data.Semigroup+import qualified Data.Sequence as S+import qualified Data.Sequence.Util as SU++++--------------------------------------------------------------------------------++data Key a = NoKey | Key { getKey :: a } deriving (Show,Eq,Ord)++instance Semigroup (Key a) where+  k <> NoKey = k+  _ <> k     = k++instance Monoid (Key a) where+  mempty = NoKey+  k `mappend` k' = k <> k'++liftCmp                     :: (a -> a -> Ordering) -> Key a -> Key a -> Ordering+liftCmp _   NoKey   NoKey   = EQ+liftCmp _   NoKey   (Key _) = LT+liftCmp _   (Key _) NoKey   = GT+liftCmp cmp (Key x) (Key y) = x `cmp` y++++-- newtype Elem a = Elem { getElem :: a } deriving (Eq,Ord,Traversable,Foldable,Functor)++-- instance Show a => Show (Elem a) where+--   show (Elem x) = "Elem " <> show x+++newtype OrdSeq a = OrdSeq { _asSeq :: S.Seq a }+                   deriving (Show,Eq)++instance Semigroup (OrdSeq a) where+  (OrdSeq s) <> (OrdSeq t) = OrdSeq $ s `mappend` t++instance Monoid (OrdSeq a) where+  mempty = OrdSeq mempty+  mappend = (<>)++instance Foldable OrdSeq where+  foldMap f = foldMap f . _asSeq+  null      = null . _asSeq+  length    = length . _asSeq+  minimum   = fromJust . lookupMin+  maximum   = fromJust . lookupMax++-- instance Measured (Key a) (Elem a) where+--   measure (Elem x) = Key x+++type Compare a = a -> a -> Ordering++-- | Insert into a monotone OrdSeq.+--+-- pre: the comparator maintains monotonicity+--+-- \(O(\log^2 n)\)+insertBy                  :: Compare a -> a -> OrdSeq a -> OrdSeq a+insertBy cmp x (OrdSeq s) = OrdSeq $ l `mappend` (x S.<| r)+  where+    (l,r) = split (\v -> cmp v x `elem` [EQ, GT]) s+++++++-- | Insert into a sorted OrdSeq+--+-- \(O(\log^2 n)\)+insert :: Ord a => a -> OrdSeq a -> OrdSeq a+insert = insertBy compare++deleteAllBy         :: Compare a -> a -> OrdSeq a -> OrdSeq a+deleteAllBy cmp x s = l <> r+  where+    (l,_,r) = splitBy cmp x s++    -- (l,m) = split (\v -> liftCmp cmp v (Key x) `elem` [EQ,GT]) s+    -- (_,r) = split (\v -> liftCmp cmp v (Key x) == GT) m+++-- | \(O(\log^2 n)\)+splitBy                  :: Compare a -> a -> OrdSeq a -> (OrdSeq a, OrdSeq a, OrdSeq a)+splitBy cmp x (OrdSeq s) = (OrdSeq l, OrdSeq m', OrdSeq r)+  where+    (l, m) = split (\v -> cmp v x `elem` [EQ,GT]) s+    (m',r) = split (\v -> cmp v x == GT) m+++-- | Given a monotonic function f that maps a to b, split the sequence s+-- depending on the b values. I.e. the result (l,m,r) is such that+-- * all (< x) . fmap f $ l+-- * all (== x) . fmap f $ m+-- * all (> x) . fmap f $ r+--+-- >>> splitOn id 3 $ fromAscList' [1..5]+-- (OrdSeq {_asSeq = fromList [Elem 1,Elem 2]},OrdSeq {_asSeq = fromList [Elem 3]},OrdSeq {_asSeq = fromList [Elem 4,Elem 5]})+-- >>> splitOn fst 2 $ fromAscList' [(0,"-"),(1,"A"),(2,"B"),(2,"C"),(3,"D"),(4,"E")]+-- (OrdSeq {_asSeq = fromList [Elem (0,"-"),Elem (1,"A")]},OrdSeq {_asSeq = fromList [Elem (2,"B"),Elem (2,"C")]},OrdSeq {_asSeq = fromList [Elem (3,"D"),Elem (4,"E")]})+--+-- \(O(\log^2 n)\)+splitOn :: Ord b => (a -> b) -> b -> OrdSeq a -> (OrdSeq a, OrdSeq a, OrdSeq a)+splitOn f x (OrdSeq s) = (OrdSeq l, OrdSeq m', OrdSeq r)+  where+    (l, m) = split (\v -> compare (f v) x `elem` [EQ,GT]) s+    (m',r) = split (\v -> compare (f v) x ==     GT)      m++-- | Given a monotonic predicate p, splits the sequence s into two sequences+--  (as,bs) such that all (not p) as and all p bs+--+-- \(O(\log^2 n)\)+splitMonotonic  :: (a -> Bool) -> OrdSeq a -> (OrdSeq a, OrdSeq a)+splitMonotonic p = bimap OrdSeq OrdSeq . split p . _asSeq+++-- monotonic split for Sequences+--+-- \(O(\log^2 n)\)+split :: (a -> Bool) -> S.Seq a -> (S.Seq a, S.Seq a)+split = SU.splitMonotone++-- Deletes all elements from the OrdDeq+--+-- \(O(\log^2 n)\)+deleteAll :: Ord a => a -> OrdSeq a -> OrdSeq a+deleteAll = deleteAllBy compare+++-- | inserts all eleements in order+-- \(O(n\log n)\)+fromListBy     :: Compare a -> [a] -> OrdSeq a+fromListBy cmp = foldr (insertBy cmp) mempty++-- | inserts all eleements in order+-- \(O(n\log n)\)+fromListByOrd :: Ord a => [a] -> OrdSeq a+fromListByOrd = fromListBy compare++-- | O(n)+fromAscList' :: [a] -> OrdSeq a+fromAscList' = OrdSeq . S.fromList+++-- | \(O(\log^2 n)\)+lookupBy                  :: Compare a -> a -> OrdSeq a -> Maybe a+lookupBy cmp x s = let (_,m,_) = splitBy cmp x s in listToMaybe . F.toList $ m++memberBy        :: Compare a -> a -> OrdSeq a -> Bool+memberBy cmp x = isJust . lookupBy cmp x+++-- | Fmap, assumes the order does not change+-- \(O(n)\)+mapMonotonic   :: (a -> b) -> OrdSeq a -> OrdSeq b+mapMonotonic f = fromAscList' . map f . F.toList+++-- | Gets the first element from the sequence+-- \(O(1)\)+viewl :: OrdSeq a -> ViewL OrdSeq a+viewl = f . S.viewl . _asSeq+  where+    f S.EmptyL         = EmptyL+    f (x S.:< s)  = x :< OrdSeq s++-- Last element+-- \(O(1)\)+viewr :: OrdSeq a -> ViewR OrdSeq a+viewr = f . S.viewr . _asSeq+  where+    f S.EmptyR    = EmptyR+    f (s S.:> x)  = OrdSeq s :> x+++-- \(O(1)\)+minView   :: OrdSeq a -> Maybe (a, OrdSeq a)+minView s = case viewl s of+              EmptyL   -> Nothing+              (x :< t) -> Just (x,t)++-- \(O(1)\)+lookupMin :: OrdSeq a -> Maybe a+lookupMin = fmap fst . minView++-- \(O(1)\)+maxView   :: OrdSeq a -> Maybe (a, OrdSeq a)+maxView s = case viewr s of+              EmptyR   -> Nothing+              (t :> x) -> Just (x,t)++-- \(O(1)\)+lookupMax :: OrdSeq a -> Maybe a+lookupMax = fmap fst . maxView
src/Data/Util.hs view
@@ -1,7 +1,6 @@ module Data.Util where  import Control.Lens-import Data.Bifunctor import Data.Semigroup  -- |  strict triple
+ src/Data/Yaml/Util.hs view
@@ -0,0 +1,22 @@+module Data.Yaml.Util where++import qualified Data.Yaml.Pretty as YamlP+import           Data.Yaml+import           Data.ByteString (ByteString)+import           Data.ByteString.Char8 as B++-- | Write the output to yaml+encodeYaml :: ToJSON a => a -> ByteString+encodeYaml = YamlP.encodePretty YamlP.defConfig++-- | Prints the yaml+printYaml :: ToJSON a => a -> IO ()+printYaml = B.putStrLn . encodeYaml++-- | alias for decodeEither' from the Yaml Package+decodeYaml :: FromJSON a => ByteString -> Either ParseException a+decodeYaml = decodeEither'++-- | alias for reading a yaml file+decodeYamlFile :: FromJSON a => FilePath -> IO (Either ParseException a)+decodeYamlFile = decodeFileEither
+ src/Test/QuickCheck/HGeometryInstances.hs view
@@ -0,0 +1,94 @@+{-# LANGUAGE UndecidableInstances  #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# OPTIONS_GHC -fno-warn-orphans #-}+module Test.QuickCheck.HGeometryInstances where++import           Control.Lens+import           Data.BinaryTree+import           Data.Ext+import           Data.Geometry hiding (vector)+import           Data.Geometry.Box+import           Data.Geometry.SubLine+import           Data.OrdSeq (OrdSeq, fromListByOrd)+import           Data.Proxy+import           Data.Semigroup+import qualified Data.Seq as Seq+import qualified Data.Seq2 as S2+import           GHC.TypeLits+import           Test.QuickCheck++--------------------------------------------------------------------------------++-- instance Arbitrary a => Arbitrary (NonEmpty.NonEmpty a) where+--   arbitrary = NonEmpty.fromList <$> listOf1 arbitrary++instance (Arbitrary a, Ord a) => Arbitrary (OrdSeq a) where+  arbitrary = fromListByOrd <$> arbitrary++instance Arbitrary a => Arbitrary (S2.Seq2 a) where+  arbitrary = S2.Seq2 <$> arbitrary <*> arbitrary <*> arbitrary++instance Arbitrary a => Arbitrary (BinaryTree a) where+  arbitrary = sized f+    where f n | n <= 0    = pure Nil+              | otherwise = do+                              l <- choose (0,n-1)+                              Internal <$> f l <*> arbitrary <*> f (n-l-1)++instance (Arbitrary a, Arbitrary v) => Arbitrary (BinLeafTree v a) where+  arbitrary = sized f+    where f n | n <= 0    = Leaf <$> arbitrary+              | otherwise = do+                              l <- choose (0,n-1)+                              Node <$> f l <*> arbitrary <*> f (n-l-1)+++instance (KnownNat n, Arbitrary a) => Arbitrary (Seq.LSeq n a) where+  arbitrary = (\s s' -> Seq.promise . Seq.fromList $ s <> s')+            <$> vector (fromInteger . natVal $ (Proxy :: Proxy n))+            <*> arbitrary++instance (Arbitrary r, Arity d) => Arbitrary (Vector d r) where+  arbitrary = vectorFromListUnsafe <$> infiniteList++instance (Arbitrary r, Arity d) => Arbitrary (Point d r) where+  arbitrary = Point <$> arbitrary++instance (Arbitrary r, Arity d, Num r, Eq r) => Arbitrary (Line d r) where+  arbitrary = do p <- arbitrary+                 q <- suchThat arbitrary (/= p)+                 return $ lineThrough p q++instance (Arbitrary r, Arity d, Ord r) => Arbitrary (Box d () r) where+  arbitrary = (\p (q :: Point d r) -> boundingBoxList' [p,q]) <$> arbitrary <*> arbitrary+++instance Arbitrary r => Arbitrary (EndPoint r) where+  arbitrary = frequency [ (1, Open   <$> arbitrary)+                        , (9, Closed <$> arbitrary)+                        ]++instance (Arbitrary r, Ord r) => Arbitrary (Range r) where+  arbitrary = do+                l <- arbitrary+                r <- suchThat arbitrary (p l)+                return $ Range l r+   where+     p (Open l)   r = l <  r^.unEndPoint+     p (Closed l) r = l <= r^.unEndPoint+++instance (Arbitrary c, Arbitrary e) => Arbitrary (c :+ e) where+  arbitrary = (:+) <$> arbitrary <*> arbitrary++instance (Arbitrary r, Arbitrary p, Ord r, Ord p) => Arbitrary (Interval p r) where+  arbitrary = GInterval <$> arbitrary+++instance (Arbitrary r, Arbitrary p, Arity d, Ord r, Ord p, Num r)+         => Arbitrary (SubLine d p r) where+  arbitrary = SubLine <$> arbitrary <*> arbitrary+++instance (Arbitrary r, Arbitrary p, Arity d) => Arbitrary (LineSegment d p r) where+  arbitrary = LineSegment <$> arbitrary <*> arbitrary
+ test/Algorithms/Geometry/ConvexHull/ConvexHullSpec.hs view
@@ -0,0 +1,41 @@+module Algorithms.Geometry.ConvexHull.ConvexHullSpec where++import qualified Algorithms.Geometry.ConvexHull.DivideAndConqueror as DivideAndConqueror+import qualified Algorithms.Geometry.ConvexHull.GrahamScan as GrahamScan+import           Control.Lens+import           Data.CircularSeq (isShiftOf)+import           Data.Ext+import           Data.Geometry.Point+import           Data.Geometry.Polygon+import           Data.Geometry.Polygon.Convex+import qualified Data.List as L+import qualified Data.List.NonEmpty as NonEmpty+import qualified Data.Map as Map+import           Data.Proxy+import           Data.Semigroup+import qualified Data.Set as Set+import           Test.Hspec+import           Test.Hspec.QuickCheck+import           Test.QuickCheck+import           Test.QuickCheck.HGeometryInstances()+import           Test.QuickCheck.Instances()+import           Util++import           Debug.Trace++spec :: Spec+spec = do+    describe "ConvexHull Algorithms" $ do+      modifyMaxSize (const 1000) . modifyMaxSuccess (const 1000) $+        it "GrahamScan and DivideAnd Conqueror are the same" $+          property $ \pts ->+            (PG $ GrahamScan.convexHull pts)+            ==+            (PG $ DivideAndConqueror.convexHull pts)++newtype PG = PG (ConvexPolygon () Rational) deriving (Show)++instance Eq PG where+  (PG a) == (PG b) = let as = a^.simplePolygon.outerBoundary+                         bs = b^.simplePolygon.outerBoundary+                     in isShiftOf as bs
test/Algorithms/Geometry/LineSegmentIntersection/BentleyOttmannSpec.hs view
@@ -1,5 +1,6 @@ module Algorithms.Geometry.LineSegmentIntersection.BentleyOttmannSpec where +import           Algorithms.Geometry.LineSegmentIntersection (hasSelfIntersections) import qualified Algorithms.Geometry.LineSegmentIntersection.BentleyOttmann as Sweep import qualified Algorithms.Geometry.LineSegmentIntersection.Naive as Naive import           Algorithms.Geometry.LineSegmentIntersection.Types@@ -9,23 +10,32 @@ import           Data.Geometry.Ipe import           Data.Geometry.LineSegment import           Data.Geometry.Point+import           Data.Geometry.Polygon import qualified Data.List as L import qualified Data.List.NonEmpty as NonEmpty import qualified Data.Map as Map+import           Data.Proxy+import           Data.Semigroup import qualified Data.Set as Set import           Test.Hspec import           Test.QuickCheck import           Util +import           Debug.Trace+ spec :: Spec spec = do   describe "Testing Bentley Ottmann LineSegment Intersection" $ do     -- toSpec (TestCase "myPoints" myPoints)     -- toSpec (TestCase "myPoints'" myPoints')     ipeSpec+  describe "Self Intersecting Polygon Tests" $ do+    siTestCases (testPath <> "selfIntersections.ipe") +testPath = "test/Algorithms/Geometry/LineSegmentIntersection/"+ ipeSpec :: Spec-ipeSpec = testCases "test/Algorithms/Geometry/LineSegmentIntersection/manual.ipe"+ipeSpec = testCases (testPath <> "manual.ipe")  testCases    :: FilePath -> Spec testCases fp = (runIO $ readInput fp) >>= \case@@ -63,3 +73,44 @@                     ) => [LineSegment 2 p r] -> Spec sameAsNaive segs = it "Same as Naive " $ do     (Sweep.intersections segs) `shouldBe` (Naive.intersections segs)+++data SelfIntersectionTestCase r = SITestCase { _siPolygon :: SimplePolygon () r+                                             , _isSelfIntersectiong :: Bool+                                             } deriving (Show,Eq)+++siTestCases    :: FilePath -> Spec+siTestCases fp = (runIO $ readSiInput fp) >>= \case+    Left e    -> it "reading SelfIntersection file" $+                   expectationFailure $ "Failed to read ipe file " ++ show e+    Right tcs -> mapM_ siToSpec tcs++-- | polygons are considered self intersecting when they are red+readSiInput    :: FilePath -> IO (Either ConversionError [SelfIntersectionTestCase Rational])+readSiInput fp = fmap f <$> readSinglePageFile fp+  where+    f page = [ SITestCase pg (isRed a)+             | pg :+ a <- polies+             ]+      where+        polies = page^..content.to flattenGroups.traverse+               ._withAttrs _IpePath _asSimplePolygon+        isRed ats = lookupAttr (Proxy :: Proxy Stroke) ats == Just (IpeColor (Named "red"))+++siToSpec                   :: SelfIntersectionTestCase Rational -> Spec+siToSpec (SITestCase pg b) = it ("SelfIntersecting?: " <> take 50 (show pg)) $ do+                               hasSelfIntersections pg `shouldBe` b++++-- flattenGroups :: [IpeObject r] -> [IpeObject r]+-- flattenGroups = concatMap flattenGroups'++-- flattenGroups'                              :: IpeObject r -> [IpeObject r]+-- flattenGroups' (IpeGroup (Group gs :+ ats)) =+--       map (applyAts ats) . concatMap flattenGroups' $ gs+--     where+--       applyAts ats = id+-- flattenGroups' o                            = [o]
+ test/Algorithms/Geometry/LineSegmentIntersection/selfIntersections.ipe view
@@ -0,0 +1,313 @@+<?xml version="1.0"?>+<!DOCTYPE ipe SYSTEM "ipe.dtd">+<ipe version="70107" creator="Ipe 7.2.2">+<info created="D:20170428203409" modified="D:20170428203521"/>+<ipestyle name="basic">+<symbol name="arrow/arc(spx)">+<path stroke="sym-stroke" fill="sym-stroke" pen="sym-pen">+0 0 m+-1 0.333 l+-1 -0.333 l+h+</path>+</symbol>+<symbol name="arrow/farc(spx)">+<path stroke="sym-stroke" fill="white" pen="sym-pen">+0 0 m+-1 0.333 l+-1 -0.333 l+h+</path>+</symbol>+<symbol name="arrow/ptarc(spx)">+<path stroke="sym-stroke" fill="sym-stroke" pen="sym-pen">+0 0 m+-1 0.333 l+-0.8 0 l+-1 -0.333 l+h+</path>+</symbol>+<symbol name="arrow/fptarc(spx)">+<path stroke="sym-stroke" fill="white" pen="sym-pen">+0 0 m+-1 0.333 l+-0.8 0 l+-1 -0.333 l+h+</path>+</symbol>+<symbol name="mark/circle(sx)" transformations="translations">+<path fill="sym-stroke">+0.6 0 0 0.6 0 0 e+0.4 0 0 0.4 0 0 e+</path>+</symbol>+<symbol name="mark/disk(sx)" transformations="translations">+<path fill="sym-stroke">+0.6 0 0 0.6 0 0 e+</path>+</symbol>+<symbol name="mark/fdisk(sfx)" transformations="translations">+<group>+<path fill="sym-fill">+0.5 0 0 0.5 0 0 e+</path>+<path fill="sym-stroke" fillrule="eofill">+0.6 0 0 0.6 0 0 e+0.4 0 0 0.4 0 0 e+</path>+</group>+</symbol>+<symbol name="mark/box(sx)" transformations="translations">+<path fill="sym-stroke" fillrule="eofill">+-0.6 -0.6 m+0.6 -0.6 l+0.6 0.6 l+-0.6 0.6 l+h+-0.4 -0.4 m+0.4 -0.4 l+0.4 0.4 l+-0.4 0.4 l+h+</path>+</symbol>+<symbol name="mark/square(sx)" transformations="translations">+<path fill="sym-stroke">+-0.6 -0.6 m+0.6 -0.6 l+0.6 0.6 l+-0.6 0.6 l+h+</path>+</symbol>+<symbol name="mark/fsquare(sfx)" transformations="translations">+<group>+<path fill="sym-fill">+-0.5 -0.5 m+0.5 -0.5 l+0.5 0.5 l+-0.5 0.5 l+h+</path>+<path fill="sym-stroke" fillrule="eofill">+-0.6 -0.6 m+0.6 -0.6 l+0.6 0.6 l+-0.6 0.6 l+h+-0.4 -0.4 m+0.4 -0.4 l+0.4 0.4 l+-0.4 0.4 l+h+</path>+</group>+</symbol>+<symbol name="mark/cross(sx)" transformations="translations">+<group>+<path fill="sym-stroke">+-0.43 -0.57 m+0.57 0.43 l+0.43 0.57 l+-0.57 -0.43 l+h+</path>+<path fill="sym-stroke">+-0.43 0.57 m+0.57 -0.43 l+0.43 -0.57 l+-0.57 0.43 l+h+</path>+</group>+</symbol>+<symbol name="arrow/fnormal(spx)">+<path stroke="sym-stroke" fill="white" pen="sym-pen">+0 0 m+-1 0.333 l+-1 -0.333 l+h+</path>+</symbol>+<symbol name="arrow/pointed(spx)">+<path stroke="sym-stroke" fill="sym-stroke" pen="sym-pen">+0 0 m+-1 0.333 l+-0.8 0 l+-1 -0.333 l+h+</path>+</symbol>+<symbol name="arrow/fpointed(spx)">+<path stroke="sym-stroke" fill="white" pen="sym-pen">+0 0 m+-1 0.333 l+-0.8 0 l+-1 -0.333 l+h+</path>+</symbol>+<symbol name="arrow/linear(spx)">+<path stroke="sym-stroke" pen="sym-pen">+-1 0.333 m+0 0 l+-1 -0.333 l+</path>+</symbol>+<symbol name="arrow/fdouble(spx)">+<path stroke="sym-stroke" fill="white" pen="sym-pen">+0 0 m+-1 0.333 l+-1 -0.333 l+h+-1 0 m+-2 0.333 l+-2 -0.333 l+h+</path>+</symbol>+<symbol name="arrow/double(spx)">+<path stroke="sym-stroke" fill="sym-stroke" pen="sym-pen">+0 0 m+-1 0.333 l+-1 -0.333 l+h+-1 0 m+-2 0.333 l+-2 -0.333 l+h+</path>+</symbol>+<pen name="heavier" value="0.8"/>+<pen name="fat" value="1.2"/>+<pen name="ultrafat" value="2"/>+<symbolsize name="large" value="5"/>+<symbolsize name="small" value="2"/>+<symbolsize name="tiny" value="1.1"/>+<arrowsize name="large" value="10"/>+<arrowsize name="small" value="5"/>+<arrowsize name="tiny" value="3"/>+<color name="red" value="1 0 0"/>+<color name="green" value="0 1 0"/>+<color name="blue" value="0 0 1"/>+<color name="yellow" value="1 1 0"/>+<color name="orange" value="1 0.647 0"/>+<color name="gold" value="1 0.843 0"/>+<color name="purple" value="0.627 0.125 0.941"/>+<color name="gray" value="0.745"/>+<color name="brown" value="0.647 0.165 0.165"/>+<color name="navy" value="0 0 0.502"/>+<color name="pink" value="1 0.753 0.796"/>+<color name="seagreen" value="0.18 0.545 0.341"/>+<color name="turquoise" value="0.251 0.878 0.816"/>+<color name="violet" value="0.933 0.51 0.933"/>+<color name="darkblue" value="0 0 0.545"/>+<color name="darkcyan" value="0 0.545 0.545"/>+<color name="darkgray" value="0.663"/>+<color name="darkgreen" value="0 0.392 0"/>+<color name="darkmagenta" value="0.545 0 0.545"/>+<color name="darkorange" value="1 0.549 0"/>+<color name="darkred" value="0.545 0 0"/>+<color name="lightblue" value="0.678 0.847 0.902"/>+<color name="lightcyan" value="0.878 1 1"/>+<color name="lightgray" value="0.827"/>+<color name="lightgreen" value="0.565 0.933 0.565"/>+<color name="lightyellow" value="1 1 0.878"/>+<dashstyle name="dashed" value="[4] 0"/>+<dashstyle name="dotted" value="[1 3] 0"/>+<dashstyle name="dash dotted" value="[4 2 1 2] 0"/>+<dashstyle name="dash dot dotted" value="[4 2 1 2 1 2] 0"/>+<textsize name="large" value="\large"/>+<textsize name="Large" value="\Large"/>+<textsize name="LARGE" value="\LARGE"/>+<textsize name="huge" value="\huge"/>+<textsize name="Huge" value="\Huge"/>+<textsize name="small" value="\small"/>+<textsize name="footnote" value="\footnotesize"/>+<textsize name="tiny" value="\tiny"/>+<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}"/>+<gridsize name="4 pts" value="4"/>+<gridsize name="8 pts (~3 mm)" value="8"/>+<gridsize name="16 pts (~6 mm)" value="16"/>+<gridsize name="32 pts (~12 mm)" value="32"/>+<gridsize name="10 pts (~3.5 mm)" value="10"/>+<gridsize name="20 pts (~7 mm)" value="20"/>+<gridsize name="14 pts (~5 mm)" value="14"/>+<gridsize name="28 pts (~10 mm)" value="28"/>+<gridsize name="56 pts (~20 mm)" value="56"/>+<anglesize name="90 deg" value="90"/>+<anglesize name="60 deg" value="60"/>+<anglesize name="45 deg" value="45"/>+<anglesize name="30 deg" value="30"/>+<anglesize name="22.5 deg" value="22.5"/>+<opacity name="10%" value="0.1"/>+<opacity name="30%" value="0.3"/>+<opacity name="50%" value="0.5"/>+<opacity name="75%" value="0.75"/>+<tiling name="falling" angle="-60" step="4" width="1"/>+<tiling name="rising" angle="30" step="4" width="1"/>+</ipestyle>+<ipestyle name="frank">+<arrowsize name="normal" value="5"/>+<arrowsize name="large" value="8"/>+<arrowsize name="huge" value="10"/>+<arrowsize name="small" value="3"/>+<arrowsize name="tiny" value="1"/>+<dashstyle name="dashed" value="[2 2] 0"/>+<dashstyle name="dotted" value="[0.5 1] 0"/>+<dashstyle name="dash dotted" value="[4 2 1 2] 0"/>+<dashstyle name="dash dot dotted" value="[4 2 1 2 1 2] 0"/>+<gridsize name="1 pts" value="1"/>+<gridsize name="2 pts" value="2"/>+<opacity name="10%" value="0.1"/>+<opacity name="30%" value="0.3"/>+<opacity name="50%" value="0.5"/>+<opacity name="20%" value="0.2"/>+<opacity name="40%" value="0.4"/>+<opacity name="60%" value="0.6"/>+<opacity name="70%" value="0.7"/>+<opacity name="80%" value="0.8"/>+<opacity name="90%" value="0.9"/>+</ipestyle>+<page>+<layer name="alpha"/>+<view layers="alpha" active="alpha"/>+<path layer="alpha" stroke="red">+96 704 m+192 816 l+352 656 l+208 640 l+336 784 l+h+</path>+<path stroke="red">+144 592 m+336 624 l+320 544 l+240 624 l+h+</path>+<path stroke="blue">+80 624 m+32 576 l+128 576 l+h+</path>+<path stroke="blue">+64 784 m+32 752 l+32 688 l+64 672 l+144 672 l+96 688 l+80 768 l+128 768 l+112 800 l+h+</path>+</page>+</ipe>
+ test/Algorithms/Geometry/LowerEnvelope/LowerEnvSpec.hs view
@@ -0,0 +1,104 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE ScopedTypeVariables #-}+module Algorithms.Geometry.LowerEnvelope.LowerEnvSpec where++import qualified Algorithms.Geometry.LowerEnvelope.DualCH as DualCH+import           Control.Lens+import           Data.Eq.Approximate+import           Data.Ext+import           Data.Geometry+import           Data.Geometry.Ipe+import           Data.Geometry.Line+import           Data.List.NonEmpty (NonEmpty(..))+import qualified Data.List.NonEmpty as NonEmpty+import           Data.Maybe (mapMaybe)+import           Data.Proxy+import           Data.Ratio+import           Data.Semigroup+import           Data.Vinyl.CoRec+import           GHC.TypeLits+import           Test.Hspec+import           Util++-- import Algorithms.Geometry.LowerEnvelope.Types++spec :: Spec+spec = testCases "test/Algorithms/Geometry/LowerEnvelope/manual.ipe"++testCases    :: FilePath -> Spec+testCases fp = (runIO $ readInput fp) >>= \case+    Left e    -> it "reading Smallest enclosing disk file" $+                   expectationFailure $ "Failed to read ipe file " ++ show e+    Right tcs -> mapM_ toSpec tcs+++type Approx r = AbsolutelyApproximateValue (Proxy 3) r++++data TestCase r = TestCase { _lines    :: NonEmpty (Line 2 r :+ ())+                           , _color    :: Maybe (IpeColor r)+                           , _solution :: [Point 2 (Approx r)]+                           }+                  deriving (Show,Eq)+++readInput    :: FilePath -> IO (Either ConversionError [TestCase Rational])+readInput fp = fmap f <$> readSinglePageFile fp+  where+    f page = [ let c = lookup' $ NonEmpty.head lSet+               in TestCase ((\l -> l^.core.to supportingLine :+ ()) <$> lSet)+                           c+                           (solutionOf c)+             | lSet <- mapMaybe NonEmpty.nonEmpty $ byStrokeColour segs+             ]+      where+        segs :: [LineSegment 2 () Rational :+ IpeAttributes Path Rational]+        segs = page^..content.traverse._withAttrs _IpePath _asLineSegment+        pts  = page^..content.traverse._IpeUse++        solutionOf c = [ AbsolutelyApproximateValue <$> p^.core.symbolPoint+                       | p <- pts, lookup' p == c+                       ]++++lookup' (_ :+ ats) = lookupAttr (Proxy :: Proxy Stroke) ats+++toSpec                    :: (Fractional r, Ord r, Show r) => TestCase r -> Spec+toSpec (TestCase ls c sol) = it ("testing the " <> show c <> " set") $+  (map (approx . (^.core))+   . DualCH.vertices . DualCH.lowerEnvelope $ ls) `shouldBe` sol+++approx = fmap AbsolutelyApproximateValue++-- shouldApprox       :: forall f r. ( Functor f, Eq (f (Approx r))+--                                   , Show (f (Approx r))+--                                   )+--                    => f r -> f r -> Expectation+-- a `shouldApprox` b = a' `shouldBe` b'+--   where+--     a' :: f (Approx r)+--     a' = AbsolutelyApproximateValue <$> a+--     b' :: f (Approx r)+--     b' = AbsolutelyApproximateValue <$> b++++instance KnownNat n => AbsoluteTolerance (Proxy n) where+  absoluteToleranceOf = toleranceFromKnownNat . getAbsoluteTolerance++toleranceFromKnownNat   :: (Fractional r, KnownNat n) => proxy n -> r+toleranceFromKnownNat p = recip . fromInteger $ (10 :: Integer) ^ (natVal p)++instance KnownNat n => RelativeTolerance (Proxy n) where+  relativeToleranceOf = toleranceFromKnownNat . getRelativeTolerance++instance KnownNat n => ZeroTolerance (Proxy n) where+  zeroToleranceOf = toleranceFromKnownNat . getZeroTolerance++--     where+--       f   :: Fractional r => AbsolutelyApproximateValue (Proxy n) r -> r+--       f _ = recip $ (fromInteger 10) ^^ (natVal (Proxy :: Proxy n))
+ test/Algorithms/Geometry/LowerEnvelope/manual.ipe view
@@ -0,0 +1,299 @@+<?xml version="1.0"?>+<!DOCTYPE ipe SYSTEM "ipe.dtd">+<ipe version="70107" creator="Ipe 7.2.2">+<info created="D:20170715125328" modified="D:20170715125434"/>+<ipestyle name="basic">+<symbol name="arrow/arc(spx)">+<path stroke="sym-stroke" fill="sym-stroke" pen="sym-pen">+0 0 m+-1 0.333 l+-1 -0.333 l+h+</path>+</symbol>+<symbol name="arrow/farc(spx)">+<path stroke="sym-stroke" fill="white" pen="sym-pen">+0 0 m+-1 0.333 l+-1 -0.333 l+h+</path>+</symbol>+<symbol name="arrow/ptarc(spx)">+<path stroke="sym-stroke" fill="sym-stroke" pen="sym-pen">+0 0 m+-1 0.333 l+-0.8 0 l+-1 -0.333 l+h+</path>+</symbol>+<symbol name="arrow/fptarc(spx)">+<path stroke="sym-stroke" fill="white" pen="sym-pen">+0 0 m+-1 0.333 l+-0.8 0 l+-1 -0.333 l+h+</path>+</symbol>+<symbol name="mark/circle(sx)" transformations="translations">+<path fill="sym-stroke">+0.6 0 0 0.6 0 0 e+0.4 0 0 0.4 0 0 e+</path>+</symbol>+<symbol name="mark/disk(sx)" transformations="translations">+<path fill="sym-stroke">+0.6 0 0 0.6 0 0 e+</path>+</symbol>+<symbol name="mark/fdisk(sfx)" transformations="translations">+<group>+<path fill="sym-fill">+0.5 0 0 0.5 0 0 e+</path>+<path fill="sym-stroke" fillrule="eofill">+0.6 0 0 0.6 0 0 e+0.4 0 0 0.4 0 0 e+</path>+</group>+</symbol>+<symbol name="mark/box(sx)" transformations="translations">+<path fill="sym-stroke" fillrule="eofill">+-0.6 -0.6 m+0.6 -0.6 l+0.6 0.6 l+-0.6 0.6 l+h+-0.4 -0.4 m+0.4 -0.4 l+0.4 0.4 l+-0.4 0.4 l+h+</path>+</symbol>+<symbol name="mark/square(sx)" transformations="translations">+<path fill="sym-stroke">+-0.6 -0.6 m+0.6 -0.6 l+0.6 0.6 l+-0.6 0.6 l+h+</path>+</symbol>+<symbol name="mark/fsquare(sfx)" transformations="translations">+<group>+<path fill="sym-fill">+-0.5 -0.5 m+0.5 -0.5 l+0.5 0.5 l+-0.5 0.5 l+h+</path>+<path fill="sym-stroke" fillrule="eofill">+-0.6 -0.6 m+0.6 -0.6 l+0.6 0.6 l+-0.6 0.6 l+h+-0.4 -0.4 m+0.4 -0.4 l+0.4 0.4 l+-0.4 0.4 l+h+</path>+</group>+</symbol>+<symbol name="mark/cross(sx)" transformations="translations">+<group>+<path fill="sym-stroke">+-0.43 -0.57 m+0.57 0.43 l+0.43 0.57 l+-0.57 -0.43 l+h+</path>+<path fill="sym-stroke">+-0.43 0.57 m+0.57 -0.43 l+0.43 -0.57 l+-0.57 0.43 l+h+</path>+</group>+</symbol>+<symbol name="arrow/fnormal(spx)">+<path stroke="sym-stroke" fill="white" pen="sym-pen">+0 0 m+-1 0.333 l+-1 -0.333 l+h+</path>+</symbol>+<symbol name="arrow/pointed(spx)">+<path stroke="sym-stroke" fill="sym-stroke" pen="sym-pen">+0 0 m+-1 0.333 l+-0.8 0 l+-1 -0.333 l+h+</path>+</symbol>+<symbol name="arrow/fpointed(spx)">+<path stroke="sym-stroke" fill="white" pen="sym-pen">+0 0 m+-1 0.333 l+-0.8 0 l+-1 -0.333 l+h+</path>+</symbol>+<symbol name="arrow/linear(spx)">+<path stroke="sym-stroke" pen="sym-pen">+-1 0.333 m+0 0 l+-1 -0.333 l+</path>+</symbol>+<symbol name="arrow/fdouble(spx)">+<path stroke="sym-stroke" fill="white" pen="sym-pen">+0 0 m+-1 0.333 l+-1 -0.333 l+h+-1 0 m+-2 0.333 l+-2 -0.333 l+h+</path>+</symbol>+<symbol name="arrow/double(spx)">+<path stroke="sym-stroke" fill="sym-stroke" pen="sym-pen">+0 0 m+-1 0.333 l+-1 -0.333 l+h+-1 0 m+-2 0.333 l+-2 -0.333 l+h+</path>+</symbol>+<pen name="heavier" value="0.8"/>+<pen name="fat" value="1.2"/>+<pen name="ultrafat" value="2"/>+<symbolsize name="large" value="5"/>+<symbolsize name="small" value="2"/>+<symbolsize name="tiny" value="1.1"/>+<arrowsize name="large" value="10"/>+<arrowsize name="small" value="5"/>+<arrowsize name="tiny" value="3"/>+<color name="red" value="1 0 0"/>+<color name="green" value="0 1 0"/>+<color name="blue" value="0 0 1"/>+<color name="yellow" value="1 1 0"/>+<color name="orange" value="1 0.647 0"/>+<color name="gold" value="1 0.843 0"/>+<color name="purple" value="0.627 0.125 0.941"/>+<color name="gray" value="0.745"/>+<color name="brown" value="0.647 0.165 0.165"/>+<color name="navy" value="0 0 0.502"/>+<color name="pink" value="1 0.753 0.796"/>+<color name="seagreen" value="0.18 0.545 0.341"/>+<color name="turquoise" value="0.251 0.878 0.816"/>+<color name="violet" value="0.933 0.51 0.933"/>+<color name="darkblue" value="0 0 0.545"/>+<color name="darkcyan" value="0 0.545 0.545"/>+<color name="darkgray" value="0.663"/>+<color name="darkgreen" value="0 0.392 0"/>+<color name="darkmagenta" value="0.545 0 0.545"/>+<color name="darkorange" value="1 0.549 0"/>+<color name="darkred" value="0.545 0 0"/>+<color name="lightblue" value="0.678 0.847 0.902"/>+<color name="lightcyan" value="0.878 1 1"/>+<color name="lightgray" value="0.827"/>+<color name="lightgreen" value="0.565 0.933 0.565"/>+<color name="lightyellow" value="1 1 0.878"/>+<dashstyle name="dashed" value="[4] 0"/>+<dashstyle name="dotted" value="[1 3] 0"/>+<dashstyle name="dash dotted" value="[4 2 1 2] 0"/>+<dashstyle name="dash dot dotted" value="[4 2 1 2 1 2] 0"/>+<textsize name="large" value="\large"/>+<textsize name="Large" value="\Large"/>+<textsize name="LARGE" value="\LARGE"/>+<textsize name="huge" value="\huge"/>+<textsize name="Huge" value="\Huge"/>+<textsize name="small" value="\small"/>+<textsize name="footnote" value="\footnotesize"/>+<textsize name="tiny" value="\tiny"/>+<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}"/>+<gridsize name="4 pts" value="4"/>+<gridsize name="8 pts (~3 mm)" value="8"/>+<gridsize name="16 pts (~6 mm)" value="16"/>+<gridsize name="32 pts (~12 mm)" value="32"/>+<gridsize name="10 pts (~3.5 mm)" value="10"/>+<gridsize name="20 pts (~7 mm)" value="20"/>+<gridsize name="14 pts (~5 mm)" value="14"/>+<gridsize name="28 pts (~10 mm)" value="28"/>+<gridsize name="56 pts (~20 mm)" value="56"/>+<anglesize name="90 deg" value="90"/>+<anglesize name="60 deg" value="60"/>+<anglesize name="45 deg" value="45"/>+<anglesize name="30 deg" value="30"/>+<anglesize name="22.5 deg" value="22.5"/>+<opacity name="10%" value="0.1"/>+<opacity name="30%" value="0.3"/>+<opacity name="50%" value="0.5"/>+<opacity name="75%" value="0.75"/>+<tiling name="falling" angle="-60" step="4" width="1"/>+<tiling name="rising" angle="30" step="4" width="1"/>+</ipestyle>+<ipestyle name="frank">+<arrowsize name="normal" value="5"/>+<arrowsize name="large" value="8"/>+<arrowsize name="huge" value="10"/>+<arrowsize name="small" value="3"/>+<arrowsize name="tiny" value="1"/>+<dashstyle name="dashed" value="[2 2] 0"/>+<dashstyle name="dotted" value="[0.5 1] 0"/>+<dashstyle name="dash dotted" value="[4 2 1 2] 0"/>+<dashstyle name="dash dot dotted" value="[4 2 1 2 1 2] 0"/>+<gridsize name="1 pts" value="1"/>+<gridsize name="2 pts" value="2"/>+<opacity name="10%" value="0.1"/>+<opacity name="30%" value="0.3"/>+<opacity name="50%" value="0.5"/>+<opacity name="20%" value="0.2"/>+<opacity name="40%" value="0.4"/>+<opacity name="60%" value="0.6"/>+<opacity name="70%" value="0.7"/>+<opacity name="80%" value="0.8"/>+<opacity name="90%" value="0.9"/>+</ipestyle>+<page>+<layer name="alpha"/>+<view layers="alpha" active="alpha"/>+<path layer="alpha" stroke="black">+80 496 m+304 624 l+</path>+<path stroke="black">+320 512 m+176 624 l+</path>+<path stroke="black">+80 560 m+368 560 l+</path>+<path stroke="black">+80 512 m+320 608 l+</path>+<use name="mark/disk(sx)" pos="173.333 549.333" size="normal" stroke="black"/>+<use name="mark/disk(sx)" pos="200 560" size="normal" stroke="black"/>+<use name="mark/disk(sx)" pos="258.286 560" size="normal" stroke="black"/>+</page>+</ipe>
+ test/Algorithms/Geometry/PolygonTriangulation/MakeMonotoneSpec.hs view
@@ -0,0 +1,58 @@+module Algorithms.Geometry.PolygonTriangulation.MakeMonotoneSpec where++import Algorithms.Geometry.PolygonTriangulation.MakeMonotone+import Data.Geometry.Polygon+import Data.Geometry+import Data.Ext+import Control.Lens+import Test.Hspec+import qualified Data.List.NonEmpty as NonEmpty+import qualified Data.Set as Set+-- import Data.Geometry.Ipe+++spec :: Spec+spec = describe "GeomBook Example" $ do+         it "Classify Verticese" $+           (fmap (^.extra.extra) . polygonVertices $ classifyVertices geomBookPoly)+           `shouldBe` geomBookVertexTypes+         it "Diagonals" $+           (Set.fromList . map (\s -> sort' (s^.start.extra,s^.end.extra))+            $ computeDiagonals geomBookPoly)+           `shouldBe` geomBookDiagonals+++  -- testCases "test/Algorithms/Geometry/SmallestEnclosingDisk/manual.ipe"++sort'       :: Ord a => (a,a) -> (a,a)+sort' (x,y) = (min x y, max x y)++geomBookPoly :: SimplePolygon Int Rational+geomBookPoly = fromPoints [ point2 20 20 :+ 1+                          , point2 18 19 :+ 2+                          , point2 16 25 :+ 3+                          , point2 13 23 :+ 4+                          , point2 10 24 :+ 5+                          , point2 6  22 :+ 6+                          , point2 8  21 :+ 7+                          , point2 7  18 :+ 8+                          , point2 2  19 :+ 9+                          , point2 1  10 :+ 10+                          , point2 3  5  :+ 11+                          , point2 11 7  :+ 12+                          , point2 15 1  :+ 13+                          , point2 12 15 :+ 14+                          , point2 15 12 :+ 15+                          ]+geomBookVertexTypes = NonEmpty.fromList [Start,Merge,Start,Merge,Start,Regular,Regular,Merge,Start,Regular,End,Split,End,Split,End]+geomBookDiagonals = Set.fromList [(4,6),(2,8),(8,14),(10,12)]++++  -- let f i     = geomBookPoly !! (i-1)+  --                       seg i j =+  --                   in++  -- [Clo++  -- LineSegment (Closed (Point2 [6 % 1,22 % 1] :+ 6)) (Closed (Point2 [13 % 1,23 % 1] :+ 4)),LineSegment (Closed (Point2 [7 % 1,18 % 1] :+ 8)) (Closed (Point2 [18 % 1,19 % 1] :+ 2)),LineSegment (Closed (Point2 [12 % 1,15 % 1] :+ 14)) (Closed (Point2 [7 % 1,18 % 1] :+ 8)),LineSegment (Closed (Point2 [11 % 1,7 % 1] :+ 12)) (Closed (Point2 [1 % 1,10 % 1] :+ 10))]
+ test/Algorithms/Geometry/PolygonTriangulation/TriangulateMonotoneSpec.hs view
@@ -0,0 +1,73 @@+module Algorithms.Geometry.PolygonTriangulation.TriangulateMonotoneSpec where++import           Algorithms.Geometry.PolygonTriangulation.TriangulateMonotone+import           Control.Lens+import           Data.Ext+import           Data.Geometry+import           Data.Geometry.Ipe+import           Data.Geometry.Polygon+import qualified Data.List.NonEmpty as NonEmpty+import           Data.Maybe+import qualified Data.Set as Set+import           Data.Vinyl+import           Test.Hspec+import           Util+++spec :: Spec+spec = do testCases "test/Algorithms/Geometry/PolygonTriangulation/monotone.ipe"+          testCases "test/Algorithms/Geometry/PolygonTriangulation/simplepolygon6.ipe"++testCases    :: FilePath -> Spec+testCases fp = (runIO $ readInput fp) >>= \case+    Left e    -> it "reading TriangulateMonotone file" $+                   expectationFailure $ "Failed to read ipe file " ++ show e+    Right tcs -> mapM_ toSpec tcs+++data TestCase r = TestCase { _polygon  :: MonotonePolygon () r :+ IpeColor r+                           , _solution :: [LineSegment 2 () r]+                           }+                  deriving (Show,Eq)+++toSpec                            :: (Num r, Ord r, Show r) => TestCase r -> Spec+toSpec (TestCase (poly :+ c) sol) =+    describe ("testing polygions of color " ++ show c) $ do+      it "comparing with manual solution" $+        (naiveSet $ computeDiagonals poly) `shouldBe` naiveSet sol+  where+    naiveSet = NaiveSet . map S++newtype S p r = S (LineSegment 2 p r) deriving (Show)++instance (Eq p, Eq r) => Eq (S p r) where+  (S s) == (S y) =  (s^.start == y^.start && s^.end == y^.end)+                 || (s^.start == y^.end   && s^.end == y^.start)++++-- | Point sets per color, Crosses form the solution+readInput    :: FilePath -> IO (Either ConversionError [TestCase Rational])+readInput fp = fmap f <$> readSinglePageFile fp+  where+    f page = [ TestCase pg (solutionOf pg segs)+             | pg <- map g polies+             ]+      where+        g x@(pg :+ _) = toCounterClockWiseOrder pg :+ lookupColor x++        polies = page^..content.traverse._withAttrs _IpePath _asSimplePolygon+        segs   = page^..content.traverse._withAttrs _IpePath _asLineSegment++        solutionOf (_ :+ c) = map (^.core) . filter ((== c) . lookupColor)+++        -- -- | Crosses form a solution+        -- isInSolution s = s^.core.symbolName == "mark/cross(sx)"++        -- right = either (const Nothing) Just+        -- solutionOf = right . fromList . map (^.core.symbolPoint) . filter isInSolution++lookupColor           :: i :+ IpeAttributes Path r -> IpeColor r+lookupColor (_ :+ ats) = fromMaybe (IpeColor $ Named "black") $ lookupAttr SStroke ats
+ test/Algorithms/Geometry/PolygonTriangulation/monotone.ipe view
@@ -0,0 +1,364 @@+<?xml version="1.0"?>+<!DOCTYPE ipe SYSTEM "ipe.dtd">+<ipe version="70107" creator="Ipe 7.2.2">+<info created="D:20170207224641" modified="D:20180526104709"/>+<ipestyle name="basic">+<symbol name="arrow/arc(spx)">+<path stroke="sym-stroke" fill="sym-stroke" pen="sym-pen">+0 0 m+-1 0.333 l+-1 -0.333 l+h+</path>+</symbol>+<symbol name="arrow/farc(spx)">+<path stroke="sym-stroke" fill="white" pen="sym-pen">+0 0 m+-1 0.333 l+-1 -0.333 l+h+</path>+</symbol>+<symbol name="arrow/ptarc(spx)">+<path stroke="sym-stroke" fill="sym-stroke" pen="sym-pen">+0 0 m+-1 0.333 l+-0.8 0 l+-1 -0.333 l+h+</path>+</symbol>+<symbol name="arrow/fptarc(spx)">+<path stroke="sym-stroke" fill="white" pen="sym-pen">+0 0 m+-1 0.333 l+-0.8 0 l+-1 -0.333 l+h+</path>+</symbol>+<symbol name="mark/circle(sx)" transformations="translations">+<path fill="sym-stroke">+0.6 0 0 0.6 0 0 e+0.4 0 0 0.4 0 0 e+</path>+</symbol>+<symbol name="mark/disk(sx)" transformations="translations">+<path fill="sym-stroke">+0.6 0 0 0.6 0 0 e+</path>+</symbol>+<symbol name="mark/fdisk(sfx)" transformations="translations">+<group>+<path fill="sym-fill">+0.5 0 0 0.5 0 0 e+</path>+<path fill="sym-stroke" fillrule="eofill">+0.6 0 0 0.6 0 0 e+0.4 0 0 0.4 0 0 e+</path>+</group>+</symbol>+<symbol name="mark/box(sx)" transformations="translations">+<path fill="sym-stroke" fillrule="eofill">+-0.6 -0.6 m+0.6 -0.6 l+0.6 0.6 l+-0.6 0.6 l+h+-0.4 -0.4 m+0.4 -0.4 l+0.4 0.4 l+-0.4 0.4 l+h+</path>+</symbol>+<symbol name="mark/square(sx)" transformations="translations">+<path fill="sym-stroke">+-0.6 -0.6 m+0.6 -0.6 l+0.6 0.6 l+-0.6 0.6 l+h+</path>+</symbol>+<symbol name="mark/fsquare(sfx)" transformations="translations">+<group>+<path fill="sym-fill">+-0.5 -0.5 m+0.5 -0.5 l+0.5 0.5 l+-0.5 0.5 l+h+</path>+<path fill="sym-stroke" fillrule="eofill">+-0.6 -0.6 m+0.6 -0.6 l+0.6 0.6 l+-0.6 0.6 l+h+-0.4 -0.4 m+0.4 -0.4 l+0.4 0.4 l+-0.4 0.4 l+h+</path>+</group>+</symbol>+<symbol name="mark/cross(sx)" transformations="translations">+<group>+<path fill="sym-stroke">+-0.43 -0.57 m+0.57 0.43 l+0.43 0.57 l+-0.57 -0.43 l+h+</path>+<path fill="sym-stroke">+-0.43 0.57 m+0.57 -0.43 l+0.43 -0.57 l+-0.57 0.43 l+h+</path>+</group>+</symbol>+<symbol name="arrow/fnormal(spx)">+<path stroke="sym-stroke" fill="white" pen="sym-pen">+0 0 m+-1 0.333 l+-1 -0.333 l+h+</path>+</symbol>+<symbol name="arrow/pointed(spx)">+<path stroke="sym-stroke" fill="sym-stroke" pen="sym-pen">+0 0 m+-1 0.333 l+-0.8 0 l+-1 -0.333 l+h+</path>+</symbol>+<symbol name="arrow/fpointed(spx)">+<path stroke="sym-stroke" fill="white" pen="sym-pen">+0 0 m+-1 0.333 l+-0.8 0 l+-1 -0.333 l+h+</path>+</symbol>+<symbol name="arrow/linear(spx)">+<path stroke="sym-stroke" pen="sym-pen">+-1 0.333 m+0 0 l+-1 -0.333 l+</path>+</symbol>+<symbol name="arrow/fdouble(spx)">+<path stroke="sym-stroke" fill="white" pen="sym-pen">+0 0 m+-1 0.333 l+-1 -0.333 l+h+-1 0 m+-2 0.333 l+-2 -0.333 l+h+</path>+</symbol>+<symbol name="arrow/double(spx)">+<path stroke="sym-stroke" fill="sym-stroke" pen="sym-pen">+0 0 m+-1 0.333 l+-1 -0.333 l+h+-1 0 m+-2 0.333 l+-2 -0.333 l+h+</path>+</symbol>+<pen name="heavier" value="0.8"/>+<pen name="fat" value="1.2"/>+<pen name="ultrafat" value="2"/>+<symbolsize name="large" value="5"/>+<symbolsize name="small" value="2"/>+<symbolsize name="tiny" value="1.1"/>+<arrowsize name="large" value="10"/>+<arrowsize name="small" value="5"/>+<arrowsize name="tiny" value="3"/>+<color name="red" value="1 0 0"/>+<color name="green" value="0 1 0"/>+<color name="blue" value="0 0 1"/>+<color name="yellow" value="1 1 0"/>+<color name="orange" value="1 0.647 0"/>+<color name="gold" value="1 0.843 0"/>+<color name="purple" value="0.627 0.125 0.941"/>+<color name="gray" value="0.745"/>+<color name="brown" value="0.647 0.165 0.165"/>+<color name="navy" value="0 0 0.502"/>+<color name="pink" value="1 0.753 0.796"/>+<color name="seagreen" value="0.18 0.545 0.341"/>+<color name="turquoise" value="0.251 0.878 0.816"/>+<color name="violet" value="0.933 0.51 0.933"/>+<color name="darkblue" value="0 0 0.545"/>+<color name="darkcyan" value="0 0.545 0.545"/>+<color name="darkgray" value="0.663"/>+<color name="darkgreen" value="0 0.392 0"/>+<color name="darkmagenta" value="0.545 0 0.545"/>+<color name="darkorange" value="1 0.549 0"/>+<color name="darkred" value="0.545 0 0"/>+<color name="lightblue" value="0.678 0.847 0.902"/>+<color name="lightcyan" value="0.878 1 1"/>+<color name="lightgray" value="0.827"/>+<color name="lightgreen" value="0.565 0.933 0.565"/>+<color name="lightyellow" value="1 1 0.878"/>+<dashstyle name="dashed" value="[4] 0"/>+<dashstyle name="dotted" value="[1 3] 0"/>+<dashstyle name="dash dotted" value="[4 2 1 2] 0"/>+<dashstyle name="dash dot dotted" value="[4 2 1 2 1 2] 0"/>+<textsize name="large" value="\large"/>+<textsize name="Large" value="\Large"/>+<textsize name="LARGE" value="\LARGE"/>+<textsize name="huge" value="\huge"/>+<textsize name="Huge" value="\Huge"/>+<textsize name="small" value="\small"/>+<textsize name="footnote" value="\footnotesize"/>+<textsize name="tiny" value="\tiny"/>+<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}"/>+<gridsize name="4 pts" value="4"/>+<gridsize name="8 pts (~3 mm)" value="8"/>+<gridsize name="16 pts (~6 mm)" value="16"/>+<gridsize name="32 pts (~12 mm)" value="32"/>+<gridsize name="10 pts (~3.5 mm)" value="10"/>+<gridsize name="20 pts (~7 mm)" value="20"/>+<gridsize name="14 pts (~5 mm)" value="14"/>+<gridsize name="28 pts (~10 mm)" value="28"/>+<gridsize name="56 pts (~20 mm)" value="56"/>+<anglesize name="90 deg" value="90"/>+<anglesize name="60 deg" value="60"/>+<anglesize name="45 deg" value="45"/>+<anglesize name="30 deg" value="30"/>+<anglesize name="22.5 deg" value="22.5"/>+<opacity name="10%" value="0.1"/>+<opacity name="30%" value="0.3"/>+<opacity name="50%" value="0.5"/>+<opacity name="75%" value="0.75"/>+<tiling name="falling" angle="-60" step="4" width="1"/>+<tiling name="rising" angle="30" step="4" width="1"/>+</ipestyle>+<ipestyle name="frank">+<arrowsize name="normal" value="5"/>+<arrowsize name="large" value="8"/>+<arrowsize name="huge" value="10"/>+<arrowsize name="small" value="3"/>+<arrowsize name="tiny" value="1"/>+<dashstyle name="dashed" value="[2 2] 0"/>+<dashstyle name="dotted" value="[0.5 1] 0"/>+<dashstyle name="dash dotted" value="[4 2 1 2] 0"/>+<dashstyle name="dash dot dotted" value="[4 2 1 2 1 2] 0"/>+<gridsize name="1 pts" value="1"/>+<gridsize name="2 pts" value="2"/>+<opacity name="10%" value="0.1"/>+<opacity name="30%" value="0.3"/>+<opacity name="50%" value="0.5"/>+<opacity name="20%" value="0.2"/>+<opacity name="40%" value="0.4"/>+<opacity name="60%" value="0.6"/>+<opacity name="70%" value="0.7"/>+<opacity name="80%" value="0.8"/>+<opacity name="90%" value="0.9"/>+</ipestyle>+<page>+<layer name="alpha"/>+<view layers="alpha" active="alpha"/>+<path layer="alpha" stroke="black">+176 736 m+240 688 l+240 608 l+128 576 l+64 640 l+80 720 l+128 752 l+h+</path>+<path stroke="black">+240 608 m+64 640 l+</path>+<path stroke="black">+64 640 m+240 688 l+</path>+<path stroke="black">+240 688 m+80 720 l+</path>+<path stroke="black">+80 720 m+176 736 l+</path>+<path matrix="1 0 0 1 32 96" stroke="red">+160 384 m+352 384 l+128 176 l+224 320 l+48 400 l+h+</path>+<path stroke="red">+384 480 m+256 416 l+</path>+<path stroke="red">+256 416 m+192 480 l+</path>+<path matrix="1 0 0 1 208 320" stroke="green">+320 320 m+256 320 l+224 320 l+128 240 l+64 224 l+256 192 l+h+</path>+<path matrix="1 0 0 1 208 320" stroke="green">+256 320 m+128 240 l+</path>+<path matrix="1 0 0 1 208 320" stroke="green">+128 240 m+320 320 l+</path>+<path matrix="1 0 0 1 208 320" stroke="green">+256 192 m+128 240 l+</path>+<path matrix="-1 0 -0 -1 592 400" stroke="violet">+320 320 m+256 320 l+224 320 l+128 240 l+64 224 l+256 192 l+h+</path>+<path stroke="violet">+464 160 m+336 208 l+</path>+<path stroke="violet">+336 80 m+336 208 l+</path>+<path stroke="violet">+368 80 m+336 208 l+</path>+</page>+</ipe>
+ test/Algorithms/Geometry/PolygonTriangulation/simplepolygon6.ipe view
@@ -0,0 +1,297 @@+<?xml version="1.0"?>+<!DOCTYPE ipe SYSTEM "ipe.dtd">+<ipe version="70107" creator="Ipe 7.2.2">+<info created="D:20180524200410" modified="D:20180524221410"/>+<ipestyle name="basic">+<symbol name="arrow/arc(spx)">+<path stroke="sym-stroke" fill="sym-stroke" pen="sym-pen">+0 0 m+-1 0.333 l+-1 -0.333 l+h+</path>+</symbol>+<symbol name="arrow/farc(spx)">+<path stroke="sym-stroke" fill="white" pen="sym-pen">+0 0 m+-1 0.333 l+-1 -0.333 l+h+</path>+</symbol>+<symbol name="arrow/ptarc(spx)">+<path stroke="sym-stroke" fill="sym-stroke" pen="sym-pen">+0 0 m+-1 0.333 l+-0.8 0 l+-1 -0.333 l+h+</path>+</symbol>+<symbol name="arrow/fptarc(spx)">+<path stroke="sym-stroke" fill="white" pen="sym-pen">+0 0 m+-1 0.333 l+-0.8 0 l+-1 -0.333 l+h+</path>+</symbol>+<symbol name="mark/circle(sx)" transformations="translations">+<path fill="sym-stroke">+0.6 0 0 0.6 0 0 e+0.4 0 0 0.4 0 0 e+</path>+</symbol>+<symbol name="mark/disk(sx)" transformations="translations">+<path fill="sym-stroke">+0.6 0 0 0.6 0 0 e+</path>+</symbol>+<symbol name="mark/fdisk(sfx)" transformations="translations">+<group>+<path fill="sym-fill">+0.5 0 0 0.5 0 0 e+</path>+<path fill="sym-stroke" fillrule="eofill">+0.6 0 0 0.6 0 0 e+0.4 0 0 0.4 0 0 e+</path>+</group>+</symbol>+<symbol name="mark/box(sx)" transformations="translations">+<path fill="sym-stroke" fillrule="eofill">+-0.6 -0.6 m+0.6 -0.6 l+0.6 0.6 l+-0.6 0.6 l+h+-0.4 -0.4 m+0.4 -0.4 l+0.4 0.4 l+-0.4 0.4 l+h+</path>+</symbol>+<symbol name="mark/square(sx)" transformations="translations">+<path fill="sym-stroke">+-0.6 -0.6 m+0.6 -0.6 l+0.6 0.6 l+-0.6 0.6 l+h+</path>+</symbol>+<symbol name="mark/fsquare(sfx)" transformations="translations">+<group>+<path fill="sym-fill">+-0.5 -0.5 m+0.5 -0.5 l+0.5 0.5 l+-0.5 0.5 l+h+</path>+<path fill="sym-stroke" fillrule="eofill">+-0.6 -0.6 m+0.6 -0.6 l+0.6 0.6 l+-0.6 0.6 l+h+-0.4 -0.4 m+0.4 -0.4 l+0.4 0.4 l+-0.4 0.4 l+h+</path>+</group>+</symbol>+<symbol name="mark/cross(sx)" transformations="translations">+<group>+<path fill="sym-stroke">+-0.43 -0.57 m+0.57 0.43 l+0.43 0.57 l+-0.57 -0.43 l+h+</path>+<path fill="sym-stroke">+-0.43 0.57 m+0.57 -0.43 l+0.43 -0.57 l+-0.57 0.43 l+h+</path>+</group>+</symbol>+<symbol name="arrow/fnormal(spx)">+<path stroke="sym-stroke" fill="white" pen="sym-pen">+0 0 m+-1 0.333 l+-1 -0.333 l+h+</path>+</symbol>+<symbol name="arrow/pointed(spx)">+<path stroke="sym-stroke" fill="sym-stroke" pen="sym-pen">+0 0 m+-1 0.333 l+-0.8 0 l+-1 -0.333 l+h+</path>+</symbol>+<symbol name="arrow/fpointed(spx)">+<path stroke="sym-stroke" fill="white" pen="sym-pen">+0 0 m+-1 0.333 l+-0.8 0 l+-1 -0.333 l+h+</path>+</symbol>+<symbol name="arrow/linear(spx)">+<path stroke="sym-stroke" pen="sym-pen">+-1 0.333 m+0 0 l+-1 -0.333 l+</path>+</symbol>+<symbol name="arrow/fdouble(spx)">+<path stroke="sym-stroke" fill="white" pen="sym-pen">+0 0 m+-1 0.333 l+-1 -0.333 l+h+-1 0 m+-2 0.333 l+-2 -0.333 l+h+</path>+</symbol>+<symbol name="arrow/double(spx)">+<path stroke="sym-stroke" fill="sym-stroke" pen="sym-pen">+0 0 m+-1 0.333 l+-1 -0.333 l+h+-1 0 m+-2 0.333 l+-2 -0.333 l+h+</path>+</symbol>+<pen name="heavier" value="0.8"/>+<pen name="fat" value="1.2"/>+<pen name="ultrafat" value="2"/>+<symbolsize name="large" value="5"/>+<symbolsize name="small" value="2"/>+<symbolsize name="tiny" value="1.1"/>+<arrowsize name="large" value="10"/>+<arrowsize name="small" value="5"/>+<arrowsize name="tiny" value="3"/>+<color name="red" value="1 0 0"/>+<color name="green" value="0 1 0"/>+<color name="blue" value="0 0 1"/>+<color name="yellow" value="1 1 0"/>+<color name="orange" value="1 0.647 0"/>+<color name="gold" value="1 0.843 0"/>+<color name="purple" value="0.627 0.125 0.941"/>+<color name="gray" value="0.745"/>+<color name="brown" value="0.647 0.165 0.165"/>+<color name="navy" value="0 0 0.502"/>+<color name="pink" value="1 0.753 0.796"/>+<color name="seagreen" value="0.18 0.545 0.341"/>+<color name="turquoise" value="0.251 0.878 0.816"/>+<color name="violet" value="0.933 0.51 0.933"/>+<color name="darkblue" value="0 0 0.545"/>+<color name="darkcyan" value="0 0.545 0.545"/>+<color name="darkgray" value="0.663"/>+<color name="darkgreen" value="0 0.392 0"/>+<color name="darkmagenta" value="0.545 0 0.545"/>+<color name="darkorange" value="1 0.549 0"/>+<color name="darkred" value="0.545 0 0"/>+<color name="lightblue" value="0.678 0.847 0.902"/>+<color name="lightcyan" value="0.878 1 1"/>+<color name="lightgray" value="0.827"/>+<color name="lightgreen" value="0.565 0.933 0.565"/>+<color name="lightyellow" value="1 1 0.878"/>+<dashstyle name="dashed" value="[4] 0"/>+<dashstyle name="dotted" value="[1 3] 0"/>+<dashstyle name="dash dotted" value="[4 2 1 2] 0"/>+<dashstyle name="dash dot dotted" value="[4 2 1 2 1 2] 0"/>+<textsize name="large" value="\large"/>+<textsize name="Large" value="\Large"/>+<textsize name="LARGE" value="\LARGE"/>+<textsize name="huge" value="\huge"/>+<textsize name="Huge" value="\Huge"/>+<textsize name="small" value="\small"/>+<textsize name="footnote" value="\footnotesize"/>+<textsize name="tiny" value="\tiny"/>+<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}"/>+<gridsize name="4 pts" value="4"/>+<gridsize name="8 pts (~3 mm)" value="8"/>+<gridsize name="16 pts (~6 mm)" value="16"/>+<gridsize name="32 pts (~12 mm)" value="32"/>+<gridsize name="10 pts (~3.5 mm)" value="10"/>+<gridsize name="20 pts (~7 mm)" value="20"/>+<gridsize name="14 pts (~5 mm)" value="14"/>+<gridsize name="28 pts (~10 mm)" value="28"/>+<gridsize name="56 pts (~20 mm)" value="56"/>+<anglesize name="90 deg" value="90"/>+<anglesize name="60 deg" value="60"/>+<anglesize name="45 deg" value="45"/>+<anglesize name="30 deg" value="30"/>+<anglesize name="22.5 deg" value="22.5"/>+<opacity name="10%" value="0.1"/>+<opacity name="30%" value="0.3"/>+<opacity name="50%" value="0.5"/>+<opacity name="75%" value="0.75"/>+<tiling name="falling" angle="-60" step="4" width="1"/>+<tiling name="rising" angle="30" step="4" width="1"/>+</ipestyle>+<ipestyle name="frank">+<arrowsize name="normal" value="5"/>+<arrowsize name="large" value="8"/>+<arrowsize name="huge" value="10"/>+<arrowsize name="small" value="3"/>+<arrowsize name="tiny" value="1"/>+<dashstyle name="dashed" value="[2 2] 0"/>+<dashstyle name="dotted" value="[0.5 1] 0"/>+<dashstyle name="dash dotted" value="[4 2 1 2] 0"/>+<dashstyle name="dash dot dotted" value="[4 2 1 2 1 2] 0"/>+<gridsize name="1 pts" value="1"/>+<gridsize name="2 pts" value="2"/>+<opacity name="10%" value="0.1"/>+<opacity name="30%" value="0.3"/>+<opacity name="50%" value="0.5"/>+<opacity name="20%" value="0.2"/>+<opacity name="40%" value="0.4"/>+<opacity name="60%" value="0.6"/>+<opacity name="70%" value="0.7"/>+<opacity name="80%" value="0.8"/>+<opacity name="90%" value="0.9"/>+</ipestyle>+<page>+<layer name="alpha"/>+<layer name="beta"/>+<view layers="alpha beta" active="beta"/>+<path layer="alpha" stroke="black">+80 544 m+320 527 l+208 496 l+48 432 l+16 560 l+h+</path>+<path stroke="black">+80 544 m+208 496 l+</path>+<path layer="beta" stroke="black">+208 496 m+16 560 l+</path>+</page>+</ipe>
test/Algorithms/Geometry/WellSeparatedPairDecomposition/WSPDSpec.hs view
@@ -13,6 +13,7 @@ import qualified Data.Vector as V import           Test.Hspec import           Util+import           GHC.TypeLits  -------------------------------------------------------------------------------- @@ -26,10 +27,10 @@     it "simple input reordering " $ do       reIndexPoints input `shouldBe` output   where-    input = v2 (ptSeq [ origin :+ 1, point2 1 1 :+ 100, point2 5 5 :+ 101 ])-               (ptSeq [ point2 1 1 :+ 100, point2 5 5 :+ 101, origin :+ 1 ])-    output = v2 (ptSeq [ origin :+ 0, point2 1 1 :+ 1, point2 5 5 :+ 2 ])-                (ptSeq [ point2 1 1 :+ 1, point2 5 5 :+ 2, origin :+ 0 ])+    input = Vector2 (ptSeq [ origin :+ 1, point2 1 1 :+ 100, point2 5 5 :+ 101 ])+                    (ptSeq [ point2 1 1 :+ 100, point2 5 5 :+ 101, origin :+ 1 ])+    output = Vector2 (ptSeq [ origin :+ 0, point2 1 1 :+ 1, point2 5 5 :+ 2 ])+                     (ptSeq [ point2 1 1 :+ 1, point2 5 5 :+ 2, origin :+ 0 ])   @@ -41,7 +42,7 @@     it "distributePoints' on a single list " $ do       distributePoints' 3 levels input `shouldBe` output     it "distributePoints on multiple lists" $ do-      distributePoints 3 levels (v2 input input) `shouldBe` output'+      distributePoints 3 levels (Vector2 input input) `shouldBe` output'    where     levels = V.fromList [Just $ Level 0 (Just 2),Just $ Level 1 (Just 1), Nothing]@@ -50,7 +51,7 @@                         , ptSeq [point2 1 1 :+ 1]                         , ptSeq [point2 2 2 :+ 2]                         ]-    output' = fmap (\pts -> v2 pts pts) output+    output' = fmap (\pts -> Vector2 pts pts) output      --     input = v2 (f [ origin :+ 1, point2 1 1 :+ 100, point2 5 5 :+ 101 ]) --                (f [ point2 1 1 :+ 100, point2 5 5 :+ 101, origin :+ 1 ])@@ -68,7 +69,7 @@   -- | Computes all pairs of points that are uncovered by the WSPD with separation s-uncovered         :: (Floating r, Ord r, AlwaysTrueWSPD d, Ord p)+uncovered         :: (Floating r, Ord r, Arity d, Arity (d+1), Ord p)                   => [Point d r :+ p] -> r -> SplitTree d p r a -> [(Point d r :+ p, Point d r :+ p)] uncovered pts s t = Set.toList $ allPairs `Set.difference` covered   where
test/Data/EdgeOracleSpec.hs view
@@ -11,7 +11,7 @@  data TestG -type Vertex = VertexId TestG Primal_+type Vertex = VertexId TestG Primal   testEdges :: [(Vertex,[Vertex])]@@ -24,7 +24,7 @@             , (5, [3,4])             ] -buildEdgeOracle'  :: [(Vertex,[Vertex])] -> EdgeOracle TestG Primal_ ()+buildEdgeOracle'  :: [(Vertex,[Vertex])] -> EdgeOracle TestG Primal () buildEdgeOracle' = buildEdgeOracle . map (second $ fmap ext)  -- | Flattens an adjacencylist representation into a set of edges
test/Data/Geometry/IntervalSpec.hs view
@@ -1,24 +1,27 @@ {-# LANGUAGE ScopedTypeVariables #-} module Data.Geometry.IntervalSpec where +import           Control.Lens import           Data.Ext import qualified Data.Foldable as F import           Data.Geometry import           Data.Geometry.Box-import qualified Data.Geometry.IntervalTree as IntTree import           Data.Geometry.IntervalTree (IntervalTree)-import qualified Data.Geometry.SegmentTree as SegTree+import qualified Data.Geometry.IntervalTree as IntTree import           Data.Geometry.SegmentTree (SegmentTree, I(..))+import qualified Data.Geometry.SegmentTree as SegTree import qualified Data.List.NonEmpty as NonEmpty+import           Data.Range import qualified Data.Seq as Seq import qualified Data.Set as Set import           GHC.TypeLits-import           QuickCheck.Instances () import           Test.Hspec+import           Test.Hspec.QuickCheck import           Test.QuickCheck+import           Test.QuickCheck.HGeometryInstances ()+import           Test.QuickCheck.Instances () import           Util - naive   :: (Ord r, Foldable f) => r -> f (Interval p r) -> [Interval p r] naive q = filter (q `inInterval`) . F.toList @@ -46,19 +49,21 @@                                          , IntTree.fromIntervals $ F.toList is))  spec :: Spec-spec = do-  describe "Same as Naive" $ do-    it "quickcheck segmentTree" $-      property $ \(is :: NonEmpty.NonEmpty (Interval () Word)) -> allSameAsNaive is-    it "quickcheck IntervalTree" $-      property $ \(Intervals is :: Intervals Word) -> allSameAsNaiveIT is+spec = modifyMaxSuccess (const 1000) $ do+    describe "Same as Naive" $ do+      it "quickcheck segmentTree" $+        property $ \(Intervals is :: Intervals Word) -> allSameAsNaive is+      it "quickcheck IntervalTree" $+        property $ \(Intervals is :: Intervals Word) -> allSameAsNaiveIT is   newtype Intervals r = Intervals (NonEmpty.NonEmpty (Interval () r)) deriving (Show,Eq) --- don't generate double open intervals+-- don't generate double open intervals, and don't generate intervals in which+-- one endpoint is open, the other is closed, but at the same point instance (Arbitrary r, Ord r) => Arbitrary (Intervals r) where   arbitrary = Intervals . NonEmpty.fromList <$> listOf1 (suchThat arbitrary p)     where       p (OpenInterval _ _) = False-      p _                  = True+      p (Interval s e)     = not (isOpen s /= isOpen e+                                  && s^.unEndPoint.core == e^.unEndPoint.core)
test/Data/Geometry/Ipe/ReaderSpec.hs view
@@ -25,7 +25,7 @@         (show $ readXML useTxt                 >>= ipeReadAttrs (Proxy :: Proxy IpeSymbol) (Proxy :: Proxy Double))         `shouldBe`-        "Right (Attrs {_unAttrs = {GAttr {_getAttr = Nothing}, GAttr {_getAttr = Nothing}, GAttr {_getAttr = Nothing}, GAttr {_getAttr = Nothing}, GAttr {_getAttr = Just (IpeColor (Valued \"black\"))}, GAttr {_getAttr = Nothing}, GAttr {_getAttr = Nothing}, GAttr {_getAttr = Just (IpeSize (Named \"normal\"))}}})"+        "Right (Attrs {_unAttrs = {GAttr {_getAttr = Nothing}, GAttr {_getAttr = Nothing}, GAttr {_getAttr = Nothing}, GAttr {_getAttr = Nothing}, GAttr {_getAttr = Just (IpeColor (Named \"black\"))}, GAttr {_getAttr = Nothing}, GAttr {_getAttr = Nothing}, GAttr {_getAttr = Just (IpeSize (Named \"normal\"))}}})"      describe "IpeRead" $ do       it "parses a Symbol" $
test/Data/Geometry/KDTreeSpec.hs view
@@ -9,7 +9,7 @@ import qualified Data.Seq as Seq import qualified Data.Set as Set import           GHC.TypeLits-import           QuickCheck.Instances()+import           Test.QuickCheck.HGeometryInstances() import           Test.Hspec import           Test.QuickCheck @@ -22,7 +22,7 @@                     => [Point d r :+ p] -> KDTree d p r -> Box d q r -> Bool sameAsNaive pts t q = Set.fromList (searchKDTree q t) == Set.fromList (naive q pts) -allSameAsNaive     :: (Ord r, Ord p, Arity d, KnownNat d, Index' 0 d, Foldable f)+allSameAsNaive     :: (Ord r, Ord p, Arity d, 1 <= d, Foldable f)                    => f (Point d r :+ p) -> [Box d () r] -> Bool allSameAsNaive pts = let pts' = F.toList pts                      in  all (sameAsNaive pts' $ buildKDTree pts')
+ test/Data/Geometry/LineSegmentSpec.hs view
@@ -0,0 +1,16 @@+{-# LANGUAGE ScopedTypeVariables #-}+module Data.Geometry.LineSegmentSpec where++import           Data.Ext+import           Data.Geometry+import           Test.Hspec+import           Test.QuickCheck.HGeometryInstances ()++spec :: Spec+spec =+  describe "onSegment" $+    it "handles zero length segments correctly" $ do+        let zeroSegment :: LineSegment 2 () Rational+            zeroSegment = ClosedLineSegment (Point2 0 0 :+ ()) (Point2 0 0 :+ ())+        (Point2 0 0 `onSegment` zeroSegment) `shouldBe` True+        (Point2 1 0 `onSegment` zeroSegment) `shouldBe` False
+ test/Data/Geometry/LineSpec.hs view
@@ -0,0 +1,48 @@+module Data.Geometry.LineSpec where++import Data.Ext+import Control.Lens+import Data.Geometry+import Data.Geometry.Box+import Data.Vinyl.CoRec+import Test.Hspec+import Data.Ratio+++++spec :: Spec+spec = do+  describe "Line x Box intersections" $ do+    boxIntersections++boxIntersections :: Spec+boxIntersections = do+    it "proper intersection" $+      (lineThrough (Point2 1 5) (Point2 10 (7 :: Rational))+       `intersect` b+      ) `shouldBe`+      (coRec $ ClosedLineSegment (ext $ Point2 (0 :: Rational) (43 % 9))+                                 (ext $ Point2 14              (71 % 9))+      )+    it "boundary segment" $+      (lineThrough (Point2 0 0) (Point2 10 (0 :: Rational))+       `intersect` b+      ) `shouldBe`+      (coRec $ ClosedLineSegment (ext $ Point2 (0 :: Rational) 0)+                                 (ext $ Point2 14              0)+      )+    it "Touching in Point" $+      (lineThrough (Point2 0 0) (Point2 (-1) (1 :: Rational))+       `intersect`+       boundingBoxList' [Point2 0 (0 :: Rational), Point2 14 9]+      ) `shouldBe`+      (coRec (origin :: Point 2 Rational))+    it "No Intersection" $+      (lineThrough (Point2 (-1) 0) (Point2 (-2) (2 :: Rational))+       `intersect`+       boundingBoxList' [Point2 0 (0 :: Rational), Point2 14 9]+      ) `shouldBe`+      (coRec NoIntersection)+  where+    b = boundingBoxList' [Point2 0 (0 :: Rational), Point2 14 9]
+ test/Data/Geometry/PlanarSubdivisionSpec.hs view
@@ -0,0 +1,221 @@+module Data.Geometry.PlanarSubdivisionSpec where+++import qualified Algorithms.Geometry.PolygonTriangulation.MakeMonotone as MM+import           Data.Bifunctor (second)+import           Data.Ext+import           Data.Foldable (toList, forM_)+import           Data.Geometry+import           Data.Geometry.PlanarSubdivision+import qualified Data.Geometry.PlanarSubdivision as PS+import           Data.Geometry.Polygon+import qualified Data.List.NonEmpty as NonEmpty+import           Data.PlanarGraph (FaceId(..),VertexId(..))+import qualified Data.PlaneGraph as PG+import           Test.Hspec+import qualified Data.Vector as V+import qualified Data.List as L++import qualified Algorithms.Geometry.PolygonTriangulation.TriangulateMonotone as TM+import qualified Algorithms.Geometry.PolygonTriangulation.Triangulate as TR++import           Control.Lens hiding (holesOf)+import           Data.Either (lefts)+import           Data.Geometry.Ipe+import           Data.Geometry.PlanarSubdivision.Draw+import           Data.Maybe (fromJust)+import           Data.PlaneGraph.Draw+++data Test = Test+data Id a = Id a+++++simplePg  = fromSimplePolygon (Id Test) simplePg' Inside Outside+simplePg' = toCounterClockWiseOrder . fromPoints $ map ext $ [ Point2 160 736+                                                             , Point2 128 688+                                                             , Point2 176 672+                                                             , Point2 256 672+                                                             , Point2 272 608+                                                             , Point2 384 656+                                                             , Point2 336 768+                                                             , Point2 272 720+                                                             ]++triangle :: PlanarSubdivision Test () () PolygonFaceData Rational+triangle = (\pg -> fromSimplePolygon (Id Test) pg Inside Outside)+         $ trianglePG++trianglePG = fromPoints . map ext $ [origin, Point2 10 0, Point2 10 10]+++toNonEmpty :: Foldable f => f a -> NonEmpty.NonEmpty a+toNonEmpty = NonEmpty.fromList . toList++spec :: Spec+spec = do+  describe "PlanarSubdivision" $ do+    it "outerFaceId = 0 " $+      outerFaceId triangle `shouldBe` (FaceId $ VertexId 0)+    it "outerFace tests" $+      let [d] = toList $ holesOf (outerFaceId triangle) triangle+      in leftFace d triangle `shouldBe` (outerFaceId triangle)+    testSpec testPoly+    testSpec testPoly2+    testSpec testPoly3+    testSpec testPoly4++    -- describe "incidentDarts" $ do+    --   forM_ (darts' triangle) $ \d ->+    --     it "incidentDarts indiv"  $+    --       boundary' d triangle `shouldBe` (toNonEmpty $ edges' triangle)+    -- this last test is nonsense+++sameAsConnectedPG      :: (Eq v, Eq e, Eq f, Eq r, Show v, Show e, Show f, Show r)+                       => PlaneGraph s v e f r -> PlanarSubdivision s v e f r+                       -> Spec+sameAsConnectedPG g ps = describe "connected planarsubdiv, same as PlaneGraph" $ do+  it "same number of vertices" $+    PG.numVertices g `shouldBe` PS.numVertices ps+  it "same number of darts" $+    PG.numDarts g `shouldBe` PS.numDarts ps+  it "same number of edges" $+    PG.numEdges g `shouldBe` PS.numEdges ps+  it "same number of faces" $+    PG.numFaces g `shouldBe` PS.numFaces ps+  it "same vertices" $+    PG.vertices g `shouldBe` vertices ps+  it "same dart data" $+    (g^.PG.rawDartData) `shouldBe` ((^.dataVal) <$> ps^.rawDartData)+  -- it "same dart endpoints" $ do+  describe "same darts" $ do+    forM_ (darts' ps) $ \d ->+      it ("sameDarts: " ++ (show d)) $ endPoints d ps `shouldBe` PG.endPoints d g+  -- sameDarts g ps+  it "same edges" $+    (V.fromList . L.sortOn fst . toList $ PG.edgeSegments g) `shouldBe` edgeSegments ps+  it "same edges per vertex" $+    forM_ (PG.vertices' g) $ \v ->+      PG.incidentEdges v g `shouldBe` PS.incidentEdges v ps+  -- it "same face Id's" $+  --   PG.faces' g `shouldBe` faces' ps+  -- it "same outerface boundary" $+  --   (second (FaceData mempty)+  -- it "same faces" $+  --   (second (FaceData mempty) <$> PG.faces g) `shouldBe` faces ps+++-- sameDart g ps d =++-- sameDarts          :: (Eq v, Eq e, Eq f, Eq r, Show v, Show e, Show f, Show r)+--                        => PlaneGraph s v e f r -> PlanarSubdivision s v e f r+--                        -> Spec+-- sameDarts g ps =+--     -- sameDart g ps+++-- sort' = V.fromList . L.sortOn fst . toList+++++testSpec    :: (Ord r, Eq p, Fractional r, Show r, Show p)+            => SimplePolygon p r -> Spec+testSpec pg = do+  sameAsConnectedPG (PG.fromSimplePolygon (Id Test) pg Inside Outside)+                    (PS.fromSimplePolygon (Id Test) pg Inside Outside)+  -- sameAsConnectedPG (TM.triangulate' (Id Test) pg)+  --                   (TM.triangulate  (Id Test) pg)+  sameAsConnectedPG (TR.triangulate' (Id Test) pg)+                    (TR.triangulate  (Id Test) pg)++++testPoly :: SimplePolygon () Rational+testPoly = toCounterClockWiseOrder . fromPoints $ map ext $ [+                                                              Point2 128 720+                                                            , Point2 192 752+                                                            , Point2 224 720+                                                            , Point2 240 672+                                                            , Point2 128 624+                                                            , Point2 176 672+                                                            ]+++testPoly2 :: SimplePolygon () Rational+testPoly2 = toCounterClockWiseOrder . fromPoints $ map ext $ [ Point2 160 736+                                                             , Point2 128 688+                                                             , Point2 176 672+                                                             , Point2 256 672+                                                             , Point2 272 608+                                                             , Point2 384 656+                                                             , Point2 336 768+                                                             , Point2 272 720+                                                             ]++++testPoly3 :: SimplePolygon () Rational+testPoly3 = toCounterClockWiseOrder . fromPoints $ map ext $ [ Point2 352 367+                                                             , Point2 128 176+                                                             , Point2 240 336+                                                             , Point2 80 272+                                                             , Point2 48 400+                                                             , Point2 96 384+                                                             , Point2 240 496+                                                             ]++++testPoly4 :: SimplePolygon () Rational+testPoly4 = toCounterClockWiseOrder . fromPoints $ map ext $ [ Point2 64 544+                                                             , Point2 320 527+                                                             , Point2 208 496+                                                             , Point2 48 432+                                                             , Point2 16 560+                                                             ]++testPoly5 :: SimplePolygon () Rational+testPoly5 = toCounterClockWiseOrder . fromPoints $ map ext $ [ Point2 352 384+                                                             , Point2 128 176+                                                             , Point2 224 320+                                                             , Point2 48 400+                                                             , Point2 160 384+                                                             , Point2 240 496+                                                             ]+++testPolyP  = fromSimplePolygon (Id Test) testPoly5 Inside Outside+testPolygPlaneG = fromJust $ testPolyP^?components.ix 0++monotonePs = MM.makeMonotone (Id Test) testPoly5+monotonePlaneG = fromJust $ monotonePs^?components.ix 0++test = TR.triangulate (Id Test) testPoly5+test' = TR.triangulate' (Id Test) testPoly5+-- test = asIpe drawPlaneGraph testPolygPlaneG mempty++printMP = mapM_ printAsIpeSelection+        . map (asIpeObject' mempty . (^.core) . snd)+        . toList . rawFacePolygons $ monotonePs++++printP = mapM_ printAsIpeSelection+       . map (asIpeObject' mempty . (^.core) . snd)+       . toList . PG.rawFacePolygons $ test'+++printPPX = mapM_ printAsIpeSelection+        . map (asIpeObject' mempty . (^.core) . snd)+        . toList . rawFacePolygons++printPP = printPPX test++parts' = map (\pg -> fromSimplePolygon (Id Test) pg Inside Outside)+       . lefts . map ((^.core) . snd) . toList . rawFacePolygons $ monotonePs++parts'' = lefts . map ((^.core) . snd) . toList . rawFacePolygons $ monotonePs
test/Data/Geometry/Polygon/Convex/ConvexSpec.hs view
@@ -13,9 +13,10 @@ import           Data.Geometry.Polygon.Convex import qualified Data.List.NonEmpty as NonEmpty import           Data.Traversable (traverse)-import           QuickCheck.Instances+import           Test.QuickCheck.HGeometryInstances () import           Test.Hspec import           Test.QuickCheck+import           Test.QuickCheck.Instances()   @@ -46,7 +47,7 @@  -- | generates 360 vectors "equally" spaced/angled directions :: Num r => [Vector 2 r]-directions = map (fmap toRat . uncurry v2 . (cos &&& sin) . toRad) ([0..359] :: [Double])+directions = map (fmap toRat . uncurry Vector2 . (cos &&& sin) . toRad) ([0..359] :: [Double])   where     toRad i = i * (pi / 180)     toRat x = fromIntegral . round $ 100000 * x
+ test/Data/Geometry/SubLineSpec.hs view
@@ -0,0 +1,50 @@+{-# LANGUAGE ScopedTypeVariables #-}+module Data.Geometry.SubLineSpec where++import Control.Lens+import Data.Ext+import Data.Geometry+import Data.Geometry.Line+import Data.Geometry.LineSegment+import Data.Geometry.SubLine+import Data.Ratio+import Data.UnBounded+import Data.Vinyl.CoRec+import Test.QuickCheck.HGeometryInstances ()+import Test.Hspec+import Test.QuickCheck+++spec :: Spec+spec = do+  describe "subLineTests" $+    it "subline specialization in R^2" $+      property $ \(alpha :: Rational) l@(Line p v) (i :: Interval () Rational)  ->+        let q  = p .+^ alpha *^ v+            sl = SubLine l i+        in onSubLineOrig q sl `shouldBe` onSubLine2 q sl++  it "manual test " $+      ((Point2 (-1) (-1 :: Rational)) `onSubLine2`+       (seg^._SubLine))+    `shouldBe` False++  it "Intersection test" $+    let mySeg  = Val <$> ClosedLineSegment (ext origin) (ext $ Point2 (14 :: Rational) 0)+        mySeg' = mySeg^._SubLine+        myLine = fromLine $ lineThrough (Point2 0 0) (Point2 10 (0 :: Rational))+    in (myLine `intersect` mySeg')+       `shouldBe`+       coRec (myLine&subRange .~ ClosedInterval (ext $ Val 0) (ext . Val $ 7 % 5))++++seg :: LineSegment 2 () Rational+seg = ClosedLineSegment (ext (Point2 1 1)) (ext (Point2 5 5))++++-- | Original def of onSubline+onSubLineOrig                 :: (Ord r, Fractional r, Arity d)+                          => Point d r -> SubLine d p r -> Bool+onSubLineOrig p (SubLine l r) = toOffset p l `inInterval` r
+ test/Data/OrdSeqSpec.hs view
@@ -0,0 +1,58 @@+{-# LANGUAGE ScopedTypeVariables #-}+module Data.OrdSeqSpec where++import qualified Data.Foldable as F+import qualified Data.List as List+import           Data.OrdSeq (OrdSeq)+import qualified Data.OrdSeq as OrdSeq+import           Data.Semigroup+import           Test.QuickCheck.HGeometryInstances+import           Test.Hspec+import           Test.QuickCheck++spec :: Spec+spec = do+  describe "OrdSeq tests" $ do+    it "fromListBy" $+      property $ \(xs :: [Int]) ->+          F.toList (OrdSeq.fromListBy compare xs) `shouldBe` List.sort xs+    it "splitOn, <" $+      property $ \x (xs :: OrdSeq Int) ->+          let (l,_,_) = OrdSeq.splitOn id x xs+          in all (< x) l+    it "splitOn, ==" $+      property $ \x (xs :: OrdSeq Int) ->+          let (_,m,_) = OrdSeq.splitOn id x xs+          in all (== x) m+    it "splitOn, >=" $+      property $ \x (xs :: OrdSeq Int) ->+          let (_,_,r) = OrdSeq.splitOn id x xs+          in all (> x) r+    it "join" $+      property $ \x (xs :: [Int]) -> let (ys,zs) = List.partition (<= x) $ xs in+          (F.toList $ OrdSeq.fromListByOrd ys <> OrdSeq.fromListByOrd zs)+          `shouldBe`+          List.sort (ys <> zs)+    it "positive member" $+      property $ \(xs :: OrdSeq Int) ->+         all (\x -> OrdSeq.memberBy compare x xs) xs+    it "member" $+      property $ \x (xs :: OrdSeq Int) ->+         OrdSeq.memberBy compare x xs+         `shouldBe`+         F.elem x (F.toList xs)+    it "lookupMin" $+       property $ \(xs :: OrdSeq Int) ->+         OrdSeq.lookupMin xs+         `shouldBe`+         (safe minimum $ F.toList xs)+    it "lookupMax" $+       property $ \(xs :: OrdSeq Int) ->+         OrdSeq.lookupMax xs+         `shouldBe`+         (safe maximum $ F.toList xs)+++safe      :: ([t] -> a) -> [t] -> Maybe a+safe _ [] = Nothing+safe f xs = Just . f $ xs
test/Data/PlanarGraphSpec.hs view
@@ -15,7 +15,7 @@  data TestG -type Vertex = VertexId TestG Primal_+type Vertex = VertexId TestG Primal  -- | Report all adjacnecies from g missing in h missingAdjacencies     :: PlanarGraph s w v e f -> PlanarGraph s w v e f@@ -59,15 +59,15 @@ --            u < v, to arcId's. -- - a: the next available unused arcID -- - x: the data value we are interested in computing-type STR' s b = STR (SM.Map (VertexId s Primal_,VertexId s Primal_) Int) Int b+type STR' s b = STR (SM.Map (VertexId s Primal,VertexId s Primal) Int) Int b  -- | Construct a planar graph from a adjacency matrix. For every vertex, all -- vertices should be given in counter clockwise order. -- -- running time: $O(n \log n)$. fromAdjacencyListsOld      :: forall s f.(Foldable f, Functor f)-                        => [(VertexId s Primal_, f (VertexId s Primal_))]-                        -> PlanarGraph s Primal_ () () ()+                        => [(VertexId s Primal, f (VertexId s Primal))]+                        -> PlanarGraph s Primal () () () fromAdjacencyListsOld adjM = planarGraph' . toCycleRep n $ perm   where     n    = sum . fmap length $ perm@@ -77,7 +77,7 @@     -- | Given a vertex with its adjacent vertices (u,vs) (in CCW order) convert this     -- vertex with its adjacent vertices into an Orbit     toOrbit                     :: Foldable f-                                => (VertexId s Primal_, f (VertexId s Primal_))+                                => (VertexId s Primal, f (VertexId s Primal))                                 -> STR' s [[Dart s]]                                 -> STR' s [[Dart s]]     toOrbit (u,vs) (STR m a dss) =@@ -87,7 +87,7 @@      -- | Given an edge (u,v) and a triplet (m,a,ds) we construct a new dart     -- representing this edge.-    toDart                    :: (VertexId s Primal_,VertexId s Primal_)+    toDart                    :: (VertexId s Primal,VertexId s Primal)                               -> STR' s [Dart s]                               -> STR' s [Dart s]     toDart (u,v) (STR m a ds) = let dir = if u < v then Positive else Negative
test/Data/RangeSpec.hs view
@@ -2,34 +2,31 @@  import Data.Geometry.Properties import Data.Range-import Frames.CoRec import Test.Hspec   spec :: Spec spec = do   describe "RangeRange Intersection" $ do-    -- it "openRange cap openrange" $ do-    --   ((OpenRange 1 (10 :: Int))  `intersect` (OpenRange 5 (10 :: Int)))-    --   `shouldBe` (coRec $ OpenRange 5 (10 :: Int))-    -- it "disjoint open ranges" $ do-    --   ((OpenRange 1 10) `intersect` (OpenRange 10 12))-    --   `shouldBe` (coRec NoIntersection)-    -- it "closed cap open, disjoint" $ do-    --   ((ClosedRange (1::Int) 10) `intersect` (OpenRange 50 (60 :: Int)))-    --   `shouldBe` (coRec NoIntersection)+    it "openRange cap openrange" $ do+      ((OpenRange 1 (10 :: Int))  `intersect` (OpenRange 5 (10 :: Int)))+      `shouldBe` (coRec $ OpenRange 5 (10 :: Int))+    it "disjoint open ranges" $ do+      ((OpenRange 1 (10 :: Int)) `intersect` (OpenRange 10 (12 :: Int)))+      `shouldBe` (coRec NoIntersection)+    it "closed cap open, disjoint" $ do+      ((ClosedRange (1::Int) 10) `intersect` (OpenRange 50 (60 :: Int)))+      `shouldBe` (coRec NoIntersection)     -- it "closed intersect open" $-    --   ((OpenRange 1 10) `intersect` (ClosedRange 10 12))-    --   `shouldBe` (coRec $ Range (Open 5) (Closed 10))+    --   ((OpenRange 1 (10 :: Int)) `intersect` (ClosedRange 10 (12 :: Int)))+    --   `shouldBe` (coRec NoIntersection) -    -- it "open rage intersect closed " $-    -- (OpenRange 1 10) `intersect` (ClosedRange 10 12)-    -- `shouldBe` (coRec $ Range (Open 10) (Open 10))+    -- it "open rage intersect closed " $ do+    --   ((OpenRange 1 (10 :: Int)) `intersect` (ClosedRange 10 (12 :: Int)))+    --   `shouldBe` (coRec $ Range (Open 10) (Open (10 :: Int)))   -- (Col Range {_lower = Closed 10, _upper = Open 10})   -- >>> (OpenRange 1 10) `intersect` (ClosedRange 10 12) -    it "returns the first element of a list" $ do-      head [23 ..] `shouldBe` (23 :: Int)      -- it "closed open " $ do     --   ((ClosedRange 1 10) `intersect` (OpenRange 5 10))
− test/QuickCheck/Instances.hs
@@ -1,91 +0,0 @@-{-# LANGUAGE ScopedTypeVariables #-}-{-# OPTIONS_GHC -fno-warn-orphans #-}-module QuickCheck.Instances where--import           Control.Lens-import           Data.BinaryTree-import           Data.Ext-import           Data.Geometry hiding (vector)-import           Data.Geometry.Box-import           Data.Geometry.Interval-import           Data.Geometry.SubLine-import           Data.Geometry.Vector-import qualified Data.List.NonEmpty as NonEmpty-import           Data.Proxy-import           Data.Range-import           Data.Semigroup-import qualified Data.Seq as Seq-import qualified Data.Seq2 as S2-import           GHC.TypeLits-import           Test.QuickCheck-------------------------------------------------------------------------------------- instance Arbitrary a => Arbitrary (NonEmpty.NonEmpty a) where---   arbitrary = NonEmpty.fromList <$> listOf1 arbitrary--instance Arbitrary a => Arbitrary (S2.Seq2 a) where-  arbitrary = S2.Seq2 <$> arbitrary <*> arbitrary <*> arbitrary--instance Arbitrary a => Arbitrary (BinaryTree a) where-  arbitrary = sized f-    where f n | n <= 0    = pure Nil-              | otherwise = do-                              l <- choose (0,n-1)-                              Internal <$> f l <*> arbitrary <*> f (n-l-1)--instance (Arbitrary a, Arbitrary v) => Arbitrary (BinLeafTree v a) where-  arbitrary = sized f-    where f n | n <= 0    = Leaf <$> arbitrary-              | otherwise = do-                              l <- choose (0,n-1)-                              Node <$> f l <*> arbitrary <*> f (n-l-1)---instance (KnownNat n, Arbitrary a) => Arbitrary (Seq.LSeq n a) where-  arbitrary = (\s s' -> Seq.promise . Seq.fromList $ s <> s')-            <$> vector (fromInteger . natVal $ (Proxy :: Proxy n))-            <*> arbitrary--instance (Arbitrary r, Arity d) => Arbitrary (Vector d r) where-  arbitrary = vectorFromListUnsafe <$> infiniteList--instance (Arbitrary r, Arity d) => Arbitrary (Point d r) where-  arbitrary = Point <$> arbitrary--instance (Arbitrary r, Arity d, Num r) => Arbitrary (Line d r) where-  arbitrary = lineThrough <$> arbitrary <*> arbitrary--instance (Arbitrary r, Arity d, Ord r) => Arbitrary (Box d () r) where-  arbitrary = (\p (q :: Point d r) -> boundingBoxList' [p,q]) <$> arbitrary <*> arbitrary---instance Arbitrary r => Arbitrary (EndPoint r) where-  arbitrary = frequency [ (1, Open   <$> arbitrary)-                        , (9, Closed <$> arbitrary)-                        ]--instance (Arbitrary r, Ord r) => Arbitrary (Range r) where-  arbitrary = do-                l <- arbitrary-                r <- suchThat arbitrary (p l)-                return $ Range l r-   where-     p (Open l)   r = l <  r^.unEndPoint-     p (Closed l) r = l <= r^.unEndPoint---instance (Arbitrary c, Arbitrary e) => Arbitrary (c :+ e) where-  arbitrary = (:+) <$> arbitrary <*> arbitrary--instance (Arbitrary r, Arbitrary p, Ord r, Ord p) => Arbitrary (Interval p r) where-  arbitrary = GInterval <$> arbitrary---instance (Arbitrary r, Arbitrary p, Arity d, Ord r, Ord p, Num r)-         => Arbitrary (SubLine d p r) where-  arbitrary = SubLine <$> arbitrary <*> arbitrary---instance (Arbitrary r, Arbitrary p, Arity d) => Arbitrary (LineSegment d p r) where-  arbitrary = LineSegment <$> arbitrary <*> arbitrary
test/Util.hs view
@@ -6,8 +6,10 @@ import Data.Ext import Data.Function(on) import qualified Data.List as L+import Data.Singletons(Apply) -byStrokeColour :: (Stroke ∈ AttributesOf g) => [IpeObject' g r] -> [[IpeObject' g r]]+byStrokeColour :: (Stroke ∈ ats, Ord (Apply f Stroke))+               => [a :+ Attributes f ats] -> [[a :+ Attributes f ats]] byStrokeColour = map (map fst) . L.groupBy ((==) `on` snd) . L.sortOn snd                . map (\x -> (x,lookup' x))   where@@ -22,3 +24,9 @@  diffBy :: (a -> a -> Bool) -> [a] -> [a] -> [a] diffBy p xs ys = foldr (L.deleteBy p) ys xs++-- | \(O(n^2)\) set that ignores duplicates and order+newtype NaiveSet a = NaiveSet [a] deriving (Show)++instance Eq a => Eq (NaiveSet a) where+  (NaiveSet xs) == (NaiveSet ys) = L.null $ difference xs ys