packages feed

hgeometry 0.7.0.0 → 0.8.0.0

raw patch · 122 files changed

+5468/−1873 lines, 122 filesdep +filepathdep +profunctorsdep ~basedep ~yamlbinary-addedPVP ok

version bump matches the API change (PVP)

Dependencies added: filepath, profunctors

Dependency ranges changed: base, yaml

API changes (from Hackage documentation)

- Algorithms.Geometry.ConvexHull.DivideAndConqueror: convexHull :: (Ord r, Num r) => NonEmpty (Point 2 r :+ p) -> ConvexPolygon p r
- 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.DivideAndConqueror: delaunayTriangulation :: (Ord r, Fractional r) => NonEmpty (Point 2 r :+ p) -> Triangulation p r
- Algorithms.Geometry.DelaunayTriangulation.DivideAndConqueror: delaunayTriangulation' :: (Ord r, Fractional r) => BinLeafTree Size (Point 2 r :+ p) -> Mapping p r -> (Adj, ConvexPolygon (p :+ VertexID) r)
- Algorithms.Geometry.DelaunayTriangulation.DivideAndConqueror: delete :: VertexID -> VertexID -> Adj -> Adj
- Algorithms.Geometry.DelaunayTriangulation.DivideAndConqueror: firsts :: ConvexPolygon (p :+ VertexID) r -> IntMap VertexID
- Algorithms.Geometry.DelaunayTriangulation.DivideAndConqueror: focus' :: CList a -> a
- Algorithms.Geometry.DelaunayTriangulation.DivideAndConqueror: fromHull :: Ord r => Mapping p r -> ConvexPolygon (p :+ q) r -> Adj
- Algorithms.Geometry.DelaunayTriangulation.DivideAndConqueror: insert :: (Num r, Ord r) => VertexID -> VertexID -> Merge p r ()
- Algorithms.Geometry.DelaunayTriangulation.DivideAndConqueror: insert' :: (Num r, Ord r) => VertexID -> VertexID -> Mapping p r -> Adj -> Adj
- Algorithms.Geometry.DelaunayTriangulation.DivideAndConqueror: isLeftOf :: (Ord r, Num r) => VertexID -> (VertexID, VertexID) -> Merge p r Bool
- Algorithms.Geometry.DelaunayTriangulation.DivideAndConqueror: isRightOf :: (Ord r, Num r) => VertexID -> (VertexID, VertexID) -> Merge p r Bool
- Algorithms.Geometry.DelaunayTriangulation.DivideAndConqueror: lookup' :: Ord k => Map k a -> k -> a
- Algorithms.Geometry.DelaunayTriangulation.DivideAndConqueror: lookup'' :: Int -> IntMap a -> a
- Algorithms.Geometry.DelaunayTriangulation.DivideAndConqueror: merge :: (Ord r, Fractional r) => Adj -> Adj -> LineSegment 2 (p :+ VertexID) r -> LineSegment 2 (p :+ VertexID) r -> Mapping p r -> Firsts -> Adj
- Algorithms.Geometry.DelaunayTriangulation.DivideAndConqueror: moveUp :: (Ord r, Fractional r) => (VertexID, VertexID) -> VertexID -> VertexID -> Merge p r ()
- Algorithms.Geometry.DelaunayTriangulation.DivideAndConqueror: nub' :: Eq a => NonEmpty (a :+ b) -> NonEmpty (a :+ b)
- Algorithms.Geometry.DelaunayTriangulation.DivideAndConqueror: pred' :: CList a -> CList a
- Algorithms.Geometry.DelaunayTriangulation.DivideAndConqueror: qTest :: (Ord r, Fractional r) => VertexID -> VertexID -> Vertex -> Vertex -> Merge p r Bool
- Algorithms.Geometry.DelaunayTriangulation.DivideAndConqueror: rotateL :: (Ord r, Fractional r) => VertexID -> VertexID -> Vertex -> Merge p r (Vertex, Bool)
- Algorithms.Geometry.DelaunayTriangulation.DivideAndConqueror: rotateL' :: (Ord r, Fractional r) => VertexID -> VertexID -> Vertex -> Vertex -> Merge p r Vertex
- Algorithms.Geometry.DelaunayTriangulation.DivideAndConqueror: rotateR :: (Ord r, Fractional r) => VertexID -> VertexID -> Vertex -> Merge p r (Vertex, Bool)
- Algorithms.Geometry.DelaunayTriangulation.DivideAndConqueror: rotateR' :: (Ord r, Fractional r) => VertexID -> VertexID -> Vertex -> Vertex -> Merge p r Vertex
- Algorithms.Geometry.DelaunayTriangulation.DivideAndConqueror: rotateTo :: Eq a => a -> CList a -> CList a
- Algorithms.Geometry.DelaunayTriangulation.DivideAndConqueror: rotateToFirst :: VertexID -> Firsts -> Merge p r ()
- Algorithms.Geometry.DelaunayTriangulation.DivideAndConqueror: size' :: BinLeafTree Size a -> Size
- Algorithms.Geometry.DelaunayTriangulation.DivideAndConqueror: succ' :: CList a -> CList a
- Algorithms.Geometry.DelaunayTriangulation.DivideAndConqueror: type Firsts = IntMap VertexID
- Algorithms.Geometry.DelaunayTriangulation.DivideAndConqueror: type Merge p r = StateT Adj (Reader (Mapping p r, Firsts))
- Algorithms.Geometry.DelaunayTriangulation.DivideAndConqueror: withID :: c :+ e -> e' -> c :+ (e :+ e')
- Algorithms.Util: SP :: !a -> !b -> SP a b
- Algorithms.Util: ST :: !a -> !b -> !c -> ST a b c
- Algorithms.Util: data SP a b
- Algorithms.Util: data ST a b c
- 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)
- Algorithms.Util: nonEmptyTails :: [a] -> [[a]]
- Algorithms.Util: uniquePairs :: [a] -> [SP a a]
- Algorithms.Util: uniqueTriplets :: [a] -> [ST a a a]
- Data.Geometry.Ipe.Attributes: IpeColor :: (IpeValue (RGB r)) -> IpeColor r
- Data.Geometry.Ipe.Attributes: Named :: Text -> IpeValue v
- Data.Geometry.Ipe.Attributes: Valued :: v -> IpeValue v
- Data.Geometry.Ipe.Attributes: [_unAttrs] :: Attributes -> Rec (Attr f) ats
- Data.Geometry.Ipe.Attributes: data IpeValue v
- Data.Geometry.Ipe.Attributes: instance Data.Foldable.Foldable Data.Geometry.Ipe.Attributes.IpeValue
- Data.Geometry.Ipe.Attributes: instance Data.String.IsString (Data.Geometry.Ipe.Attributes.IpeValue v)
- 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.Eq v => GHC.Classes.Eq (Data.Geometry.Ipe.Attributes.IpeValue v)
- Data.Geometry.Ipe.Attributes: instance GHC.Classes.Ord r => GHC.Classes.Ord (Data.Geometry.Ipe.Attributes.IpeColor r)
- Data.Geometry.Ipe.Attributes: instance GHC.Classes.Ord v => GHC.Classes.Ord (Data.Geometry.Ipe.Attributes.IpeValue v)
- Data.Geometry.Ipe.Attributes: instance GHC.Show.Show r => GHC.Show.Show (Data.Geometry.Ipe.Attributes.IpeColor r)
- Data.Geometry.Ipe.Attributes: instance GHC.Show.Show v => GHC.Show.Show (Data.Geometry.Ipe.Attributes.IpeValue v)
- Data.Geometry.Ipe.Attributes: newtype IpeColor r
- Data.Geometry.Ipe.IpeOut: IpeOut :: g -> i -> IpeOut g i
- Data.Geometry.Ipe.IpeOut: [asIpe] :: IpeOut g i -> g -> i
- Data.Geometry.Ipe.IpeOut: addAttributes :: extra -> IpeOut g core -> IpeOut g (core :+ extra)
- Data.Geometry.Ipe.IpeOut: asIpeGroup :: [IpeObject r] -> IpeObject r
- Data.Geometry.Ipe.IpeOut: asIpeGroup' :: [IpeObject r] -> IpeAttributes Group r -> IpeObject r
- Data.Geometry.Ipe.IpeOut: asIpeObject :: (HasDefaultIpeOut g, DefaultIpeOut g ~ i, NumType g ~ r) => g -> IpeAttributes i r -> IpeObject r
- Data.Geometry.Ipe.IpeOut: asIpeObject' :: (HasDefaultIpeOut g, DefaultIpeOut g ~ i, NumType g ~ r) => IpeAttributes i r -> g -> IpeObject r
- Data.Geometry.Ipe.IpeOut: asIpeObjectWith :: (ToObject i, NumType g ~ r) => IpeOut g (IpeObject' i r) -> g -> IpeAttributes i r -> IpeObject r
- Data.Geometry.Ipe.IpeOut: coreOut :: IpeOut g i -> IpeOut (g :+ a) i
- Data.Geometry.Ipe.IpeOut: defaultClipRectangle :: (Num r, Ord r) => Rectangle () r
- Data.Geometry.Ipe.IpeOut: defaultIpeOut :: HasDefaultIpeOut g => IpeOut g (IpeObject' (DefaultIpeOut g) (NumType g))
- Data.Geometry.Ipe.IpeOut: fromPathSegment :: IpeOut g (PathSegment r) -> IpeOut g (Path r)
- Data.Geometry.Ipe.IpeOut: instance GHC.Base.Functor (Data.Geometry.Ipe.IpeOut.IpeOut g)
- Data.Geometry.Ipe.IpeOut: ipeCircle' :: Floating r => IpeOut (Circle p r) (PathSegment r)
- Data.Geometry.Ipe.IpeOut: ipeLineSegment' :: IpeOut (LineSegment 2 p r) (PathSegment r)
- Data.Geometry.Ipe.IpeOut: ipeObject :: (ToObject i, NumType g ~ r) => IpeOut g (IpeObject' i r) -> IpeAttributes i r -> IpeOut g (IpeObject r)
- Data.Geometry.Ipe.IpeOut: ipePolyLine' :: IpeOut (PolyLine 2 a r) (PathSegment 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.IpeOut: newtype IpeOut g i
- Data.Geometry.Ipe.IpeOut: noAttrs :: Monoid extra => IpeOut g core -> IpeOut g (core :+ extra)
- 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.Types: AttrMapSym0KindInference :: AttrMapSym0
- Data.Geometry.Ipe.Types: AttrMapSym1KindInference :: AttrMapSym1
- Data.Geometry.Ipe.Types: [_groupItems] :: Group r -> [IpeObject r]
- Data.Geometry.Ipe.Types: instance Data.Singletons.SuppressUnusedWarnings.SuppressUnusedWarnings Data.Geometry.Ipe.Types.AttrMapSym1
- 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 v => Data.Geometry.Ipe.Writer.IpeWriteText (Data.Geometry.Ipe.Attributes.IpeValue v)
- 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.PlanarSubdivision: fromPolygons :: (Ord r, Fractional r) => proxy s -> NonEmpty (SimplePolygon p r :+ f) -> f -> PlanarSubdivision s (Maybe p) () f r
- Data.Geometry.Slab: instance (GHC.Real.Fractional r, GHC.Classes.Ord r, Data.Geometry.Slab.HasBoundingLines o) => Data.Geometry.Properties.IsIntersectableWith (Data.Geometry.SubLine.SubLine 2 a r) (Data.Geometry.Slab.Slab o a r)
- Data.Geometry.Slab: test :: SubLine 2 () Double
- 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.Classes.Ord r, GHC.Real.Fractional r) => Data.Geometry.Properties.IsIntersectableWith (Data.Geometry.SubLine.SubLine 2 p r) (Data.Geometry.SubLine.SubLine 2 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: pointAt :: (Num r, Arity d) => r -> Line d r -> Point d r
- Data.Geometry.SubLine: toOffset :: (Eq r, Fractional r, Arity d) => Point d r -> Line d r -> r
- Data.Permutation: ix' :: (Vector v a, Index (v a) ~ Int, IxValue (v a) ~ a, Ixed (v a)) => Int -> Lens' (v a) a
- Data.Seq: (<|) :: a -> LSeq n a -> LSeq (1 + n) a
- Data.Seq: (><) :: LSeq n a -> LSeq m a -> LSeq (n + m) a
- Data.Seq: (|>) :: LSeq n a -> a -> LSeq (1 + n) a
- Data.Seq: [:<] :: a -> LSeq n a -> ViewL (1 + n) a
- Data.Seq: [:>] :: LSeq n a -> a -> ViewR (1 + n) a
- Data.Seq: adjust :: (a -> a) -> Int -> LSeq n a -> LSeq n a
- Data.Seq: data LSeq (n :: Nat) a
- Data.Seq: data ViewL n a
- Data.Seq: data ViewR n a
- Data.Seq: drop :: Int -> LSeq n a -> LSeq 0 a
- Data.Seq: empty :: LSeq 0 a
- Data.Seq: eval :: forall proxy n m a. KnownNat n => proxy n -> LSeq m a -> Maybe (LSeq n a)
- Data.Seq: fromList :: Foldable f => f a -> LSeq 0 a
- Data.Seq: fromNonEmpty :: NonEmpty a -> LSeq 1 a
- Data.Seq: fromSeq :: Seq a -> LSeq 0 a
- Data.Seq: index :: LSeq n a -> Int -> a
- Data.Seq: infix 5 ><
- Data.Seq: infixl 5 :|>
- Data.Seq: infixr 5 :<<
- Data.Seq: instance Control.Lens.At.Ixed (Data.Seq.LSeq n a)
- Data.Seq: instance Data.Foldable.Foldable (Data.Seq.LSeq n)
- Data.Seq: instance Data.Foldable.Foldable (Data.Seq.ViewL n)
- Data.Seq: instance Data.Foldable.Foldable (Data.Seq.ViewR n)
- Data.Seq: instance Data.Traversable.Traversable (Data.Seq.LSeq n)
- Data.Seq: instance Data.Traversable.Traversable (Data.Seq.ViewL n)
- Data.Seq: instance Data.Traversable.Traversable (Data.Seq.ViewR n)
- Data.Seq: instance GHC.Base.Functor (Data.Seq.LSeq n)
- Data.Seq: instance GHC.Base.Functor (Data.Seq.ViewL n)
- Data.Seq: instance GHC.Base.Functor (Data.Seq.ViewR n)
- Data.Seq: instance GHC.Base.Monoid (Data.Seq.LSeq 0 a)
- 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.Seq: instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Seq.LSeq n a)
- Data.Seq: instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Seq.ViewL n a)
- Data.Seq: instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Seq.ViewR n a)
- Data.Seq: instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.Seq.LSeq n a)
- Data.Seq: instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.Seq.ViewL n a)
- Data.Seq: instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.Seq.ViewR n a)
- Data.Seq: instance GHC.Read.Read a => GHC.Read.Read (Data.Seq.LSeq n a)
- Data.Seq: instance GHC.Show.Show a => GHC.Show.Show (Data.Seq.LSeq n a)
- Data.Seq: instance GHC.Show.Show a => GHC.Show.Show (Data.Seq.ViewL n a)
- Data.Seq: instance GHC.Show.Show a => GHC.Show.Show (Data.Seq.ViewR n a)
- Data.Seq: mapWithIndex :: (Int -> a -> b) -> LSeq n a -> LSeq n b
- Data.Seq: partition :: (a -> Bool) -> LSeq n a -> (LSeq 0 a, LSeq 0 a)
- Data.Seq: promise :: LSeq m a -> LSeq n a
- Data.Seq: take :: Int -> LSeq n a -> LSeq 0 a
- Data.Seq: toNonEmpty :: LSeq (1 + n) a -> NonEmpty a
- Data.Seq: toSeq :: LSeq n a -> Seq a
- Data.Seq: unstableSortBy :: (a -> a -> Ordering) -> LSeq n a -> LSeq n a
- Data.Seq: viewl :: LSeq (1 + n) a -> ViewL (1 + n) a
- Data.Seq: viewr :: LSeq (1 + n) a -> ViewR (1 + n) a
- Data.Seq2: (:<) :: a -> Seq a -> ViewL1 a
- Data.Seq2: (:<<) :: a -> ViewR1 a -> ViewL2 a
- Data.Seq2: (:>) :: Seq a -> a -> ViewR1 a
- Data.Seq2: (:>>) :: ViewL1 a -> a -> ViewR2 a
- Data.Seq2: (<|) :: a -> Seq2 a -> Seq2 a
- Data.Seq2: (><) :: Seq2 a -> Seq2 a -> Seq2 a
- Data.Seq2: (|>) :: Seq2 a -> a -> Seq2 a
- Data.Seq2: Seq2 :: a -> (Seq a) -> a -> Seq2 a
- Data.Seq2: adjust :: (a -> a) -> Int -> Seq2 a -> Seq2 a
- Data.Seq2: data Seq2 a
- Data.Seq2: data ViewL1 a
- Data.Seq2: data ViewL2 a
- Data.Seq2: data ViewR1 a
- Data.Seq2: data ViewR2 a
- Data.Seq2: drop :: Int -> Seq2 a -> Seq a
- Data.Seq2: duo :: a -> a -> Seq2 a
- Data.Seq2: fromList :: [a] -> Seq2 a
- Data.Seq2: fromSeqUnsafe :: Seq a -> Seq2 a
- Data.Seq2: headL1 :: Lens' (ViewL1 a) a
- Data.Seq2: index :: Seq2 a -> Int -> a
- Data.Seq2: instance Control.Lens.At.Ixed (Data.Seq2.Seq2 a)
- Data.Seq2: instance Data.Foldable.Foldable Data.Seq2.Seq2
- Data.Seq2: instance Data.Foldable.Foldable Data.Seq2.ViewL1
- Data.Seq2: instance Data.Foldable.Foldable Data.Seq2.ViewL2
- Data.Seq2: instance Data.Foldable.Foldable Data.Seq2.ViewR1
- Data.Seq2: instance Data.Foldable.Foldable Data.Seq2.ViewR2
- Data.Seq2: instance Data.Traversable.Traversable Data.Seq2.Seq2
- Data.Seq2: instance Data.Traversable.Traversable Data.Seq2.ViewL1
- Data.Seq2: instance Data.Traversable.Traversable Data.Seq2.ViewL2
- Data.Seq2: instance Data.Traversable.Traversable Data.Seq2.ViewR1
- Data.Seq2: instance Data.Traversable.Traversable Data.Seq2.ViewR2
- Data.Seq2: instance GHC.Base.Functor Data.Seq2.Seq2
- Data.Seq2: instance GHC.Base.Functor Data.Seq2.ViewL1
- Data.Seq2: instance GHC.Base.Functor Data.Seq2.ViewL2
- Data.Seq2: instance GHC.Base.Functor Data.Seq2.ViewR1
- Data.Seq2: instance GHC.Base.Functor Data.Seq2.ViewR2
- Data.Seq2: instance GHC.Base.Semigroup (Data.Seq2.Seq2 a)
- Data.Seq2: instance GHC.Base.Semigroup (Data.Seq2.ViewL1 a)
- Data.Seq2: instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Seq2.Seq2 a)
- Data.Seq2: instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Seq2.ViewL1 a)
- Data.Seq2: instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Seq2.ViewL2 a)
- Data.Seq2: instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Seq2.ViewR1 a)
- Data.Seq2: instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Seq2.ViewR2 a)
- Data.Seq2: instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.Seq2.Seq2 a)
- Data.Seq2: instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.Seq2.ViewL1 a)
- Data.Seq2: instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.Seq2.ViewL2 a)
- Data.Seq2: instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.Seq2.ViewR1 a)
- Data.Seq2: instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.Seq2.ViewR2 a)
- Data.Seq2: instance GHC.Read.Read a => GHC.Read.Read (Data.Seq2.ViewR1 a)
- Data.Seq2: instance GHC.Show.Show a => GHC.Show.Show (Data.Seq2.Seq2 a)
- Data.Seq2: instance GHC.Show.Show a => GHC.Show.Show (Data.Seq2.ViewL1 a)
- Data.Seq2: instance GHC.Show.Show a => GHC.Show.Show (Data.Seq2.ViewL2 a)
- Data.Seq2: instance GHC.Show.Show a => GHC.Show.Show (Data.Seq2.ViewR1 a)
- Data.Seq2: instance GHC.Show.Show a => GHC.Show.Show (Data.Seq2.ViewR2 a)
- Data.Seq2: l1Singleton :: a -> ViewL1 a
- Data.Seq2: mapWithIndex :: (Int -> a -> b) -> Seq2 a -> Seq2 b
- Data.Seq2: partition :: (a -> Bool) -> Seq2 a -> (Seq a, Seq a)
- Data.Seq2: r1Singleton :: a -> ViewR1 a
- Data.Seq2: take :: Int -> Seq2 a -> Seq a
- Data.Seq2: toNonEmpty :: ViewL1 a -> NonEmpty a
- Data.Seq2: toSeq :: Seq2 a -> Seq a
- Data.Seq2: viewL1FromNonEmpty :: NonEmpty a -> ViewL1 a
- Data.Seq2: viewL1FromSeq :: Seq a -> ViewL1 a
- Data.Seq2: viewL1toR1 :: ViewL1 a -> ViewR1 a
- Data.Seq2: viewl :: Seq2 a -> ViewL2 a
- Data.Seq2: viewr :: Seq2 a -> ViewR2 a
- 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 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 a => Test.QuickCheck.Arbitrary.Arbitrary (Data.Seq2.Seq2 a)
+ Algorithms.Geometry.ClosestPair.DivideAndConquer: CCP :: NonEmpty (Point 2 r :+ p) -> !CP (Point 2 r :+ p) r -> CCP p r
+ Algorithms.Geometry.ClosestPair.DivideAndConquer: closestPair :: (Ord r, Num r) => LSeq 2 (Point 2 r :+ p) -> Two (Point 2 r :+ p)
+ Algorithms.Geometry.ClosestPair.DivideAndConquer: data CCP p r
+ Algorithms.Geometry.ClosestPair.DivideAndConquer: getDist :: CP a r -> Top r
+ Algorithms.Geometry.ClosestPair.DivideAndConquer: instance (GHC.Classes.Eq r, GHC.Classes.Eq p) => GHC.Classes.Eq (Algorithms.Geometry.ClosestPair.DivideAndConquer.CCP p r)
+ Algorithms.Geometry.ClosestPair.DivideAndConquer: instance (GHC.Num.Num r, GHC.Classes.Ord r) => GHC.Base.Semigroup (Algorithms.Geometry.ClosestPair.DivideAndConquer.CCP p r)
+ Algorithms.Geometry.ClosestPair.DivideAndConquer: instance (GHC.Show.Show r, GHC.Show.Show p) => GHC.Show.Show (Algorithms.Geometry.ClosestPair.DivideAndConquer.CCP p r)
+ Algorithms.Geometry.ClosestPair.DivideAndConquer: mergePairs :: forall p r. (Ord r, Num r) => CP (Point 2 r :+ p) r -> NonEmpty (Point 2 r :+ p) -> NonEmpty (Point 2 r :+ p) -> CP (Point 2 r :+ p) r
+ Algorithms.Geometry.ClosestPair.DivideAndConquer: mergeSortedBy :: (a -> a -> Ordering) -> NonEmpty a -> NonEmpty a -> NonEmpty a
+ Algorithms.Geometry.ClosestPair.DivideAndConquer: minBy :: Ord b => (a -> b) -> a -> a -> a
+ Algorithms.Geometry.ClosestPair.DivideAndConquer: runWhile :: s -> [a] -> (s -> a -> Bool) -> (s -> a -> s) -> s
+ Algorithms.Geometry.ClosestPair.DivideAndConquer: type CP q r = Top (SP (Two q) r)
+ Algorithms.Geometry.ClosestPair.Naive: closestPair :: (Ord r, Arity d, Num r) => LSeq 2 (Point d r :+ p) -> Two (Point d r :+ p)
+ Algorithms.Geometry.ClosestPair.Naive: mkPair :: (Arity d, Num r) => (Point d r :+ p) -> (Point d r :+ p) -> PP d p r
+ Algorithms.Geometry.ClosestPair.Naive: pairs :: LSeq 2 a -> NonEmpty (Two a)
+ Algorithms.Geometry.ClosestPair.Naive: type PP d p r = ArgMin r (Two (Point d r :+ p))
+ Algorithms.Geometry.ConvexHull.DivideAndConquer: convexHull :: (Ord r, Num r) => NonEmpty (Point 2 r :+ p) -> ConvexPolygon p r
+ Algorithms.Geometry.ConvexHull.DivideAndConquer: instance (GHC.Num.Num r, GHC.Classes.Ord r) => GHC.Base.Semigroup (Algorithms.Geometry.ConvexHull.DivideAndConquer.Merge r p)
+ Algorithms.Geometry.DelaunayTriangulation.DivideAndConquer: delaunayTriangulation :: (Ord r, Fractional r) => NonEmpty (Point 2 r :+ p) -> Triangulation p r
+ Algorithms.Geometry.DelaunayTriangulation.DivideAndConquer: delaunayTriangulation' :: (Ord r, Fractional r) => BinLeafTree Size (Point 2 r :+ p) -> Mapping p r -> (Adj, ConvexPolygon (p :+ VertexID) r)
+ Algorithms.Geometry.DelaunayTriangulation.DivideAndConquer: delete :: VertexID -> VertexID -> Adj -> Adj
+ Algorithms.Geometry.DelaunayTriangulation.DivideAndConquer: firsts :: ConvexPolygon (p :+ VertexID) r -> IntMap VertexID
+ Algorithms.Geometry.DelaunayTriangulation.DivideAndConquer: focus' :: CList a -> a
+ Algorithms.Geometry.DelaunayTriangulation.DivideAndConquer: fromHull :: Ord r => Mapping p r -> ConvexPolygon (p :+ q) r -> Adj
+ Algorithms.Geometry.DelaunayTriangulation.DivideAndConquer: insert :: (Num r, Ord r) => VertexID -> VertexID -> Merge p r ()
+ Algorithms.Geometry.DelaunayTriangulation.DivideAndConquer: insert' :: (Num r, Ord r) => VertexID -> VertexID -> Mapping p r -> Adj -> Adj
+ Algorithms.Geometry.DelaunayTriangulation.DivideAndConquer: isLeftOf :: (Ord r, Num r) => VertexID -> (VertexID, VertexID) -> Merge p r Bool
+ Algorithms.Geometry.DelaunayTriangulation.DivideAndConquer: isRightOf :: (Ord r, Num r) => VertexID -> (VertexID, VertexID) -> Merge p r Bool
+ Algorithms.Geometry.DelaunayTriangulation.DivideAndConquer: lookup' :: Ord k => Map k a -> k -> a
+ Algorithms.Geometry.DelaunayTriangulation.DivideAndConquer: lookup'' :: Int -> IntMap a -> a
+ Algorithms.Geometry.DelaunayTriangulation.DivideAndConquer: merge :: (Ord r, Fractional r) => Adj -> Adj -> LineSegment 2 (p :+ VertexID) r -> LineSegment 2 (p :+ VertexID) r -> Mapping p r -> Firsts -> Adj
+ Algorithms.Geometry.DelaunayTriangulation.DivideAndConquer: moveUp :: (Ord r, Fractional r) => (VertexID, VertexID) -> VertexID -> VertexID -> Merge p r ()
+ Algorithms.Geometry.DelaunayTriangulation.DivideAndConquer: nub' :: Eq a => NonEmpty (a :+ b) -> NonEmpty (a :+ b)
+ Algorithms.Geometry.DelaunayTriangulation.DivideAndConquer: pred' :: CList a -> CList a
+ Algorithms.Geometry.DelaunayTriangulation.DivideAndConquer: qTest :: (Ord r, Fractional r) => VertexID -> VertexID -> Vertex -> Vertex -> Merge p r Bool
+ Algorithms.Geometry.DelaunayTriangulation.DivideAndConquer: rotateL :: (Ord r, Fractional r) => VertexID -> VertexID -> Vertex -> Merge p r (Vertex, Bool)
+ Algorithms.Geometry.DelaunayTriangulation.DivideAndConquer: rotateL' :: (Ord r, Fractional r) => VertexID -> VertexID -> Vertex -> Vertex -> Merge p r Vertex
+ Algorithms.Geometry.DelaunayTriangulation.DivideAndConquer: rotateR :: (Ord r, Fractional r) => VertexID -> VertexID -> Vertex -> Merge p r (Vertex, Bool)
+ Algorithms.Geometry.DelaunayTriangulation.DivideAndConquer: rotateR' :: (Ord r, Fractional r) => VertexID -> VertexID -> Vertex -> Vertex -> Merge p r Vertex
+ Algorithms.Geometry.DelaunayTriangulation.DivideAndConquer: rotateTo :: Eq a => a -> CList a -> CList a
+ Algorithms.Geometry.DelaunayTriangulation.DivideAndConquer: rotateToFirst :: VertexID -> Firsts -> Merge p r ()
+ Algorithms.Geometry.DelaunayTriangulation.DivideAndConquer: size' :: BinLeafTree Size a -> Size
+ Algorithms.Geometry.DelaunayTriangulation.DivideAndConquer: succ' :: CList a -> CList a
+ Algorithms.Geometry.DelaunayTriangulation.DivideAndConquer: type Firsts = IntMap VertexID
+ Algorithms.Geometry.DelaunayTriangulation.DivideAndConquer: type Merge p r = StateT Adj (Reader (Mapping p r, Firsts))
+ Algorithms.Geometry.DelaunayTriangulation.DivideAndConquer: withID :: (c :+ e) -> e' -> c :+ (e :+ e')
+ Data.Ext: infixr 1 :+
+ Data.Geometry: infixl 6 ^-^
+ Data.Geometry: readVec :: forall d r. (Arity d, Read r) => ReadP (Vector d r)
+ Data.Geometry: xComponent :: (1 <= d, Arity d) => Lens' (Vector d r) r
+ Data.Geometry: yComponent :: (2 <= d, Arity d) => Lens' (Vector d r) r
+ Data.Geometry: zComponent :: (3 <= d, Arity d) => Lens' (Vector d r) r
+ Data.Geometry.Arrangement: Arrangement :: Vector (Line 2 r :+ l) -> PlanarSubdivision s v e f r -> Rectangle () r -> ArrangementBoundary s l r -> Arrangement s l v e f r
+ Data.Geometry.Arrangement: [_boundedArea] :: Arrangement s l v e f r -> Rectangle () r
+ Data.Geometry.Arrangement: [_inputLines] :: Arrangement s l v e f r -> Vector (Line 2 r :+ l)
+ Data.Geometry.Arrangement: [_subdivision] :: Arrangement s l v e f r -> PlanarSubdivision s v e f r
+ Data.Geometry.Arrangement: [_unboundedIntersections] :: Arrangement s l v e f r -> ArrangementBoundary s l r
+ Data.Geometry.Arrangement: boundedArea :: forall s_a4mh6 l_a4mh7 v_a4mh8 e_a4mh9 f_a4mha r_a4mhb. Lens' (Arrangement s_a4mh6 l_a4mh7 v_a4mh8 e_a4mh9 f_a4mha r_a4mhb) (Rectangle () r_a4mhb)
+ Data.Geometry.Arrangement: constructArrangement :: (Ord r, Fractional r) => proxy s -> [Line 2 r :+ l] -> Arrangement s l () (Maybe l) () r
+ Data.Geometry.Arrangement: constructArrangementInBox :: (Ord r, Fractional r) => proxy s -> Rectangle () r -> [Line 2 r :+ l] -> Arrangement s l () (Maybe l) () r
+ Data.Geometry.Arrangement: constructArrangementInBox' :: (Ord r, Fractional r) => proxy s -> Rectangle () r -> [Line 2 r :+ l] -> Arrangement s l () (Maybe l) () r
+ Data.Geometry.Arrangement: data Arrangement s l v e f r
+ Data.Geometry.Arrangement: findStart :: (Ord r, Fractional r) => Line 2 r -> Arrangement s l v (Maybe e) f r -> Maybe (Dart s)
+ Data.Geometry.Arrangement: findStartDart :: PlanarSubdivision s v (Maybe e) f r -> VertexId' s -> Maybe (Dart s)
+ Data.Geometry.Arrangement: findStartVertex :: (Ord r, Fractional r) => Point 2 r -> Arrangement s l v e f r -> Maybe (Point 2 r, VertexId' s, Maybe (Line 2 r :+ l))
+ Data.Geometry.Arrangement: follow :: (Ord r, Num r) => Arrangement s l v e f r -> Dart s -> Maybe (Dart s)
+ Data.Geometry.Arrangement: inputLines :: forall s_a4mh6 l_a4mh7 v_a4mh8 e_a4mh9 f_a4mha r_a4mhb. Lens' (Arrangement s_a4mh6 l_a4mh7 v_a4mh8 e_a4mh9 f_a4mha r_a4mhb) (Vector ((:+) (Line 2 r_a4mhb) l_a4mh7))
+ Data.Geometry.Arrangement: subdivision :: forall s_a4mh6 l_a4mh7 v_a4mh8 e_a4mh9 f_a4mha r_a4mhb v_a4moY e_a4moZ f_a4mp0. Lens (Arrangement s_a4mh6 l_a4mh7 v_a4mh8 e_a4mh9 f_a4mha r_a4mhb) (Arrangement s_a4mh6 l_a4mh7 v_a4moY e_a4moZ f_a4mp0 r_a4mhb) (PlanarSubdivision s_a4mh6 v_a4mh8 e_a4mh9 f_a4mha r_a4mhb) (PlanarSubdivision s_a4mh6 v_a4moY e_a4moZ f_a4mp0 r_a4mhb)
+ Data.Geometry.Arrangement: traverseLine :: (Ord r, Fractional r) => Line 2 r -> Arrangement s l v (Maybe e) f r -> [Dart s]
+ Data.Geometry.Arrangement: type ArrangementBoundary s e r = Vector (Point 2 r, VertexId' s, Maybe (Line 2 r :+ e))
+ Data.Geometry.Arrangement: unboundedIntersections :: forall s_a4mh6 l_a4mh7 v_a4mh8 e_a4mh9 f_a4mha r_a4mhb. Lens' (Arrangement s_a4mh6 l_a4mh7 v_a4mh8 e_a4mh9 f_a4mha r_a4mhb) (ArrangementBoundary s_a4mh6 l_a4mh7 r_a4mhb)
+ Data.Geometry.Arrangement.Draw: drawArrangement :: IpeOut (Arrangement s l v e f r) Group r
+ Data.Geometry.Arrangement.Draw: drawColoredArrangement :: IpeOut (Arrangement s l v e (Maybe (IpeColor r)) r) Group r
+ Data.Geometry.Arrangement.Internal: Arrangement :: Vector (Line 2 r :+ l) -> PlanarSubdivision s v e f r -> Rectangle () r -> ArrangementBoundary s l r -> Arrangement s l v e f r
+ Data.Geometry.Arrangement.Internal: [_boundedArea] :: Arrangement s l v e f r -> Rectangle () r
+ Data.Geometry.Arrangement.Internal: [_inputLines] :: Arrangement s l v e f r -> Vector (Line 2 r :+ l)
+ Data.Geometry.Arrangement.Internal: [_subdivision] :: Arrangement s l v e f r -> PlanarSubdivision s v e f r
+ Data.Geometry.Arrangement.Internal: [_unboundedIntersections] :: Arrangement s l v e f r -> ArrangementBoundary s l r
+ Data.Geometry.Arrangement.Internal: alignWith :: (a -> b -> Bool) -> CSeq a -> CSeq b -> Maybe (CSeq (a, b))
+ Data.Geometry.Arrangement.Internal: allPairs :: [a] -> [(a, a)]
+ Data.Geometry.Arrangement.Internal: boundedArea :: forall s_a4mh6 l_a4mh7 v_a4mh8 e_a4mh9 f_a4mha r_a4mhb. Lens' (Arrangement s_a4mh6 l_a4mh7 v_a4mh8 e_a4mh9 f_a4mha r_a4mhb) (Rectangle () r_a4mhb)
+ Data.Geometry.Arrangement.Internal: computeSegsAndParts :: (Ord r, Fractional r) => Rectangle () r -> [Line 2 r :+ l] -> ([LineSegment 2 () r :+ Maybe l], [(Point 2 r, Maybe (Line 2 r :+ l))])
+ Data.Geometry.Arrangement.Internal: constructArrangement :: (Ord r, Fractional r) => proxy s -> [Line 2 r :+ l] -> Arrangement s l () (Maybe l) () r
+ Data.Geometry.Arrangement.Internal: constructArrangementInBox :: (Ord r, Fractional r) => proxy s -> Rectangle () r -> [Line 2 r :+ l] -> Arrangement s l () (Maybe l) () r
+ Data.Geometry.Arrangement.Internal: constructArrangementInBox' :: (Ord r, Fractional r) => proxy s -> Rectangle () r -> [Line 2 r :+ l] -> Arrangement s l () (Maybe l) () r
+ Data.Geometry.Arrangement.Internal: data Arrangement s l v e f r
+ Data.Geometry.Arrangement.Internal: findStart :: (Ord r, Fractional r) => Line 2 r -> Arrangement s l v (Maybe e) f r -> Maybe (Dart s)
+ Data.Geometry.Arrangement.Internal: findStartDart :: PlanarSubdivision s v (Maybe e) f r -> VertexId' s -> Maybe (Dart s)
+ Data.Geometry.Arrangement.Internal: findStartVertex :: (Ord r, Fractional r) => Point 2 r -> Arrangement s l v e f r -> Maybe (Point 2 r, VertexId' s, Maybe (Line 2 r :+ l))
+ Data.Geometry.Arrangement.Internal: follow :: (Ord r, Num r) => Arrangement s l v e f r -> Dart s -> Maybe (Dart s)
+ Data.Geometry.Arrangement.Internal: inputLines :: forall s_a4mh6 l_a4mh7 v_a4mh8 e_a4mh9 f_a4mha r_a4mhb. Lens' (Arrangement s_a4mh6 l_a4mh7 v_a4mh8 e_a4mh9 f_a4mha r_a4mhb) (Vector ((:+) (Line 2 r_a4mhb) l_a4mh7))
+ Data.Geometry.Arrangement.Internal: instance forall k (s :: k) l v e f r. (GHC.Real.Fractional r, GHC.Classes.Eq r, GHC.Classes.Eq l, GHC.Classes.Eq v, GHC.Classes.Eq e, GHC.Classes.Eq f) => GHC.Classes.Eq (Data.Geometry.Arrangement.Internal.Arrangement s l v e f r)
+ Data.Geometry.Arrangement.Internal: instance forall k (s :: k) l v e f r. (GHC.Show.Show r, GHC.Show.Show l, GHC.Show.Show v, GHC.Show.Show e, GHC.Show.Show f) => GHC.Show.Show (Data.Geometry.Arrangement.Internal.Arrangement s l v e f r)
+ Data.Geometry.Arrangement.Internal: intersectionPoint :: (Ord r, Fractional r) => (Line 2 r :+ l) -> (Line 2 r :+ l) -> Maybe (Point 2 r)
+ Data.Geometry.Arrangement.Internal: intersections :: (Ord r, Fractional r) => [Line 2 r :+ l] -> [Point 2 r]
+ Data.Geometry.Arrangement.Internal: link :: Eq r => [(Point 2 r, a)] -> PlanarSubdivision s v (Maybe e) f r -> Vector (Point 2 r, VertexId' s, a)
+ Data.Geometry.Arrangement.Internal: makeBoundingBox :: (Ord r, Fractional r) => [Line 2 r :+ l] -> Rectangle () r
+ Data.Geometry.Arrangement.Internal: makePairs :: [a] -> [(a, [a])]
+ Data.Geometry.Arrangement.Internal: map4 :: (a -> b) -> (a, a, a, a) -> (b, b, b, b)
+ Data.Geometry.Arrangement.Internal: perLine :: forall r l. (Ord r, Fractional r) => Rectangle () r -> (Line 2 r :+ l) -> [Line 2 r :+ l] -> [LineSegment 2 () r :+ l]
+ Data.Geometry.Arrangement.Internal: sideIntersections :: (Ord r, Fractional r) => [Line 2 r :+ l] -> LineSegment 2 q r -> [(Point 2 r, Line 2 r :+ l)]
+ Data.Geometry.Arrangement.Internal: subdivision :: forall s_a4mh6 l_a4mh7 v_a4mh8 e_a4mh9 f_a4mha r_a4mhb v_a4moY e_a4moZ f_a4mp0. Lens (Arrangement s_a4mh6 l_a4mh7 v_a4mh8 e_a4mh9 f_a4mha r_a4mhb) (Arrangement s_a4mh6 l_a4mh7 v_a4moY e_a4moZ f_a4mp0 r_a4mhb) (PlanarSubdivision s_a4mh6 v_a4mh8 e_a4mh9 f_a4mha r_a4mhb) (PlanarSubdivision s_a4mh6 v_a4moY e_a4moZ f_a4mp0 r_a4mhb)
+ Data.Geometry.Arrangement.Internal: toSegments :: Ord r => [Point 2 r] -> [LineSegment 2 () r]
+ Data.Geometry.Arrangement.Internal: traverseLine :: (Ord r, Fractional r) => Line 2 r -> Arrangement s l v (Maybe e) f r -> [Dart s]
+ Data.Geometry.Arrangement.Internal: type ArrangementBoundary s e r = Vector (Point 2 r, VertexId' s, Maybe (Line 2 r :+ e))
+ Data.Geometry.Arrangement.Internal: unBoundedParts :: (Ord r, Fractional r) => Rectangle () r -> [Line 2 r :+ l] -> [(Point 2 r, Maybe (Line 2 r :+ l))]
+ Data.Geometry.Arrangement.Internal: unboundedIntersections :: forall s_a4mh6 l_a4mh7 v_a4mh8 e_a4mh9 f_a4mha r_a4mhb. Lens' (Arrangement s_a4mh6 l_a4mh7 v_a4mh8 e_a4mh9 f_a4mha r_a4mhb) (ArrangementBoundary s_a4mh6 l_a4mh7 r_a4mhb)
+ Data.Geometry.Box.Internal: grow :: (Num r, Arity d) => r -> Box d p r -> Box d p r
+ Data.Geometry.HyperPlane: HyperPlane :: !Point d r -> !Vector d r -> HyperPlane
+ Data.Geometry.HyperPlane: [_inPlane] :: HyperPlane -> !Point d r
+ Data.Geometry.HyperPlane: [_normalVec] :: HyperPlane -> !Vector d r
+ Data.Geometry.HyperPlane: class HasSupportingPlane t
+ Data.Geometry.HyperPlane: data HyperPlane (d :: Nat) (r :: *)
+ Data.Geometry.HyperPlane: from3Points :: Num r => Point 3 r -> Point 3 r -> Point 3 r -> HyperPlane 3 r
+ Data.Geometry.HyperPlane: inPlane :: forall d_a30lp r_a30lq. Lens' (HyperPlane d_a30lp r_a30lq) (Point d_a30lp r_a30lq)
+ Data.Geometry.HyperPlane: instance (Control.DeepSeq.NFData r, Data.Geometry.Vector.VectorFamily.Arity d) => Control.DeepSeq.NFData (Data.Geometry.HyperPlane.HyperPlane d r)
+ Data.Geometry.HyperPlane: instance (Data.Geometry.Vector.VectorFamily.Arity d, Data.Geometry.Vector.VectorFamily.Arity (d GHC.TypeNats.+ 1), GHC.Real.Fractional r) => Data.Geometry.Transformation.IsTransformable (Data.Geometry.HyperPlane.HyperPlane d r)
+ Data.Geometry.HyperPlane: instance (Data.Geometry.Vector.VectorFamily.Arity d, GHC.Classes.Eq r) => GHC.Classes.Eq (Data.Geometry.HyperPlane.HyperPlane d r)
+ Data.Geometry.HyperPlane: instance (Data.Geometry.Vector.VectorFamily.Arity d, GHC.Show.Show r) => GHC.Show.Show (Data.Geometry.HyperPlane.HyperPlane d r)
+ Data.Geometry.HyperPlane: instance (GHC.Classes.Eq r, GHC.Real.Fractional r) => Data.Geometry.Properties.IsIntersectableWith (Data.Geometry.Line.Internal.Line 3 r) (Data.Geometry.HyperPlane.Plane r)
+ Data.Geometry.HyperPlane: instance Data.Geometry.HyperPlane.HasSupportingPlane (Data.Geometry.HyperPlane.HyperPlane d r)
+ Data.Geometry.HyperPlane: instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Foldable.Foldable (Data.Geometry.HyperPlane.HyperPlane d)
+ Data.Geometry.HyperPlane: instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Traversable.Traversable (Data.Geometry.HyperPlane.HyperPlane d)
+ Data.Geometry.HyperPlane: instance Data.Geometry.Vector.VectorFamily.Arity d => GHC.Base.Functor (Data.Geometry.HyperPlane.HyperPlane d)
+ Data.Geometry.HyperPlane: instance GHC.Generics.Generic (Data.Geometry.HyperPlane.HyperPlane d r)
+ Data.Geometry.HyperPlane: normalVec :: forall d_a30lp r_a30lq. Lens' (HyperPlane d_a30lp r_a30lq) (Vector d_a30lp r_a30lq)
+ Data.Geometry.HyperPlane: onHyperPlane :: (Num r, Eq r, Arity d) => Point d r -> HyperPlane d r -> Bool
+ Data.Geometry.HyperPlane: supportingPlane :: HasSupportingPlane t => t -> HyperPlane (Dimension t) (NumType t)
+ Data.Geometry.HyperPlane: type Plane = HyperPlane 3
+ Data.Geometry.Ipe: IpeColor :: IpeValue (RGB r) -> IpeColor r
+ Data.Geometry.Ipe: newtype IpeColor r
+ Data.Geometry.Ipe.Attributes: type family AllSatisfy (c :: k -> Constraint) (xs :: [k]) :: Constraint
+ Data.Geometry.Ipe.Color: IpeColor :: IpeValue (RGB r) -> IpeColor r
+ Data.Geometry.Ipe.Color: blue :: IpeColor r
+ Data.Geometry.Ipe.Color: brown :: IpeColor r
+ Data.Geometry.Ipe.Color: darkblue :: IpeColor r
+ Data.Geometry.Ipe.Color: darkcyan :: IpeColor r
+ Data.Geometry.Ipe.Color: darkgray :: IpeColor r
+ Data.Geometry.Ipe.Color: darkgreen :: IpeColor r
+ Data.Geometry.Ipe.Color: darkmagenta :: IpeColor r
+ Data.Geometry.Ipe.Color: darkorange :: IpeColor r
+ Data.Geometry.Ipe.Color: darkred :: IpeColor r
+ Data.Geometry.Ipe.Color: gold :: IpeColor r
+ Data.Geometry.Ipe.Color: gray :: IpeColor r
+ Data.Geometry.Ipe.Color: green :: IpeColor r
+ Data.Geometry.Ipe.Color: instance GHC.Classes.Eq r => GHC.Classes.Eq (Data.Geometry.Ipe.Color.IpeColor r)
+ Data.Geometry.Ipe.Color: instance GHC.Classes.Ord r => GHC.Classes.Ord (Data.Geometry.Ipe.Color.IpeColor r)
+ Data.Geometry.Ipe.Color: instance GHC.Read.Read r => GHC.Read.Read (Data.Geometry.Ipe.Color.IpeColor r)
+ Data.Geometry.Ipe.Color: instance GHC.Show.Show r => GHC.Show.Show (Data.Geometry.Ipe.Color.IpeColor r)
+ Data.Geometry.Ipe.Color: lightblue :: IpeColor r
+ Data.Geometry.Ipe.Color: lightcyan :: IpeColor r
+ Data.Geometry.Ipe.Color: lightgray :: IpeColor r
+ Data.Geometry.Ipe.Color: lightgreen :: IpeColor r
+ Data.Geometry.Ipe.Color: lightyellow :: IpeColor r
+ Data.Geometry.Ipe.Color: named :: Text -> IpeColor r
+ Data.Geometry.Ipe.Color: navy :: IpeColor r
+ Data.Geometry.Ipe.Color: newtype IpeColor r
+ Data.Geometry.Ipe.Color: orange :: IpeColor r
+ Data.Geometry.Ipe.Color: pink :: IpeColor r
+ Data.Geometry.Ipe.Color: purple :: IpeColor r
+ Data.Geometry.Ipe.Color: red :: IpeColor r
+ Data.Geometry.Ipe.Color: seagreen :: IpeColor r
+ Data.Geometry.Ipe.Color: turquoise :: IpeColor r
+ Data.Geometry.Ipe.Color: violet :: IpeColor r
+ Data.Geometry.Ipe.Color: yellow :: IpeColor r
+ Data.Geometry.Ipe.FromIpe: _asTriangle :: Prism' (Path r) (Triangle 2 () r)
+ Data.Geometry.Ipe.FromIpe: fromSingleton :: a -> LSeq 1 a
+ Data.Geometry.Ipe.IpeOut: (!) :: IpeObject' i r -> IpeAttributes i r -> IpeObject' i r
+ Data.Geometry.Ipe.IpeOut: defIO :: HasDefaultIpeOut g => IpeOut g (DefaultIpeOut g) (NumType g)
+ Data.Geometry.Ipe.IpeOut: iO :: ToObject i => IpeObject' i r -> IpeObject r
+ Data.Geometry.Ipe.IpeOut: iO' :: HasDefaultIpeOut g => g -> IpeObject (NumType g)
+ Data.Geometry.Ipe.IpeOut: iO'' :: (HasDefaultIpeOut g, NumType g ~ r, DefaultIpeOut g ~ i, ToObject i) => g -> IpeAttributes i r -> IpeObject r
+ Data.Geometry.Ipe.IpeOut: instance (Data.Geometry.Ipe.IpeOut.HasDefaultIpeOut g, a Data.Type.Equality.~ Data.Geometry.Ipe.Types.IpeAttributes (Data.Geometry.Ipe.IpeOut.DefaultIpeOut g) (Data.Geometry.Properties.NumType g)) => Data.Geometry.Ipe.IpeOut.HasDefaultIpeOut (g Data.Ext.:+ a)
+ Data.Geometry.Ipe.IpeOut: instance (GHC.Real.Fractional r, GHC.Classes.Ord r) => Data.Geometry.Ipe.IpeOut.HasDefaultIpeOut (Data.Geometry.Line.Internal.Line 2 r)
+ Data.Geometry.Ipe.IpeOut: instance Data.Geometry.Ipe.IpeOut.HasDefaultIpeOut a => Data.Geometry.Ipe.IpeOut.HasDefaultIpeOut [a]
+ Data.Geometry.Ipe.IpeOut: ipeGroup :: IpeOut [IpeObject r] Group r
+ Data.Geometry.Ipe.IpeOut: path :: PathSegment r -> Path r
+ Data.Geometry.Ipe.IpeOut: pathSegment :: LineSegment 2 p r -> PathSegment r
+ Data.Geometry.Ipe.IpeOut: type IpeOut g i r = g -> IpeObject' i r
+ Data.Geometry.Ipe.Reader: instance Data.Geometry.Ipe.PathParser.Coordinate r => Data.Geometry.Ipe.Reader.IpeReadText (Data.Geometry.Ipe.Color.IpeColor r)
+ Data.Geometry.Ipe.Types: [AttrMapSym0KindInference] :: forall r6989586621679826752 arg_a3qGT. SameKind (Apply AttrMapSym0 arg_a3qGT) (AttrMapSym1 arg_a3qGT) => AttrMapSym0 r6989586621679826752
+ Data.Geometry.Ipe.Types: [AttrMapSym1KindInference] :: forall r6989586621679826752 l6989586621679826753 arg_a3qGS. SameKind (Apply (AttrMapSym1 r6989586621679826752) arg_a3qGS) (AttrMapSym2 r6989586621679826752 arg_a3qGS) => AttrMapSym1 r6989586621679826752 l6989586621679826753
+ Data.Geometry.Ipe.Types: instance Data.Singletons.SuppressUnusedWarnings.SuppressUnusedWarnings (Data.Geometry.Ipe.Types.AttrMapSym1 r6989586621679826752)
+ Data.Geometry.Ipe.Types: mkIpeObject :: ToObject i => IpeObject' i r -> IpeObject r
+ Data.Geometry.Ipe.Types: type family AttributesOf (t :: * -> *) :: [u]
+ Data.Geometry.Ipe.Value: Named :: Text -> IpeValue v
+ Data.Geometry.Ipe.Value: Valued :: v -> IpeValue v
+ Data.Geometry.Ipe.Value: data IpeValue v
+ Data.Geometry.Ipe.Value: instance Data.Foldable.Foldable Data.Geometry.Ipe.Value.IpeValue
+ Data.Geometry.Ipe.Value: instance Data.String.IsString (Data.Geometry.Ipe.Value.IpeValue v)
+ Data.Geometry.Ipe.Value: instance Data.Traversable.Traversable Data.Geometry.Ipe.Value.IpeValue
+ Data.Geometry.Ipe.Value: instance GHC.Base.Functor Data.Geometry.Ipe.Value.IpeValue
+ Data.Geometry.Ipe.Value: instance GHC.Classes.Eq v => GHC.Classes.Eq (Data.Geometry.Ipe.Value.IpeValue v)
+ Data.Geometry.Ipe.Value: instance GHC.Classes.Ord v => GHC.Classes.Ord (Data.Geometry.Ipe.Value.IpeValue v)
+ Data.Geometry.Ipe.Value: instance GHC.Read.Read v => GHC.Read.Read (Data.Geometry.Ipe.Value.IpeValue v)
+ Data.Geometry.Ipe.Value: instance GHC.Show.Show v => GHC.Show.Show (Data.Geometry.Ipe.Value.IpeValue v)
+ Data.Geometry.Ipe.Writer: instance Data.Geometry.Ipe.Writer.IpeWrite t => Data.Geometry.Ipe.Writer.IpeWrite [t]
+ Data.Geometry.Ipe.Writer: instance Data.Geometry.Ipe.Writer.IpeWriteText r => Data.Geometry.Ipe.Writer.IpeWriteText (Data.Geometry.Ipe.Color.IpeColor r)
+ Data.Geometry.Ipe.Writer: instance Data.Geometry.Ipe.Writer.IpeWriteText v => Data.Geometry.Ipe.Writer.IpeWriteText (Data.Geometry.Ipe.Value.IpeValue v)
+ Data.Geometry.Line.Internal: instance (Data.Geometry.Vector.VectorFamily.Arity d, GHC.Classes.Eq r, GHC.Real.Fractional r) => GHC.Classes.Eq (Data.Geometry.Line.Internal.Line d r)
+ Data.Geometry.Line.Internal: pointAt :: (Num r, Arity d) => r -> Line d r -> Point d r
+ Data.Geometry.Line.Internal: toOffset :: (Eq r, Fractional r, Arity d) => Point d r -> Line d r -> Maybe r
+ Data.Geometry.Line.Internal: toOffset' :: (Eq r, Fractional r, Arity d) => Point d r -> Line d r -> r
+ Data.Geometry.PlanarSubdivision.Basic: dartData :: Lens (PlanarSubdivision s v e f r) (PlanarSubdivision s v e' f r) (Vector (Dart s, e)) (Vector (Dart s, e'))
+ Data.Geometry.PlanarSubdivision.Basic: faceData :: Lens (PlanarSubdivision s v e f r) (PlanarSubdivision s v e f' r) (Vector f) (Vector f')
+ Data.Geometry.PlanarSubdivision.Basic: instance forall k (s :: k) ia a. GHC.Generics.Generic (Data.Geometry.PlanarSubdivision.Basic.Raw s ia a)
+ Data.Geometry.PlanarSubdivision.Basic: instance forall k (s :: k) v e f r. GHC.Generics.Generic (Data.Geometry.PlanarSubdivision.Basic.PlanarSubdivision s v e f r)
+ Data.Geometry.PlanarSubdivision.Basic: instance forall k (s :: k). Data.Aeson.Types.FromJSON.FromJSON (Data.Geometry.PlanarSubdivision.Basic.ComponentId s)
+ Data.Geometry.PlanarSubdivision.Basic: instance forall k (s :: k). Data.Aeson.Types.ToJSON.ToJSON (Data.Geometry.PlanarSubdivision.Basic.ComponentId s)
+ Data.Geometry.PlanarSubdivision.Basic: instance forall k ia a (s :: k). (Data.Aeson.Types.FromJSON.FromJSON ia, Data.Aeson.Types.FromJSON.FromJSON a) => Data.Aeson.Types.FromJSON.FromJSON (Data.Geometry.PlanarSubdivision.Basic.Raw s ia a)
+ Data.Geometry.PlanarSubdivision.Basic: instance forall k ia a (s :: k). (Data.Aeson.Types.ToJSON.ToJSON ia, Data.Aeson.Types.ToJSON.ToJSON a) => Data.Aeson.Types.ToJSON.ToJSON (Data.Geometry.PlanarSubdivision.Basic.Raw s ia a)
+ Data.Geometry.PlanarSubdivision.Basic: vertexData :: Lens (PlanarSubdivision s v e f r) (PlanarSubdivision s v' e f r) (Vector v) (Vector v')
+ Data.Geometry.PlanarSubdivision.Draw: drawColoredPlanarSubdivision :: IpeOut (PlanarSubdivision s v e (Maybe (IpeColor r)) r) Group r
+ Data.Geometry.PlanarSubdivision.Draw: drawPlanarSubdivision' :: forall s v e f r. IpeOut (PlanarSubdivision s v e f r) Group r
+ Data.Geometry.PlanarSubdivision.Draw: drawPlanarSubdivisionWith :: (ToObject vi, ToObject ei, ToObject fi) => MIO (VertexId' s, VertexData r v) vi r -> MIO (Dart s, LineSegment 2 v r :+ e) ei r -> MIO (FaceId' s, SomePolygon v r :+ f) fi r -> IpeOut (PlanarSubdivision s v e f r) Group r
+ Data.Geometry.PlanarSubdivision.Draw: type MIO g i r = g -> Maybe (IpeObject' i r)
+ Data.Geometry.Point: instance (GHC.Read.Read r, Data.Geometry.Vector.VectorFamily.Arity d) => GHC.Read.Read (Data.Geometry.Point.Point d r)
+ Data.Geometry.Point: readPt :: forall d r. (Arity d, Read r) => ReadP (Point d r)
+ Data.Geometry.Properties: type family Union g h :: *
+ Data.Geometry.SegmentTree.Generic: instance GHC.Base.Monoid Data.Geometry.SegmentTree.Generic.Count
+ Data.Geometry.Slab: instance (GHC.Real.Fractional r, GHC.Classes.Ord r, Data.Geometry.Slab.HasBoundingLines o) => Data.Geometry.Properties.IsIntersectableWith (Data.Geometry.SubLine.SubLine 2 a r r) (Data.Geometry.Slab.Slab o a r)
+ Data.Geometry.SubLine: _unBounded :: Prism' (SubLine d p (UnBounded r) r) (SubLine d p r r)
+ Data.Geometry.SubLine: dropExtra :: SubLine d p s r -> SubLine d () s r
+ Data.Geometry.SubLine: fromUnbounded :: SubLine d p (UnBounded r) r -> Maybe (SubLine d p r r)
+ Data.Geometry.SubLine: getEndPointsUnBounded :: (Num r, Arity d) => SubLine d p (UnBounded r) r -> Interval p (UnBounded (Point d r))
+ Data.Geometry.SubLine: instance (GHC.Classes.Eq r, GHC.Classes.Eq s, GHC.Real.Fractional r, GHC.Classes.Eq p, Data.Geometry.Vector.VectorFamily.Arity d) => GHC.Classes.Eq (Data.Geometry.SubLine.SubLine d p s r)
+ Data.Geometry.SubLine: instance (GHC.Classes.Ord r, GHC.Real.Fractional r) => Data.Geometry.Properties.IsIntersectableWith (Data.Geometry.SubLine.SubLine 2 p (Data.UnBounded.UnBounded r) r) (Data.Geometry.SubLine.SubLine 2 p (Data.UnBounded.UnBounded r) r)
+ Data.Geometry.SubLine: instance (GHC.Classes.Ord r, GHC.Real.Fractional r) => Data.Geometry.Properties.IsIntersectableWith (Data.Geometry.SubLine.SubLine 2 p r r) (Data.Geometry.SubLine.SubLine 2 p r r)
+ Data.Geometry.SubLine: instance (GHC.Show.Show r, GHC.Show.Show s, GHC.Show.Show p, Data.Geometry.Vector.VectorFamily.Arity d) => GHC.Show.Show (Data.Geometry.SubLine.SubLine d p s r)
+ Data.Geometry.SubLine: instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Foldable.Foldable (Data.Geometry.SubLine.SubLine d p s)
+ Data.Geometry.SubLine: instance Data.Geometry.Vector.VectorFamily.Arity d => Data.Traversable.Traversable (Data.Geometry.SubLine.SubLine d p s)
+ Data.Geometry.SubLine: instance Data.Geometry.Vector.VectorFamily.Arity d => GHC.Base.Functor (Data.Geometry.SubLine.SubLine d p s)
+ Data.Geometry.SubLine: onSubLine2UB :: (Ord r, Fractional r) => Point 2 r -> SubLine 2 p (UnBounded r) r -> Bool
+ Data.Geometry.SubLine: onSubLineUB :: (Ord r, Fractional r) => Point 2 r -> SubLine 2 p (UnBounded r) r -> Bool
+ Data.Geometry.SubLine: testz :: SubLine 2 () Rational Rational
+ Data.Geometry.SubLine: toUnbounded :: SubLine d p r r -> SubLine d p (UnBounded r) r
+ Data.Geometry.Transformation: class Invertible n r
+ Data.Geometry.Transformation: instance GHC.Real.Fractional r => Data.Geometry.Transformation.Invertible 2 r
+ Data.Geometry.Transformation: instance GHC.Real.Fractional r => Data.Geometry.Transformation.Invertible 3 r
+ Data.Geometry.Transformation: instance GHC.Real.Fractional r => Data.Geometry.Transformation.Invertible 4 r
+ Data.Geometry.Transformation: inverse' :: Invertible n r => Matrix n n r -> Matrix n n r
+ Data.Geometry.Transformation: inverseOf :: (Fractional r, Invertible (d + 1) r) => Transformation d r -> Transformation d r
+ Data.Geometry.Transformation: rotateTo :: Num r => Vector 3 (Vector 3 r) -> Transformation 3 r
+ Data.Geometry.Triangle: fromBarricentric :: (Arity d, Num r) => Vector 3 r -> Triangle d p r -> Point d r
+ Data.Geometry.Triangle: inTriangle :: (Ord r, Fractional r) => Point 2 r -> Triangle 2 p r -> PointLocationResult
+ Data.Geometry.Triangle: instance (Data.Geometry.Vector.VectorFamily.Arity d, GHC.Classes.Eq r, GHC.Classes.Eq p) => GHC.Classes.Eq (Data.Geometry.Triangle.Triangle d p r)
+ Data.Geometry.Triangle: instance (Data.Geometry.Vector.VectorFamily.Arity d, GHC.Read.Read r, GHC.Read.Read p) => GHC.Read.Read (Data.Geometry.Triangle.Triangle d p r)
+ Data.Geometry.Triangle: instance (GHC.Real.Fractional r, GHC.Classes.Ord r) => Data.Geometry.Properties.IsIntersectableWith (Data.Geometry.Line.Internal.Line 2 r) (Data.Geometry.Triangle.Triangle 2 p r)
+ Data.Geometry.Triangle: instance (GHC.Real.Fractional r, GHC.Classes.Ord r) => Data.Geometry.Properties.IsIntersectableWith (Data.Geometry.Line.Internal.Line 3 r) (Data.Geometry.Triangle.Triangle 3 p r)
+ Data.Geometry.Triangle: instance GHC.Num.Num r => Data.Geometry.HyperPlane.HasSupportingPlane (Data.Geometry.Triangle.Triangle 3 p r)
+ Data.Geometry.Triangle: isDegenerateTriangle :: (Num r, Eq r) => Triangle 2 p r -> Bool
+ Data.Geometry.Triangle: onTriangle :: (Ord r, Fractional r) => Point 2 r -> Triangle 2 p r -> Bool
+ Data.Geometry.Triangle: sideSegments :: Triangle d p r -> [LineSegment d p r]
+ Data.Geometry.Triangle: toBarricentric :: Fractional r => Point 2 r -> Triangle 2 p r -> Vector 3 r
+ Data.Geometry.Triangle: triangle' :: Point d r -> Point d r -> Point d r -> Triangle d () r
+ Data.Geometry.Vector: infixl 6 .-^
+ Data.Geometry.Vector: xComponent :: (1 <= d, Arity d) => Lens' (Vector d r) r
+ Data.Geometry.Vector: yComponent :: (2 <= d, Arity d) => Lens' (Vector d r) r
+ Data.Geometry.Vector: zComponent :: (3 <= d, Arity d) => Lens' (Vector d r) r
+ Data.Geometry.Vector.VectorFamily: instance (GHC.Read.Read r, Data.Geometry.Vector.VectorFamily.Arity d) => GHC.Read.Read (Data.Geometry.Vector.VectorFamily.Vector d r)
+ Data.Geometry.Vector.VectorFamily: readVec :: forall d r. (Arity d, Read r) => ReadP (Vector d r)
+ Data.Geometry.Vector.VectorFamilyPeano: type family VectorFamilyF (d :: PeanoNum) :: * -> *
+ Data.LSeq: (<|) :: a -> LSeq n a -> LSeq (1 + n) a
+ Data.LSeq: (><) :: LSeq n a -> LSeq m a -> LSeq (n + m) a
+ Data.LSeq: (|>) :: LSeq n a -> a -> LSeq (1 + n) a
+ Data.LSeq: [:<] :: a -> LSeq n a -> ViewL (1 + n) a
+ Data.LSeq: [:>] :: LSeq n a -> a -> ViewR (1 + n) a
+ Data.LSeq: adjust :: (a -> a) -> Int -> LSeq n a -> LSeq n a
+ Data.LSeq: append :: LSeq n a -> LSeq m a -> LSeq (n + m) a
+ Data.LSeq: data LSeq (n :: Nat) a
+ Data.LSeq: data ViewL n a
+ Data.LSeq: data ViewR n a
+ Data.LSeq: drop :: Int -> LSeq n a -> LSeq 0 a
+ Data.LSeq: empty :: LSeq 0 a
+ Data.LSeq: eval :: forall proxy n m a. KnownNat n => proxy n -> LSeq m a -> Maybe (LSeq n a)
+ Data.LSeq: forceLSeq :: KnownNat n => proxy n -> LSeq m a -> LSeq n a
+ Data.LSeq: fromList :: Foldable f => f a -> LSeq 0 a
+ Data.LSeq: fromNonEmpty :: NonEmpty a -> LSeq 1 a
+ Data.LSeq: fromSeq :: Seq a -> LSeq 0 a
+ Data.LSeq: head :: LSeq (1 + n) a -> a
+ Data.LSeq: index :: LSeq n a -> Int -> a
+ Data.LSeq: infix 5 ><
+ Data.LSeq: infixl 5 :|>
+ Data.LSeq: infixr 5 :<<
+ Data.LSeq: instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Data.LSeq.LSeq n a)
+ Data.LSeq: instance Control.Lens.At.Ixed (Data.LSeq.LSeq n a)
+ Data.LSeq: instance Data.Foldable.Foldable (Data.LSeq.LSeq n)
+ Data.LSeq: instance Data.Foldable.Foldable (Data.LSeq.ViewL n)
+ Data.LSeq: instance Data.Foldable.Foldable (Data.LSeq.ViewR n)
+ Data.LSeq: instance Data.Traversable.Traversable (Data.LSeq.LSeq n)
+ Data.LSeq: instance Data.Traversable.Traversable (Data.LSeq.ViewL n)
+ Data.LSeq: instance Data.Traversable.Traversable (Data.LSeq.ViewR n)
+ Data.LSeq: instance GHC.Base.Functor (Data.LSeq.LSeq n)
+ Data.LSeq: instance GHC.Base.Functor (Data.LSeq.ViewL n)
+ Data.LSeq: instance GHC.Base.Functor (Data.LSeq.ViewR n)
+ Data.LSeq: instance GHC.Base.Monoid (Data.LSeq.LSeq 0 a)
+ Data.LSeq: instance GHC.Base.Semigroup (Data.LSeq.LSeq n a)
+ Data.LSeq: instance GHC.Base.Semigroup (Data.LSeq.ViewL n a)
+ Data.LSeq: instance GHC.Base.Semigroup (Data.LSeq.ViewR n a)
+ Data.LSeq: instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.LSeq.LSeq n a)
+ Data.LSeq: instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.LSeq.ViewL n a)
+ Data.LSeq: instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.LSeq.ViewR n a)
+ Data.LSeq: instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.LSeq.LSeq n a)
+ Data.LSeq: instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.LSeq.ViewL n a)
+ Data.LSeq: instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.LSeq.ViewR n a)
+ Data.LSeq: instance GHC.Generics.Generic (Data.LSeq.LSeq n a)
+ Data.LSeq: instance GHC.Read.Read a => GHC.Read.Read (Data.LSeq.LSeq n a)
+ Data.LSeq: instance GHC.Show.Show a => GHC.Show.Show (Data.LSeq.LSeq n a)
+ Data.LSeq: instance GHC.Show.Show a => GHC.Show.Show (Data.LSeq.ViewL n a)
+ Data.LSeq: instance GHC.Show.Show a => GHC.Show.Show (Data.LSeq.ViewR n a)
+ Data.LSeq: last :: LSeq (1 + n) a -> a
+ Data.LSeq: mapWithIndex :: (Int -> a -> b) -> LSeq n a -> LSeq n b
+ Data.LSeq: partition :: (a -> Bool) -> LSeq n a -> (LSeq 0 a, LSeq 0 a)
+ Data.LSeq: promise :: LSeq m a -> LSeq n a
+ Data.LSeq: take :: Int -> LSeq n a -> LSeq 0 a
+ Data.LSeq: toNonEmpty :: LSeq (1 + n) a -> NonEmpty a
+ Data.LSeq: toSeq :: LSeq n a -> Seq a
+ Data.LSeq: unstableSort :: Ord a => LSeq n a -> LSeq n a
+ Data.LSeq: unstableSortBy :: (a -> a -> Ordering) -> LSeq n a -> LSeq n a
+ Data.LSeq: viewl :: LSeq (1 + n) a -> ViewL (1 + n) a
+ Data.LSeq: viewr :: LSeq (1 + n) a -> ViewR (1 + n) a
+ Data.Permutation: instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Data.Permutation.Permutation a)
+ Data.Permutation: instance GHC.Generics.Generic (Data.Permutation.Permutation a)
+ Data.PlanarGraph: boundaryDart :: FaceId s w -> PlanarGraph s w v e f -> Dart s
+ Data.PlanarGraph: instance Control.DeepSeq.NFData Data.PlanarGraph.Direction
+ Data.PlanarGraph: instance GHC.Generics.Generic Data.PlanarGraph.Direction
+ Data.PlanarGraph: instance forall k (s :: k) (w :: Data.PlanarGraph.World) v e f. GHC.Generics.Generic (Data.PlanarGraph.PlanarGraph s w v e f)
+ Data.PlanarGraph: instance forall k (s :: k) (w :: Data.PlanarGraph.World). Control.DeepSeq.NFData (Data.PlanarGraph.VertexId s w)
+ Data.PlanarGraph: instance forall k (s :: k) (w :: Data.PlanarGraph.World). GHC.Enum.Enum (Data.PlanarGraph.FaceId s w)
+ Data.PlanarGraph: instance forall k (s :: k) (w :: Data.PlanarGraph.World). GHC.Generics.Generic (Data.PlanarGraph.VertexId s w)
+ Data.PlanarGraph: instance forall k (s :: k). Control.DeepSeq.NFData (Data.PlanarGraph.Arc s)
+ Data.PlanarGraph: instance forall k (s :: k). Control.DeepSeq.NFData (Data.PlanarGraph.Dart s)
+ Data.PlanarGraph: instance forall k (s :: k). GHC.Generics.Generic (Data.PlanarGraph.Arc s)
+ Data.PlanarGraph: instance forall k (s :: k). GHC.Generics.Generic (Data.PlanarGraph.Dart s)
+ Data.PlanarGraph: traverseDarts :: Applicative m => (Dart s -> e -> m e') -> PlanarGraph s w v e f -> m (PlanarGraph s w v e' f)
+ Data.PlanarGraph: traverseFaces :: Applicative m => (FaceId s w -> f -> m f') -> PlanarGraph s w v e f -> m (PlanarGraph s w v e f')
+ Data.PlanarGraph: traverseVertices :: Applicative m => (VertexId s w -> v -> m v') -> PlanarGraph s w v e f -> m (PlanarGraph s w v' e f)
+ Data.PlaneGraph: instance GHC.Generics.Generic (Data.PlaneGraph.VertexData r v)
+ Data.PlaneGraph: instance forall k (s :: k) v e f r. GHC.Generics.Generic (Data.PlaneGraph.PlaneGraph s v e f r)
+ Data.PlaneGraph: readPlaneGraph :: (FromJSON v, FromJSON e, FromJSON f, FromJSON r) => proxy s -> ByteString -> Either ParseException (PlaneGraph s v e f r)
+ Data.PlaneGraph: traverseDarts :: Applicative m => (Dart s -> e -> m e') -> PlaneGraph s v e f r -> m (PlaneGraph s v e' f r)
+ Data.PlaneGraph: traverseFaces :: Applicative m => (FaceId' s -> f -> m f') -> PlaneGraph s v e f r -> m (PlaneGraph s v e f' r)
+ Data.PlaneGraph: traverseVertices :: Applicative m => (VertexId' s -> v -> m v') -> PlaneGraph s v e f r -> m (PlaneGraph s v' e f r)
+ Data.PlaneGraph: writePlaneGraph :: (ToJSON v, ToJSON e, ToJSON f, ToJSON r) => PlaneGraph s v e f r -> ByteString
+ Data.Tree.Util: Zipper :: Tree a -> [([Tree a], a, [Tree a])] -> Zipper a
+ Data.Tree.Util: [ancestors] :: Zipper a -> [([Tree a], a, [Tree a])]
+ Data.Tree.Util: [focus] :: Zipper a -> Tree a
+ Data.Tree.Util: allChildren :: Zipper a -> [Zipper a]
+ Data.Tree.Util: allTrees :: Zipper a -> [Zipper a]
+ Data.Tree.Util: constructTree :: [([Tree a], a, [Tree a])] -> Maybe (Tree a)
+ Data.Tree.Util: data Zipper a
+ Data.Tree.Util: findEvert :: (a -> Bool) -> Tree a -> Maybe (Tree a)
+ Data.Tree.Util: findEvert' :: (Tree a -> Bool) -> Tree a -> Maybe (Tree a)
+ Data.Tree.Util: findNode :: (a -> Bool) -> Tree a -> Maybe [a]
+ Data.Tree.Util: findNodes :: (Tree a -> Bool) -> Tree a -> [[a]]
+ Data.Tree.Util: findPath :: (a -> Bool) -> (a -> Bool) -> Tree a -> Maybe [a]
+ Data.Tree.Util: firstChild :: Zipper a -> Maybe (Zipper a)
+ Data.Tree.Util: instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Tree.Util.Zipper a)
+ Data.Tree.Util: instance GHC.Show.Show a => GHC.Show.Show (Data.Tree.Util.Zipper a)
+ Data.Tree.Util: nextSibling :: Zipper a -> Maybe (Zipper a)
+ Data.Tree.Util: prevSibling :: Zipper a -> Maybe (Zipper a)
+ Data.Tree.Util: root :: Tree a -> Zipper a
+ Data.Tree.Util: unZipperLocal :: Zipper a -> Tree a
+ Data.Tree.Util: up :: Zipper a -> Maybe (Zipper a)
+ Data.UnBounded: instance Data.Functor.Classes.Eq1 Data.UnBounded.Bottom
+ Data.UnBounded: instance Data.Functor.Classes.Eq1 Data.UnBounded.Top
+ Data.UnBounded: instance Data.Functor.Classes.Ord1 Data.UnBounded.Bottom
+ Data.UnBounded: instance Data.Functor.Classes.Ord1 Data.UnBounded.Top
+ Data.Util: instance (Control.DeepSeq.NFData a, Control.DeepSeq.NFData b) => Control.DeepSeq.NFData (Data.Util.SP a b)
+ Data.Util: instance (Control.DeepSeq.NFData a, Control.DeepSeq.NFData b, Control.DeepSeq.NFData c) => Control.DeepSeq.NFData (Data.Util.STR a b c)
+ Data.Util: instance (GHC.Base.Semigroup a, GHC.Base.Semigroup b, GHC.Base.Monoid a, GHC.Base.Monoid b) => GHC.Base.Monoid (Data.Util.SP a b)
+ Data.Util: instance (GHC.Base.Semigroup a, GHC.Base.Semigroup b, GHC.Base.Semigroup c) => GHC.Base.Semigroup (Data.Util.STR a b c)
+ Data.Util: instance (GHC.Base.Semigroup a, GHC.Base.Semigroup b, GHC.Base.Semigroup c, GHC.Base.Monoid a, GHC.Base.Monoid b, GHC.Base.Monoid c) => GHC.Base.Monoid (Data.Util.STR a b c)
+ Data.Util: instance GHC.Generics.Generic (Data.Util.SP a b)
+ Data.Util: instance GHC.Generics.Generic (Data.Util.STR a b c)
+ Data.Util: nonEmptyTails :: [a] -> [[a]]
+ Data.Util: uniquePairs :: [a] -> [Two a]
+ Data.Util: uniqueTriplets :: [a] -> [STR a a a]
+ Data.Yaml.Util: Versioned :: Version -> a -> Versioned a
+ Data.Yaml.Util: data Versioned a
+ Data.Yaml.Util: encodeYamlFile :: ToJSON a => FilePath -> a -> IO ()
+ Data.Yaml.Util: instance Data.Aeson.Types.FromJSON.FromJSON Data.Yaml.Util.V
+ Data.Yaml.Util: instance Data.Aeson.Types.ToJSON.ToJSON a => Data.Aeson.Types.ToJSON.ToJSON (Data.Yaml.Util.Versioned a)
+ Data.Yaml.Util: instance Data.Foldable.Foldable Data.Yaml.Util.Versioned
+ Data.Yaml.Util: instance Data.Traversable.Traversable Data.Yaml.Util.Versioned
+ Data.Yaml.Util: instance GHC.Base.Functor Data.Yaml.Util.Versioned
+ Data.Yaml.Util: instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Yaml.Util.Versioned a)
+ Data.Yaml.Util: instance GHC.Generics.Generic (Data.Yaml.Util.Versioned a)
+ Data.Yaml.Util: instance GHC.Read.Read a => GHC.Read.Read (Data.Yaml.Util.Versioned a)
+ Data.Yaml.Util: instance GHC.Show.Show a => GHC.Show.Show (Data.Yaml.Util.Versioned a)
+ Data.Yaml.Util: parseVersioned :: [(Version -> Bool, Value -> Parser a)] -> Value -> Parser (Versioned a)
+ Data.Yaml.Util: unversioned :: Versioned a -> a
+ Graphics.Camera: Camera :: !Point 3 r -> !Vector 3 r -> !Vector 3 r -> !r -> !r -> !r -> !Vector 2 r -> Camera r
+ Graphics.Camera: cameraNormal :: Floating r => Lens' (Camera r) (Vector 3 r)
+ Graphics.Camera: cameraPosition :: forall r_a4zsw. Lens' (Camera r_a4zsw) (Point 3 r_a4zsw)
+ Graphics.Camera: cameraTransform :: Fractional r => Camera r -> Transformation 3 r
+ Graphics.Camera: data Camera r
+ Graphics.Camera: farDist :: forall r_a4zsw. Lens' (Camera r_a4zsw) r_a4zsw
+ Graphics.Camera: flipAxes :: Num r => Transformation 3 r
+ Graphics.Camera: instance GHC.Classes.Eq r => GHC.Classes.Eq (Graphics.Camera.Camera r)
+ Graphics.Camera: instance GHC.Classes.Ord r => GHC.Classes.Ord (Graphics.Camera.Camera r)
+ Graphics.Camera: instance GHC.Show.Show r => GHC.Show.Show (Graphics.Camera.Camera r)
+ Graphics.Camera: nearDist :: forall r_a4zsw. Lens' (Camera r_a4zsw) r_a4zsw
+ Graphics.Camera: perspectiveProjection :: Fractional r => Camera r -> Transformation 3 r
+ Graphics.Camera: rawCameraNormal :: forall r_a4zsw. Lens' (Camera r_a4zsw) (Vector 3 r_a4zsw)
+ Graphics.Camera: rawViewUp :: forall r_a4zsw. Lens' (Camera r_a4zsw) (Vector 3 r_a4zsw)
+ Graphics.Camera: rotateCoordSystem :: Num r => Camera r -> Transformation 3 r
+ Graphics.Camera: screenDimensions :: forall r_a4zsw. Lens' (Camera r_a4zsw) (Vector 2 r_a4zsw)
+ Graphics.Camera: toViewPort :: Fractional r => Camera r -> Transformation 3 r
+ Graphics.Camera: viewPlaneDepth :: forall r_a4zsw. Lens' (Camera r_a4zsw) r_a4zsw
+ Graphics.Camera: viewUp :: Floating r => Lens' (Camera r) (Vector 3 r)
+ Graphics.Camera: worldToView :: Fractional r => Camera r -> Transformation 3 r
+ Test.QuickCheck.HGeometryInstances: instance (GHC.TypeNats.KnownNat n, Test.QuickCheck.Arbitrary.Arbitrary a) => Test.QuickCheck.Arbitrary.Arbitrary (Data.LSeq.LSeq n a)
+ Test.QuickCheck.HGeometryInstances: instance (Test.QuickCheck.Arbitrary.Arbitrary r, Test.QuickCheck.Arbitrary.Arbitrary p, Test.QuickCheck.Arbitrary.Arbitrary s, Data.Geometry.Vector.VectorFamily.Arity d, GHC.Classes.Ord r, GHC.Classes.Ord s, GHC.Classes.Ord p, GHC.Num.Num r) => Test.QuickCheck.Arbitrary.Arbitrary (Data.Geometry.SubLine.SubLine d p s r)
+ Test.QuickCheck.HGeometryInstances: instance Test.QuickCheck.Arbitrary.Arbitrary Data.PlanarGraph.Direction
+ Test.QuickCheck.HGeometryInstances: instance forall k (s :: k). Test.QuickCheck.Arbitrary.Arbitrary (Data.PlanarGraph.Arc s)
+ Test.QuickCheck.HGeometryInstances: instance forall k (s :: k). Test.QuickCheck.Arbitrary.Arbitrary (Data.PlanarGraph.Dart s)
- Algorithms.Geometry.DelaunayTriangulation.Types: drawTriangulation :: IpeOut (Triangulation p r) (IpeObject r)
+ Algorithms.Geometry.DelaunayTriangulation.Types: drawTriangulation :: IpeOut (Triangulation p r) Group r
- Algorithms.Geometry.DelaunayTriangulation.Types: neighbours :: forall p_a3M9c r_a3M9d. Lens' (Triangulation p_a3M9c r_a3M9d) (Vector (CList VertexID))
+ Algorithms.Geometry.DelaunayTriangulation.Types: neighbours :: forall p_a4x0H r_a4x0I. Lens' (Triangulation p_a4x0H r_a4x0I) (Vector (CList VertexID))
- 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: positions :: forall p_a4x0H r_a4x0I p_a4x5y. Lens (Triangulation p_a4x0H r_a4x0I) (Triangulation p_a4x5y r_a4x0I) (Vector ((:+) (Point 2 r_a4x0I) p_a4x0H)) (Vector ((:+) (Point 2 r_a4x0I) p_a4x5y))
- Algorithms.Geometry.DelaunayTriangulation.Types: vertexIds :: forall p_a3M9c r_a3M9d. Lens' (Triangulation p_a3M9c r_a3M9d) (Map (Point 2 r_a3M9d) VertexID)
+ Algorithms.Geometry.DelaunayTriangulation.Types: vertexIds :: forall p_a4x0H r_a4x0I. Lens' (Triangulation p_a4x0H r_a4x0I) (Map (Point 2 r_a4x0I) VertexID)
- Algorithms.Geometry.EuclideanMST.EuclideanMST: drawTree' :: IpeOut (Tree (Point 2 r :+ p)) (IpeObject r)
+ Algorithms.Geometry.EuclideanMST.EuclideanMST: drawTree' :: IpeOut (Tree (Point 2 r :+ p)) Group r
- Algorithms.Geometry.LineSegmentIntersection.BentleyOttmann: Event :: !(Point 2 r) -> !(EventType (LineSegment 2 p r)) -> Event p r
+ Algorithms.Geometry.LineSegmentIntersection.BentleyOttmann: Event :: !Point 2 r -> !EventType (LineSegment 2 p r) -> Event p r
- Algorithms.Geometry.LineSegmentIntersection.BentleyOttmann: Start :: !(NonEmpty s) -> EventType s
+ Algorithms.Geometry.LineSegmentIntersection.BentleyOttmann: Start :: !NonEmpty s -> EventType s
- Algorithms.Geometry.LineSegmentIntersection.BentleyOttmann: [eventPoint] :: Event p r -> !(Point 2 r)
+ Algorithms.Geometry.LineSegmentIntersection.BentleyOttmann: [eventPoint] :: Event p r -> !Point 2 r
- Algorithms.Geometry.LineSegmentIntersection.BentleyOttmann: [eventType] :: Event p r -> !(EventType (LineSegment 2 p r))
+ Algorithms.Geometry.LineSegmentIntersection.BentleyOttmann: [eventType] :: Event p r -> !EventType (LineSegment 2 p r)
- Algorithms.Geometry.LineSegmentIntersection.Types: IntersectionPoint :: !(Point 2 r) -> !(Associated p r) -> IntersectionPoint p r
+ Algorithms.Geometry.LineSegmentIntersection.Types: IntersectionPoint :: !Point 2 r -> !Associated p r -> IntersectionPoint p r
- Algorithms.Geometry.LineSegmentIntersection.Types: [_associatedSegs] :: IntersectionPoint p r -> !(Associated p r)
+ Algorithms.Geometry.LineSegmentIntersection.Types: [_associatedSegs] :: IntersectionPoint p r -> !Associated p r
- Algorithms.Geometry.LineSegmentIntersection.Types: [_intersectionPoint] :: IntersectionPoint p r -> !(Point 2 r)
+ Algorithms.Geometry.LineSegmentIntersection.Types: [_intersectionPoint] :: IntersectionPoint p r -> !Point 2 r
- 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: associatedSegs :: forall p_a2PdN r_a2PdO p_a2Ptg. Lens (IntersectionPoint p_a2PdN r_a2PdO) (IntersectionPoint p_a2Ptg r_a2PdO) (Associated p_a2PdN r_a2PdO) (Associated p_a2Ptg r_a2PdO)
- Algorithms.Geometry.LineSegmentIntersection.Types: intersectionPoint :: forall p_a2uCP r_a2uCQ. Lens' (IntersectionPoint p_a2uCP r_a2uCQ) (Point 2 r_a2uCQ)
+ Algorithms.Geometry.LineSegmentIntersection.Types: intersectionPoint :: forall p_a2PdN r_a2PdO. Lens' (IntersectionPoint p_a2PdN r_a2PdO) (Point 2 r_a2PdO)
- 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: intersect' :: forall r a. (Ord r, Fractional r) => (Line 2 r :+ a) -> (Line 2 r :+ a) -> Point 2 r :+ (a, a)
- Algorithms.Geometry.PolyLineSimplification.DouglasPeucker: maxDist :: (Ord r, Fractional r, Arity d) => Seq2 (Point d r :+ p) -> LineSegment d p r -> (Int, r)
+ Algorithms.Geometry.PolyLineSimplification.DouglasPeucker: maxDist :: (Ord r, Fractional r, Arity d) => LSeq n (Point d r :+ p) -> LineSegment d p r -> (Int, r)
- Algorithms.Geometry.PolygonTriangulation.MakeMonotone: SS :: !(OrdSeq (LineSegment 2 Int r)) -> !(IntMap Int) -> StatusStruct r
+ Algorithms.Geometry.PolygonTriangulation.MakeMonotone: SS :: !OrdSeq (LineSegment 2 Int r) -> !IntMap Int -> StatusStruct r
- Algorithms.Geometry.PolygonTriangulation.MakeMonotone: [_helper] :: StatusStruct r -> !(IntMap Int)
+ 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: [_statusStruct] :: StatusStruct r -> !OrdSeq (LineSegment 2 Int r)
- Algorithms.Geometry.PolygonTriangulation.MakeMonotone: cmpSweep :: Ord r => Point 2 r :+ e -> Point 2 r :+ e -> Ordering
+ Algorithms.Geometry.PolygonTriangulation.MakeMonotone: cmpSweep :: Ord r => (Point 2 r :+ e) -> (Point 2 r :+ e) -> Ordering
- Algorithms.Geometry.PolygonTriangulation.MakeMonotone: helper :: forall r_a3Q8C. Lens' (StatusStruct r_a3Q8C) (IntMap Int)
+ Algorithms.Geometry.PolygonTriangulation.MakeMonotone: helper :: forall r_a4rEx. Lens' (StatusStruct r_a4rEx) (IntMap Int)
- 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: statusStruct :: forall r_a4rEx r_a4rPD. Lens (StatusStruct r_a4rEx) (StatusStruct r_a4rPD) (OrdSeq (LineSegment 2 Int r_a4rEx)) (OrdSeq (LineSegment 2 Int r_a4rPD))
- Algorithms.Geometry.SmallestEnclosingBall.Naive: disk' :: (Ord r, Fractional r) => Point 2 r :+ p -> Point 2 r :+ p -> Point 2 r :+ p -> Disk () r
+ Algorithms.Geometry.SmallestEnclosingBall.Naive: disk' :: (Ord r, Fractional r) => (Point 2 r :+ p) -> (Point 2 r :+ p) -> (Point 2 r :+ p) -> Disk () r
- Algorithms.Geometry.SmallestEnclosingBall.RandomizedIncrementalConstruction: initial :: Fractional r => Point 2 r :+ p -> Point 2 r :+ p -> DiskResult p r
+ Algorithms.Geometry.SmallestEnclosingBall.RandomizedIncrementalConstruction: initial :: Fractional r => (Point 2 r :+ p) -> (Point 2 r :+ p) -> DiskResult p r
- Algorithms.Geometry.SmallestEnclosingBall.RandomizedIncrementalConstruction: smallestEnclosingDisk' :: (Ord r, Fractional r) => Point 2 r :+ p -> Point 2 r :+ p -> [Point 2 r :+ p] -> DiskResult p r
+ Algorithms.Geometry.SmallestEnclosingBall.RandomizedIncrementalConstruction: smallestEnclosingDisk' :: (Ord r, Fractional r) => (Point 2 r :+ p) -> (Point 2 r :+ p) -> [Point 2 r :+ p] -> DiskResult p r
- Algorithms.Geometry.SmallestEnclosingBall.RandomizedIncrementalConstruction: smallestEnclosingDiskWithPoint :: (Ord r, Fractional r) => Point 2 r :+ p -> NonEmpty (Point 2 r :+ p) -> DiskResult p r
+ Algorithms.Geometry.SmallestEnclosingBall.RandomizedIncrementalConstruction: smallestEnclosingDiskWithPoint :: (Ord r, Fractional r) => (Point 2 r :+ p) -> NonEmpty (Point 2 r :+ p) -> DiskResult p r
- Algorithms.Geometry.SmallestEnclosingBall.RandomizedIncrementalConstruction: smallestEnclosingDiskWithPoints :: (Ord r, Fractional r) => Point 2 r :+ p -> Point 2 r :+ p -> [Point 2 r :+ p] -> DiskResult p r
+ Algorithms.Geometry.SmallestEnclosingBall.RandomizedIncrementalConstruction: smallestEnclosingDiskWithPoints :: (Ord r, Fractional r) => (Point 2 r :+ p) -> (Point 2 r :+ p) -> [Point 2 r :+ p] -> DiskResult p r
- 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: definingPoints :: forall p_a3W34 r_a3W35 p_a3Wgr. Lens (DiskResult p_a3W34 r_a3W35) (DiskResult p_a3Wgr r_a3W35) (TwoOrThree ((:+) (Point 2 r_a3W35) p_a3W34)) (TwoOrThree ((:+) (Point 2 r_a3W35) p_a3Wgr))
- Algorithms.Geometry.SmallestEnclosingBall.Types: enclosingDisk :: forall p_a3KgM r_a3KgN. Lens' (DiskResult p_a3KgM r_a3KgN) (Disk () r_a3KgN)
+ Algorithms.Geometry.SmallestEnclosingBall.Types: enclosingDisk :: forall p_a3W34 r_a3W35. Lens' (DiskResult p_a3W34 r_a3W35) (Disk () r_a3W35)
- Algorithms.Geometry.Sweep: Timed :: (Tagged s t) -> a -> Timed s t 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: [atTime] :: Timed s t a -> Tagged s t -> a
- Algorithms.Geometry.WellSeparatedPairDecomposition.Types: FAC :: !(Seq (Point d r :+ p)) -> !(Seq (Point d r :+ p)) -> !ShortSide -> FindAndCompact d r p
+ Algorithms.Geometry.WellSeparatedPairDecomposition.Types: FAC :: !Seq (Point d r :+ p) -> !Seq (Point d r :+ p) -> !ShortSide -> FindAndCompact d r p
- Algorithms.Geometry.WellSeparatedPairDecomposition.Types: NodeData :: !Int -> !(Box d () r) -> !a -> NodeData d r a
+ Algorithms.Geometry.WellSeparatedPairDecomposition.Types: NodeData :: !Int -> !Box d () r -> !a -> NodeData d r a
- Algorithms.Geometry.WellSeparatedPairDecomposition.Types: [_bBox] :: NodeData d r a -> !(Box d () r)
+ Algorithms.Geometry.WellSeparatedPairDecomposition.Types: [_bBox] :: NodeData d r a -> !Box d () r
- Algorithms.Geometry.WellSeparatedPairDecomposition.Types: [_leftPart] :: FindAndCompact d r p -> !(Seq (Point d r :+ p))
+ Algorithms.Geometry.WellSeparatedPairDecomposition.Types: [_leftPart] :: FindAndCompact d r p -> !Seq (Point d r :+ p)
- Algorithms.Geometry.WellSeparatedPairDecomposition.Types: [_rightPart] :: FindAndCompact d r p -> !(Seq (Point d r :+ p))
+ Algorithms.Geometry.WellSeparatedPairDecomposition.Types: [_rightPart] :: FindAndCompact d r p -> !Seq (Point d r :+ p)
- 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: bBox :: forall d_a2KXt r_a2KXu a_a2KXv d_a2L2n r_a2L2o. Lens (NodeData d_a2KXt r_a2KXu a_a2KXv) (NodeData d_a2L2n r_a2L2o a_a2KXv) (Box d_a2KXt () r_a2KXu) (Box d_a2L2n () r_a2L2o)
- 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: leftPart :: forall d_a2Ley r_a2Lez p_a2LeA. Lens' (FindAndCompact d_a2Ley r_a2Lez p_a2LeA) (Seq ((:+) (Point d_a2Ley r_a2Lez) p_a2LeA))
- 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: nodeData :: forall d_a2KXt r_a2KXu a_a2KXv a_a2L2p. Lens (NodeData d_a2KXt r_a2KXu a_a2KXv) (NodeData d_a2KXt r_a2KXu a_a2L2p) a_a2KXv a_a2L2p
- 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: rightPart :: forall d_a2Ley r_a2Lez p_a2LeA. Lens' (FindAndCompact d_a2Ley r_a2Lez p_a2LeA) (Seq ((:+) (Point d_a2Ley r_a2Lez) p_a2LeA))
- 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: shortSide :: forall d_a2Ley r_a2Lez p_a2LeA. Lens' (FindAndCompact d_a2Ley r_a2Lez p_a2LeA) ShortSide
- Algorithms.Geometry.WellSeparatedPairDecomposition.Types: splitDim :: forall d_a2qoM r_a2qoN a_a2qoO. Lens' (NodeData d_a2qoM r_a2qoN a_a2qoO) Int
+ Algorithms.Geometry.WellSeparatedPairDecomposition.Types: splitDim :: forall d_a2KXt r_a2KXu a_a2KXv. Lens' (NodeData d_a2KXt r_a2KXu a_a2KXv) Int
- Algorithms.Geometry.WellSeparatedPairDecomposition.Types: type PointSeq d p r = ViewL1 (Point d r :+ p)
+ Algorithms.Geometry.WellSeparatedPairDecomposition.Types: type PointSeq d p r = LSeq 1 (Point d r :+ p)
- Algorithms.Geometry.WellSeparatedPairDecomposition.WSPD: dropIdx :: core :+ (t :+ extra) -> core :+ extra
+ Algorithms.Geometry.WellSeparatedPairDecomposition.WSPD: dropIdx :: (core :+ (t :+ extra)) -> core :+ extra
- Algorithms.Geometry.WellSeparatedPairDecomposition.WSPD: fromSeqUnsafe :: Seq a -> ViewL1 a
+ Algorithms.Geometry.WellSeparatedPairDecomposition.WSPD: fromSeqUnsafe :: () => Seq a -> LSeq n a
- Algorithms.Geometry.WellSeparatedPairDecomposition.WSPD: hasLevel :: c :+ (Idx :+ p) -> RST s Bool
+ Algorithms.Geometry.WellSeparatedPairDecomposition.WSPD: hasLevel :: (c :+ (Idx :+ p)) -> RST s Bool
- Data.BalBST: BalBST :: !(TreeNavigator k a) -> !(Tree k a) -> BalBST k a
+ Data.BalBST: BalBST :: !TreeNavigator k a -> !Tree k a -> BalBST k 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.BalBST: Node :: !Color -> !Height -> (Tree k a) -> !k -> (Tree k a) -> Tree k a
+ Data.BalBST: Node :: !Color -> !Height -> Tree k a -> !k -> Tree k a -> Tree k a
- Data.BalBST: [nav] :: BalBST k a -> !(TreeNavigator k a)
+ Data.BalBST: [nav] :: BalBST k a -> !TreeNavigator k a
- Data.BalBST: [toTree] :: BalBST k a -> !(Tree k a)
+ Data.BalBST: [toTree] :: BalBST k a -> !Tree k a
- Data.BinaryTree: Internal :: (BinaryTree a) -> !a -> (BinaryTree a) -> BinaryTree a
+ Data.BinaryTree: Internal :: BinaryTree a -> !a -> BinaryTree a -> BinaryTree a
- Data.BinaryTree: Node :: (BinLeafTree v a) -> !v -> (BinLeafTree v a) -> BinLeafTree v a
+ Data.BinaryTree: Node :: BinLeafTree v a -> !v -> BinLeafTree v a -> BinLeafTree v a
- Data.BinaryTree.Zipper: L :: (Ctx a) -> a -> (BinaryTree a) -> Ctx a
+ Data.BinaryTree.Zipper: L :: Ctx a -> a -> BinaryTree a -> Ctx a
- Data.BinaryTree.Zipper: Loc :: (BinaryTree a) -> (Ctx a) -> BinaryTreeZipper a
+ Data.BinaryTree.Zipper: Loc :: BinaryTree a -> Ctx a -> BinaryTreeZipper a
- Data.BinaryTree.Zipper: R :: (BinaryTree a) -> a -> (Ctx a) -> Ctx a
+ Data.BinaryTree.Zipper: R :: BinaryTree a -> a -> Ctx a -> Ctx a
- Data.Ext: data core (:+) extra
+ Data.Ext: data core :+ extra
- Data.Geometry: E :: forall x (f :: * -> *). Functor f => x -> f x -> t x -> f t x -> E
+ Data.Geometry: E :: (forall x. () => Lens' (t x) x) -> E
- Data.Geometry: PolyLine :: Seq2 (Point d r :+ p) -> PolyLine d p r
+ Data.Geometry: PolyLine :: LSeq 2 (Point d r :+ p) -> PolyLine d p r
- Data.Geometry: [_points] :: PolyLine d p r -> Seq2 (Point d r :+ p)
+ Data.Geometry: [_points] :: PolyLine d p r -> LSeq 2 (Point d r :+ p)
- Data.Geometry: [el] :: E -> forall x (f :: * -> *). Functor f => x -> f x -> t x -> f t x
+ Data.Geometry: [el] :: E -> forall x. () => Lens' (t x) x
- Data.Geometry: class Functor f => Additive (f :: * -> *)
+ Data.Geometry: class Functor f => Additive (f :: Type -> Type)
- Data.Geometry: class Additive Diff p => Affine (p :: * -> *) where {
+ Data.Geometry: class Additive Diff p => Affine (p :: Type -> Type) where {
- Data.Geometry: cmpExtreme :: (Num r, Ord r) => Vector 2 r -> Point 2 r :+ p -> Point 2 r :+ q -> Ordering
+ Data.Geometry: cmpExtreme :: (Num r, Ord r) => Vector 2 r -> (Point 2 r :+ p) -> (Point 2 r :+ q) -> Ordering
- Data.Geometry: distanceA :: (Floating a, Foldable Diff p, Affine p) => p a -> p a -> a
+ Data.Geometry: distanceA :: (Floating a, Foldable (Diff p), Affine p) => p a -> p a -> a
- Data.Geometry: fromPoints' :: (Monoid p) => [Point d r] -> PolyLine d p r
+ Data.Geometry: fromPoints' :: Monoid p => [Point d r] -> PolyLine d p r
- Data.Geometry: imap :: (Vector v a, Vector v b) => Int -> a -> b -> v a -> v b
+ Data.Geometry: imap :: (Vector v a, Vector v b) => (Int -> a -> b) -> v a -> v b
- Data.Geometry: liftI2 :: Additive f => a -> b -> c -> f a -> f b -> f c
+ 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: liftU2 :: Additive f => (a -> a -> a) -> f a -> f a -> f a
- Data.Geometry: newtype E (t :: * -> *)
+ Data.Geometry: newtype E (t :: Type -> Type)
- Data.Geometry: outer :: (Functor f, Functor g, Num a) => f a -> g a -> f g a
+ Data.Geometry: outer :: (Functor f, Functor g, Num a) => f a -> g a -> f (g a)
- 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: points :: forall d_a2J4J p_a2J4K r_a2J4L d_a2J5r p_a2J5s r_a2J5t. Iso (PolyLine d_a2J4J p_a2J4K r_a2J4L) (PolyLine d_a2J5r p_a2J5s r_a2J5t) (LSeq 2 ((:+) (Point d_a2J4J r_a2J4L) p_a2J4K)) (LSeq 2 ((:+) (Point d_a2J5r r_a2J5t) p_a2J5s))
- Data.Geometry: qdA :: (Affine p, Foldable Diff p, Num a) => p a -> p a -> a
+ Data.Geometry: qdA :: (Affine p, Foldable (Diff p), Num a) => p a -> p a -> a
- Data.Geometry: scaled :: (Traversable t, Num a) => t a -> t t a
+ Data.Geometry: scaled :: (Traversable t, Num a) => t a -> t (t a)
- Data.Geometry: sumV :: (Foldable f, Additive v, Num a) => f v a -> v a
+ Data.Geometry: sumV :: (Foldable f, Additive v, Num a) => f (v a) -> v a
- Data.Geometry: type family Diff (p :: * -> *) :: * -> *;
+ Data.Geometry: type family Diff (p :: Type -> Type) :: Type -> Type;
- Data.Geometry: unit :: (Additive t, Num a) => ASetter' t a a -> t a
+ Data.Geometry: unit :: (Additive t, Num a) => ASetter' (t a) a -> t a
- Data.Geometry.Ball: Ball :: !(Point d r :+ p) -> !r -> Ball d p r
+ Data.Geometry.Ball: Ball :: !Point d r :+ p -> !r -> Ball d p r
- Data.Geometry.Ball: [_center] :: Ball d p r -> !(Point d r :+ p)
+ Data.Geometry.Ball: [_center] :: Ball d p r -> !Point d r :+ p
- 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: center :: forall d_a333Z p_a3340 r_a3341 d_a336H p_a336I. Lens (Ball d_a333Z p_a3340 r_a3341) (Ball d_a336H p_a336I r_a3341) ((:+) (Point d_a333Z r_a3341) p_a3340) ((:+) (Point d_a336H r_a3341) p_a336I)
- Data.Geometry.Ball: from3Points :: Fractional r => Point 2 r :+ p -> Point 2 r :+ q -> Point 2 r :+ s -> Circle () r
+ Data.Geometry.Ball: from3Points :: Fractional r => (Point 2 r :+ p) -> (Point 2 r :+ q) -> (Point 2 r :+ s) -> Circle () r
- Data.Geometry.Ball: fromCenterAndPoint :: (Arity d, Num r) => Point d r :+ p -> Point d r :+ p -> Ball d p r
+ Data.Geometry.Ball: fromCenterAndPoint :: (Arity d, Num r) => (Point d r :+ p) -> (Point d r :+ p) -> Ball d p r
- Data.Geometry.Ball: squaredRadius :: forall d_a2FhO p_a2FhP r_a2FhQ. Lens' (Ball d_a2FhO p_a2FhP r_a2FhQ) r_a2FhQ
+ Data.Geometry.Ball: squaredRadius :: forall d_a333Z p_a3340 r_a3341. Lens' (Ball d_a333Z p_a3340 r_a3341) r_a3341
- Data.Geometry.Box.Internal: Box :: !(CWMin (Point d r) :+ p) -> !(CWMax (Point d r) :+ p) -> Box d p r
+ Data.Geometry.Box.Internal: Box :: !CWMin (Point d r) :+ p -> !CWMax (Point d r) :+ p -> Box d p r
- Data.Geometry.Box.Internal: [_maxP] :: Box d p r -> !(CWMax (Point d r) :+ p)
+ Data.Geometry.Box.Internal: [_maxP] :: Box d p r -> !CWMax (Point d r) :+ p
- Data.Geometry.Box.Internal: [_minP] :: Box d p r -> !(CWMin (Point d r) :+ p)
+ Data.Geometry.Box.Internal: [_minP] :: Box d p r -> !CWMin (Point d r) :+ p
- Data.Geometry.Box.Internal: box :: Point d r :+ p -> Point d r :+ p -> Box d p r
+ Data.Geometry.Box.Internal: box :: (Point d r :+ p) -> (Point d r :+ p) -> Box d p r
- 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: cwMax :: forall a_a2oCa a_a2oTa. Iso (CWMax a_a2oCa) (CWMax a_a2oTa) a_a2oCa a_a2oTa
- 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: cwMin :: forall a_a2ony a_a2oC4. Iso (CWMin a_a2ony) (CWMin a_a2oC4) a_a2ony a_a2oC4
- 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: maxP :: forall d_a2oTh p_a2oTi r_a2oTj. Lens' (Box d_a2oTh p_a2oTi r_a2oTj) ((:+) (CWMax (Point d_a2oTh r_a2oTj)) p_a2oTi)
- 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: minP :: forall d_a2oTh p_a2oTi r_a2oTj. Lens' (Box d_a2oTh p_a2oTi r_a2oTj) ((:+) (CWMin (Point d_a2oTh r_a2oTj)) p_a2oTi)
- Data.Geometry.HalfLine: fromSubLine :: (Num r, Arity d) => SubLine d p (UnBounded r) -> Maybe (HalfLine d r)
+ Data.Geometry.HalfLine: fromSubLine :: (Num r, Arity d) => SubLine d p (UnBounded r) r -> Maybe (HalfLine d r)
- Data.Geometry.HalfLine: halfLineDirection :: forall d_a2JLv r_a2JLw. Lens' (HalfLine d_a2JLv r_a2JLw) (Vector d_a2JLv r_a2JLw)
+ Data.Geometry.HalfLine: halfLineDirection :: forall d_a3bNu r_a3bNv. Lens' (HalfLine d_a3bNu r_a3bNv) (Vector d_a3bNu r_a3bNv)
- Data.Geometry.HalfLine: halfLineToSubLine :: (Arity d, Num r) => HalfLine d r -> SubLine d () (UnBounded r)
+ Data.Geometry.HalfLine: halfLineToSubLine :: (Arity d, Num r) => HalfLine d r -> SubLine d () (UnBounded r) r
- Data.Geometry.HalfLine: startPoint :: forall d_a2JLv r_a2JLw. Lens' (HalfLine d_a2JLv r_a2JLw) (Point d_a2JLv r_a2JLw)
+ Data.Geometry.HalfLine: startPoint :: forall d_a3bNu r_a3bNv. Lens' (HalfLine d_a3bNu r_a3bNv) (Point d_a3bNu r_a3bNv)
- 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: unL :: forall r_a2bL1 r_a2bQf. Iso (L r_a2bL1) (L r_a2bQf) (EndPoint r_a2bL1) (EndPoint r_a2bQf)
- 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.Interval.Util: unR :: forall r_a2bQl r_a2c2y. Iso (R r_a2bQl) (R r_a2c2y) (EndPoint r_a2bQl) (EndPoint r_a2c2y)
- Data.Geometry.IntervalTree: NodeData :: !r -> !(Map (L r) [i]) -> !(Map (R r) [i]) -> NodeData i r
+ Data.Geometry.IntervalTree: NodeData :: !r -> !Map (L r) [i] -> !Map (R r) [i] -> NodeData i r
- Data.Geometry.IntervalTree: [_intervalsLeft] :: NodeData i r -> !(Map (L r) [i])
+ Data.Geometry.IntervalTree: [_intervalsLeft] :: NodeData i r -> !Map (L r) [i]
- Data.Geometry.IntervalTree: [_intervalsRight] :: NodeData i r -> !(Map (R r) [i])
+ Data.Geometry.IntervalTree: [_intervalsRight] :: NodeData i r -> !Map (R r) [i]
- Data.Geometry.IntervalTree: intervalsLeft :: forall i_a1PKp r_a1PKq. Lens' (NodeData i_a1PKp r_a1PKq) (Map (L r_a1PKq) [i_a1PKp])
+ Data.Geometry.IntervalTree: intervalsLeft :: forall i_a2etc r_a2etd. Lens' (NodeData i_a2etc r_a2etd) (Map (L r_a2etd) [i_a2etc])
- Data.Geometry.IntervalTree: intervalsRight :: forall i_a1PKp r_a1PKq. Lens' (NodeData i_a1PKp r_a1PKq) (Map (R r_a1PKq) [i_a1PKp])
+ Data.Geometry.IntervalTree: intervalsRight :: forall i_a2etc r_a2etd. Lens' (NodeData i_a2etc r_a2etd) (Map (R r_a2etd) [i_a2etc])
- Data.Geometry.IntervalTree: splitPoint :: forall i_a1PKp r_a1PKq. Lens' (NodeData i_a1PKp r_a1PKq) r_a1PKq
+ Data.Geometry.IntervalTree: splitPoint :: forall i_a2etc r_a2etd. Lens' (NodeData i_a2etc r_a2etd) r_a2etd
- 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.IntervalTree: unIntervalTree :: forall i_a2eD8 r_a2eD9 i_a2eKL r_a2eKM. Iso (IntervalTree i_a2eD8 r_a2eD9) (IntervalTree i_a2eKL r_a2eKM) (BinaryTree (NodeData i_a2eD8 r_a2eD9)) (BinaryTree (NodeData i_a2eKL r_a2eKM))
- Data.Geometry.Ipe.Attributes: IpePen :: (IpeValue r) -> IpePen r
+ Data.Geometry.Ipe.Attributes: IpePen :: IpeValue r -> IpePen r
- Data.Geometry.Ipe.Attributes: IpeSize :: (IpeValue r) -> IpeSize r
+ Data.Geometry.Ipe.Attributes: IpeSize :: IpeValue r -> IpeSize r
- Data.Geometry.Ipe.Attributes: arrowName :: forall r_aKOp. Lens' (IpeArrow r_aKOp) Text
+ Data.Geometry.Ipe.Attributes: arrowName :: forall r_aY5G. Lens' (IpeArrow r_aY5G) Text
- 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: arrowSize :: forall r_aY5G r_aZfg. Lens (IpeArrow r_aY5G) (IpeArrow r_aZfg) (IpeSize r_aY5G) (IpeSize r_aZfg)
- Data.Geometry.Ipe.Attributes: attrLens :: (at ∈ ats) => proxy at -> Lens' (Attributes f ats) (Maybe (Apply f at))
+ Data.Geometry.Ipe.Attributes: attrLens :: at ∈ ats => proxy at -> Lens' (Attributes f ats) (Maybe (Apply f at))
- 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: getAttr :: forall f_aWEE label_aWEF f_aY50 label_aY51. Iso (Attr f_aWEE label_aWEF) (Attr f_aY50 label_aY51) (Maybe (Apply f_aWEE label_aWEF)) (Maybe (Apply f_aY50 label_aY51))
- Data.Geometry.Ipe.Attributes: lookupAttr :: (at ∈ ats) => proxy at -> Attributes f ats -> Maybe (Apply f at)
+ Data.Geometry.Ipe.Attributes: lookupAttr :: at ∈ ats => proxy at -> Attributes f ats -> Maybe (Apply f at)
- Data.Geometry.Ipe.Attributes: setAttr :: forall proxy at ats f. (at ∈ ats) => proxy at -> Apply f at -> Attributes f ats -> Attributes f ats
+ Data.Geometry.Ipe.Attributes: setAttr :: forall proxy at ats f. at ∈ ats => proxy at -> Apply f at -> Attributes f ats -> Attributes f ats
- Data.Geometry.Ipe.Attributes: takeAttr :: forall proxy at ats f. (at ∈ ats) => proxy at -> Attributes f ats -> (Maybe (Apply f at), Attributes f ats)
+ Data.Geometry.Ipe.Attributes: takeAttr :: forall proxy at ats f. at ∈ ats => proxy at -> Attributes f ats -> (Maybe (Apply f at), Attributes f ats)
- Data.Geometry.Ipe.Attributes: type ArrowSym0 = Arrow
+ Data.Geometry.Ipe.Attributes: type ArrowSym0 = 'Arrow
- Data.Geometry.Ipe.Attributes: type ClipSym0 = Clip
+ Data.Geometry.Ipe.Attributes: type ClipSym0 = 'Clip
- Data.Geometry.Ipe.Attributes: type DashSym0 = Dash
+ Data.Geometry.Ipe.Attributes: type DashSym0 = 'Dash
- Data.Geometry.Ipe.Attributes: type FillRuleSym0 = FillRule
+ Data.Geometry.Ipe.Attributes: type FillRuleSym0 = 'FillRule
- Data.Geometry.Ipe.Attributes: type FillSym0 = Fill
+ Data.Geometry.Ipe.Attributes: type FillSym0 = 'Fill
- Data.Geometry.Ipe.Attributes: type GradientSym0 = Gradient
+ Data.Geometry.Ipe.Attributes: type GradientSym0 = 'Gradient
- Data.Geometry.Ipe.Attributes: type LayerSym0 = Layer
+ Data.Geometry.Ipe.Attributes: type LayerSym0 = 'Layer
- Data.Geometry.Ipe.Attributes: type LineCapSym0 = LineCap
+ Data.Geometry.Ipe.Attributes: type LineCapSym0 = 'LineCap
- Data.Geometry.Ipe.Attributes: type LineJoinSym0 = LineJoin
+ Data.Geometry.Ipe.Attributes: type LineJoinSym0 = 'LineJoin
- Data.Geometry.Ipe.Attributes: type MatrixSym0 = Matrix
+ Data.Geometry.Ipe.Attributes: type MatrixSym0 = 'Matrix
- Data.Geometry.Ipe.Attributes: type OpacitySym0 = Opacity
+ Data.Geometry.Ipe.Attributes: type OpacitySym0 = 'Opacity
- Data.Geometry.Ipe.Attributes: type PenSym0 = Pen
+ Data.Geometry.Ipe.Attributes: type PenSym0 = 'Pen
- Data.Geometry.Ipe.Attributes: type PinSym0 = Pin
+ Data.Geometry.Ipe.Attributes: type PinSym0 = 'Pin
- Data.Geometry.Ipe.Attributes: type RArrowSym0 = RArrow
+ Data.Geometry.Ipe.Attributes: type RArrowSym0 = 'RArrow
- Data.Geometry.Ipe.Attributes: type SizeSym0 = Size
+ Data.Geometry.Ipe.Attributes: type SizeSym0 = 'Size
- Data.Geometry.Ipe.Attributes: type StrokeSym0 = Stroke
+ Data.Geometry.Ipe.Attributes: type StrokeSym0 = 'Stroke
- Data.Geometry.Ipe.Attributes: type TilingSym0 = Tiling
+ Data.Geometry.Ipe.Attributes: type TilingSym0 = 'Tiling
- Data.Geometry.Ipe.Attributes: type TransformationsSym0 = Transformations
+ Data.Geometry.Ipe.Attributes: type TransformationsSym0 = 'Transformations
- 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.Attributes: unAttrs :: Lens (Attributes f ats) (Attributes f' ats') (Rec (Attr f) ats) (Rec (Attr f') ats')
- Data.Geometry.Ipe.Attributes: unSetAttr :: forall proxy at ats f. (at ∈ ats) => proxy at -> Attributes f ats -> Attributes f ats
+ Data.Geometry.Ipe.Attributes: unSetAttr :: forall proxy at ats f. at ∈ ats => proxy at -> Attributes f ats -> Attributes f ats
- Data.Geometry.Ipe.FromIpe: defaultFromIpe :: (HasDefaultFromIpe g, (r ~ NumType g)) => Prism' (IpeObject r) (g :+ IpeAttributes (DefaultFromIpe g) r)
+ Data.Geometry.Ipe.FromIpe: defaultFromIpe :: (HasDefaultFromIpe g, r ~ NumType g) => Prism' (IpeObject r) (g :+ IpeAttributes (DefaultFromIpe g) r)
- Data.Geometry.Ipe.IpeOut: ipeCircle :: Floating r => IpeOut (Circle p r) (Path r)
+ Data.Geometry.Ipe.IpeOut: ipeCircle :: Floating r => IpeOut (Circle p r) Path r
- Data.Geometry.Ipe.IpeOut: ipeDisk :: Floating r => IpeOut (Disk p r) (IpeObject' Path r)
+ Data.Geometry.Ipe.IpeOut: ipeDisk :: Floating r => IpeOut (Disk p r) Path r
- Data.Geometry.Ipe.IpeOut: ipeDiskMark :: IpeOut (Point 2 r) (IpeObject' IpeSymbol r)
+ Data.Geometry.Ipe.IpeOut: ipeDiskMark :: IpeOut (Point 2 r) IpeSymbol r
- Data.Geometry.Ipe.IpeOut: ipeLineSegment :: IpeOut (LineSegment 2 p r) (IpeObject' Path r)
+ Data.Geometry.Ipe.IpeOut: ipeLineSegment :: IpeOut (LineSegment 2 p r) Path r
- Data.Geometry.Ipe.IpeOut: ipeMark :: Text -> IpeOut (Point 2 r) (IpeObject' IpeSymbol r)
+ Data.Geometry.Ipe.IpeOut: ipeMark :: Text -> IpeOut (Point 2 r) IpeSymbol r
- Data.Geometry.Ipe.IpeOut: ipePolyLine :: IpeOut (PolyLine 2 p r) (Path r)
+ Data.Geometry.Ipe.IpeOut: ipePolyLine :: IpeOut (PolyLine 2 p r) Path r
- Data.Geometry.Ipe.IpeOut: ipePolygon :: IpeOut (Polygon t p r) (Path r)
+ Data.Geometry.Ipe.IpeOut: ipePolygon :: IpeOut (Polygon t p r) Path r
- Data.Geometry.Ipe.Types: ArcTo :: (Matrix 3 3 r) -> (Point 2 r) -> Operation r
+ Data.Geometry.Ipe.Types: ArcTo :: Matrix 3 3 r -> Point 2 r -> Operation r
- Data.Geometry.Ipe.Types: CurveTo :: (Point 2 r) -> (Point 2 r) -> (Point 2 r) -> Operation r
+ Data.Geometry.Ipe.Types: CurveTo :: Point 2 r -> Point 2 r -> Point 2 r -> Operation r
- Data.Geometry.Ipe.Types: Ellipse :: (Matrix 3 3 r) -> Operation r
+ Data.Geometry.Ipe.Types: Ellipse :: Matrix 3 3 r -> Operation r
- Data.Geometry.Ipe.Types: EllipseSegment :: (Matrix 3 3 r) -> PathSegment r
+ Data.Geometry.Ipe.Types: EllipseSegment :: Matrix 3 3 r -> PathSegment r
- Data.Geometry.Ipe.Types: IpeGroup :: (IpeObject' Group r) -> IpeObject r
+ Data.Geometry.Ipe.Types: IpeGroup :: IpeObject' Group r -> IpeObject r
- Data.Geometry.Ipe.Types: IpeImage :: (IpeObject' Image r) -> IpeObject r
+ Data.Geometry.Ipe.Types: IpeImage :: IpeObject' Image r -> IpeObject r
- Data.Geometry.Ipe.Types: IpeMiniPage :: (IpeObject' MiniPage r) -> IpeObject r
+ Data.Geometry.Ipe.Types: IpeMiniPage :: IpeObject' MiniPage r -> IpeObject r
- Data.Geometry.Ipe.Types: IpePath :: (IpeObject' Path r) -> IpeObject r
+ Data.Geometry.Ipe.Types: IpePath :: IpeObject' Path r -> IpeObject r
- Data.Geometry.Ipe.Types: IpeTextLabel :: (IpeObject' TextLabel r) -> IpeObject r
+ Data.Geometry.Ipe.Types: IpeTextLabel :: IpeObject' TextLabel r -> IpeObject r
- Data.Geometry.Ipe.Types: IpeUse :: (IpeObject' IpeSymbol r) -> IpeObject r
+ Data.Geometry.Ipe.Types: IpeUse :: IpeObject' IpeSymbol r -> IpeObject r
- Data.Geometry.Ipe.Types: Label :: Text -> (Point 2 r) -> TextLabel r
+ Data.Geometry.Ipe.Types: Label :: Text -> Point 2 r -> TextLabel r
- Data.Geometry.Ipe.Types: LineTo :: (Point 2 r) -> Operation r
+ Data.Geometry.Ipe.Types: LineTo :: Point 2 r -> Operation r
- Data.Geometry.Ipe.Types: MiniPage :: Text -> (Point 2 r) -> r -> MiniPage r
+ Data.Geometry.Ipe.Types: MiniPage :: Text -> Point 2 r -> r -> MiniPage r
- Data.Geometry.Ipe.Types: MoveTo :: (Point 2 r) -> Operation r
+ Data.Geometry.Ipe.Types: MoveTo :: Point 2 r -> Operation r
- Data.Geometry.Ipe.Types: Path :: ViewL1 (PathSegment r) -> Path r
+ Data.Geometry.Ipe.Types: Path :: LSeq 1 (PathSegment r) -> Path r
- Data.Geometry.Ipe.Types: PolyLineSegment :: (PolyLine 2 () r) -> PathSegment r
+ Data.Geometry.Ipe.Types: PolyLineSegment :: PolyLine 2 () r -> PathSegment r
- Data.Geometry.Ipe.Types: PolygonPath :: (SimplePolygon () r) -> PathSegment r
+ Data.Geometry.Ipe.Types: PolygonPath :: SimplePolygon () r -> PathSegment r
- Data.Geometry.Ipe.Types: QCurveTo :: (Point 2 r) -> (Point 2 r) -> Operation r
+ Data.Geometry.Ipe.Types: QCurveTo :: Point 2 r -> Point 2 r -> Operation r
- Data.Geometry.Ipe.Types: [_pathSegments] :: Path r -> ViewL1 (PathSegment r)
+ Data.Geometry.Ipe.Types: [_pathSegments] :: Path r -> LSeq 1 (PathSegment r)
- Data.Geometry.Ipe.Types: _ArcSegment :: forall r_a3exU. Prism' (PathSegment r_a3exU) ()
+ Data.Geometry.Ipe.Types: _ArcSegment :: forall r_a3q2u. Prism' (PathSegment r_a3q2u) ()
- 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: _ArcTo :: forall r_a3qlO. Prism' (Operation r_a3qlO) (Matrix 3 3 r_a3qlO, Point 2 r_a3qlO)
- Data.Geometry.Ipe.Types: _ClosePath :: forall r_a3eQ4. Prism' (Operation r_a3eQ4) ()
+ Data.Geometry.Ipe.Types: _ClosePath :: forall r_a3qlO. Prism' (Operation r_a3qlO) ()
- Data.Geometry.Ipe.Types: _ClosedSpline :: forall r_a3eQ4. Prism' (Operation r_a3eQ4) [Point 2 r_a3eQ4]
+ Data.Geometry.Ipe.Types: _ClosedSpline :: forall r_a3qlO. Prism' (Operation r_a3qlO) [Point 2 r_a3qlO]
- Data.Geometry.Ipe.Types: _ClosedSplineSegment :: forall r_a3exU. Prism' (PathSegment r_a3exU) ()
+ Data.Geometry.Ipe.Types: _ClosedSplineSegment :: forall r_a3q2u. Prism' (PathSegment r_a3q2u) ()
- Data.Geometry.Ipe.Types: _CubicBezierSegment :: forall r_a3exU. Prism' (PathSegment r_a3exU) ()
+ Data.Geometry.Ipe.Types: _CubicBezierSegment :: forall r_a3q2u. Prism' (PathSegment r_a3q2u) ()
- 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: _CurveTo :: forall r_a3qlO. Prism' (Operation r_a3qlO) (Point 2 r_a3qlO, Point 2 r_a3qlO, Point 2 r_a3qlO)
- Data.Geometry.Ipe.Types: _Ellipse :: forall r_a3eQ4. Prism' (Operation r_a3eQ4) (Matrix 3 3 r_a3eQ4)
+ Data.Geometry.Ipe.Types: _Ellipse :: forall r_a3qlO. Prism' (Operation r_a3qlO) (Matrix 3 3 r_a3qlO)
- Data.Geometry.Ipe.Types: _EllipseSegment :: forall r_a3exU. Prism' (PathSegment r_a3exU) (Matrix 3 3 r_a3exU)
+ Data.Geometry.Ipe.Types: _EllipseSegment :: forall r_a3q2u. Prism' (PathSegment r_a3q2u) (Matrix 3 3 r_a3q2u)
- Data.Geometry.Ipe.Types: _IpeGroup :: forall r_a3faD. Prism' (IpeObject r_a3faD) (IpeObject' Group r_a3faD)
+ Data.Geometry.Ipe.Types: _IpeGroup :: forall r_a3qHd. Prism' (IpeObject r_a3qHd) (IpeObject' Group r_a3qHd)
- Data.Geometry.Ipe.Types: _IpeImage :: forall r_a3faD. Prism' (IpeObject r_a3faD) (IpeObject' Image r_a3faD)
+ Data.Geometry.Ipe.Types: _IpeImage :: forall r_a3qHd. Prism' (IpeObject r_a3qHd) (IpeObject' Image r_a3qHd)
- Data.Geometry.Ipe.Types: _IpeMiniPage :: forall r_a3faD. Prism' (IpeObject r_a3faD) (IpeObject' MiniPage r_a3faD)
+ Data.Geometry.Ipe.Types: _IpeMiniPage :: forall r_a3qHd. Prism' (IpeObject r_a3qHd) (IpeObject' MiniPage r_a3qHd)
- Data.Geometry.Ipe.Types: _IpePath :: forall r_a3faD. Prism' (IpeObject r_a3faD) (IpeObject' Path r_a3faD)
+ Data.Geometry.Ipe.Types: _IpePath :: forall r_a3qHd. Prism' (IpeObject r_a3qHd) (IpeObject' Path r_a3qHd)
- Data.Geometry.Ipe.Types: _IpeTextLabel :: forall r_a3faD. Prism' (IpeObject r_a3faD) (IpeObject' TextLabel r_a3faD)
+ Data.Geometry.Ipe.Types: _IpeTextLabel :: forall r_a3qHd. Prism' (IpeObject r_a3qHd) (IpeObject' TextLabel r_a3qHd)
- Data.Geometry.Ipe.Types: _IpeUse :: forall r_a3faD. Prism' (IpeObject r_a3faD) (IpeObject' IpeSymbol r_a3faD)
+ Data.Geometry.Ipe.Types: _IpeUse :: forall r_a3qHd. Prism' (IpeObject r_a3qHd) (IpeObject' IpeSymbol r_a3qHd)
- Data.Geometry.Ipe.Types: _LineTo :: forall r_a3eQ4. Prism' (Operation r_a3eQ4) (Point 2 r_a3eQ4)
+ Data.Geometry.Ipe.Types: _LineTo :: forall r_a3qlO. Prism' (Operation r_a3qlO) (Point 2 r_a3qlO)
- Data.Geometry.Ipe.Types: _MoveTo :: forall r_a3eQ4. Prism' (Operation r_a3eQ4) (Point 2 r_a3eQ4)
+ Data.Geometry.Ipe.Types: _MoveTo :: forall r_a3qlO. Prism' (Operation r_a3qlO) (Point 2 r_a3qlO)
- Data.Geometry.Ipe.Types: _PolyLineSegment :: forall r_a3exU. Prism' (PathSegment r_a3exU) (PolyLine 2 () r_a3exU)
+ Data.Geometry.Ipe.Types: _PolyLineSegment :: forall r_a3q2u. Prism' (PathSegment r_a3q2u) (PolyLine 2 () r_a3q2u)
- Data.Geometry.Ipe.Types: _PolygonPath :: forall r_a3exU. Prism' (PathSegment r_a3exU) (SimplePolygon () r_a3exU)
+ Data.Geometry.Ipe.Types: _PolygonPath :: forall r_a3q2u. Prism' (PathSegment r_a3q2u) (SimplePolygon () r_a3q2u)
- Data.Geometry.Ipe.Types: _QCurveTo :: forall r_a3eQ4. Prism' (Operation r_a3eQ4) (Point 2 r_a3eQ4, Point 2 r_a3eQ4)
+ Data.Geometry.Ipe.Types: _QCurveTo :: forall r_a3qlO. Prism' (Operation r_a3qlO) (Point 2 r_a3qlO, Point 2 r_a3qlO)
- Data.Geometry.Ipe.Types: _QuadraticBezierSegment :: forall r_a3exU. Prism' (PathSegment r_a3exU) ()
+ Data.Geometry.Ipe.Types: _QuadraticBezierSegment :: forall r_a3q2u. Prism' (PathSegment r_a3q2u) ()
- Data.Geometry.Ipe.Types: _Spline :: forall r_a3eQ4. Prism' (Operation r_a3eQ4) [Point 2 r_a3eQ4]
+ Data.Geometry.Ipe.Types: _Spline :: forall r_a3qlO. Prism' (Operation r_a3qlO) [Point 2 r_a3qlO]
- Data.Geometry.Ipe.Types: _SplineSegment :: forall r_a3exU. Prism' (PathSegment r_a3exU) ()
+ Data.Geometry.Ipe.Types: _SplineSegment :: forall r_a3q2u. Prism' (PathSegment r_a3q2u) ()
- 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: content :: forall r_a3rvE r_a3rzt. Lens (IpePage r_a3rvE) (IpePage r_a3rzt) [IpeObject r_a3rvE] [IpeObject r_a3rzt]
- Data.Geometry.Ipe.Types: data AttrMapSym0 (l_a3fah :: TyFun Type (TyFun AttributeUniverse Type -> Type))
+ Data.Geometry.Ipe.Types: data AttrMapSym0 :: (~>) Type ((~>) AttributeUniverse Type)
- Data.Geometry.Ipe.Types: data AttrMapSym1 (l_a3faf :: Type) (l_a3fae :: TyFun AttributeUniverse Type)
+ Data.Geometry.Ipe.Types: data AttrMapSym1 (r6989586621679826752 :: Type) :: (~>) AttributeUniverse Type
- 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: groupItems :: Lens (Group r) (Group s) [IpeObject r] [IpeObject s]
- Data.Geometry.Ipe.Types: imageData :: forall r_a3e0l. Lens' (Image r_a3e0l) ()
+ Data.Geometry.Ipe.Types: imageData :: forall r_a3ps2. Lens' (Image r_a3ps2) ()
- Data.Geometry.Ipe.Types: layers :: forall r_a3fWP. Lens' (IpePage r_a3fWP) [LayerName]
+ Data.Geometry.Ipe.Types: layers :: forall r_a3rvE. Lens' (IpePage r_a3rvE) [LayerName]
- 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: pages :: forall r_a3rzS r_a3rF7. Lens (IpeFile r_a3rzS) (IpeFile r_a3rF7) (NonEmpty (IpePage r_a3rzS)) (NonEmpty (IpePage r_a3rF7))
- 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: pathSegments :: forall r_a3qbg r_a3qlB. Iso (Path r_a3qbg) (Path r_a3qlB) (LSeq 1 (PathSegment r_a3qbg)) (LSeq 1 (PathSegment r_a3qlB))
- Data.Geometry.Ipe.Types: preamble :: forall r_a3g0W. Lens' (IpeFile r_a3g0W) (Maybe IpePreamble)
+ Data.Geometry.Ipe.Types: preamble :: forall r_a3rzS. Lens' (IpeFile r_a3rzS) (Maybe IpePreamble)
- 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: rect :: forall r_a3ps2 r_a3pGH. Lens (Image r_a3ps2) (Image r_a3pGH) (Rectangle () r_a3ps2) (Rectangle () r_a3pGH)
- Data.Geometry.Ipe.Types: styles :: forall r_a3g0W. Lens' (IpeFile r_a3g0W) [IpeStyle]
+ Data.Geometry.Ipe.Types: styles :: forall r_a3rzS. Lens' (IpeFile r_a3rzS) [IpeStyle]
- Data.Geometry.Ipe.Types: symbolName :: forall r_a3eda. Lens' (IpeSymbol r_a3eda) Text
+ Data.Geometry.Ipe.Types: symbolName :: forall r_a3pH1. Lens' (IpeSymbol r_a3pH1) Text
- 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: symbolPoint :: forall r_a3pH1 r_a3q2a. Lens (IpeSymbol r_a3pH1) (IpeSymbol r_a3q2a) (Point 2 r_a3pH1) (Point 2 r_a3q2a)
- Data.Geometry.Ipe.Types: type AttrMapSym2 (t_a3fac :: Type) (t_a3fad :: AttributeUniverse) = AttrMap t_a3fac t_a3fad
+ Data.Geometry.Ipe.Types: type AttrMapSym2 (r6989586621679826752 :: Type) (l6989586621679826753 :: AttributeUniverse) = AttrMap r6989586621679826752 l6989586621679826753
- Data.Geometry.Ipe.Types: views :: forall r_a3fWP. Lens' (IpePage r_a3fWP) [View]
+ Data.Geometry.Ipe.Types: views :: forall r_a3rvE. Lens' (IpePage r_a3rvE) [View]
- Data.Geometry.KDTree: Split :: !(Coord d) -> !r -> !(Box d () r) -> Split d r
+ Data.Geometry.KDTree: Split :: !Coord d -> !r -> !Box d () r -> Split d r
- Data.Geometry.KDTree: Tree :: (KDTree' d p r) -> KDTree d p r
+ Data.Geometry.KDTree: Tree :: KDTree' d p r -> KDTree d p r
- Data.Geometry.KDTree: compareOn :: (Ord r, Arity d) => Int -> Point d r :+ e -> Point d r :+ e -> Ordering
+ Data.Geometry.KDTree: compareOn :: (Ord r, Arity d) => Int -> (Point d r :+ e) -> (Point d r :+ e) -> Ordering
- Data.Geometry.Line.Internal: Line :: !(Point d r) -> !(Vector d r) -> Line d r
+ Data.Geometry.Line.Internal: Line :: !Point d r -> !Vector d r -> Line d r
- Data.Geometry.Line.Internal: [_anchorPoint] :: Line d r -> !(Point d r)
+ Data.Geometry.Line.Internal: [_anchorPoint] :: Line d r -> !Point d r
- Data.Geometry.Line.Internal: [_direction] :: Line d r -> !(Vector d r)
+ Data.Geometry.Line.Internal: [_direction] :: Line d r -> !Vector d r
- 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: anchorPoint :: forall d_a1FRC r_a1FRD. Lens' (Line d_a1FRC r_a1FRD) (Point d_a1FRC r_a1FRD)
- Data.Geometry.Line.Internal: direction :: forall d_a1oSx r_a1oSy. Lens' (Line d_a1oSx r_a1oSy) (Vector d_a1oSx r_a1oSy)
+ Data.Geometry.Line.Internal: direction :: forall d_a1FRC r_a1FRD. Lens' (Line d_a1FRC r_a1FRD) (Vector d_a1FRC r_a1FRD)
- Data.Geometry.LineSegment: Range :: !(EndPoint a) -> !(EndPoint a) -> Range a
+ Data.Geometry.LineSegment: Range :: !EndPoint a -> !EndPoint a -> Range a
- Data.Geometry.LineSegment: [_lower] :: Range a -> !(EndPoint a)
+ Data.Geometry.LineSegment: [_lower] :: Range a -> !EndPoint a
- Data.Geometry.LineSegment: [_upper] :: Range a -> !(EndPoint a)
+ Data.Geometry.LineSegment: [_upper] :: Range a -> !EndPoint a
- Data.Geometry.LineSegment: _SubLine :: (Fractional r, Eq r, Arity d) => Iso' (LineSegment d p r) (SubLine d p r)
+ Data.Geometry.LineSegment: _SubLine :: (Num r, Arity d) => Iso' (LineSegment d p r) (SubLine d p r r)
- Data.Geometry.LineSegment: covers :: (Ord a) => Range a -> Range a -> Bool
+ Data.Geometry.LineSegment: covers :: Ord a => Range a -> Range a -> Bool
- Data.Geometry.LineSegment: lower :: forall a_a1Ji7. Lens' (Range a_a1Ji7) (EndPoint a_a1Ji7)
+ Data.Geometry.LineSegment: lower :: forall a_a27Ds. Lens' (Range a_a27Ds) (EndPoint a_a27Ds)
- Data.Geometry.LineSegment: upper :: forall a_a1Ji7. Lens' (Range a_a1Ji7) (EndPoint a_a1Ji7)
+ Data.Geometry.LineSegment: upper :: forall a_a27Ds. Lens' (Range a_a27Ds) (EndPoint a_a27Ds)
- Data.Geometry.PlanarSubdivision.Basic: FaceData :: (Seq h) -> !f -> FaceData h f
+ Data.Geometry.PlanarSubdivision.Basic: FaceData :: Seq h -> !f -> FaceData h f
- Data.Geometry.PlanarSubdivision.Basic: Raw :: {-# UNPACK #-} !(ComponentId s) -> {-# UNPACK #-} !ia -> !a -> Raw s ia a
+ Data.Geometry.PlanarSubdivision.Basic: Raw :: !ComponentId s -> !ia -> !a -> Raw s ia a
- Data.Geometry.PlanarSubdivision.Basic: VertexData :: !(Point 2 r) -> !v -> VertexData r v
+ Data.Geometry.PlanarSubdivision.Basic: VertexData :: !Point 2 r -> !v -> VertexData r v
- Data.Geometry.PlanarSubdivision.Basic: [_compId] :: Raw s ia a -> {-# UNPACK #-} !(ComponentId s)
+ Data.Geometry.PlanarSubdivision.Basic: [_compId] :: Raw s ia a -> !ComponentId s
- Data.Geometry.PlanarSubdivision.Basic: [_idxVal] :: Raw s ia a -> {-# UNPACK #-} !ia
+ Data.Geometry.PlanarSubdivision.Basic: [_idxVal] :: Raw s ia a -> !ia
- 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: components :: forall s_a49bH v_a49bI e_a49bJ f_a49bK r_a49bL r_a4aeo. Lens (PlanarSubdivision s_a49bH v_a49bI e_a49bJ f_a49bK r_a49bL) (PlanarSubdivision s_a49bH v_a49bI e_a49bJ f_a49bK r_a4aeo) (Vector (Component s_a49bH r_a49bL)) (Vector (Component s_a49bH r_a4aeo))
- Data.Geometry.PlanarSubdivision.Basic: dartMapping :: () => PlanarSubdivision s v e f r -> Vector (Dart Wrap s, Dart s)
+ Data.Geometry.PlanarSubdivision.Basic: dartMapping :: PlanarSubdivision s v e f r -> Vector (Dart (Wrap s), Dart s)
- 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: dataVal :: Lens (Raw s ia a) (Raw s ia b) a b
- 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: fData :: forall h_a48YT f_a48YU f_a49bd. Lens (FaceData h_a48YT f_a48YU) (FaceData h_a48YT f_a49bd) f_a48YU f_a49bd
- 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: holes :: forall h_a48YT f_a48YU h_a49be. Lens (FaceData h_a48YT f_a48YU) (FaceData h_a49be f_a48YU) (Seq h_a48YT) (Seq h_a49be)
- 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: location :: forall r_a41DU v_a41DV r_a41RH. Lens (VertexData r_a41DU v_a41DV) (VertexData r_a41RH v_a41DV) (Point 2 r_a41DU) (Point 2 r_a41RH)
- 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: rawDartData :: forall s_a49bH v_a49bI e_a49bJ f_a49bK r_a49bL e_a4aep. Lens (PlanarSubdivision s_a49bH v_a49bI e_a49bJ f_a49bK r_a49bL) (PlanarSubdivision s_a49bH v_a49bI e_a4aep f_a49bK r_a49bL) (Vector (Raw s_a49bH (Dart (Wrap s_a49bH)) e_a49bJ)) (Vector (Raw s_a49bH (Dart (Wrap s_a49bH)) e_a4aep))
- 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: rawFaceData :: forall s_a49bH v_a49bI e_a49bJ f_a49bK r_a49bL f_a4aeq. Lens (PlanarSubdivision s_a49bH v_a49bI e_a49bJ f_a49bK r_a49bL) (PlanarSubdivision s_a49bH v_a49bI e_a49bJ f_a4aeq r_a49bL) (Vector (Raw s_a49bH (FaceId' (Wrap s_a49bH)) f_a49bK)) (Vector (Raw s_a49bH (FaceId' (Wrap s_a49bH)) f_a4aeq))
- 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: rawVertexData :: forall s_a49bH v_a49bI e_a49bJ f_a49bK r_a49bL v_a4aer. Lens (PlanarSubdivision s_a49bH v_a49bI e_a49bJ f_a49bK r_a49bL) (PlanarSubdivision s_a49bH v_a4aer e_a49bJ f_a49bK r_a49bL) (Vector (Raw s_a49bH (VertexId' (Wrap s_a49bH)) v_a49bI)) (Vector (Raw s_a49bH (VertexId' (Wrap s_a49bH)) v_a4aer))
- 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: vData :: forall r_a41DU v_a41DV v_a41RI. Lens (VertexData r_a41DU v_a41DV) (VertexData r_a41DU v_a41RI) v_a41DV v_a41RI
- Data.Geometry.PlanarSubdivision.Draw: drawPlanarSubdivision :: forall s v e f r. IpeOut (PlanarSubdivision s v e f r) (IpeObject r)
+ Data.Geometry.PlanarSubdivision.Draw: drawPlanarSubdivision :: forall s r. IpeOut (PlanarSubdivision s (Maybe (IpeAttributes IpeSymbol r)) (Maybe (IpeAttributes Path r)) (Maybe (IpeAttributes Path r)) r) Group 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: ccw' :: (Ord r, Num r) => (Point 2 r :+ a) -> (Point 2 r :+ b) -> (Point 2 r :+ c) -> CCW
- Data.Geometry.Point: ccwCmpAround :: (Num r, Ord r) => Point 2 r :+ qc -> Point 2 r :+ p -> Point 2 r :+ q -> Ordering
+ Data.Geometry.Point: ccwCmpAround :: (Num r, Ord r) => (Point 2 r :+ qc) -> (Point 2 r :+ p) -> (Point 2 r :+ q) -> Ordering
- Data.Geometry.Point: cwCmpAround :: (Num r, Ord r) => Point 2 r :+ qc -> Point 2 r :+ p -> Point 2 r :+ q -> Ordering
+ Data.Geometry.Point: cwCmpAround :: (Num r, Ord r) => (Point 2 r :+ qc) -> (Point 2 r :+ p) -> (Point 2 r :+ q) -> Ordering
- Data.Geometry.Point: insertIntoCyclicOrder :: (Ord r, Num r) => Point 2 r :+ q -> Point 2 r :+ p -> CList (Point 2 r :+ p) -> CList (Point 2 r :+ p)
+ Data.Geometry.Point: insertIntoCyclicOrder :: (Ord r, Num r) => (Point 2 r :+ q) -> (Point 2 r :+ p) -> CList (Point 2 r :+ p) -> CList (Point 2 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: 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, Arity 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, Arity 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: sortArround :: (Ord r, Num r) => Point 2 r :+ q -> [Point 2 r :+ p] -> [Point 2 r :+ p]
+ Data.Geometry.Point: sortArround :: (Ord r, Num r) => (Point 2 r :+ q) -> [Point 2 r :+ p] -> [Point 2 r :+ p]
- Data.Geometry.PolyLine: PolyLine :: Seq2 (Point d r :+ p) -> PolyLine d p r
+ Data.Geometry.PolyLine: PolyLine :: LSeq 2 (Point d r :+ p) -> PolyLine d p r
- Data.Geometry.PolyLine: [_points] :: PolyLine d p r -> Seq2 (Point d r :+ p)
+ Data.Geometry.PolyLine: [_points] :: PolyLine d p r -> LSeq 2 (Point d r :+ p)
- Data.Geometry.PolyLine: fromPoints' :: (Monoid p) => [Point d r] -> PolyLine d p r
+ Data.Geometry.PolyLine: fromPoints' :: Monoid p => [Point d r] -> PolyLine d p r
- 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.PolyLine: points :: forall d_a2J4J p_a2J4K r_a2J4L d_a2J5r p_a2J5s r_a2J5t. Iso (PolyLine d_a2J4J p_a2J4K r_a2J4L) (PolyLine d_a2J5r p_a2J5s r_a2J5t) (LSeq 2 ((:+) (Point d_a2J4J r_a2J4L) p_a2J4K)) (LSeq 2 ((:+) (Point d_a2J5r r_a2J5t) p_a2J5s))
- Data.Geometry.Polygon: cmpExtreme :: (Num r, Ord r) => Vector 2 r -> Point 2 r :+ p -> Point 2 r :+ q -> Ordering
+ Data.Geometry.Polygon: cmpExtreme :: (Num r, Ord r) => Vector 2 r -> (Point 2 r :+ p) -> (Point 2 r :+ q) -> Ordering
- Data.Geometry.Polygon.Convex: isLeftOf :: (Num r, Ord r) => Point 2 r :+ p -> (Point 2 r :+ p', Point 2 r :+ p'') -> Bool
+ Data.Geometry.Polygon.Convex: isLeftOf :: (Num r, Ord r) => (Point 2 r :+ p) -> (Point 2 r :+ p', Point 2 r :+ p'') -> Bool
- Data.Geometry.Polygon.Convex: isRightOf :: (Num r, Ord r) => Point 2 r :+ p -> (Point 2 r :+ p', Point 2 r :+ p'') -> Bool
+ Data.Geometry.Polygon.Convex: isRightOf :: (Num r, Ord r) => (Point 2 r :+ p) -> (Point 2 r :+ p', Point 2 r :+ p'') -> Bool
- 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.Polygon.Convex: simplePolygon :: forall p_a3ltd r_a3lte p_a3lxK r_a3lxL. Iso (ConvexPolygon p_a3ltd r_a3lte) (ConvexPolygon p_a3lxK r_a3lxL) (SimplePolygon p_a3ltd r_a3lte) (SimplePolygon p_a3lxK r_a3lxL)
- Data.Geometry.Properties: coRec :: (a ∈ as) => a -> CoRec Identity as
+ Data.Geometry.Properties: coRec :: a ∈ as => a -> CoRec Identity as
- Data.Geometry.SegmentTree.Generic: Count :: Int -> Count
+ Data.Geometry.SegmentTree.Generic: Count :: Word -> Count
- Data.Geometry.SegmentTree.Generic: LeafData :: !(AtomicRange r) -> !v -> LeafData v r
+ Data.Geometry.SegmentTree.Generic: LeafData :: !AtomicRange r -> !v -> LeafData v r
- Data.Geometry.SegmentTree.Generic: NodeData :: !(EndPoint r) -> !(Range r) -> !v -> NodeData v r
+ Data.Geometry.SegmentTree.Generic: NodeData :: !EndPoint r -> !Range r -> !v -> NodeData v r
- Data.Geometry.SegmentTree.Generic: [_atomicRange] :: LeafData v r -> !(AtomicRange r)
+ Data.Geometry.SegmentTree.Generic: [_atomicRange] :: LeafData v r -> !AtomicRange r
- Data.Geometry.SegmentTree.Generic: [_range] :: NodeData v r -> !(Range r)
+ Data.Geometry.SegmentTree.Generic: [_range] :: NodeData v r -> !Range r
- Data.Geometry.SegmentTree.Generic: [_splitPoint] :: NodeData v r -> !(EndPoint r)
+ Data.Geometry.SegmentTree.Generic: [_splitPoint] :: NodeData v r -> !EndPoint r
- Data.Geometry.SegmentTree.Generic: [getCount] :: Count -> Int
+ Data.Geometry.SegmentTree.Generic: [getCount] :: Count -> Word
- 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: assoc :: forall v_a2hnV r_a2hnW v_a2hv1. Lens (NodeData v_a2hnV r_a2hnW) (NodeData v_a2hv1 r_a2hnW) v_a2hnV v_a2hv1
- 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: atomicRange :: forall v_a2hvr r_a2hvs r_a2hJj. Lens (LeafData v_a2hvr r_a2hvs) (LeafData v_a2hvr r_a2hJj) (AtomicRange r_a2hvs) (AtomicRange r_a2hJj)
- 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: leafAssoc :: forall v_a2hvr r_a2hvs v_a2hJk. Lens (LeafData v_a2hvr r_a2hvs) (LeafData v_a2hJk r_a2hvs) v_a2hvr v_a2hJk
- Data.Geometry.SegmentTree.Generic: range :: forall v_a1Szp r_a1Szq. Lens' (NodeData v_a1Szp r_a1Szq) (Range r_a1Szq)
+ Data.Geometry.SegmentTree.Generic: range :: forall v_a2hnV r_a2hnW. Lens' (NodeData v_a2hnV r_a2hnW) (Range r_a2hnW)
- Data.Geometry.SegmentTree.Generic: splitPoint :: forall v_a1Szp r_a1Szq. Lens' (NodeData v_a1Szp r_a1Szq) (EndPoint r_a1Szq)
+ Data.Geometry.SegmentTree.Generic: splitPoint :: forall v_a2hnV r_a2hnW. Lens' (NodeData v_a2hnV r_a2hnW) (EndPoint r_a2hnW)
- 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.SegmentTree.Generic: unSegmentTree :: forall v_a2hJy r_a2hJz v_a2hRl r_a2hRm. Iso (SegmentTree v_a2hJy r_a2hJz) (SegmentTree v_a2hRl r_a2hRm) (BinLeafTree (NodeData v_a2hJy r_a2hJz) (LeafData v_a2hJy r_a2hJz)) (BinLeafTree (NodeData v_a2hRl r_a2hRm) (LeafData v_a2hRl r_a2hRm))
- 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.Slab: unSlab :: forall o_a2WZU a_a2WZV r_a2WZW o_a2X5N a_a2X5O r_a2X5P. Iso (Slab o_a2WZU a_a2WZV r_a2WZW) (Slab o_a2X5N a_a2X5O r_a2X5P) (Interval a_a2WZV r_a2WZW) (Interval a_a2X5O r_a2X5P)
- Data.Geometry.SubLine: SubLine :: Line d r -> Interval p r -> SubLine d p r
+ Data.Geometry.SubLine: SubLine :: Line d r -> Interval p s -> SubLine d p s r
- Data.Geometry.SubLine: [_line] :: SubLine d p r -> Line d r
+ Data.Geometry.SubLine: [_line] :: SubLine d p s r -> Line d r
- Data.Geometry.SubLine: [_subRange] :: SubLine d p r -> Interval p r
+ Data.Geometry.SubLine: [_subRange] :: SubLine d p s r -> Interval p s
- Data.Geometry.SubLine: data SubLine d p r
+ Data.Geometry.SubLine: data SubLine d p s r
- Data.Geometry.SubLine: fixEndPoints :: (Num r, Arity d) => SubLine d p r -> SubLine d (Point d r :+ p) r
+ Data.Geometry.SubLine: fixEndPoints :: (Num r, Arity d) => SubLine d p r r -> SubLine d (Point d r :+ p) r r
- Data.Geometry.SubLine: fromLine :: Arity d => Line d r -> SubLine d () (UnBounded r)
+ Data.Geometry.SubLine: fromLine :: Arity d => Line d r -> SubLine d () (UnBounded r) r
- 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: line :: forall d_a2AnC p_a2AnD s_a2AnE r_a2AnF d_a2Aow r_a2Aox. Lens (SubLine d_a2AnC p_a2AnD s_a2AnE r_a2AnF) (SubLine d_a2Aow p_a2AnD s_a2AnE r_a2Aox) (Line d_a2AnC r_a2AnF) (Line d_a2Aow r_a2Aox)
- Data.Geometry.SubLine: onSubLine :: (Ord r, Fractional r, Arity d) => Point d r -> SubLine d p r -> Bool
+ Data.Geometry.SubLine: onSubLine :: (Ord r, Fractional r, Arity d) => Point d r -> SubLine d p r r -> Bool
- Data.Geometry.SubLine: onSubLine2 :: (Ord r, Num r) => Point 2 r -> SubLine 2 p r -> Bool
+ Data.Geometry.SubLine: onSubLine2 :: (Ord r, Num r) => Point 2 r -> SubLine 2 p r r -> Bool
- 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.SubLine: subRange :: forall d_a2AnC p_a2AnD s_a2AnE r_a2AnF p_a2Aoy s_a2Aoz. Lens (SubLine d_a2AnC p_a2AnD s_a2AnE r_a2AnF) (SubLine d_a2AnC p_a2Aoy s_a2Aoz r_a2AnF) (Interval p_a2AnD s_a2AnE) (Interval p_a2Aoy s_a2Aoz)
- Data.Geometry.Transformation: Matrix :: (Vector n (Vector m r)) -> Matrix n m r
+ Data.Geometry.Transformation: Matrix :: Vector n (Vector m r) -> Matrix n m r
- Data.Geometry.Vector: class Additive Diff p => Affine (p :: * -> *) where {
+ Data.Geometry.Vector: class Additive Diff p => Affine (p :: Type -> Type) 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: imap :: (Vector v a, Vector v b) => Int -> a -> b -> v a -> v b
+ Data.Geometry.Vector: imap :: (Vector v a, Vector v b) => (Int -> a -> b) -> v a -> v b
- 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: type family Diff (p :: * -> *) :: * -> *;
+ Data.Geometry.Vector: type family Diff (p :: Type -> Type) :: Type -> Type;
- Data.Geometry.Vector.VectorFamilyPeano: [SS] :: !(SingPeano d) -> SingPeano (S d)
+ Data.Geometry.Vector.VectorFamilyPeano: [SS] :: !SingPeano d -> SingPeano (S d)
- Data.Permutation: indexes :: forall a_a1wrM. Lens' (Permutation a_a1wrM) (Vector (Int, Int))
+ Data.Permutation: indexes :: forall a_a1SkN. Lens' (Permutation a_a1SkN) (Vector (Int, Int))
- Data.Permutation: orbits :: forall a_a1wrM a_a1wuT. Lens (Permutation a_a1wrM) (Permutation a_a1wuT) (Vector (Orbit a_a1wrM)) (Vector (Orbit a_a1wuT))
+ Data.Permutation: orbits :: forall a_a1SkN a_a1SpL. Lens (Permutation a_a1SkN) (Permutation a_a1SpL) (Vector (Orbit a_a1SkN)) (Vector (Orbit a_a1SpL))
- Data.PlanarGraph: Dart :: {-# UNPACK #-} !(Arc s) -> {-# UNPACK #-} !Direction -> Dart s
+ Data.PlanarGraph: Dart :: !Arc s -> !Direction -> Dart s
- Data.PlanarGraph: [_arc] :: Dart s -> {-# UNPACK #-} !(Arc s)
+ Data.PlanarGraph: [_arc] :: Dart s -> !Arc s
- Data.PlanarGraph: [_direction] :: Dart s -> {-# UNPACK #-} !Direction
+ Data.PlanarGraph: [_direction] :: Dart s -> !Direction
- Data.PlanarGraph: arc :: forall s_a1zg0 s_a1zwA. Lens (Dart s_a1zg0) (Dart s_a1zwA) (Arc s_a1zg0) (Arc s_a1zwA)
+ Data.PlanarGraph: arc :: forall s_a1Vwo s_a1W0l. Lens (Dart s_a1Vwo) (Dart s_a1W0l) (Arc s_a1Vwo) (Arc s_a1W0l)
- Data.PlanarGraph: buildEdgeOracle :: forall f s w e. (Foldable f) => [(VertexId s w, f (VertexId s w :+ e))] -> EdgeOracle s w e
+ Data.PlanarGraph: buildEdgeOracle :: forall f s w e. Foldable f => [(VertexId s w, f (VertexId s w :+ e))] -> EdgeOracle s w e
- Data.PlanarGraph: direction :: forall s_a1zg0. Lens' (Dart s_a1zg0) Direction
+ Data.PlanarGraph: direction :: forall s_a1Vwo. Lens' (Dart s_a1Vwo) Direction
- Data.PlaneGraph: VertexData :: !(Point 2 r) -> !v -> VertexData r v
+ Data.PlaneGraph: VertexData :: !Point 2 r -> !v -> VertexData r v
- 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: graph :: forall s_a41RX v_a41RY e_a41RZ f_a41S0 r_a41S1 s_a42lj v_a42lk e_a42ll f_a42lm r_a42ln. Iso (PlaneGraph s_a41RX v_a41RY e_a41RZ f_a41S0 r_a41S1) (PlaneGraph s_a42lj v_a42lk e_a42ll f_a42lm r_a42ln) (PlanarGraph s_a41RX 'Primal (VertexData r_a41S1 v_a41RY) e_a41RZ f_a41S0) (PlanarGraph s_a42lj 'Primal (VertexData r_a42ln v_a42lk) e_a42ll f_a42lm)
- 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: location :: forall r_a41DU v_a41DV r_a41RH. Lens (VertexData r_a41DU v_a41DV) (VertexData r_a41RH v_a41DV) (Point 2 r_a41DU) (Point 2 r_a41RH)
- 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: vData :: forall r_a41DU v_a41DV v_a41RI. Lens (VertexData r_a41DU v_a41DV) (VertexData r_a41DU v_a41RI) v_a41DV v_a41RI
- Data.PlaneGraph.Draw: drawPlaneGraph :: forall s v e f r. IpeOut (PlaneGraph s v e f r) (IpeObject r)
+ Data.PlaneGraph.Draw: drawPlaneGraph :: IpeOut (PlaneGraph s v e f r) Group r
- Data.Range: Range :: !(EndPoint a) -> !(EndPoint a) -> Range a
+ Data.Range: Range :: !EndPoint a -> !EndPoint a -> Range a
- Data.Range: [_lower] :: Range a -> !(EndPoint a)
+ Data.Range: [_lower] :: Range a -> !EndPoint a
- Data.Range: [_upper] :: Range a -> !(EndPoint a)
+ Data.Range: [_upper] :: Range a -> !EndPoint a
- Data.Range: covers :: (Ord a) => Range a -> Range a -> Bool
+ Data.Range: covers :: Ord a => Range a -> Range a -> Bool
- Data.Range: lower :: forall a_a1Ji7. Lens' (Range a_a1Ji7) (EndPoint a_a1Ji7)
+ Data.Range: lower :: forall a_a27Ds. Lens' (Range a_a27Ds) (EndPoint a_a27Ds)
- Data.Range: upper :: forall a_a1Ji7. Lens' (Range a_a1Ji7) (EndPoint a_a1Ji7)
+ Data.Range: upper :: forall a_a27Ds. Lens' (Range a_a27Ds) (EndPoint a_a27Ds)
- Data.UnBounded: unUnBounded :: forall a_a2d8w a_a2e5G. Traversal (UnBounded a_a2d8w) (UnBounded a_a2e5G) a_a2d8w a_a2e5G
+ Data.UnBounded: unUnBounded :: forall a_a2wej a_a2xGA. Traversal (UnBounded a_a2wej) (UnBounded a_a2xGA) a_a2wej a_a2xGA

Files

README.md view
@@ -17,7 +17,7 @@ ```haskell newtype Point (d :: Nat) (r :: *) = Point { toVec :: Vector d r } ```-- the vertices of a `PolyLine d p r` are stored in a `Data.Seq2` which enforces+- the vertices of a `PolyLine d p r` are stored in a `Data.LSeq` which enforces that a polyline is a proper polyline, and thus has at least two vertices.  Please note that aspect (2), implementing good algorithms, is much work in@@ -25,11 +25,11 @@ some improvements. Currently, HGeometry provides the following algorithms:  * two \(O(n \log n)\) time algorithms for convex hull in-  $\mathbb{R}^2$: the typical Graham scan, and a divide and conqueror algorithm,+  $\mathbb{R}^2$: the typical Graham scan, and a divide and conquer algorithm, * an \(O(n)\) expected time algorithm for smallest enclosing disk in $\mathbb{R}^$2, * the well-known Douglas Peucker polyline line simplification algorithm, * an \(O(n \log n)\) time algorithm for computing the Delaunay triangulation-(using divide and conqueror).+(using divide and conquer). * an \(O(n \log n)\) time algorithm for computing the Euclidean Minimum Spanning Tree (EMST), based on computing the Delaunay Triangulation. * an \(O(\log^2 n)\) time algorithm to find extremal points and tangents on/to a@@ -38,6 +38,8 @@ polygons. * An \(O(1/\varepsilon^dn\log n)\) time algorithm for constructing a Well-Separated pair   decomposition.+* The classic (optimal) \(O(n\log n)\) time divide and conquer algorithm to+  compute the closest pair among a set of \(n\) points in \(\mathbb{R}^2\).  It also has some geometric data structures. In particular, HGeometry contans an implementation of@@ -108,7 +110,7 @@            let pts  = syms&traverse.core %~ (^.symbolPoint)                pts' = NonEmpty.fromList pts                dt   = delaunayTriangulation $ pts'-               out  = [asIpe drawTriangulation dt]+               out  = [iO $ drawTriangulation dt]            writeIpeFile outFile . singlePageFromContent $ out ``` 
+ benchmark/Algorithms/Geometry/ClosestPair/Bench.hs view
@@ -0,0 +1,48 @@+module Algorithms.Geometry.ClosestPair.Bench where++import qualified Algorithms.Geometry.ClosestPair.DivideAndConquer as DivideAndConquer+import qualified Algorithms.Geometry.ClosestPair.Naive as Naive+import           Benchmark.Util+import           Control.DeepSeq+import           Criterion.Main+import           Criterion.Types+import           Data.Ext+import           Data.Geometry.Point+import           Data.Proxy+import           Test.QuickCheck+import           Test.QuickCheck.HGeometryInstances ()+import           Data.LSeq (LSeq)+import qualified Data.LSeq as LSeq++--------------------------------------------------------------------------------++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 (LSeq 2 (Point 2 r :+ ()))+genPts _ n | n >= 2    = generate (LSeq.promise . LSeq.fromList <$> vectorOf n arbitrary)+           | otherwise = error "genPts: Need at least 2 points"++-- | Benchmark computing the closest pair+benchBuild    :: (Ord r, Num r, NFData r) => LSeq 2 (Point 2 r :+ ()) -> Benchmark+benchBuild ps = bgroup "closestPair" [ bgroup (show n) (build $ take' n ps)+                                     | n <- sizes' ps+                                     ]+  where+    take' n = LSeq.promise . LSeq.take n+    sizes' pts = let n = length pts in [ n*i `div` 100 | i <- [10,20,25,50,75,100]]++    build pts = [ bench "sort"     $ nf LSeq.unstableSort pts+                , bench "Div&Conq" $ nf DivideAndConquer.closestPair pts+                , bench "Naive"    $ nf Naive.closestPair pts+                ]
benchmark/Algorithms/Geometry/ConvexHull/Bench.hs view
@@ -1,6 +1,6 @@ module Algorithms.Geometry.ConvexHull.Bench where -import qualified Algorithms.Geometry.ConvexHull.DivideAndConqueror as DivideAndConqueror+import qualified Algorithms.Geometry.ConvexHull.DivideAndConquer as DivideAndConquer import qualified Algorithms.Geometry.ConvexHull.GrahamScan as GrahamScan  -- | copies of the convex hull algo with different point types@@ -62,7 +62,7 @@                 , bench "grahamScan_Family"    $ nf GFam.convexHull       ptsFam                 , bench "grahamScan_Fixed"     $ nf GFix.convexHull       ptsFix -                , bench "Div&Conq"             $ nf DivideAndConqueror.convexHull pts+                , bench "Div&Conq"             $ nf DivideAndConquer.convexHull pts                 ]       where         ptsV2       = fmap (GV.fromP) pts
benchmark/Benchmarks.hs view
@@ -1,6 +1,6 @@ module Main where -import qualified Algorithms.Geometry.ConvexHull.Bench as M+import qualified Algorithms.Geometry.ClosestPair.Bench as M  main :: IO () main = M.main
benchmark/Data/Geometry/Vector/VectorFamily6.hs view
@@ -10,7 +10,6 @@ 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(..))
changelog.md view
@@ -1,3 +1,13 @@+#### 0.8 ###++- Compatibility with GHC 8.6+- Added \(O(n\log n)\) time closest pair algorithm.+- Added arrangement data type+- Various Bugfixes+- Added Camera data type with some world to screen transformations.+- Additional read/show instances+- Updated some of the show instances for Ipe related types.+ #### 0.7 ###  - Compatibility with GHC 8.0-8.4
+ docs/Data/PlanarGraph/testG.png view

binary file changed (absent → 38819 bytes)

doctests.hs view
@@ -33,27 +33,40 @@           , "FlexibleContexts"           ] -files = mconcat [ geomModules-                , dataModules-                ]+files = map toFile modules -prefixWith s = map (\s' -> "src/" <> s <> s')+toFile = (\s -> "src/" <> s <> ".hs") . replace '.' '/' +replace     :: Eq a => a -> a -> [a] -> [a]+replace a b = go+  where+    go []                 = []+    go (c:cs) | c == a    = b:go cs+              | otherwise = c:go cs -dataModules = prefixWith "Data/" [ "Range.hs"-                                 , "CircularList/Util.hs"-                                 , "Permutation.hs"-                                 , "CircularSeq.hs"-                                 , "PlanarGraph.hs"-                                 ]+modules =+  [ "Data.Range"+  , "Data.CircularList.Util"+  , "Data.Permutation"+  , "Data.CircularSeq"+  , "Data.LSeq"+  , "Data.PlanarGraph"+  , "Data.Tree.Util" -geomModules = prefixWith "Data/Geometry/" [ "Point.hs"-                                          , "Vector.hs"-                                          , "Line.hs"-                                          , "Line/Internal.hs"                                                                        , "Interval.hs"-                                          , "LineSegment.hs"-                                          , "PolyLine.hs"-                                          , "Polygon.hs"-                                          , "Ball.hs"-                                          , "Box.hs"-                                          ]+  , "Data.Geometry.Point"+  , "Data.Geometry.Vector"+  , "Data.Geometry.Transformation"+  , "Data.Geometry.Line"+  , "Data.Geometry.Line.Internal"+  , "Data.Geometry.Interval"+  , "Data.Geometry.LineSegment"+  , "Data.Geometry.PolyLine"+  , "Data.Geometry.Polygon"+  , "Data.Geometry.Ball"+  , "Data.Geometry.Box"++  , "Data.Geometry.Ipe.IpeOut"+  , "Data.Geometry.Ipe.FromIpe"++  -- , "Algorithms.Geometry.HiddenSurfaceRemoval.HiddenSurfaceRemoval"+  ]
examples/Demo/Delaunay.hs view
@@ -1,7 +1,7 @@ {-# LANGUAGE ScopedTypeVariables #-} module Demo.Delaunay where -import           Algorithms.Geometry.DelaunayTriangulation.DivideAndConqueror+import           Algorithms.Geometry.DelaunayTriangulation.DivideAndConquer import           Algorithms.Geometry.DelaunayTriangulation.Types import           Algorithms.Geometry.EuclideanMST.EuclideanMST import           Control.Lens@@ -45,7 +45,7 @@                pts' = NonEmpty.fromList pts                dt   = delaunayTriangulation $ pts'                emst = euclideanMST pts'-               out  = [asIpe drawTriangulation dt, asIpe drawTree' emst]+               out  = [iO $ drawTriangulation dt, iO $ drawTree' emst]            -- print $ length $ edges' dt            -- print $ toPlaneGraph (Proxy :: Proxy DT) dt            writeIpeFile outFile . singlePageFromContent $ out
examples/Demo/DrawGPX.hs view
@@ -61,7 +61,7 @@     tks   <- concatMap (_tracks . combineTracks) <$> mapM readGPXFile files     let polies  = mapMaybe asPolyLine tks         polies' = map (douglasPeucker 0.01 . scaleUniformlyBy 100) polies-        pg = singlePageFromContent $ map (asIpeObject' mempty) polies'+        pg = singlePageFromContent $ map (iO . defIO) polies'     -- print pg     writeIpeFile outPath pg 
examples/Demo/GPXParser.hs view
@@ -6,9 +6,8 @@ module Demo.GPXParser where  -import           Control.Applicative+ import           Control.Lens-import           Control.Monad import qualified Data.ByteString.Lazy as B import           Data.Ext import           Data.Geometry.Point
examples/Demo/MinDisk.hs view
@@ -3,7 +3,6 @@  import           Algorithms.Geometry.SmallestEnclosingBall.RandomizedIncrementalConstruction import           Algorithms.Geometry.SmallestEnclosingBall.Types-import           Control.Applicative import           Control.Lens import           Data.Data import           Data.Ext@@ -11,16 +10,10 @@ import           Data.Geometry import           Data.Geometry.Ball import           Data.Geometry.Ipe-import           Data.Geometry.Ipe.Types import           Data.Geometry.Line-import           Data.Geometry.PolyLine-import           Data.Maybe-import           Data.Semigroup-import           Data.Seq2+import qualified Data.LSeq as LSeq import qualified Data.Traversable as Tr-import           Data.Vinyl import           Options.Applicative-import           System.Environment (getArgs) import           System.Random  --------------------------------------------------------------------------------@@ -39,12 +32,10 @@  -------------------------------------------------------------------------------- -diskResult :: Floating r => IpeOut (DiskResult p r) (IpeObject r)-diskResult = IpeOut f+diskResult :: Floating r => IpeOut (DiskResult p r) Group r+diskResult (DiskResult d pts) = ipeGroup (iO' d  : (F.toList . fmap g $ pts))   where-    f (DiskResult d pts) = asIpeGroup (asIpeObject d mempty : (F.toList . fmap g $ pts))-    g p = asIpeObject (p^.core) mempty-+    g p = iO' (p^.core)  mainWith              :: Options -> IO () mainWith (Options fp) = do@@ -56,7 +47,7 @@         case map ext $ ipeP^..content.Tr.traverse._IpeUse.core.symbolPoint of           pts@(_:_:_) -> do                            let res = smallestEnclosingDisk gen pts-                           printAsIpeSelection . asIpe diskResult $ res+                           printAsIpeSelection . iO . diskResult $ res           _           -> putStrLn "Not enough points!"  
examples/Demo/TriangulateWorld.hs view
@@ -37,20 +37,6 @@                          <> 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 ()@@ -68,14 +54,10 @@                      . 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 ]+          out     = mconcat [ [ iO' pg | pg <- polies ]+                            , [ iO' s  | s  <- segs ]+                            , [ iO' pg | pg <- yMonotones ]+                            ]       mapM_ print . map (\pg -> pg^.core.to polygonVertices.to length) $ polies'       writeIpeFile outFile . singlePageFromContent $ out @@ -104,3 +86,15 @@ --     where --       applyAts ats = id -- flattenGroups' o                            = [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
examples/Demo/WriteEnsemble.hs view
@@ -3,17 +3,14 @@ import Control.Lens import Data.Data import Data.Ext-import Control.Applicative import Data.Fixed import qualified Data.Text as T import qualified Data.Text.IO as TIO import Data.Geometry.Ipe import Data.Geometry import Data.Geometry.PolyLine(fromPoints)-import System.Environment import System.Directory import Data.List(isSuffixOf)-import Data.Monoid import Data.Time.Calendar import Options.Applicative @@ -54,7 +51,7 @@           _        -> asTempPt     polies <- mapM (fmap (asPts f) . readFile' . ((inPath ++ "/") ++)) inFiles     let polies' = map (fromPoints . take 100) . trim $ polies-    writeIpeFile outPath . singlePageFromContent . map (flip asIpeObject mempty) $ polies'+    writeIpeFile outPath . singlePageFromContent . map iO' $ polies'  readFile'    :: String -> IO T.Text readFile' fp = putStrLn fp >> TIO.readFile fp
hgeometry.cabal view
@@ -2,7 +2,7 @@ -- documentation, see http://haskell.org/cabal/users-guide/  name:                hgeometry-version:             0.7.0.0+version:             0.8.0.0 synopsis:            Geometric Algorithms, Data structures, and Data types. description:   HGeometry provides some basic geometry types, and geometric algorithms and@@ -30,7 +30,13 @@                      test/Algorithms/Geometry/PolygonTriangulation/simplepolygon6.ipe                      test/Algorithms/Geometry/SmallestEnclosingDisk/manual.ipe                      test/Data/Geometry/pointInPolygon.ipe+                     test/Data/Geometry/pointInTriangle.ipe                      test/Data/Geometry/Polygon/Convex/convexTests.ipe+                     test/Data/Geometry/arrangement.ipe+                     test/Data/Geometry/arrangement.ipe.out.ipe+                     test/Data/myGraph.yaml+                     test/Data/myPlaneGraph.yaml+                      examples/BAPC2014/sample.in                      examples/BAPC2014/sample.out                      examples/BAPC2014/testdata.in@@ -40,11 +46,16 @@                      examples/BAPC2012/sampleG.in                      examples/BAPC2012/sampleG.out -+                     -- in the future (cabal >=2.4) we can use+                     -- examples/**/*.in+                     -- examples/**/*.out  extra-source-files:  README.md                      changelog.md +Extra-doc-files:     docs/Data/PlanarGraph/testG.png+                     -- docs/**/*.png+ cabal-version:       2.0 source-repository head   type:     git@@ -93,6 +104,7 @@                     Data.Geometry.SubLine                     Data.Geometry.HalfLine                     Data.Geometry.PolyLine+                    Data.Geometry.HyperPlane                     Data.Geometry.Triangle                     -- Data.Geometry.Plane                     Data.Geometry.Slab@@ -108,16 +120,20 @@                     Data.Geometry.SegmentTree.Generic                      Data.Geometry.KDTree+                     Data.Geometry.PlanarSubdivision                     Data.Geometry.PlanarSubdivision.Basic                     Data.Geometry.PlanarSubdivision.Draw +                    Data.Geometry.Arrangement+                    Data.Geometry.Arrangement.Internal+                    Data.Geometry.Arrangement.Draw+                     -- * Algorithms-                    Algorithms.Util                      -- * Geometric Algorithms                     Algorithms.Geometry.ConvexHull.GrahamScan-                    Algorithms.Geometry.ConvexHull.DivideAndConqueror+                    Algorithms.Geometry.ConvexHull.DivideAndConquer                      Algorithms.Geometry.LowerEnvelope.DualCH @@ -126,7 +142,7 @@                     Algorithms.Geometry.SmallestEnclosingBall.Naive                      Algorithms.Geometry.DelaunayTriangulation.Types-                    Algorithms.Geometry.DelaunayTriangulation.DivideAndConqueror+                    Algorithms.Geometry.DelaunayTriangulation.DivideAndConquer                     Algorithms.Geometry.DelaunayTriangulation.Naive                      Algorithms.Geometry.PolyLineSimplification.DouglasPeucker@@ -150,6 +166,12 @@                     Algorithms.Geometry.LineSegmentIntersection.BentleyOttmann                     Algorithms.Geometry.LineSegmentIntersection.Types +                    -- Algorithms.Geometry.HiddenSurfaceRemoval.HiddenSurfaceRemoval++                    Algorithms.Geometry.ClosestPair.Naive+                    Algorithms.Geometry.ClosestPair.DivideAndConquer++                     -- * Graph Algorithms                     Algorithms.Graph.DFS                     Algorithms.Graph.MST@@ -157,6 +179,8 @@                     -- * Ipe Types                     Data.Geometry.Ipe                     Data.Geometry.Ipe.Literal+                    Data.Geometry.Ipe.Value+                    Data.Geometry.Ipe.Color                     Data.Geometry.Ipe.Attributes                     Data.Geometry.Ipe.Types                     Data.Geometry.Ipe.Writer@@ -169,8 +193,7 @@                     Data.UnBounded                     Data.Range                     Data.Ext-                    Data.Seq2-                    Data.Seq+                    Data.LSeq                     Data.CircularSeq                     Data.Sequence.Util                     Data.BinaryTree@@ -180,6 +203,7 @@                     Data.BalBST                     Data.OrdSeq                     Data.SlowSeq+                    Data.Tree.Util                     Data.Util                      -- * Planar Graphs@@ -188,6 +212,9 @@                     Data.PlaneGraph                     Data.PlaneGraph.Draw +                    -- * Graphics stuff+                    Graphics.Camera+                     -- * Other                     System.Random.Shuffle                     Control.Monad.State.Persistent@@ -203,42 +230,44 @@    -- other-extensions:   build-depends:-                  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-                , semigroupoids    >= 5-                , semigroups       >= 0.18-                , singletons       >= 2.0-                , text             >= 1.1.1.0-                , vinyl            >= 0.6-                , deepseq          >= 1.1-                , fingertree       >= 0.1-                , colour           >= 2.3.3-                , reflection       >= 2.1+                base             >= 4.10      &&     < 5+              , bifunctors       >= 4.1+              , bytestring       >= 0.10+              , containers       >= 0.5.5+              , dlist            >= 0.7+              , contravariant    >= 1.4+              , profunctors      >= 5.2.1+              , lens             >= 4.2+              , linear           >= 1.10+              , semigroupoids    >= 5+              , semigroups       >= 0.18+              , singletons       >= 2.0+              , text             >= 1.1.1.0+              , vinyl            >= 0.6        && < 0.9+              , deepseq          >= 1.1+              , fingertree       >= 0.1+              , colour           >= 2.3.3+              , reflection       >= 2.1 -               -- , validation       >= 0.4 -               , parsec           >= 3-               -- , tranformers      > 0.3+              -- , validation       >= 0.4 -               , vector           >= 0.11-               , fixed-vector     >= 1.0-               , data-clist       >= 0.0.7.2+              , parsec           >= 3+                -- , tranformers      > 0.3 -               , hexpat           >= 0.20.9-               , aeson            >= 1.0-               , yaml             >= 0.8+              , vector           >= 0.11+              , fixed-vector     >= 1.0+              , data-clist       >= 0.0.7.2 +              , hexpat           >= 0.20.9+              , aeson            >= 1.0+              , yaml             >= 0.8 -               , mtl-               , random-               , template-haskell +              , mtl+              , random+              , template-haskell+   if flag(with-quickcheck)     build-depends: QuickCheck              >= 2.5                  , quickcheck-instances    >= 0.3@@ -416,7 +445,8 @@   ghc-options:   -threaded   main-is:       doctests.hs   build-depends: base-               , doctest >= 0.8+               , doctest             >= 0.8+--               , doctest-discover    default-language:    Haskell2010 @@ -425,7 +455,9 @@   default-language:     Haskell2010   hs-source-dirs:       test   main-is:              Spec.hs-  ghc-options:   -O2 -fno-warn-unticked-promoted-constructors+  ghc-options:   -fno-warn-unticked-promoted-constructors+                 -fno-warn-partial-type-signatures+                 -fno-warn-missing-signatures    build-tool-depends: hspec-discover:hspec-discover @@ -433,6 +465,7 @@   other-modules: Data.RangeSpec                  Data.EdgeOracleSpec                  Data.PlanarGraphSpec+                 Data.PlaneGraphSpec                  Data.OrdSeqSpec                  Data.Geometry.Ipe.ReaderSpec                  Data.Geometry.PolygonSpec@@ -445,6 +478,8 @@                  Data.Geometry.LineSpec                  Data.Geometry.SubLineSpec                  Data.Geometry.PlanarSubdivisionSpec+                 Data.Geometry.TriangleSpec+                 Data.Geometry.ArrangementSpec                   Algorithms.Geometry.SmallestEnclosingDisk.RISpec                  Algorithms.Geometry.DelaunayTriangulation.DTSpec@@ -454,6 +489,8 @@                  Algorithms.Geometry.PolygonTriangulation.TriangulateMonotoneSpec                  Algorithms.Geometry.LowerEnvelope.LowerEnvSpec                  Algorithms.Geometry.ConvexHull.ConvexHullSpec+                 -- Algorithms.Geometry.HiddenSurfaceRemoval.HiddenSurfaceRemovalSpec+                 Algorithms.Geometry.ClosestPair.ClosestPairSpec                   Util @@ -475,7 +512,11 @@                       , random                       , singletons                       , colour+                      , filepath+                      , directory+                      , yaml +   default-extensions: TypeFamilies                     , GADTs                     , KindSignatures@@ -551,6 +592,7 @@                  Demo.ExpectedPairwiseDistance                  Demo.TriangulateWorld                  WSPDBench+                 Algorithms.Geometry.ClosestPair.Bench    build-depends:                 base
+ src/Algorithms/Geometry/ClosestPair/DivideAndConquer.hs view
@@ -0,0 +1,129 @@+{-# LANGUAGE ScopedTypeVariables #-}+--------------------------------------------------------------------------------+-- |+-- Module      :  Algorithms.Geometry.ClosestPair.DivideAndConquer+-- Copyright   :  (C) Frank Staals+-- License     :  see the LICENSE file+-- Maintainer  :  Frank Staals+--+-- Classical \(O(n\log n)\) time divide and conquer algorithm to compute the+-- closest pair among a set of \(n\) points in \(\mathbb{R}^2\).+--+--------------------------------------------------------------------------------+module Algorithms.Geometry.ClosestPair.DivideAndConquer where++import           Control.Lens+import           Data.BinaryTree+import           Data.Ext+import qualified Data.Foldable as F+import           Data.Geometry.Point+import           Data.LSeq (LSeq)+import qualified Data.LSeq as LSeq+import qualified Data.List as List+import           Data.List.NonEmpty (NonEmpty(..))+import qualified Data.List.NonEmpty as NonEmpty+import           Data.Ord (comparing)+import           Data.Semigroup.Foldable(foldMap1)+import           Data.UnBounded+import           Data.Util++--------------------------------------------------------------------------------++-- | Classical divide and conquer algorithm to compute the closest pair among+-- \(n\) points.+--+-- running time: \(O(n)\)+closestPair :: ( Ord r, Num r) => LSeq 2 (Point 2 r :+ p) -> Two (Point 2 r :+ p)+closestPair = f . foldMap1 mkCCP . asBalancedBinLeafTree . LSeq.toNonEmpty+            . LSeq.unstableSortBy (comparing (^.core))+  where+    mkCCP (Elem p) = CCP (p :| []) Top+    f = \case+          CCP _ (ValT (SP cp _)) -> cp+          CCP _ Top              -> error "closestPair: absurd."+++-- | the closest pair and its (squared) distance+type CP q r = Top (SP (Two q) r)++-- | Type used in the closest pair computation. The fields represent the points+-- ordered on increasing y-order and the closest pair (if we know it)+data CCP p r = CCP (NonEmpty (Point 2 r :+ p))+                   !(CP (Point 2 r :+ p) r)+            deriving (Show,Eq)++instance (Num r, Ord r) => Semigroup (CCP p r) where+  (CCP ptsl cpl) <> (CCP ptsr cpr) = CCP (mergeSortedBy cmp ptsl ptsr)+                                         (mergePairs (minBy getDist cpl cpr) ptsl ptsr)+    where+      -- compare on y first then on x+      cmp     :: Point 2 r :+ p -> Point 2 r :+ p -> Ordering+      cmp p q = comparing (^.core.yCoord) p q <> comparing (^.core.xCoord) p q+++-- | Given an ordering and two nonempty sequences ordered according to that+-- ordering, merge them+mergeSortedBy           :: (a -> a -> Ordering) -> NonEmpty a -> NonEmpty a -> NonEmpty a+mergeSortedBy cmp ls rs = NonEmpty.fromList $ go (F.toList ls) (F.toList rs)+  where+    go []         ys     = ys+    go xs         []     = xs+    go xs@(x:xs') ys@(y:ys') = case x `cmp` y of+                                 LT -> x : go xs' ys+                                 EQ -> x : go xs' ys+                                 GT -> y : go xs  ys'++-- | Function that does the actual merging work+mergePairs            :: forall p r. (Ord r, Num r)+                      => CP (Point 2 r :+ p) r -- ^ current closest pair and its dist+                      -> NonEmpty (Point 2 r :+ p) -- ^ pts on the left+                      -> NonEmpty (Point 2 r :+ p) -- ^ pts on the right+                      -> CP (Point 2 r :+ p) r+mergePairs cp' ls' rs' = go cp' (NonEmpty.toList ls') (NonEmpty.toList rs')+  where++    -- scan through the points on the right in increasing order.+    go              :: CP (Point 2 r :+ p) r -> [Point 2 r :+ p] -> [Point 2 r :+ p]+                    -> CP (Point 2 r :+ p) r+    go cp _  []     = cp+    go cp ls (r:rs) = let ls'' = trim (getDist cp) ls r+                          cp'' = run cp r ls'' -- try to find a new closer pair with r.+                      in go cp'' ls'' rs   -- and then process the remaining points++    -- ditch the points on the left that are too low anyway+    trim               :: Top r -> [Point 2 r :+ q] -> Point 2 r :+ a+                       -> [Point 2 r :+ q]+    trim (ValT d) ls r = List.dropWhile (\l -> sqVertDist l r > d) ls+    trim _        ls _ = ls++    -- the squared vertical distance (in case r lies above l) or 0 otherwise+    sqVertDist l r = let d = 0 `max` (r^.core.yCoord - l^.core.yCoord) in d*d++    -- try and find a new closest pair with r. If we get to points that are too far above+    -- r we stop (since none of those points will be closer to r anyway)+    run          :: CP (Point 2 r :+ p) r -> Point 2 r :+ p -> [Point 2 r :+ p]+                 -> CP (Point 2 r :+ p) r+    run cp'' r ls =+      runWhile cp'' ls+               (\cp l -> ValT (l^.core.yCoord - r^.core.yCoord) < (getDist cp))+               (\cp l -> minBy getDist cp (ValT $ SP (Two l r) (dist l r)))++    dist (p :+ _) (q :+ _) = squaredEuclideanDist p q+++-- | Given some function that decides when to keep things while maintaining some state.+runWhile           :: s -> [a] -> (s -> a -> Bool) -> (s -> a -> s) -> s+runWhile s' ys p f = go s' ys+  where+    go s []                 = s+    go s (x:xs) | p s x     = go (f s x) xs  -- continue with new state+                | otherwise = s -- stop, return the current state++-- | returns the minimum element according to some function.+minBy                   :: Ord b => (a -> b) -> a -> a -> a+minBy f a b | f a < f b = a+            | otherwise = b++-- | Get the distance of a (candidate) closest pair+getDist :: CP a r -> Top r+getDist = fmap (view _2)
+ src/Algorithms/Geometry/ClosestPair/Naive.hs view
@@ -0,0 +1,48 @@+--------------------------------------------------------------------------------+-- |+-- Module      :  Algorithms.Geometry.ClosestPair.Naive+-- Copyright   :  (C) Frank Staals+-- License     :  see the LICENSE file+-- Maintainer  :  Frank Staals+--+-- Naive \O(n\^2)\) time algorithm to compute the closest pair of points among+-- \(n\) points in \(\mathbb{R}^d\).+--+--------------------------------------------------------------------------------+module Algorithms.Geometry.ClosestPair.Naive where++import           Data.Ext+import qualified Data.Foldable as F+import           Data.Geometry (qdA)+import           Data.Geometry.Point+import           Data.Geometry.Vector (Arity)+import           Data.LSeq (LSeq)+import qualified Data.List.NonEmpty as NonEmpty+import           Data.Semigroup+import           Data.Util++--------------------------------------------------------------------------------++-- | Naive algorithm to compute the closest pair in \(d\) dimensions. Runs in+-- \(O(n^2)\) time (for any constant \(d\)). Note that we need at least two elements+-- for there to be a closest pair.+closestPair :: ( Ord r, Arity d, Num r+               ) => LSeq 2 (Point d r :+ p) -> Two (Point d r :+ p)+closestPair = getVal . getMin . sconcat . fmap (uncurry' mkPair) . pairs+  where+    uncurry' f (Two a b) = f a b+    getVal (Arg _ x) = x++-- | A pair of points+type PP d p r = ArgMin r (Two (Point d r :+ p))++-- | Create a pair of points+mkPair                         :: (Arity d, Num r)+                               => Point d r :+ p -> Point d r :+ p -> PP d p r+mkPair pp@(p :+ _) qq@(q :+ _) = let dst = qdA p q+                                 in Min (Arg dst (Two pp qq))++-- | Produce all lists from a vec of elements. Since the Vec contains at least two+-- elements, the resulting list is non-empty+pairs :: LSeq 2 a -> NonEmpty.NonEmpty (Two a)+pairs = NonEmpty.fromList . uniquePairs . F.toList
+ src/Algorithms/Geometry/ConvexHull/DivideAndConquer.hs view
@@ -0,0 +1,38 @@+--------------------------------------------------------------------------------+-- |+-- Module      :  Algorithms.Geometry.ConvexHull.DivideAndConquer+-- Copyright   :  (C) Frank Staals+-- License     :  see the LICENSE file+-- Maintainer  :  Frank Staals+--+-- \(O(n\log n)\) time divide and conquer algorithm to compute the convex hull+-- of a set of \(n\) points in \(\mathbb{R}^2\).+--+--------------------------------------------------------------------------------+module Algorithms.Geometry.ConvexHull.DivideAndConquer(convexHull) where++import           Control.Lens ((^.))+import           Data.BinaryTree+import           Data.Ext+import           Data.Function (on)+import           Data.Geometry.Point+import           Data.Geometry.Polygon+import           Data.Geometry.Polygon.Convex+import qualified Data.List.NonEmpty as NonEmpty+import           Data.Semigroup.Foldable++--------------------------------------------------------------------------------++-- | \(O(n \log n)\) time ConvexHull using divide and conquer. The resulting polygon is+-- given in clockwise order.+convexHull :: (Ord r, Num r)+           => NonEmpty.NonEmpty (Point 2 r :+ p) -> ConvexPolygon p r+convexHull = unMerge+           . foldMap1 (Merge . ConvexPolygon . fromPoints . (:[]) . _unElem)+           . asBalancedBinLeafTree+           . NonEmpty.sortBy (compare `on` (^.core))++newtype Merge r p = Merge { unMerge :: ConvexPolygon p r }++instance (Num r, Ord r) => Semigroup (Merge r p) where+  (Merge lp) <> (Merge rp) = let (ch,_,_) = merge lp rp in Merge ch
− src/Algorithms/Geometry/ConvexHull/DivideAndConqueror.hs
@@ -1,27 +0,0 @@-module Algorithms.Geometry.ConvexHull.DivideAndConqueror( convexHull-                                                        ) where--import           Control.Lens ((^.))-import           Data.BinaryTree-import           Data.Ext-import           Data.Function (on)-import           Data.Geometry.Point-import           Data.Geometry.Polygon-import           Data.Geometry.Polygon.Convex-import qualified Data.List.NonEmpty as NonEmpty-import           Data.Semigroup-import           Data.Semigroup.Foldable---- | \(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-           . foldMap1 (Merge . ConvexPolygon . fromPoints . (:[]) . _unElem)-           . asBalancedBinLeafTree-           . NonEmpty.sortBy (compare `on` (^.core))--newtype Merge r p = Merge { unMerge :: ConvexPolygon p r }--instance (Num r, Ord r) => Semigroup (Merge r p) where-  (Merge lp) <> (Merge rp) = let (ch,_,_) = merge lp rp in Merge ch
src/Algorithms/Geometry/ConvexHull/GrahamScan.hs view
@@ -10,7 +10,6 @@ import           Data.Geometry.Polygon.Convex (ConvexPolygon(..)) import qualified Data.List.NonEmpty as NonEmpty import           Data.List.NonEmpty (NonEmpty(..))-import           Data.Monoid   -- | \(O(n \log n)\) time ConvexHull using Graham-Scan. The resulting polygon is
+ src/Algorithms/Geometry/DelaunayTriangulation/DivideAndConquer.hs view
@@ -0,0 +1,296 @@+{-# LANGUAGE ScopedTypeVariables #-}+module Algorithms.Geometry.DelaunayTriangulation.DivideAndConquer where++import           Algorithms.Geometry.ConvexHull.GrahamScan as GS+import           Algorithms.Geometry.DelaunayTriangulation.Types+import           Control.Lens+import           Control.Monad.Reader+import           Control.Monad.State+import           Data.BinaryTree+import qualified Data.CircularList as CL+import qualified Data.CircularSeq as CS+import qualified Data.CircularList.Util as CU+import           Data.Ext+import qualified Data.Foldable as F+import           Data.Function (on)+import           Data.Geometry hiding (rotateTo)+import           Data.Geometry.Ball (disk, insideBall)+import           Data.Geometry.Polygon+import qualified Data.Geometry.Polygon.Convex as Convex+import           Data.Geometry.Polygon.Convex (ConvexPolygon(..), simplePolygon)+import qualified Data.IntMap.Strict as IM+import qualified Data.List as L+import qualified Data.List.NonEmpty as NonEmpty+import qualified Data.Map as M+import           Data.Maybe (fromJust, fromMaybe)+import qualified Data.Vector as V++-------------------------------------------------------------------------------+-- * Divide & Conqueror Delaunay Triangulation+--+-- Implementation of the Divide & Conqueror algorithm as described in:+--+-- Two Algorithms for Constructing a Delaunay Triangulation+-- Lee and Schachter+-- International Journal of Computer and Information Sciences, Vol 9, No. 3, 1980+--+-- We store all adjacency lists in clockwise order+--+-- : If v on the convex hull, then its first entry in the adj. lists is its CCW+-- successor (i.e. its predecessor) on the convex hull+--+-- Rotating Right <-> rotate clockwise+++-- | Computes the delaunay triangulation of a set of points.+--+-- Running time: \(O(n \log n)\)+-- (note: We use an IntMap in the implementation. So maybe actually \(O(n \log^2 n)\))+--+-- pre: the input is a *SET*, i.e. contains no duplicate points. (If the+-- input does contain duplicate points, the implementation throws them away)+delaunayTriangulation      :: (Ord r, Fractional r)+                           => NonEmpty.NonEmpty (Point 2 r :+ p) -> Triangulation p r+delaunayTriangulation pts' = Triangulation vtxMap ptsV adjV+  where+    pts    = nub' . NonEmpty.sortBy (compare `on` (^.core)) $ pts'+    ptsV   = V.fromList . F.toList $ pts+    vtxMap = M.fromList $ zip (map (^.core) . V.toList $ ptsV) [0..]++    tr     = _unElem <$> asBalancedBinLeafTree pts++    (adj,_) = delaunayTriangulation' tr (vtxMap,ptsV)+    adjV    = V.fromList . IM.elems $ adj++++-- : pre: - Input points are sorted lexicographically+delaunayTriangulation' :: (Ord r, Fractional r)+                       => BinLeafTree Size (Point 2 r :+ p)+                       -> Mapping p r+                       -> (Adj, ConvexPolygon (p :+ VertexID) r)+delaunayTriangulation' pts mapping'@(vtxMap,_)+  | size' pts == 1 = let (Leaf p) = pts+                         i        = lookup' vtxMap (p^.core)+                     in (IM.singleton i CL.empty, ConvexPolygon $ fromPoints [withID p i])+  | size' pts <= 3 = let pts'  = NonEmpty.fromList+                               . map (\p -> withID p (lookup' vtxMap (p^.core)))+                               . F.toList $ pts+                         ch    = GS.convexHull pts'+                     in (fromHull mapping' ch, ch)+  | otherwise      = let (Node lt _ rt) = pts+                         (ld,lch)       = delaunayTriangulation' lt mapping'+                         (rd,rch)       = delaunayTriangulation' rt mapping'+                         (ch, bt, ut)   = Convex.merge lch rch+                     in (merge ld rd bt ut mapping' (firsts ch), ch)++--------------------------------------------------------------------------------+-- * Implementation++-- | Mapping that says for each vtx in the convex hull what the first entry in+-- the adj. list should be. The input polygon is given in Clockwise order+firsts :: ConvexPolygon (p :+ VertexID) r -> IM.IntMap VertexID+firsts = IM.fromList . map (\s -> (s^.end.extra.extra, s^.start.extra.extra))+       . F.toList . outerBoundaryEdges . _simplePolygon+++-- | Given a polygon; construct the adjacency list representation+-- pre: at least two elements+fromHull              :: Ord r => Mapping p r -> ConvexPolygon (p :+ q) r -> Adj+fromHull (vtxMap,_) p = let vs@(u:v:vs') = map (lookup' vtxMap . (^.core))+                                         . F.toList . CS.rightElements+                                         $ p^.simplePolygon.outerBoundary+                            es           = zipWith3 f vs (tail vs ++ [u]) (vs' ++ [u,v])+                            f prv c nxt  = (c,CL.fromList . L.nub $ [prv, nxt])+                        in IM.fromList es+++-- | Merge the two delaunay triangulations.+--+-- running time: \(O(n)\) (although we cheat a bit by using a IntMap)+merge                            :: (Ord r, Fractional r)+                                 => Adj+                                 -> Adj+                                 -> LineSegment 2 (p :+ VertexID) r -- ^ lower tangent+                                 -> LineSegment 2 (p :+ VertexID) r -- ^ upper tangent+                                 -> Mapping p r+                                 -> Firsts+                                 -> Adj+merge ld rd bt ut mapping'@(vtxMap,_) fsts =+    flip runReader (mapping', fsts) . flip execStateT adj $ moveUp (tl,tr) l r+  where+    l   = lookup' vtxMap (bt^.start.core)+    r   = lookup' vtxMap (bt^.end.core)+    tl  = lookup' vtxMap (ut^.start.core)+    tr  = lookup' vtxMap (ut^.end.core)+    adj = ld `IM.union` rd++type Merge p r = StateT Adj (Reader (Mapping p r, Firsts))++type Firsts = IM.IntMap VertexID++-- | Merges the two delaunay traingulations.+moveUp          :: (Ord r, Fractional r)+                => (VertexID,VertexID) -> VertexID -> VertexID -> Merge p r ()+moveUp ut l r+  | (l,r) == ut = insert l r+  | otherwise   = do+                     insert l r+                     -- Get the neighbours of r and l along the convex hull+                     r1 <- pred' . rotateTo l . lookup'' r <$> get+                     l1 <- succ' . rotateTo r . lookup'' l <$> get++                     (r1',a) <- rotateR l r r1+                     (l1',b) <- rotateL l r l1+                     c       <- qTest l r r1' l1'+                     let (l',r') = case (a,b,c) of+                                     (True,_,_)          -> (focus' l1', r)+                                     (False,True,_)      -> (l,          focus' r1')+                                     (False,False,True)  -> (l,          focus' r1')+                                     (False,False,False) -> (focus' l1', r)+                     moveUp ut l' r'+++-- | ''rotates'' around r and removes all neighbours of r that violate the+-- delaunay condition. Returns the first vertex (as a Neighbour of r) that+-- should remain in the Delaunay Triangulation, as well as a boolean A that+-- helps deciding if we merge up by rotating left or rotating right (See+-- description in the paper for more info)+rotateR        :: (Ord r, Fractional r)+               => VertexID -> VertexID -> Vertex -> Merge p r (Vertex, Bool)+rotateR l r r1 = focus' r1 `isLeftOf` (l, r) >>= \case+                   True  -> (,False) <$> rotateR' l r r1 (pred' r1)+                   False -> pure (r1,True)++-- | The code that does the actual rotating+rotateR'     :: (Ord r, Fractional r)+             => VertexID -> VertexID -> Vertex -> Vertex -> Merge p r Vertex+rotateR' l r = go+  where+    go r1 r2 = qTest l r r1 r2 >>= \case+                 True  -> pure r1+                 False -> do modify $ delete r (focus' r1)+                             go r2 (pred' r2)+++-- | Symmetric to rotateR+rotateL     :: (Ord r, Fractional r)+                     => VertexID -> VertexID -> Vertex -> Merge p r (Vertex, Bool)+rotateL l r l1 = focus' l1 `isRightOf` (r, l) >>= \case+                   True  -> (,False) <$> rotateL' l r l1 (succ' l1)+                   False -> pure (l1,True)++-- | The code that does the actual rotating. Symmetric to rotateR'+rotateL'     :: (Ord r, Fractional r)+             => VertexID -> VertexID -> Vertex -> Vertex -> Merge p r Vertex+rotateL' l r = go+  where+    go l1 l2 = qTest l r l1 l2 >>= \case+                 True  -> pure l1+                 False -> do modify $ delete l (focus' l1)+                             go l2 (succ' l2)++--------------------------------------------------------------------------------+-- * Primitives used by the Algorithm++-- | returns True if the forth point (vertex) does not lie in the disk defined+-- by the first three points.+qTest         :: (Ord r, Fractional r)+              => VertexID -> VertexID -> Vertex -> Vertex -> Merge p r Bool+qTest h i j k = withPtMap . snd . fst <$> ask+  where+    withPtMap ptMap = let h' = ptMap V.! h+                          i' = ptMap V.! i+                          j' = ptMap V.! (focus' j)+                          k' = ptMap V.! (focus' k)+                      in not . maybe True ((k'^.core) `insideBall`) $ disk' h' i' j'+    disk' p q r = disk (p^.core) (q^.core) (r^.core)++-- | Inserts an edge into the right position.+insert     :: (Num r, Ord r) => VertexID -> VertexID -> Merge p r ()+insert u v = do+               (mapping',fsts) <- ask+               modify $ insert' u v mapping'+               rotateToFirst u fsts+               rotateToFirst v fsts+++-- | make sure that the first vtx in the adj list of v is its predecessor on the CH+rotateToFirst        :: VertexID -> Firsts -> Merge p r ()+rotateToFirst v fsts = modify $ IM.adjust f v+  where+    mfst   = IM.lookup v fsts+    f  cl  = fromMaybe cl $ mfst >>= flip CL.rotateTo cl+++-- | Inserts an edge (and makes sure that the vertex is inserted in the+-- correct. pos in the adjacency lists)+insert'               :: (Num r, Ord r)+                      => VertexID -> VertexID -> Mapping p r -> Adj -> Adj+insert' u v (_,ptMap) = IM.adjustWithKey (insert'' v) u+                      . IM.adjustWithKey (insert'' u) v+  where+    -- inserts b into the adjacency list of a+    insert'' bi ai = CU.insertOrdBy (cwCmpAround (ptMap V.! ai) `on` (ptMap V.!)) bi+++-- | Deletes an edge+delete     :: VertexID -> VertexID -> Adj -> Adj+delete u v = IM.adjust (delete' v) u . IM.adjust (delete' u) v+  where+    delete' x = CL.filterL (/= x) -- should we rotate left or right if it is the focus?+++++-- | Lifted version of Convex.IsLeftOf+isLeftOf           :: (Ord r, Num r)+                   => VertexID -> (VertexID, VertexID) -> Merge p r Bool+p `isLeftOf` (l,r) = withPtMap . snd . fst <$> ask+  where+    withPtMap ptMap = (ptMap V.! p) `Convex.isLeftOf` (ptMap V.! l, ptMap V.! r)++-- | Lifted version of Convex.IsRightOf+isRightOf           :: (Ord r, Num r)+                    => VertexID -> (VertexID, VertexID) -> Merge p r Bool+p `isRightOf` (l,r) = withPtMap . snd . fst <$> ask+  where+    withPtMap ptMap = (ptMap V.! p) `Convex.isRightOf` (ptMap V.! l, ptMap V.! r)++--------------------------------------------------------------------------------+-- * Some Helper functions+++lookup'     :: Ord k => M.Map k a -> k -> a+lookup' m x = fromJust $ M.lookup x m++size'              :: BinLeafTree Size a -> Size+size' (Leaf _)     = 1+size' (Node _ s _) = s++-- | an 'unsafe' version of rotateTo that assumes the element to rotate to+-- occurs in the list.+rotateTo   :: Eq a => a -> CL.CList a -> CL.CList a+rotateTo x = fromJust . CL.rotateTo x++-- | Adjacency lists are stored in clockwise order, so pred means rotate right+pred' :: CL.CList a -> CL.CList a+pred' = CL.rotR++-- | Adjacency lists are stored in clockwise order, so pred and succ rotate left+succ' :: CL.CList a -> CL.CList a+succ' = CL.rotL++focus' :: CL.CList a -> a+focus' = fromJust . CL.focus++-- | Removes duplicates from a sorted list+nub' :: Eq a => NonEmpty.NonEmpty (a :+ b) -> NonEmpty.NonEmpty (a :+ b)+nub' = fmap NonEmpty.head . NonEmpty.groupBy1 ((==) `on` (^.core))+++withID     :: c :+ e -> e' -> c :+ (e :+ e')+withID p i = p&extra %~ (:+i)++lookup'' :: Int -> IM.IntMap a -> a+lookup'' k m = fromJust . IM.lookup k $ m
− src/Algorithms/Geometry/DelaunayTriangulation/DivideAndConqueror.hs
@@ -1,296 +0,0 @@-{-# LANGUAGE ScopedTypeVariables #-}-module Algorithms.Geometry.DelaunayTriangulation.DivideAndConqueror where--import           Algorithms.Geometry.ConvexHull.GrahamScan as GS-import           Algorithms.Geometry.DelaunayTriangulation.Types-import           Control.Lens-import           Control.Monad.Reader-import           Control.Monad.State-import           Data.BinaryTree-import qualified Data.CircularList as CL-import qualified Data.CircularSeq as CS-import qualified Data.CircularList.Util as CU-import           Data.Ext-import qualified Data.Foldable as F-import           Data.Function (on)-import           Data.Geometry-import           Data.Geometry.Ball (disk, insideBall)-import           Data.Geometry.Polygon-import qualified Data.Geometry.Polygon.Convex as Convex-import           Data.Geometry.Polygon.Convex (ConvexPolygon(..), simplePolygon)-import qualified Data.IntMap.Strict as IM-import qualified Data.List as L-import qualified Data.List.NonEmpty as NonEmpty-import qualified Data.Map as M-import           Data.Maybe (fromJust, fromMaybe)-import qualified Data.Vector as V------------------------------------------------------------------------------------ * Divide & Conqueror Delaunay Triangulation------ Implementation of the Divide & Conqueror algorithm as described in:------ Two Algorithms for Constructing a Delaunay Triangulation--- Lee and Schachter--- International Journal of Computer and Information Sciences, Vol 9, No. 3, 1980------ We store all adjacency lists in clockwise order------ : If v on the convex hull, then its first entry in the adj. lists is its CCW--- successor (i.e. its predecessor) on the convex hull------ Rotating Right <-> rotate clockwise----- | Computes the delaunay triangulation of a set of points.------ Running time: \(O(n \log n)\)--- (note: We use an IntMap in the implementation. So maybe actually \(O(n \log^2 n)\))------ pre: the input is a *SET*, i.e. contains no duplicate points. (If the--- input does contain duplicate points, the implementation throws them away)-delaunayTriangulation      :: (Ord r, Fractional r)-                           => NonEmpty.NonEmpty (Point 2 r :+ p) -> Triangulation p r-delaunayTriangulation pts' = Triangulation vtxMap ptsV adjV-  where-    pts    = nub' . NonEmpty.sortBy (compare `on` (^.core)) $ pts'-    ptsV   = V.fromList . F.toList $ pts-    vtxMap = M.fromList $ zip (map (^.core) . V.toList $ ptsV) [0..]--    tr     = _unElem <$> asBalancedBinLeafTree pts--    (adj,_) = delaunayTriangulation' tr (vtxMap,ptsV)-    adjV    = V.fromList . IM.elems $ adj------ : pre: - Input points are sorted lexicographically-delaunayTriangulation' :: (Ord r, Fractional r)-                       => BinLeafTree Size (Point 2 r :+ p)-                       -> Mapping p r-                       -> (Adj, ConvexPolygon (p :+ VertexID) r)-delaunayTriangulation' pts mapping'@(vtxMap,_)-  | size' pts == 1 = let (Leaf p) = pts-                         i        = lookup' vtxMap (p^.core)-                     in (IM.singleton i CL.empty, ConvexPolygon $ fromPoints [withID p i])-  | size' pts <= 3 = let pts'  = NonEmpty.fromList-                               . map (\p -> withID p (lookup' vtxMap (p^.core)))-                               . F.toList $ pts-                         ch    = GS.convexHull pts'-                     in (fromHull mapping' ch, ch)-  | otherwise      = let (Node lt _ rt) = pts-                         (ld,lch)       = delaunayTriangulation' lt mapping'-                         (rd,rch)       = delaunayTriangulation' rt mapping'-                         (ch, bt, ut)   = Convex.merge lch rch-                     in (merge ld rd bt ut mapping' (firsts ch), ch)------------------------------------------------------------------------------------- * Implementation---- | Mapping that says for each vtx in the convex hull what the first entry in--- the adj. list should be. The input polygon is given in Clockwise order-firsts :: ConvexPolygon (p :+ VertexID) r -> IM.IntMap VertexID-firsts = IM.fromList . map (\s -> (s^.end.extra.extra, s^.start.extra.extra))-       . F.toList . outerBoundaryEdges . _simplePolygon----- | Given a polygon; construct the adjacency list representation--- pre: at least two elements-fromHull              :: Ord r => Mapping p r -> ConvexPolygon (p :+ q) r -> Adj-fromHull (vtxMap,_) p = let vs@(u:v:vs') = map (lookup' vtxMap . (^.core))-                                         . F.toList . CS.rightElements-                                         $ p^.simplePolygon.outerBoundary-                            es           = zipWith3 f vs (tail vs ++ [u]) (vs' ++ [u,v])-                            f prv c nxt  = (c,CL.fromList . L.nub $ [prv, nxt])-                        in IM.fromList es----- | Merge the two delaunay triangulations.------ running time: \(O(n)\) (although we cheat a bit by using a IntMap)-merge                            :: (Ord r, Fractional r)-                                 => Adj-                                 -> Adj-                                 -> LineSegment 2 (p :+ VertexID) r -- ^ lower tangent-                                 -> LineSegment 2 (p :+ VertexID) r -- ^ upper tangent-                                 -> Mapping p r-                                 -> Firsts-                                 -> Adj-merge ld rd bt ut mapping'@(vtxMap,_) fsts =-    flip runReader (mapping', fsts) . flip execStateT adj $ moveUp (tl,tr) l r-  where-    l   = lookup' vtxMap (bt^.start.core)-    r   = lookup' vtxMap (bt^.end.core)-    tl  = lookup' vtxMap (ut^.start.core)-    tr  = lookup' vtxMap (ut^.end.core)-    adj = ld `IM.union` rd--type Merge p r = StateT Adj (Reader (Mapping p r, Firsts))--type Firsts = IM.IntMap VertexID---- | Merges the two delaunay traingulations.-moveUp          :: (Ord r, Fractional r)-                => (VertexID,VertexID) -> VertexID -> VertexID -> Merge p r ()-moveUp ut l r-  | (l,r) == ut = insert l r-  | otherwise   = do-                     insert l r-                     -- Get the neighbours of r and l along the convex hull-                     r1 <- pred' . rotateTo l . lookup'' r <$> get-                     l1 <- succ' . rotateTo r . lookup'' l <$> get--                     (r1',a) <- rotateR l r r1-                     (l1',b) <- rotateL l r l1-                     c       <- qTest l r r1' l1'-                     let (l',r') = case (a,b,c) of-                                     (True,_,_)          -> (focus' l1', r)-                                     (False,True,_)      -> (l,          focus' r1')-                                     (False,False,True)  -> (l,          focus' r1')-                                     (False,False,False) -> (focus' l1', r)-                     moveUp ut l' r'----- | ''rotates'' around r and removes all neighbours of r that violate the--- delaunay condition. Returns the first vertex (as a Neighbour of r) that--- should remain in the Delaunay Triangulation, as well as a boolean A that--- helps deciding if we merge up by rotating left or rotating right (See--- description in the paper for more info)-rotateR        :: (Ord r, Fractional r)-               => VertexID -> VertexID -> Vertex -> Merge p r (Vertex, Bool)-rotateR l r r1 = focus' r1 `isLeftOf` (l, r) >>= \case-                   True  -> (,False) <$> rotateR' l r r1 (pred' r1)-                   False -> pure (r1,True)---- | The code that does the actual rotating-rotateR'     :: (Ord r, Fractional r)-             => VertexID -> VertexID -> Vertex -> Vertex -> Merge p r Vertex-rotateR' l r = go-  where-    go r1 r2 = qTest l r r1 r2 >>= \case-                 True  -> pure r1-                 False -> do modify $ delete r (focus' r1)-                             go r2 (pred' r2)----- | Symmetric to rotateR-rotateL     :: (Ord r, Fractional r)-                     => VertexID -> VertexID -> Vertex -> Merge p r (Vertex, Bool)-rotateL l r l1 = focus' l1 `isRightOf` (r, l) >>= \case-                   True  -> (,False) <$> rotateL' l r l1 (succ' l1)-                   False -> pure (l1,True)---- | The code that does the actual rotating. Symmetric to rotateR'-rotateL'     :: (Ord r, Fractional r)-             => VertexID -> VertexID -> Vertex -> Vertex -> Merge p r Vertex-rotateL' l r = go-  where-    go l1 l2 = qTest l r l1 l2 >>= \case-                 True  -> pure l1-                 False -> do modify $ delete l (focus' l1)-                             go l2 (succ' l2)------------------------------------------------------------------------------------- * Primitives used by the Algorithm---- | returns True if the forth point (vertex) does not lie in the disk defined--- by the first three points.-qTest         :: (Ord r, Fractional r)-              => VertexID -> VertexID -> Vertex -> Vertex -> Merge p r Bool-qTest h i j k = withPtMap . snd . fst <$> ask-  where-    withPtMap ptMap = let h' = ptMap V.! h-                          i' = ptMap V.! i-                          j' = ptMap V.! (focus' j)-                          k' = ptMap V.! (focus' k)-                      in not . maybe True ((k'^.core) `insideBall`) $ disk' h' i' j'-    disk' p q r = disk (p^.core) (q^.core) (r^.core)---- | Inserts an edge into the right position.-insert     :: (Num r, Ord r) => VertexID -> VertexID -> Merge p r ()-insert u v = do-               (mapping',fsts) <- ask-               modify $ insert' u v mapping'-               rotateToFirst u fsts-               rotateToFirst v fsts----- | make sure that the first vtx in the adj list of v is its predecessor on the CH-rotateToFirst        :: VertexID -> Firsts -> Merge p r ()-rotateToFirst v fsts = modify $ IM.adjust f v-  where-    mfst   = IM.lookup v fsts-    f  cl  = fromMaybe cl $ mfst >>= flip CL.rotateTo cl----- | Inserts an edge (and makes sure that the vertex is inserted in the--- correct. pos in the adjacency lists)-insert'               :: (Num r, Ord r)-                      => VertexID -> VertexID -> Mapping p r -> Adj -> Adj-insert' u v (_,ptMap) = IM.adjustWithKey (insert'' v) u-                      . IM.adjustWithKey (insert'' u) v-  where-    -- inserts b into the adjacency list of a-    insert'' bi ai = CU.insertOrdBy (cwCmpAround (ptMap V.! ai) `on` (ptMap V.!)) bi----- | Deletes an edge-delete     :: VertexID -> VertexID -> Adj -> Adj-delete u v = IM.adjust (delete' v) u . IM.adjust (delete' u) v-  where-    delete' x = CL.filterL (/= x) -- should we rotate left or right if it is the focus?------- | Lifted version of Convex.IsLeftOf-isLeftOf           :: (Ord r, Num r)-                   => VertexID -> (VertexID, VertexID) -> Merge p r Bool-p `isLeftOf` (l,r) = withPtMap . snd . fst <$> ask-  where-    withPtMap ptMap = (ptMap V.! p) `Convex.isLeftOf` (ptMap V.! l, ptMap V.! r)---- | Lifted version of Convex.IsRightOf-isRightOf           :: (Ord r, Num r)-                    => VertexID -> (VertexID, VertexID) -> Merge p r Bool-p `isRightOf` (l,r) = withPtMap . snd . fst <$> ask-  where-    withPtMap ptMap = (ptMap V.! p) `Convex.isRightOf` (ptMap V.! l, ptMap V.! r)------------------------------------------------------------------------------------- * Some Helper functions---lookup'     :: Ord k => M.Map k a -> k -> a-lookup' m x = fromJust $ M.lookup x m--size'              :: BinLeafTree Size a -> Size-size' (Leaf _)     = 1-size' (Node _ s _) = s---- | an 'unsafe' version of rotateTo that assumes the element to rotate to--- occurs in the list.-rotateTo   :: Eq a => a -> CL.CList a -> CL.CList a-rotateTo x = fromJust . CL.rotateTo x---- | Adjacency lists are stored in clockwise order, so pred means rotate right-pred' :: CL.CList a -> CL.CList a-pred' = CL.rotR---- | Adjacency lists are stored in clockwise order, so pred and succ rotate left-succ' :: CL.CList a -> CL.CList a-succ' = CL.rotL--focus' :: CL.CList a -> a-focus' = fromJust . CL.focus---- | Removes duplicates from a sorted list-nub' :: Eq a => NonEmpty.NonEmpty (a :+ b) -> NonEmpty.NonEmpty (a :+ b)-nub' = fmap NonEmpty.head . NonEmpty.groupBy1 ((==) `on` (^.core))---withID     :: c :+ e -> e' -> c :+ (e :+ e')-withID p i = p&extra %~ (:+i)--lookup'' :: Int -> IM.IntMap a -> a-lookup'' k m = fromJust . IM.lookup k $ m
src/Algorithms/Geometry/DelaunayTriangulation/Types.hs view
@@ -40,7 +40,10 @@                          deriving (Show,Eq) makeLenses ''Triangulation +type instance NumType   (Triangulation p r) = r+type instance Dimension (Triangulation p r) = 2 + type Mapping p r = (M.Map (Point 2 r) VertexID, V.Vector (Point 2 r :+ p))  @@ -59,11 +62,11 @@ tEdges = concatMap (\(i,ns) -> map (i,) . filter (> i) . C.toList $ ns)        . zip [0..] . V.toList . _neighbours -drawTriangulation :: IpeOut (Triangulation p r) (IpeObject r)-drawTriangulation = IpeOut $ \tr ->-    let es = map (uncurry ClosedLineSegment) . triangulationEdges $ tr-    in asIpeGroup $ map (\e -> asIpeObjectWith ipeLineSegment e mempty) es-+drawTriangulation :: IpeOut (Triangulation p r) Group r+drawTriangulation tr =+  ipeGroup [ iO $ ipeLineSegment e+           | e <- map (uncurry ClosedLineSegment) . triangulationEdges $ tr+           ]  -------------------------------------------------------------------------------- 
src/Algorithms/Geometry/EuclideanMST/EuclideanMST.hs view
@@ -1,6 +1,17 @@+--------------------------------------------------------------------------------+-- |+-- Module      :  Algorithms.Geometry.EuclideanMST.EuclideanMST+-- Copyright   :  (C) Frank Staals+-- License     :  see the LICENSE file+-- Maintainer  :  Frank Staals+--+-- \(O(n\log n)\) time algorithm algorithm to compute the Euclidean minimum+-- spanning tree of a set of \(n\) points in \(\mathbb{R}^2\).+--+-------------------------------------------------------------------------------- module Algorithms.Geometry.EuclideanMST.EuclideanMST where -import           Algorithms.Geometry.DelaunayTriangulation.DivideAndConqueror+import           Algorithms.Geometry.DelaunayTriangulation.DivideAndConquer import           Algorithms.Geometry.DelaunayTriangulation.Types import           Algorithms.Graph.MST import           Control.Lens@@ -12,7 +23,6 @@ import           Data.Proxy import           Data.Tree - --------------------------------------------------------------------------------  -- | Computes the Euclidean Minimum Spanning Tree. We compute the Delaunay@@ -38,9 +48,8 @@ data MSTW  -drawTree' :: IpeOut (Tree (Point 2 r :+ p)) (IpeObject r)-drawTree' = IpeOut $-  asIpeGroup . map (asIpeObject' mempty . uncurry ClosedLineSegment) . treeEdges+drawTree' :: IpeOut (Tree (Point 2 r :+ p)) Group r+drawTree' = ipeGroup . map (iO . defIO  . uncurry ClosedLineSegment) . treeEdges   treeEdges              :: Tree a -> [(a,a)]
src/Algorithms/Geometry/LineSegmentIntersection/BentleyOttmann.hs view
@@ -17,7 +17,6 @@ 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           Data.Vinyl.CoRec
src/Algorithms/Geometry/LineSegmentIntersection/Naive.hs view
@@ -9,7 +9,6 @@ import           Data.Geometry.Point import           Data.Geometry.Properties import qualified Data.Map as M-import           Data.Semigroup import           Data.Vinyl import           Data.Vinyl.CoRec 
src/Algorithms/Geometry/LineSegmentIntersection/Types.hs view
@@ -11,8 +11,8 @@ import qualified Data.List.NonEmpty as NonEmpty import qualified Data.List as L import qualified Data.Map as Map-import           Data.Semigroup +--------------------------------------------------------------------------------  -- get the endpoints of a line segment endPoints'   :: (HasEnd s, HasStart s) => s -> (StartCore s, EndCore s)
src/Algorithms/Geometry/PolyLineSimplification/DouglasPeucker.hs view
@@ -1,17 +1,18 @@ module Algorithms.Geometry.PolyLineSimplification.DouglasPeucker where -import Data.Semigroup-import Data.Ord(comparing)-import Control.Lens hiding (only)-import Data.Ext-import Data.Geometry.PolyLine-import Data.Geometry.Point-import Data.Geometry.Vector-import Data.Geometry.LineSegment-import qualified Data.Seq2 as S2-import qualified Data.Sequence as S+import           Control.Lens hiding (only)+import           Data.Ext import qualified Data.Foldable as F+import           Data.Geometry.LineSegment+import           Data.Geometry.Point+import           Data.Geometry.PolyLine+import           Data.Geometry.Vector+import qualified Data.LSeq as LSeq+import           Data.LSeq (LSeq, pattern (:|>))+import           Data.Ord (comparing) +--------------------------------------------------------------------------------+ -- | Line simplification with the well-known Douglas Peucker alogrithm. Given a distance -- value eps adn a polyline pl, constructs a simplification of pl (i.e. with -- vertices from pl) s.t. all other vertices are within dist eps to the@@ -24,7 +25,9 @@     | dst <= (eps*eps) = fromPoints [a,b]     | otherwise        = douglasPeucker eps pref `merge` douglasPeucker eps subf   where-    pts@(S2.Seq2 a _ b) = pl^.points+    pts     = pl^.points+    a       = LSeq.head pts+    b       = LSeq.last pts     (i,dst)             = maxDist pts (ClosedLineSegment a b)      (pref,subf)         = split i pl@@ -34,24 +37,27 @@  -- | Concatenate the two polylines, dropping their shared vertex merge          :: PolyLine d p r -> PolyLine d p r -> PolyLine d p r-merge pref sub = PolyLine $ pref' >+< (sub^.points)+merge pref sub = PolyLine $ pref' `append` (sub^.points)   where-    (pref' S2.:>> _) = S2.viewr $ pref^.points-    ~(a S2.:< as) >+< bs = S2.fromSeqUnsafe $ a S.<| as <> S2.toSeq bs+    (pref' :|> _) = pref^.points+    append     :: LSeq.LSeq n a ->  LSeq.LSeq m a -> LSeq.LSeq m a+    append a b = LSeq.promise $ LSeq.append a b+    -- our seq is actually even longer + -- | Split the polyline at the given vertex. Both polylines contain this vertex split                  :: Int -> PolyLine d p r                        -> (PolyLine d p r, PolyLine d p r) split i (PolyLine pts) = bimap f f (as,bs)   where-    f = PolyLine . S2.fromSeqUnsafe-    as = S2.take (i+1) pts-    bs = S2.drop i     pts+    f = PolyLine . LSeq.forceLSeq (C  :: C 2)+    as = LSeq.take (i+1) pts+    bs = LSeq.drop i     pts  -- | Given a sequence of points, find the index of the point that has the -- Furthest distance to the LineSegment. The result is the index of the point -- and this distance. maxDist       :: (Ord r, Fractional r, Arity d)-              => S2.Seq2 (Point d r :+ p) -> LineSegment d p r -> (Int,r)-maxDist pts s = F.maximumBy (comparing snd) . S2.mapWithIndex (\i (p :+ _) ->+              => LSeq n (Point d r :+ p) -> LineSegment d p r -> (Int,r)+maxDist pts s = F.maximumBy (comparing snd) . LSeq.mapWithIndex (\i (p :+ _) ->                                                      (i,sqDistanceToSeg p s)) $ pts
src/Algorithms/Geometry/PolygonTriangulation/MakeMonotone.hs view
@@ -24,7 +24,6 @@ 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@@ -209,7 +208,7 @@  -- | 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)+getHelper i = do ui         <- gets (^?!helper.ix i)                  STR u _ ut <- asks (^.ix' ui)                  pure $ SP (u :+ ui) ut @@ -222,7 +221,7 @@   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)+handleSplit i (v :+ adj) = do ej <- gets $ \ss -> ss^?!statusStruct.to (lookupLE v)._Just                               let j = ej^.start.extra                               SP u _ <- getHelper j                               -- update the status struct:@@ -244,7 +243,7 @@ -- | 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)+connectToLeft i v = do ej <- gets $ \ss -> ss^?!statusStruct.to (lookupLE v)._Just                        let j = ej^.start.extra                        tellIfMerge i v j                        modify $ \ss -> ss&helper %~ IntMap.insert j i
src/Algorithms/Geometry/PolygonTriangulation/Triangulate.hs view
@@ -12,7 +12,8 @@ import           Data.Geometry.PlanarSubdivision.Basic import           Data.Geometry.Polygon import           Data.PlaneGraph (PlaneGraph)-import           Data.Semigroup++--------------------------------------------------------------------------------  -- | Triangulates a polygon of \(n\) vertices --
src/Algorithms/Geometry/PolygonTriangulation/TriangulateMonotone.hs view
@@ -10,7 +10,6 @@ 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)
src/Algorithms/Geometry/PolygonTriangulation/Types.hs view
@@ -10,7 +10,6 @@ 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 --------------------------------------------------------------------------------
src/Algorithms/Geometry/SmallestEnclosingBall/Naive.hs view
@@ -1,3 +1,14 @@+--------------------------------------------------------------------------------+-- |+-- Module      :  Algorithms.Geometry.SmallestEnclosingBall.Naive+-- Copyright   :  (C) Frank Staals+-- License     :  see the LICENSE file+-- Maintainer  :  Frank Staals+--+-- Naive implementation to compute the smallest enclosing disk of a set of+-- points in \(\mathbb{R}^2\)+--+-------------------------------------------------------------------------------- module Algorithms.Geometry.SmallestEnclosingBall.Naive where  -- just for the types@@ -6,10 +17,10 @@ import Algorithms.Geometry.SmallestEnclosingBall.Types import Data.Geometry.Ball import Data.Geometry.Point-import Data.List(minimumBy)-import Data.Function(on)-import Data.Maybe(fromMaybe)-import Algorithms.Util+import Data.List (minimumBy)+import Data.Function (on)+import Data.Maybe (fromMaybe)+import Data.Util(STR(..),SP(..), uniquePairs, uniqueTriplets)  -------------------------------------------------------------------------------- @@ -24,12 +35,12 @@ smallestEnclosingDisk _           = error "smallestEnclosingDisk: Too few points"  pairs     :: Fractional r => [Point 2 r :+ p] -> [DiskResult p r]-pairs pts = [DiskResult (fromDiameter (a^.core) (b^.core)) (Two a b)+pairs pts = [ DiskResult (fromDiameter (a^.core) (b^.core)) (Two a b)             | SP a b <- uniquePairs pts]  triplets     :: (Ord r, Fractional r) => [Point 2 r :+ p] -> [DiskResult p r] triplets pts = [DiskResult (disk' a b c) (Three a b c)-               | ST a b c <- uniqueTriplets pts]+               | STR a b c <- uniqueTriplets pts]  disk'       :: (Ord r, Fractional r)             => Point 2 r :+ p -> Point 2 r :+ p -> Point 2 r :+ p -> Disk () r
src/Algorithms/Geometry/SmallestEnclosingBall/RandomizedIncrementalConstruction.hs view
@@ -1,5 +1,16 @@ {-# LANGUAGE DeriveFunctor  #-} {-# LANGUAGE TemplateHaskell  #-}+--------------------------------------------------------------------------------+-- |+-- Module      :  Algorithms.Geometry.SmallestEnclosingBall.RandomizedIncrementalConstruction+-- Copyright   :  (C) Frank Staals+-- License     :  see the LICENSE file+-- Maintainer  :  Frank Staals+--+-- An randomized algorithm to compute the smallest enclosing disk of a set of+-- \(n\) points in \(\mathbb{R}^2\). The expected running time is \(O(n)\).+--+-------------------------------------------------------------------------------- module Algorithms.Geometry.SmallestEnclosingBall.RandomizedIncrementalConstruction where  import           Algorithms.Geometry.SmallestEnclosingBall.Types@@ -13,7 +24,7 @@ import           System.Random import           System.Random.Shuffle (shuffle) -+--------------------------------------------------------------------------------  -- | O(n) expected time algorithm to compute the smallest enclosing disk of a -- set of points. we need at least two points.
src/Algorithms/Geometry/SmallestEnclosingBall/Types.hs view
@@ -1,8 +1,18 @@ {-# LANGUAGE DeriveFunctor  #-} {-# LANGUAGE TemplateHaskell  #-}+--------------------------------------------------------------------------------+-- |+-- Module      :  Algorithms.Geometry.SmallestEnclosingBall.Types+-- Copyright   :  (C) Frank Staals+-- License     :  see the LICENSE file+-- Maintainer  :  Frank Staals+--+-- Types to represent the smallest enclosing disk of a set of points in+-- \(\mathbb{R}^2\)+--+-------------------------------------------------------------------------------- module Algorithms.Geometry.SmallestEnclosingBall.Types where -import           Data.Monoid import qualified Data.Foldable as F import           Data.Geometry import           Data.Geometry.Ball
src/Algorithms/Geometry/Sweep.hs view
@@ -1,5 +1,15 @@ {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE UndecidableInstances #-}+--------------------------------------------------------------------------------+-- |+-- Module      :  Algorithms.Geometry.Sweep+-- Copyright   :  (C) Frank Staals+-- License     :  see the LICENSE file+-- Maintainer  :  Frank Staals+--+-- Helper types and functions for implementing Sweep line algorithms.+--+-------------------------------------------------------------------------------- module Algorithms.Geometry.Sweep where  import qualified Data.Map as Map@@ -8,13 +18,15 @@ 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 ++-- | Represent a computation that needs a particular time as input. newtype Timed s t a = Timed {atTime :: (Tagged s t) -> a }  @@ -24,6 +36,7 @@ instance (Reifies s t, Ord k) => Eq (Timed s t k) where   a == b = a `compare` b == EQ +-- | Comparison function for timed values compare_                       :: forall s t k. (Ord k, Reifies s t)                                => Timed s t k -> Timed s t k                                -> Ordering@@ -31,9 +44,11 @@                                  in f (Tagged t) `compare` g (Tagged t)  -coerceTo :: proxy s -> f (Timed s' t k) v -> f (Timed s t k) v+-- | Coerce timed values+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 ()) @@ -46,10 +61,15 @@             -> 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     :: proxy s -> Int -> Timed s Int Int constT _ i = Timed (const i)  
src/Algorithms/Geometry/WellSeparatedPairDecomposition/Types.hs view
@@ -1,5 +1,15 @@ {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE UndecidableInstances  #-}+--------------------------------------------------------------------------------+-- |+-- Module      :  Algorithms.Geometry.WellSeparatedPairDecomposition.Types+-- Copyright   :  (C) Frank Staals+-- License     :  see the LICENSE file+-- Maintainer  :  Frank Staals+--+-- Data types that can represent a well separated pair decomposition (wspd).+--+-------------------------------------------------------------------------------- module Algorithms.Geometry.WellSeparatedPairDecomposition.Types where  import           Control.Lens hiding (Level)@@ -8,8 +18,7 @@ import           Data.Geometry.Box import           Data.Geometry.Point import           Data.Geometry.Vector-import           Data.Semigroup-import qualified Data.Seq2 as S2+import qualified Data.LSeq as LSeq import qualified Data.Sequence as S import qualified Data.Traversable as Tr @@ -46,7 +55,7 @@ -------------------------------------------------------------------------------- -- * Implementation types -type PointSeq d p r = S2.ViewL1 (Point d r :+ p)+type PointSeq d p r = LSeq.LSeq 1 (Point d r :+ p)   data Level = Level { _unLevel   :: Int
src/Algorithms/Geometry/WellSeparatedPairDecomposition/WSPD.hs view
@@ -1,4 +1,13 @@-{-# LANGUAGE LambdaCase  #-}+--------------------------------------------------------------------------------+-- |+-- Module      :  Algorithms.Geometry.WellSeparatedPairDecomposition.WSPD+-- Copyright   :  (C) Frank Staals+-- License     :  see the LICENSE file+-- Maintainer  :  Frank Staals+--+-- Algorithm to construct a well separated pair decomposition (wspd).+--+-------------------------------------------------------------------------------- module Algorithms.Geometry.WellSeparatedPairDecomposition.WSPD where  import           Algorithms.Geometry.WellSeparatedPairDecomposition.Types@@ -9,26 +18,26 @@ import           Data.Ext import qualified Data.Foldable as F import           Data.Geometry.Box-import           Data.Geometry.Transformation-import           Data.Geometry.Properties import           Data.Geometry.Point+import           Data.Geometry.Properties+import           Data.Geometry.Transformation import           Data.Geometry.Vector import qualified Data.Geometry.Vector as GV+import qualified Data.IntMap.Strict as IntMap+import qualified Data.LSeq as LSeq+import           Data.LSeq (LSeq(..),toSeq,ViewL(..),ViewR(..),pattern (:<|),pattern (:|>)) import qualified Data.List as L import qualified Data.List.NonEmpty as NonEmpty import           Data.Maybe import           Data.Ord (comparing) import           Data.Range import qualified Data.Range as Range-import           Data.Semigroup-import qualified Data.Seq2 as S2 import qualified Data.Sequence as S import qualified Data.Vector as V import qualified Data.Vector.Mutable as MV import           GHC.TypeLits-import qualified Data.IntMap.Strict as IntMap -import Debug.Trace+import           Debug.Trace  -------------------------------------------------------------------------------- @@ -45,7 +54,7 @@     n    = length $ pts'^.GV.element (C :: C 0)      sortOn' i = NonEmpty.sortWith (^.core.unsafeCoord i)-    sortOn  i = S2.viewL1FromNonEmpty . sortOn' (i + 1)+    sortOn  i = LSeq.fromNonEmpty . sortOn' (i + 1)     -- sorts the points on the first coordinate, and then associates each point     -- with an index,; its rank in terms of this first coordinate.     g = NonEmpty.zipWith (\i (p :+ e) -> p :+ (i :+ e)) (NonEmpty.fromList [0..])@@ -110,7 +119,7 @@                      => Int -> GV.Vector d (PointSeq d (Idx :+ p) r)                      -> BinLeafTree Int (Point d r :+ p) fairSplitTree' n pts-    | n <= 1    = let (p S2.:< _) = pts^.GV.element (C :: C 0) in Leaf (dropIdx p)+    | n <= 1    = let p = LSeq.head $ pts^.GV.element (C :: C 0) in Leaf (dropIdx p)     | otherwise = foldr node' (V.last path) $ V.zip nodeLevels (V.init path)   where     -- note that points may also be assigned level 'Nothing'.@@ -168,7 +177,7 @@     level p = maybe (k-1) _unLevel $ levels V.! (p^.extra.core)     append v i p = MV.read v i >>= MV.write v i . (S.|> p) -+fromSeqUnsafe = LSeq.promise . LSeq.fromSeq  -- | Given a sequence of points, whose index is increasing in the first -- dimension, i.e. if idx p < idx q, then p[0] < q[0].@@ -250,9 +259,9 @@ -- | Remove allready assigned points from the sequence -- -- pre: there are points remaining-compactEnds'               :: PointSeq d (Idx :+ p) r-                           -> RST s (PointSeq d (Idx :+ p) r)-compactEnds' (l0 S2.:< s0) = fmap fromSeqUnsafe . goL $ l0 S.<| s0+compactEnds'              :: PointSeq d (Idx :+ p) r+                          -> RST s (PointSeq d (Idx :+ p) r)+compactEnds' (l0 :<| s0) = fmap fromSeqUnsafe . goL $ l0 S.<| toSeq s0   where     goL s@(S.viewl -> l S.:< s') = hasLevel l >>= \case                                      False -> goR s@@ -288,7 +297,7 @@                                  -> RST s ( PointSeq d (Idx :+ p) r                                           , PointSeq d (Idx :+ p) r                                           )-findAndCompact j (l0 S2.:< s0) m = fmap select . stepL $ l0 S.<| s0+findAndCompact j (l0 :<| s0) m = fmap select . stepL $ l0 S.<| toSeq s0   where     -- stepL and stepR together build a data structure (FAC l r S) that     -- contains the left part of the list, i.e. the points before midpoint, and@@ -345,10 +354,9 @@ -- -- pre: points are sorted according to their dimension extends :: Arity d => GV.Vector d (PointSeq d p r) -> GV.Vector d (Range r)-extends = GV.imap (\i pts@(l S2.:< _) ->-                     let (_ S2.:> r) = S2.viewL1toR1 pts-                     in ClosedRange (l^.core.unsafeCoord (i + 1))-                                    (r^.core.unsafeCoord (i + 1)))+extends = GV.imap (\i pts ->+                     ClosedRange ((LSeq.head pts)^.core.unsafeCoord (i + 1))+                                 ((LSeq.last pts)^.core.unsafeCoord (i + 1)))   --------------------------------------------------------------------------------@@ -442,11 +450,6 @@ children'              :: BinLeafTree v a -> [BinLeafTree v a] children' (Leaf _)     = [] children' (Node l _ r) = [l,r]---fromSeqUnsafe                         :: S.Seq a -> S2.ViewL1 a-fromSeqUnsafe (S.viewl -> (l S.:< s)) = l S2.:< s-fromSeqUnsafe _                       = error "fromSeqUnsafe: Empty seq"   -- | Turn a traversal into lens
− src/Algorithms/Util.hs
@@ -1,20 +0,0 @@-module Algorithms.Util where--import qualified Data.List as L---data SP a b = SP !a !b deriving (Eq,Ord,Show)---- | Given a list xs, generate all unique (unordered) pairs.-uniquePairs    :: [a] -> [SP a a]-uniquePairs xs = [ SP x y | (x:ys) <- nonEmptyTails xs, y <- ys ]--nonEmptyTails :: [a] -> [[a]]-nonEmptyTails = L.init . L.tails---data ST a b c = ST !a !b !c deriving (Eq,Ord,Show)---- | All unieuqe unordered triplets.-uniqueTriplets    :: [a] -> [ST a a a]-uniqueTriplets xs = [ ST x y z | (x:ys) <- nonEmptyTails xs, SP y z <- uniquePairs ys]
src/Data/BinaryTree.hs view
@@ -1,12 +1,21 @@ {-# Language DeriveFunctor#-} {-# Language FunctionalDependencies #-}+--------------------------------------------------------------------------------+-- |+-- Module      :  Data.BinaryTree+-- Copyright   :  (C) Frank Staals+-- License     :  see the LICENSE file+-- Maintainer  :  Frank Staals+--+-- Several types of Binary trees.+--+-------------------------------------------------------------------------------- module Data.BinaryTree where  import           Control.DeepSeq import           Data.List.NonEmpty (NonEmpty(..),(<|)) import qualified Data.List.NonEmpty as NonEmpty import           Data.Maybe (mapMaybe)-import           Data.Semigroup import           Data.Semigroup.Foldable import qualified Data.Tree as Tree import qualified Data.Vector as V@@ -14,6 +23,8 @@  -------------------------------------------------------------------------------- +-- | Binary tree that stores its values (of type a) in the leaves. Internal+-- nodes store something of type v. data BinLeafTree v a = Leaf !a                      | Node (BinLeafTree v a) !v (BinLeafTree v a)                      deriving (Show,Read,Eq,Ord,Functor,Generic)@@ -146,7 +157,7 @@ -------------------------------------------------------------------------------- -- * Internal Node Tree -+-- | Binary tree in which we store the values of type a in internal nodes. data BinaryTree a = Nil                   | Internal (BinaryTree a) !a (BinaryTree a)                   deriving (Show,Read,Eq,Ord,Functor,Foldable,Traversable,Generic)@@ -157,9 +168,9 @@ access Nil              = Nothing access (Internal _ x _) = Just x --- | Create a balanced binary tree+-- | Create a balanced binary tree. ----- \(O(n)\)+-- running time: \(O(n)\) asBalancedBinTree :: [a] -> BinaryTree a asBalancedBinTree = mkTree . V.fromList   where@@ -170,7 +181,7 @@                             else Internal (mkTree $ V.slice 0 h v) x                                           (mkTree $ V.slice (h+1) (n - h -1) v) -+-- | Fold function for folding over a binary tree. foldBinaryUp                      :: b -> (a -> b -> b -> b)                                   -> BinaryTree a -> BinaryTree (a,b) foldBinaryUp _ _ Nil              = Nil@@ -180,9 +191,11 @@                                         b  = f x (g l') (g r')                                     in Internal l' (x,b) r' +-- | Convert a @BinaryTree@ into a RoseTree toRoseTree'                  :: BinaryTree a -> Maybe (Tree.Tree a) toRoseTree' Nil              = Nothing toRoseTree' (Internal l v r) = Just $ Tree.Node v $ mapMaybe toRoseTree' [l,r] +-- | Draw a binary tree. drawTree' :: Show a => BinaryTree a -> String drawTree' = maybe "Nil" (Tree.drawTree . fmap show) . toRoseTree'
src/Data/BinaryTree/Zipper.hs view
@@ -1,7 +1,6 @@ module Data.BinaryTree.Zipper where  import Data.BinaryTree-import Data.Semigroup  -------------------------------------------------------------------------------- 
src/Data/CircularSeq.hs view
@@ -38,7 +38,6 @@ import qualified Data.List as L import qualified Data.List.NonEmpty as NonEmpty import           Data.Maybe (listToMaybe)-import           Data.Semigroup import           Data.Semigroup.Foldable hiding (toNonEmpty) import           Data.Sequence ((|>),(<|),ViewL(..),ViewR(..),Seq) import qualified Data.Sequence as S
src/Data/Ext.hs view
@@ -1,26 +1,32 @@ {-# 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+-- Copyright   :  (C) Frank Staals+-- License     :  see the LICENSE file+-- Maintainer  :  Frank Staals+--+-- A pair-like data type to represent a 'core' type that has extra information+-- as well.+--+-------------------------------------------------------------------------------- module Data.Ext where +import Control.DeepSeq import Control.Lens hiding ((.=))+import Data.Aeson+import Data.Aeson.Types (typeMismatch) import Data.Biapplicative import Data.Bifoldable import Data.Bifunctor.Apply import Data.Bitraversable import Data.Functor.Apply (liftF2)-import Data.Semigroup+import Data.Geometry.Properties import Data.Semigroup.Bifoldable 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@@ -28,6 +34,8 @@ data core :+ extra = core :+ extra deriving (Show,Read,Eq,Ord,Bounded,Generic,NFData) infixr 1 :+ +type instance NumType   (core :+ ext) = NumType   core+type instance Dimension (core :+ ext) = Dimension core  instance Bifunctor (:+) where   bimap f g (c :+ e) = f c :+ g e
src/Data/Geometry.hs view
@@ -1,9 +1,14 @@-{-|-Module    : Data.Geometry-Description: Basic Geometry types-Copyright : (c) Frank Staals-License : See LICENCE file--}++--------------------------------------------------------------------------------+-- |+-- Module      :  Data.Geometry+-- Copyright   :  (C) Frank Staals+-- License     :  see the LICENSE file+-- Maintainer  :  Frank Staals+--+-- Basic Geometry Types+--+-------------------------------------------------------------------------------- module Data.Geometry( module Data.Geometry.Properties                     , module Data.Geometry.Transformation                     , module Data.Geometry.Point@@ -26,3 +31,5 @@ import Data.Geometry.Transformation -- import Linear.Affine hiding (Point, Vector, origin) -- import Linear.Vector++--------------------------------------------------------------------------------
+ src/Data/Geometry/Arrangement.hs view
@@ -0,0 +1,25 @@+--------------------------------------------------------------------------------+-- |+-- Module      :  Data.Geometry.Arrangement+-- Copyright   :  (C) Frank Staals+-- License     :  see the LICENSE file+-- Maintainer  :  Frank Staals+--+-- Data type for representing an Arrangement of lines in \(\mathbb{R}^2\).+--+--------------------------------------------------------------------------------+module Data.Geometry.Arrangement( Arrangement(..)+                                , inputLines, subdivision, boundedArea, unboundedIntersections+                                , ArrangementBoundary++                                , constructArrangement+                                , constructArrangementInBox+                                , constructArrangementInBox'++                                , traverseLine+                                , findStart, findStartVertex, findStartDart+                                , follow+                                ) where+++import Data.Geometry.Arrangement.Internal
+ src/Data/Geometry/Arrangement/Draw.hs view
@@ -0,0 +1,24 @@+--------------------------------------------------------------------------------+-- |+-- Module      :  Data.Geometry.Arrangement.Draw+-- Copyright   :  (C) Frank Staals+-- License     :  see the LICENSE file+-- Maintainer  :  Frank Staals+--+-- Functions for Drawing arrangements++--------------------------------------------------------------------------------+module Data.Geometry.Arrangement.Draw where++import Control.Lens+import Data.Geometry.Arrangement+import Data.Geometry.Ipe+import Data.Geometry.PlanarSubdivision.Draw++-- | Draws an arrangement+drawArrangement :: IpeOut (Arrangement s l v e f r) Group r+drawArrangement = drawPlanarSubdivision' . view subdivision++-- | Draws an arrangement+drawColoredArrangement :: IpeOut (Arrangement s l v e (Maybe (IpeColor r)) r) Group r+drawColoredArrangement = drawColoredPlanarSubdivision . view subdivision
+ src/Data/Geometry/Arrangement/Internal.hs view
@@ -0,0 +1,328 @@+{-# LANGUAGE TemplateHaskell  #-}+{-# LANGUAGE ScopedTypeVariables  #-}+--------------------------------------------------------------------------------+-- |+-- Module      :  Data.Geometry.Arrangement.Internal+-- Copyright   :  (C) Frank Staals+-- License     :  see the LICENSE file+-- Maintainer  :  Frank Staals+--+-- Data type for representing an Arrangement of lines in \(\mathbb{R}^2\).+--+--------------------------------------------------------------------------------+module Data.Geometry.Arrangement.Internal where++import           Control.Lens+import qualified Data.CircularSeq as CSeq+import           Data.Ext+import qualified Data.Foldable as F+import           Data.Geometry.Boundary+import           Data.Geometry.Box+import           Data.Geometry.Line+import           Data.Geometry.LineSegment+import           Data.Geometry.PlanarSubdivision+import           Data.Geometry.Point+import           Data.Geometry.Properties+import qualified Data.List as List+import           Data.Maybe+import           Data.Ord (Down(..))+import           Data.Proxy+import           Data.Sequence.Util+import qualified Data.Vector as V+import           Data.Vinyl.CoRec++--------------------------------------------------------------------------------++type ArrangementBoundary s e r = V.Vector (Point 2 r, VertexId' s, Maybe (Line 2 r :+ e))++-- | Data type representing a two dimensional planar arrangement+data Arrangement s l v e f r = Arrangement {+    _inputLines             :: V.Vector (Line 2 r :+ l)+  , _subdivision            :: PlanarSubdivision s v e f r+  , _boundedArea            :: Rectangle () r+  , _unboundedIntersections :: ArrangementBoundary s l r+  } deriving (Show,Eq)+  -- unboundedIntersections also stores the corners of the box. They are not+  -- associated with any line+makeLenses ''Arrangement++type instance NumType   (Arrangement s l v e f r) = r+type instance Dimension (Arrangement s l v e f r) = 2++--------------------------------------------------------------------------------++-- | Builds an arrangement of \(n\) lines+--+-- running time: \(O(n^2\log n\)+constructArrangement       :: (Ord r, Fractional r)+                           => proxy s+                           -> [Line 2 r :+ l]+                           -> Arrangement s l () (Maybe l) () r+constructArrangement px ls = let b  = makeBoundingBox ls+                             in constructArrangementInBox' px b ls++-- | Constructs the arrangemnet inside the box.  note that the resulting box+-- may be larger than the given box to make sure that all vertices of the+-- arrangement actually fit.+--+-- running time: \(O(n^2\log n\)+constructArrangementInBox            :: (Ord r, Fractional r)+                                     => proxy s+                                     -> Rectangle () r+                                     -> [Line 2 r :+ l]+                                     -> Arrangement s l () (Maybe l) () r+constructArrangementInBox px rect ls = let b  = makeBoundingBox ls+                                       in constructArrangementInBox' px (b <> rect) ls+++-- | Constructs the arrangemnet inside the box. (for parts to be useful, it is+-- assumed this boxfits at least the boundingbox of the intersections in the+-- Arrangement)+constructArrangementInBox'            :: (Ord r, Fractional r)+                                      => proxy s+                                      -> Rectangle () r+                                      -> [Line 2 r :+ l]+                                      -> Arrangement s l () (Maybe l) () r+constructArrangementInBox' px rect ls =+    Arrangement (V.fromList ls) subdiv rect (link parts' subdiv)+  where+    subdiv = fromConnectedSegments px segs+                & rawVertexData.traverse.dataVal .~ ()+    (segs,parts') = computeSegsAndParts rect ls++computeSegsAndParts         :: (Ord r, Fractional r)+                            => Rectangle () r+                            -> [Line 2 r :+ l]+                            -> ( [LineSegment 2 () r :+ Maybe l]+                               , [(Point 2 r, Maybe (Line 2 r :+ l))]+                               )+computeSegsAndParts rect ls = ( segs <> boundarySegs, parts')+  where+    segs         = map (&extra %~ Just)+                 . concatMap (\(l,ls') -> perLine rect l ls') $ makePairs ls+    boundarySegs = map (:+ Nothing) . toSegments . dupFirst $ map fst parts'+    dupFirst = \case []       -> []+                     xs@(x:_) -> xs ++ [x]+    parts'       = unBoundedParts rect ls+++perLine       :: forall r l. (Ord r, Fractional r)+              => Rectangle () r -> Line 2 r :+ l -> [Line 2 r :+ l]+              -> [LineSegment 2 () r :+ l]+perLine b m ls = map (:+ m^.extra) . toSegments . rmDuplicates . List.sort $ vs <> vs'+  where+    rmDuplicates = map head . List.group+    vs  = mapMaybe (m `intersectionPoint`) ls+    vs' = maybe [] (\(p,q) -> [p,q]) . asA (Proxy :: Proxy (Point 2 r, Point 2 r))+        $ (m^.core) `intersect` (Boundary b)+++intersectionPoint                   :: (Ord r, Fractional r)+                                    => Line 2 r :+ l -> Line 2 r :+ l -> Maybe (Point 2 r)+intersectionPoint (l :+ _) (m :+ _) = asA (Proxy :: Proxy (Point 2 r)) $ l `intersect` m+++toSegments      :: Ord r => [Point 2 r] -> [LineSegment 2 () r]+toSegments ps = let pts = map ext $ ps in+  zipWith ClosedLineSegment pts (tail pts)+++-- | Constructs a boundingbox containing all intersections+--+-- running time: \(O(n^2)\), where \(n\) is the number of input lines+makeBoundingBox :: (Ord r, Fractional r) => [Line 2 r :+ l] -> Rectangle () r+makeBoundingBox = grow 1 . boundingBoxList' . intersections++-- | Computes all intersections+intersections :: (Ord r, Fractional r) => [Line 2 r :+ l] -> [Point 2 r]+intersections = mapMaybe (uncurry intersectionPoint) . allPairs+++-- intersections :: forall p r. (Ord r, Fractional r)+--               => [Line 2 r :+ p] -> Map.Map (Point 2 r) (NonEmpty (Line 2 r :+ p))+-- intersections = Map.map sortNub . collect+--               . mapMaybe (\(l,m) -> (l, m,) <$> f l m) . allPairs+--   where+--     f (l :+ _) (m :+ _) = asA (Proxy :: Proxy (Point 2 r)) $ l `intersect` m++++-- collect :: Ord k => [(v,v,k)] -> Map.Map k (NonEmpty v)+-- collect = foldr f mempty+--   where+--     f (l,m,p) = Map.insertWith (<>) p (NonEmpty.fromList [l,m])++-- sortNub :: Ord r => NonEmpty (Line 2 r :+ p) -> NonEmpty (Line 2 r :+ p)+-- sortNub = fmap (NonEmpty.head) .  groupLines++-- groupLines :: Ord r => NonEmpty (Line 2 r :+ p)+--            -> NonEmpty (NonEmpty (Line 2 r :+ p))+-- groupLines = NonEmpty.groupWith1 L2 . NonEmpty.sortWith L2+++-- -- | Newtype wrapper that allows us to sort lines+-- newtype L2 r p = L2 (Line 2 r :+ p) deriving (Show)++-- instance Eq r => Eq (L2 r p) where+--   (L2 (Line p u :+ _)) == (L2 (Line q v :+ _)) = (p,u) == (q,v)+-- instance Ord r => Ord (L2 r p) where+--   (L2 (Line p u :+ _)) `compare` (L2 (Line q v :+ _)) = p `compare` q <> u `compare` v++-- -- | Collect the intersection points per line+-- byLine :: Ord r+--        => Map.Map (Point 2 r) (NonEmpty (Line 2 r :+ p))+--        -> Map.Map (L2 r p)    (NonEmpty (Point 2 r))+-- byLine = foldr f mempty . flatten . Map.assocs+--   where+--     flatten = concatMap (\(p,ls) -> map (\l -> (L2 l,p)) $ NonEmpty.toList ls)+--     f (l,p) = Map.insertWith (<>) l $ NonEmpty.fromList [p]+++-- | Computes the intersections with a particular side+sideIntersections      :: (Ord r, Fractional r)+                       => [Line 2 r :+ l] -> LineSegment 2 q r+                       -> [(Point 2 r, Line 2 r :+ l)]+sideIntersections ls s = let l   = supportingLine s :+ undefined+                         in List.sortOn fst . filter (flip onSegment s . fst)+                          . mapMaybe (\m -> (,m) <$> l `intersectionPoint` m) $ ls++-- | Constructs the unbounded intersections. Reported in clockwise direction.+unBoundedParts         :: (Ord r, Fractional r)+                       => Rectangle () r+                       -> [Line 2 r :+ l]+                       -> [(Point 2 r, Maybe (Line 2 r :+ l))]+unBoundedParts rect ls = [tl] <> t <> [tr] <> reverse r <> [br] <> reverse b <> [bl] <> l+  where+    sideIntersections' = over (traverse._2) Just . sideIntersections ls+    (t,r,b,l)     = map4 sideIntersections'      $ sides   rect+    (tl,tr,br,bl) = map4 ((,Nothing) . (^.core)) $ corners rect+++map4              :: (a -> b) -> (a,a,a,a) -> (b,b,b,b)+map4 f (a,b',c,d) = (f a, f b', f c, f d)++-- | Links the vertices  of the outer boundary with those in the subdivision+link       :: Eq r => [(Point 2 r, a)] -> PlanarSubdivision s v (Maybe e) f r+           -> V.Vector (Point 2 r, VertexId' s, a)+link vs ps = V.fromList . map (\((p,x),(_,y)) -> (p,y,x)) . F.toList+           . fromJust' $ alignWith (\(p,_) (q,_) -> p == q) (CSeq.fromList vs) vs'+  where+    vs' = CSeq.fromList . map (\v -> (ps^.locationOf v,v) ) . V.toList+        $ boundaryVertices (outerFaceId ps) ps+    fromJust' = fromMaybe (error "Data.Geometry.Arrangement.link: fromJust")++--------------------------------------------------------------------------------++makePairs :: [a] -> [(a,[a])]+makePairs = go+  where+    go []     = []+    go (x:xs) = (x,xs) : map (\(y,ys) -> (y,x:ys)) (go xs)++allPairs    :: [a] -> [(a,a)]+allPairs ys = go ys+  where+    go []     = []+    go (x:xs) = map (x,) xs ++ go xs++-- | Given a predicate that tests if two elements of a CSeq match, find a+-- rotation of the seqs such at they match.+--+-- Running time: \(O(n)\)+alignWith         :: (a -> b -> Bool) -> CSeq.CSeq a -> CSeq.CSeq b+                  -> Maybe (CSeq.CSeq (a,b))+alignWith p xs ys = CSeq.zipL xs <$> CSeq.findRotateTo (p (CSeq.focus xs)) ys++--------------------------------------------------------------------------------++-- | Given an Arrangement and a line in the arrangement, follow the line+-- through he arrangement.+--+traverseLine       :: (Ord r, Fractional r)+                   => Line 2 r -> Arrangement s l v (Maybe e) f r -> [Dart s]+traverseLine l arr = let md    = findStart l arr+                         dup x = (x,x)+                     in maybe [] (List.unfoldr (fmap dup . follow arr)) md++-- | Find the starting point of the line  the arrangement+findStart       :: (Ord r, Fractional r)+                => Line 2 r -> Arrangement s l v (Maybe e) f r -> Maybe (Dart s)+findStart l arr = do+    (p,_)   <- asA (Proxy :: Proxy (Point 2 r, Point 2 r)) $+                 l `intersect` (Boundary $ arr^.boundedArea)+    (_,v,_) <- findStartVertex p arr+    findStartDart (arr^.subdivision) v++++-- | Given a point on the boundary of the boundedArea box; find the vertex+--  this point corresponds to.+--+-- running time: \(O(\log n)\)+--+-- basically; maps every point to a tuple of the point and the side the+-- point occurs on. We then binary search to find the point we are looking+-- for.+findStartVertex       :: (Ord r, Fractional r)+                      => Point 2 r+                      -> Arrangement s l v e f r+                      -> Maybe (Point 2 r, VertexId' s, Maybe (Line 2 r :+ l))+findStartVertex p arr = do+    ss <- findSide p+    i  <- binarySearchVec (pred' ss) (arr^.unboundedIntersections)+    pure $ arr^.unboundedIntersections.singular (ix i)+  where+    (t,r,b,l) = sides'' $ arr^.boundedArea+    sides'' = map4 (\(ClosedLineSegment a c) -> LineSegment (Closed a) (Open c)) . sides++    findSide q = fmap fst . List.find (onSegment q . snd) $ zip [1..] [t,r,b,l]++    pred' ss (q,_,_) = let Just j = findSide q+                           x      = before (ss,p) (j,q)+                       in  x == LT || x == EQ++    before (i,p') (j,q') = case i `compare` j of+                                LT -> LT+                                GT -> GT+                                EQ | i == 2 || i == 3 -> Down p' `compare` Down q'+                                   | otherwise        -> p' `compare` q'+++-- | Find the starting dart of the given vertex v. Reports a dart s.t.+-- tailOf d = v+--+-- running me: \(O(k)\) where \(k\) is the degree of the vertex+findStartDart      :: PlanarSubdivision s v (Maybe e) f r -> VertexId' s -> Maybe (Dart s)+findStartDart ps v = V.find (\d -> isJust $ ps^.dataOf d) $ incidentEdges v ps+    -- the "real" dart is the one that has ata associated to it.+++-- | Given a dart d that incoming to v (headOf d == v), find the outgoing dart+-- colinear with the incoming one. Again reports dart d' s.t. tailOf d' = v+--+-- running time: \(O(k)\), where k is the degree of the vertex d points to+follow       :: (Ord r, Num r) => Arrangement s l v e f r -> Dart s -> Maybe (Dart s)+follow arr d = V.find extends $ incidentEdges v ps+  where+    ps = arr^.subdivision+    v  = headOf d ps+    (up,vp) = over both (^.location) $ endPointData d ps++    extends d' = let wp = ps^.locationOf (headOf d' ps)+                 in d' /= twin d && ccw up vp wp == CoLinear++--------------------------------------------------------------------------------++-- TODO: we can skip the findStart by just traversing from all boundary points++-- computeFaceData :: (Arrangement s v e f r -> Dart s -> f')+--                -> Arrangement s v e f r -> V.Vertex f'+-- computeFaceData arr f = fmap fromJust . V.create $ do+--                           v <- MV.replicate (arr^.subdivision.to numFaces) Nothing+--                           mapM_ (computeFaceData' arr f v) $ arr^.inputLines+--                           pure v+++-- computeFaceData' arr f v l = mapM_ (assign ) traverseLine arr l++--------------------------------------------------------------------------------
src/Data/Geometry/Ball.hs view
@@ -1,11 +1,15 @@ {-# 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+-- Copyright   :  (C) Frank Staals+-- License     :  see the LICENSE file+-- Maintainer  :  Frank Staals+--+-- \(d\)-dimensional Balls and Spheres+--+-------------------------------------------------------------------------------- module Data.Geometry.Ball where  import           Control.DeepSeq
src/Data/Geometry/Box.hs view
@@ -3,12 +3,16 @@ {-# 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+-- Copyright   :  (C) Frank Staals+-- License     :  see the LICENSE file+-- Maintainer  :  Frank Staals+--+-- Orthogonal \(d\)-dimensiontal boxes (e.g. rectangles)+--+-------------------------------------------------------------------------------- module Data.Geometry.Box( module Data.Geometry.Box.Internal                         , topSide, leftSide, bottomSide, rightSide                         , sides, sides'
src/Data/Geometry/Box/Internal.hs view
@@ -2,6 +2,16 @@ {-# LANGUAGE ScopedTypeVariables  #-} {-# LANGUAGE UndecidableInstances  #-} {-# LANGUAGE InstanceSigs  #-}+--------------------------------------------------------------------------------+-- |+-- Module      :  Data.Geometry.Box.Internal+-- Copyright   :  (C) Frank Staals+-- License     :  see the LICENSE file+-- Maintainer  :  Frank Staals+--+-- Orthogonal \(d\)-dimensiontal boxes (e.g. rectangles)+--+-------------------------------------------------------------------------------- module Data.Geometry.Box.Internal where  import           Control.DeepSeq@@ -11,19 +21,17 @@ import           Data.Geometry.Point import           Data.Geometry.Properties import           Data.Geometry.Transformation-import           Data.Geometry.Vector (Vector, Arity, C(..))+import           Data.Geometry.Vector import qualified Data.Geometry.Vector as V import qualified Data.List.NonEmpty as NE import           Data.Proxy import qualified Data.Range as R-import           Data.Semigroup import qualified Data.Semigroup.Foldable as F import qualified Data.Vector.Fixed as FV import           Data.Vinyl.CoRec (asA) import           GHC.Generics (Generic) import           GHC.TypeLits - --------------------------------------------------------------------------------  -- | Coordinate wize minimum@@ -56,6 +64,12 @@ -- coordinates, create a box. box          :: Point d r :+ p -> Point d r :+ p -> Box d p r box low high = Box (low&core %~ CWMin) (high&core %~ CWMax)++-- | 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 v = V.replicate x+           in b&minP.core.cwMin %~ (.-^ v)+               &maxP.core.cwMax %~ (.+^ v)  -- | Build a d dimensional Box given d ranges. fromExtent    :: Arity d => Vector d (R.Range r) -> Box d () r
src/Data/Geometry/HalfLine.hs view
@@ -60,23 +60,18 @@ --------------------------------------------------------------------------------  halfLineToSubLine                :: (Arity d, Num r)-                                 => HalfLine d r -> SubLine d () (UnBounded r)-halfLineToSubLine (HalfLine p v) = let l = fmap Val $ Line p v+                                 => HalfLine d r -> SubLine d () (UnBounded r) r+halfLineToSubLine (HalfLine p v) = let l = Line p v                                    in SubLine l (Interval (Closed $ ext (Val 0))                                                           (Open   $ ext MaxInfinity))  -fromSubLine               :: (Num r, Arity d) => SubLine d p (UnBounded r) -> Maybe (HalfLine d r)-fromSubLine (SubLine l' i) = case (i^.start.core, i^.end.core) of-                               (Val x, MaxInfinity) -> f x-                               (MinInfinity, Val x) -> f x-                               _                    -> Nothing-  where-    f x = (\l@(Line _ v) -> HalfLine (pointAt x l) v)-       <$> T.mapM unBoundedToMaybe l'---+fromSubLine               :: (Num r, Arity d) => SubLine d p (UnBounded r) r+                          -> Maybe (HalfLine d r)+fromSubLine (SubLine l i) = case (i^.start.core, i^.end.core) of+   (Val x, MaxInfinity) -> Just $ HalfLine (pointAt x l) (l^.direction)+   (MinInfinity, Val x) -> Just $ HalfLine (pointAt x l) ((-1) *^ l^.direction)+   _                    -> Nothing  type instance IntersectionOf (HalfLine 2 r) (Line 2 r) = [ NoIntersection                                                          , Point 2 r
+ src/Data/Geometry/HyperPlane.hs view
@@ -0,0 +1,94 @@+{-# LANGUAGE DeriveAnyClass  #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE TemplateHaskell  #-}+module Data.Geometry.HyperPlane where++import Control.DeepSeq+import Control.Lens+import Data.Geometry.Line+import Data.Geometry.Point+import Data.Geometry.Properties+import Data.Geometry.Transformation+import Data.Geometry.Vector+import GHC.Generics (Generic)+import GHC.TypeLits++--------------------------------------------------------------------------------++-- | Hyperplanes embedded in a \(d\) dimensional space.+data HyperPlane (d :: Nat) (r :: *) = HyperPlane { _inPlane   :: !(Point d r)+                                                 , _normalVec :: !(Vector d r)+                                                 } deriving Generic+makeLenses ''HyperPlane++type instance Dimension (HyperPlane d r) = d+type instance NumType   (HyperPlane d r) = r++deriving instance (Arity d, Show r)   => Show    (HyperPlane d r)+deriving instance (Arity d, Eq r)     => Eq      (HyperPlane d r)+deriving instance (NFData r, Arity d) => NFData  (HyperPlane d r)+deriving instance Arity d => Functor     (HyperPlane d)+deriving instance Arity d => Foldable    (HyperPlane d)+deriving instance Arity d => Traversable (HyperPlane d)++instance (Arity d, Arity (d + 1), Fractional r) => IsTransformable (HyperPlane d r) where+  transformBy t (HyperPlane p v) = HyperPlane (transformBy t p) (transformBy t v)++--------------------------------------------------------------------------------++-- | Test if a point lies on a hyperplane.+onHyperPlane                      :: (Num r, Eq r, Arity d)+                                  => Point d r -> HyperPlane d r -> Bool+q `onHyperPlane` (HyperPlane p n) = n `dot` (q .-. p) == 0+++-- -- | Compute a transformation that maps the last dimension (i.e. the d-axis) to+-- -- the normal vector of the plane. The origin of the coordinate system will+-- -- correspond to the inPlane point.+-- changeCoordinateSystem                  :: Floating r => HyperPlane 3 r -> Vector 3 r+--                                         -> Transformation 3 r+-- changeCoordinateSystem (HyperPlane p n) u = rotateTo (Vector3 u v w)+--                                        |.| translation (origin .-. p)+--   where+--     v = undefined+--     w = normalize n++-- toPlaneCoordinates :: HyperPlane d r ->++--------------------------------------------------------------------------------+-- * 3 Dimensional planes++type Plane = HyperPlane 3++pattern Plane     :: Point 3 r -> Vector 3 r -> Plane r+pattern Plane p n = HyperPlane p n++from3Points       :: Num r => Point 3 r -> Point 3 r -> Point 3 r -> HyperPlane 3 r+from3Points p q r = let u = q .-. p+                        v = r .-. p+                    in HyperPlane p (u `cross` v)+++type instance IntersectionOf (Line 3 r) (Plane r) = [NoIntersection, Point 3 r, Line 3 r]++instance (Eq r, Fractional r) => (Line 3 r) `IsIntersectableWith` (Plane r) where+  nonEmptyIntersection = defaultNonEmptyIntersection+  l@(Line p v) `intersect` (HyperPlane q n)+      | denum == 0 = if num == 0 then coRec l else coRec NoIntersection+      | otherwise  = coRec $ p .+^ (num / denum) *^ v+    where+      num   = (q .-. p) `dot` n+      denum = v `dot` n+    -- see https://en.wikipedia.org/wiki/Line%E2%80%93plane_intersection+++--------------------------------------------------------------------------------+-- * Supporting Planes++-- | Types for which we can compute a supporting hyperplane, i.e. a hyperplane+-- that contains the thing of type t.+class HasSupportingPlane t where+  supportingPlane :: t -> HyperPlane (Dimension t) (NumType t)++instance HasSupportingPlane (HyperPlane d r) where+  supportingPlane = id
src/Data/Geometry/Interval.hs view
@@ -24,7 +24,7 @@ import qualified Data.Foldable as F import           Data.Geometry.Properties import           Data.Range-import           Data.Semigroup+import           Data.Semigroup(Arg(..)) import qualified Data.Traversable as T import           Data.Vinyl import           Data.Vinyl.CoRec
src/Data/Geometry/Ipe.hs view
@@ -1,15 +1,21 @@-{-|-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+-- Copyright   :  (C) Frank Staals+-- License     :  see the LICENSE file+-- Maintainer  :  Frank Staals+--+-- Reexports the functionality for reading and writing Ipe files.+--+-------------------------------------------------------------------------------- module Data.Geometry.Ipe( module Data.Geometry.Ipe.Types                         , module Data.Geometry.Ipe.Writer                         , module Data.Geometry.Ipe.Reader                         , module Data.Geometry.Ipe.IpeOut                         , module Data.Geometry.Ipe.FromIpe                         , module Data.Geometry.Ipe.Attributes+                        , module Data.Geometry.Ipe.Value+                        , module Data.Geometry.Ipe.Color                         ) where  import Data.Geometry.Ipe.Types@@ -18,3 +24,5 @@ import Data.Geometry.Ipe.IpeOut import Data.Geometry.Ipe.FromIpe import Data.Geometry.Ipe.Attributes+import Data.Geometry.Ipe.Value+import Data.Geometry.Ipe.Color(IpeColor(..))
src/Data/Geometry/Ipe/Attributes.hs view
@@ -3,11 +3,20 @@ {-# LANGUAGE UnicodeSyntax #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE UndecidableInstances #-}+--------------------------------------------------------------------------------+-- |+-- Module      :  Data.Geometry.Ipe.Attributes+-- Copyright   :  (C) Frank Staals+-- License     :  see the LICENSE file+-- Maintainer  :  Frank Staals+--+-- Possible Attributes we can assign to items in an Ipe file+--+-------------------------------------------------------------------------------- module Data.Geometry.Ipe.Attributes where  import Control.Lens hiding (rmap, Const)-import Data.Colour.SRGB-import Data.Semigroup+import Data.Geometry.Ipe.Value import Data.Singletons import Data.Singletons.TH import Data.Text (Text)@@ -15,6 +24,8 @@ import Data.Vinyl.Functor import Data.Vinyl.TypeLevel import GHC.Exts+import Text.Read(lexP, step, parens, prec, (+++)+                , Lexeme(Ident), readPrec, readListPrec, readListPrecDefault)  -------------------------------------------------------------------------------- @@ -62,19 +73,44 @@                                    -- Labels in universe u to concrete types              (label :: u) = GAttr { _getAttr :: Maybe (Apply f label) } -deriving instance Show (Apply f label) => Show (Attr f label)-deriving instance Read (Apply f label) => Read (Attr f label)++ deriving instance Eq   (Apply f label) => Eq   (Attr f label) deriving instance Ord  (Apply f label) => Ord  (Attr f label)  makeLenses ''Attr +-- | Constructor for constructing an Attr given an actual value. pattern Attr   :: Apply f label -> Attr f label pattern Attr x = GAttr (Just x) +-- | An Attribute that is not set pattern NoAttr :: Attr f label pattern NoAttr = GAttr Nothing+{-# COMPLETE NoAttr, Attr #-} +instance Show (Apply f label) => Show (Attr f label) where+  showsPrec d NoAttr   = showParen (d > app_prec) $ showString "NoAttr"+    where app_prec = 10+  showsPrec d (Attr a) = showParen (d > up_prec) $+                           showString "Attr " . showsPrec (up_prec+1) a+    where up_prec  = 5++instance Read (Apply f label) => Read (Attr f label) where+  readPrec = parens $ (prec app_prec $ do+                                         Ident "NoAttr" <- lexP+                                         pure NoAttr)+                  +++ (prec up_prec $ do+                                         Ident "Attr" <- lexP+                                         a <- step readPrec+                                         pure $ Attr a)+    where+      app_prec = 10+      up_prec = 5+  readListPrec = readListPrecDefault+++ -- | Give pref. to the *RIGHT* instance Semigroup (Attr f l) where   _ <> b@(Attr _) = b@@ -84,17 +120,13 @@   mempty  = NoAttr   mappend = (<>) -newtype Attributes (f :: TyFun u * -> *) (ats :: [u]) =-  Attrs { _unAttrs :: Rec (Attr f) ats }--makeLenses ''Attributes----- type All' c i = RecAll (Attr (IpeObjectSymbolF i)) (IpeObjectAttrF i) c+newtype Attributes (f :: TyFun u * -> *) (ats :: [u]) = Attrs (Rec (Attr f) ats) --- deriving instance All' Show atsShow (Attributes f ats)+unAttrs :: Lens (Attributes f ats) (Attributes f' ats') (Rec (Attr f) ats) (Rec (Attr f') ats')+unAttrs = lens (\(Attrs r) -> r) (const Attrs)  deriving instance (RecAll (Attr f) ats Show) => Show (Attributes f ats)+-- deriving instance (RecAll (Attr f) ats Read) => Read (Attributes f ats)  instance (RecAll (Attr f) ats Eq)   => Eq   (Attributes f ats) where   (Attrs a) == (Attrs b) = and . recordToList@@ -192,20 +224,10 @@ --                              deriving (Show,Eq)  --- | 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,Functor,Foldable,Traversable) -instance IsString (IpeValue v) where-  fromString = Named . fromString- 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) -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
+ src/Data/Geometry/Ipe/Color.hs view
@@ -0,0 +1,110 @@+{-# LANGUAGE OverloadedStrings #-}+--------------------------------------------------------------------------------+-- |+-- Module      :  Data.Geometry.Ipe.Color+-- Copyright   :  (C) Frank Staals+-- License     :  see the LICENSE file+-- Maintainer  :  Frank Staals+--+-- Data type for representing colors in ipe as well as the colors available in+-- the standard ipe stylesheet.+--+--------------------------------------------------------------------------------+module Data.Geometry.Ipe.Color where++import           Data.Colour.SRGB (RGB(..))+import           Data.Geometry.Ipe.Value+import           Data.Text+--------------------------------------------------------------------------------++newtype IpeColor r = IpeColor (IpeValue (RGB r))    deriving (Show,Read,Eq)++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)++-- | Creates a named color+named :: Text -> IpeColor r+named = IpeColor . Named++--------------------------------------------------------------------------------+-- * Basic Named colors++red :: IpeColor r+red = named "red"++green :: IpeColor r+green = named "green"++blue :: IpeColor r+blue = named "blue"++yellow :: IpeColor r+yellow = named "yellow"++orange :: IpeColor r+orange = named "orange"++gold :: IpeColor r+gold = named "gold"++purple :: IpeColor r+purple = named "purple"++gray :: IpeColor r+gray = named "gray"++brown :: IpeColor r+brown = named "brown"++navy :: IpeColor r+navy = named "navy"++pink :: IpeColor r+pink = named "pink"++seagreen :: IpeColor r+seagreen = named "seagreen"++turquoise :: IpeColor r+turquoise = named "turquoise"++violet :: IpeColor r+violet = named "violet"++darkblue :: IpeColor r+darkblue = named "darkblue"++darkcyan :: IpeColor r+darkcyan = named "darkcyan"++darkgray :: IpeColor r+darkgray = named "darkgray"++darkgreen :: IpeColor r+darkgreen = named "darkgreen"++darkmagenta :: IpeColor r+darkmagenta = named "darkmagenta"++darkorange :: IpeColor r+darkorange = named "darkorange"++darkred :: IpeColor r+darkred = named "darkred"++lightblue :: IpeColor r+lightblue = named "lightblue"++lightcyan :: IpeColor r+lightcyan = named "lightcyan"++lightgray :: IpeColor r+lightgray = named "lightgray"++lightgreen :: IpeColor r+lightgreen = named "lightgreen"++lightyellow :: IpeColor r+lightyellow = named "lightyellow"
src/Data/Geometry/Ipe/FromIpe.hs view
@@ -1,4 +1,14 @@ {-# LANGUAGE OverloadedStrings #-}+--------------------------------------------------------------------------------+-- |+-- Module      :  Data.Geometry.Ipe.FromIpe+-- Copyright   :  (C) Frank Staals+-- License     :  see the LICENSE file+-- Maintainer  :  Frank Staals+--+-- Functions that help reading geometric values from ipe images.+--+-------------------------------------------------------------------------------- module Data.Geometry.Ipe.FromIpe where  import           Control.Lens hiding (Simple)@@ -9,21 +19,23 @@ import qualified Data.Geometry.PolyLine as PolyLine import           Data.Geometry.Polygon import           Data.Geometry.Properties-import qualified Data.Seq2 as S2-import qualified Data.List.NonEmpty as NonEmpty+import           Data.Geometry.Triangle+import qualified Data.LSeq as LSeq+import           Data.List.NonEmpty (NonEmpty(..))  -------------------------------------------------------------------------------- -- $setup+-- >>> :set -XOverloadedStrings+-- >>> import Data.Geometry.Ipe.Attributes+-- >>> import Data.Geometry.Ipe.Color(IpeColor(..))+-- >>> import Data.Geometry.Point -- >>> :{--- import           Data.Geometry.Ipe.Attributes--- -- let testPath :: Path Int---     testPath = Path . S2.l1Singleton  . PolyLineSegment . PolyLine.fromPoints . map ext+--     testPath = Path . fromSingleton  . PolyLineSegment+--              . PolyLine.fromPoints . map ext --              $ [ origin, point2 10 10, point2 200 100 ]--- --     testPathAttrs :: IpeAttributes Path Int---     testPathAttrs = attr SStroke (IpeColor (Named "red"))-+--     testPathAttrs = attr SStroke (IpeColor "red") --     testObject :: IpeObject Int --     testObject = IpePath (testPath :+ testPathAttrs) -- :}@@ -42,11 +54,11 @@ -- | 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] :+ ())})+-- Just (PolyLine {_points = LSeq (fromList [Point2 [0,0] :+ (),Point2 [10,10] :+ (),Point2 [200,100] :+ ()])}) _asPolyLine :: Prism' (Path r) (PolyLine.PolyLine 2 () r) _asPolyLine = prism' poly2path path2poly   where-    poly2path = Path . S2.l1Singleton  . PolyLineSegment+    poly2path = Path . fromSingleton  . PolyLineSegment     path2poly = preview (pathSegments.traverse._PolyLineSegment)     -- TODO: Check that the path actually is a polyline, rather     -- than ignoring everything that does not fit@@ -57,6 +69,19 @@   where     path2poly p = pathToPolygon p >>= either pure (const Nothing) +-- | Convert to a triangle+_asTriangle :: Prism' (Path r) (Triangle 2 () r)+_asTriangle = prism' triToPath path2tri+  where+    triToPath (Triangle p q r) = polygonToPath . fromPoints . map (&extra .~ ()) $ [p,q,r]+    path2tri p = case p^..pathSegments.traverse._PolygonPath of+                    []   -> Nothing+                    [pg] -> case polygonVertices pg of+                              (a :| [b,c]) -> Just $ Triangle a b c+                              _            -> Nothing+                    _    -> Nothing++ -- | Convert to a multipolygon _asMultiPolygon :: Prism' (Path r) (MultiPolygon () r) _asMultiPolygon = prism' polygonToPath path2poly@@ -64,9 +89,9 @@     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+polygonToPath pg@(SimplePolygon _) = Path . fromSingleton . PolygonPath $ pg+polygonToPath (MultiPolygon vs hs) = Path . LSeq.fromNonEmpty . fmap PolygonPath+                                   $ (SimplePolygon vs) :| hs   pathToPolygon   :: Path r -> Maybe (Either (SimplePolygon () r) (MultiPolygon () r))@@ -77,12 +102,12 @@   --- | use the first prism to select the ipe object to depicle with, and the second+-- | 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}}})+-- Just (PolyLine {_points = LSeq (fromList [Point2 [0,0] :+ (),Point2 [10,10] :+ (),Point2 [200,100] :+ ()])} :+ Attrs {NoAttr, NoAttr, NoAttr, NoAttr, Attr IpeColor (Named "red"), NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr}) _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@@ -144,3 +169,5 @@                => FilePath -> IO [g :+ IpeAttributes (DefaultFromIpe g) r] readAllFrom fp = readAll <$> readSinglePageFile fp +fromSingleton :: a -> LSeq.LSeq 1 a+fromSingleton = LSeq.fromNonEmpty . (:| [])
src/Data/Geometry/Ipe/IpeOut.hs view
@@ -1,7 +1,22 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-}+--------------------------------------------------------------------------------+-- |+-- Module      :  Data.Geometry.Ipe.IpeOut+-- Copyright   :  (C) Frank Staals+-- License     :  see the LICENSE file+-- Maintainer  :  Frank Staals+--+-- Functions that help drawing geometric values in ipe. An "IpeOut" is+-- essenitally a function that converts a geometric type g into an IpeObject.+--+-- We also proivde a "HasDefaultIpeOut" typeclass that defines a default+-- conversion function from a geometry type g to an ipe type.+--+-------------------------------------------------------------------------------- module Data.Geometry.Ipe.IpeOut where + import           Control.Lens hiding (Simple) import           Data.Bifunctor import           Data.Ext@@ -9,72 +24,83 @@ import           Data.Geometry.Boundary import           Data.Geometry.Box import           Data.Geometry.Ipe.Attributes+import           Data.Geometry.Ipe.Color (IpeColor(..)) 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+import           Data.Geometry.PolyLine(PolyLine,fromLineSegment) import           Data.Geometry.Polygon import           Data.Geometry.Polygon.Convex import           Data.Geometry.Properties import           Data.Geometry.Transformation-import           Data.Maybe (fromMaybe)+import qualified Data.LSeq as LSeq+import           Data.List.NonEmpty (NonEmpty(..)) import           Data.Proxy-import           Data.Semigroup-import qualified Data.Seq2 as S2 import           Data.Text (Text)+import           Data.Maybe (fromMaybe)+import           Linear.Affine ((.+^)) import           Data.Vinyl.CoRec  -------------------------------------------------------------------------------- --- | An IpeOut is essentially a funciton to convert a geometry object of type--- 'g' into an ipe object of type 'i'.-newtype IpeOut g i = IpeOut { asIpe :: g -> i } deriving (Functor)----- | Given an geometry object, and a record with its attributes, construct an ipe--- Object representing it using the default conversion.-asIpeObject :: (HasDefaultIpeOut g, DefaultIpeOut g ~ i, NumType g ~ r)-            => g -> IpeAttributes i r -> IpeObject r-asIpeObject = asIpeObjectWith defaultIpeOut---- | asIpeObject with its arguments flipped. Convenient if you don't want to--- map asIpeObject over a list or so.-asIpeObject' :: (HasDefaultIpeOut g, DefaultIpeOut g ~ i, NumType g ~ r)-             => IpeAttributes i r -> g -> IpeObject r-asIpeObject' = flip asIpeObject+-- $setup+-- >>> :set -XOverloadedStrings+-- >>> :{+-- let myPolygon = fromPoints . map ext $ [origin, Point2 10 10, Point2 100 200]+-- :} +--------------------------------------------------------------------------------+-- * The IpeOut type and the default combinator to use it --- -- | Given a IpeOut that specifies how to convert a geometry object into an--- 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-asIpeObjectWith io g ats = asIpe (ipeObject io ats) g+type IpeOut g i r = g -> IpeObject' i r  --- | Create an ipe group without group attributes-asIpeGroup :: [IpeObject r] -> IpeObject r-asIpeGroup = flip asIpeGroup' mempty---- | Creates a group out of ipe-asIpeGroup'        :: [IpeObject r] -> IpeAttributes Group r -> IpeObject r-asIpeGroup' gs ats = IpeGroup $ Group gs :+ ats+-- | Add attributes to an IpeObject'+(!)       :: IpeObject' i r -> IpeAttributes i r -> IpeObject' i r+(!) i ats = i&extra %~ (<> ats) ---------------------------------------------------------------------------------+-- | Render an ipe object+--+--+-- >>> :{+--   iO $ defIO myPolygon ! attr SFill (IpeColor "blue")+--                        ! attr SLayer "alpha"+--                        ! attr SLayer "beta"+-- :}+-- IpePath (Path {_pathSegments = LSeq (fromList [PolygonPath SimplePolygon CSeq [Point2 [0,0] :+ (),Point2 [10,10] :+ (),Point2 [100,200] :+ ()]])} :+ Attrs {Attr LayerName {_layerName = "beta"}, NoAttr, NoAttr, NoAttr, NoAttr, Attr IpeColor (Named "blue"), NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr})+--+-- >>> :{+--   iO $ ipeGroup [ iO $ ipePolygon myPolygon ! attr SFill (IpeColor "red")+--                 ] ! attr SLayer "alpha"+-- :}+-- IpeGroup (Group [IpePath (Path {_pathSegments = LSeq (fromList [PolygonPath SimplePolygon CSeq [Point2 [0,0] :+ (),Point2 [10,10] :+ (),Point2 [100,200] :+ ()]])} :+ Attrs {NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, Attr IpeColor (Named "red"), NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr})] :+ Attrs {Attr LayerName {_layerName = "alpha"}, NoAttr, NoAttr, NoAttr, NoAttr})+--+iO :: ToObject i => IpeObject' i r -> IpeObject r+iO = mkIpeObject --- | Helper to construct an IpeOut g IpeObject , if we already know how to--- construct a specific Ipe type.-ipeObject        :: (ToObject i, NumType g ~ r)-                   => IpeOut g (IpeObject' i r) -> IpeAttributes i r -> IpeOut g (IpeObject r)-ipeObject io ats = IpeOut $ \g -> let (i :+ ats') = asIpe io g-                                    in ipeObject' i (ats' <> ats)+-- | Render to an ipe object using the defIO IpeOut+--+--+-- >>> :{+--   iO'' myPolygon $  attr SFill (IpeColor "red")+--                  <> attr SLayer "alpha"+--                  <> attr SLayer "beta"+-- :}+-- IpePath (Path {_pathSegments = LSeq (fromList [PolygonPath SimplePolygon CSeq [Point2 [0,0] :+ (),Point2 [10,10] :+ (),Point2 [100,200] :+ ()]])} :+ Attrs {Attr LayerName {_layerName = "beta"}, NoAttr, NoAttr, NoAttr, NoAttr, Attr IpeColor (Named "red"), NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr})+--+-- >>> iO'' [ myPolygon , myPolygon ] $ attr SLayer "alpha"+-- IpeGroup (Group [IpePath (Path {_pathSegments = LSeq (fromList [PolygonPath SimplePolygon CSeq [Point2 [0,0] :+ (),Point2 [10,10] :+ (),Point2 [100,200] :+ ()]])} :+ Attrs {NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr}),IpePath (Path {_pathSegments = LSeq (fromList [PolygonPath SimplePolygon CSeq [Point2 [0,0] :+ (),Point2 [10,10] :+ (),Point2 [100,200] :+ ()]])} :+ Attrs {NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr, NoAttr})] :+ Attrs {Attr LayerName {_layerName = "alpha"}, NoAttr, NoAttr, NoAttr, NoAttr})+iO''       :: ( HasDefaultIpeOut g, NumType g ~ r+             , DefaultIpeOut g ~ i, ToObject i+             ) => g -> IpeAttributes i r+           -> IpeObject r+iO'' g ats = iO $ defIO g ! ats --- | Construct an ipe object from the core of an Ext-coreOut    :: IpeOut g i -> IpeOut (g :+ a) i-coreOut io = IpeOut $ asIpe io . (^.core)+-- | generate an ipe object without any specific attributes+iO' :: HasDefaultIpeOut g => g -> IpeObject (NumType g)+iO' = iO . defIO  -------------------------------------------------------------------------------- -- * Default Conversions@@ -84,157 +110,105 @@ class ToObject (DefaultIpeOut g) => HasDefaultIpeOut g where   type DefaultIpeOut g :: * -> * -  defaultIpeOut :: IpeOut g (IpeObject' (DefaultIpeOut g) (NumType g))+  defIO :: IpeOut g (DefaultIpeOut g) (NumType g) -  -- defaultIpeObject :: RecApplicative (AttributesOf (DefaultIpeOut g))-  --                  => IpeOut g (IpeObject (NumType g))-  -- defaultIpeObject = IpeOut $ flip asIpeObject mempty+instance (HasDefaultIpeOut g, a ~ IpeAttributes (DefaultIpeOut g) (NumType g))+        => HasDefaultIpeOut (g :+ a) where+  type DefaultIpeOut (g :+ a) = DefaultIpeOut g+  defIO (g :+ ats) = defIO g ! ats --- instance HasDefaultIpeOut g => HasDefaultIpeOut [g] where---   type DefaultIpeOut [g] = Group---   defaultIpeOut = IpeOut $ asIpeGroup . map (asIpeObject' mempty)+instance HasDefaultIpeOut a => HasDefaultIpeOut [a] where+  type DefaultIpeOut [a] = Group+  defIO = ipeGroup . map (iO .  defIO)  instance HasDefaultIpeOut (Point 2 r) where   type DefaultIpeOut (Point 2 r) = IpeSymbol-  defaultIpeOut = ipeDiskMark+  defIO = ipeDiskMark  instance HasDefaultIpeOut (LineSegment 2 p r) where   type DefaultIpeOut (LineSegment 2 p r) = Path-  defaultIpeOut = ipeLineSegment--instance Floating r => HasDefaultIpeOut (Disk p r) where-  type DefaultIpeOut (Disk p r) = Path-  defaultIpeOut = ipeDisk+  defIO = ipeLineSegment  instance HasDefaultIpeOut (PolyLine 2 p r) where   type DefaultIpeOut (PolyLine 2 p r) = Path-  defaultIpeOut = noAttrs ipePolyLine+  defIO = ipePolyLine +instance (Fractional r, Ord r) => HasDefaultIpeOut (Line 2 r) where+  type DefaultIpeOut (Line 2 r) = Path+  defIO = ipeLineSegment . toSeg+    where+      b :: Rectangle () r+      b = box (ext $ Point2 (-200) (-200)) (ext $ Point2 1200 1200)+      naive (Line p v) = ClosedLineSegment (ext p) (ext $ p .+^ v)+      toSeg l = fromMaybe (naive l) . asA (Proxy :: Proxy (LineSegment 2 () r))+              $ l `intersect` b+ 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")+  defIO = ipePolygon  instance HasDefaultIpeOut (SomePolygon p r) where   type DefaultIpeOut (SomePolygon p r) = Path-  defaultIpeOut = IpeOut $ either (asIpe defaultIpeOut) (asIpe defaultIpeOut)+  defIO = either defIO defIO  instance HasDefaultIpeOut (ConvexPolygon p r) where   type DefaultIpeOut (ConvexPolygon p r) = Path-  defaultIpeOut = IpeOut $ asIpe defaultIpeOut . view simplePolygon+  defIO = defIO . view simplePolygon ++instance Floating r => HasDefaultIpeOut (Disk p r) where+  type DefaultIpeOut (Disk p r) = Path+  defIO = ipeDisk+ -------------------------------------------------------------------------------- -- * Point Converters -ipeMark   :: Text -> IpeOut (Point 2 r) (IpeObject' IpeSymbol r)-ipeMark n = noAttrs . IpeOut $ flip Symbol n+ipeMark     :: Text -> IpeOut (Point 2 r) IpeSymbol r+ipeMark n p = Symbol p n :+ mempty -ipeDiskMark :: IpeOut (Point 2 r) (IpeObject' IpeSymbol r)+ipeDiskMark :: IpeOut (Point 2 r) IpeSymbol r ipeDiskMark = ipeMark "mark/disk(sx)"  ----------------------------------------------------------------------------------noAttrs :: Monoid extra => IpeOut g core -> IpeOut g (core :+ extra)-noAttrs = addAttributes mempty--addAttributes :: extra -> IpeOut g core -> IpeOut g (core :+ extra)-addAttributes ats io = IpeOut $ \g -> asIpe io g :+ ats----- | Default size of the cliping rectangle used to clip lines. This is--- Rectangle is large enough to cover the normal page size in ipe.-defaultClipRectangle :: (Num r, Ord r) => Rectangle () r-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 :: (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'--ipeLineSegment' :: IpeOut (LineSegment 2 p r) (PathSegment r)-ipeLineSegment' = IpeOut $ PolyLineSegment . fromLineSegment . first (const ())---ipePolyLine :: IpeOut (PolyLine 2 p r) (Path r)-ipePolyLine = fromPathSegment ipePolyLine'+-- * Path Converters -ipePolyLine' :: IpeOut (PolyLine 2 a r) (PathSegment r)-ipePolyLine' = IpeOut $ PolyLineSegment . first (const ())+ipeLineSegment   :: IpeOut (LineSegment 2 p r) Path r+ipeLineSegment s = (path . pathSegment $ s) :+ mempty -ipeDisk :: Floating r => IpeOut (Disk p r) (IpeObject' Path r)-ipeDisk = noAttrs . IpeOut $ asIpe ipeCircle . Boundary+ipePolyLine   :: IpeOut (PolyLine 2 p r) Path r+ipePolyLine p = (path . PolyLineSegment . first (const ()) $ p) :+ mempty -ipeCircle :: Floating r => IpeOut (Circle p r) (Path r)-ipeCircle = fromPathSegment ipeCircle'+ipeDisk   :: Floating r => IpeOut (Disk p r) Path r+ipeDisk d = ipeCircle (Boundary d) ! attr SFill (IpeColor "0.722 0.145 0.137") -ipeCircle' :: Floating r => IpeOut (Circle p r) (PathSegment r)-ipeCircle' = IpeOut circle''-  where-    circle'' (Circle (c :+ _) r) = EllipseSegment m+ipeCircle                     :: Floating r => IpeOut (Circle p r) Path r+ipeCircle (Circle (c :+ _) r) = (path $ EllipseSegment m) :+ mempty       where         m = translation (toVec c) |.| uniformScaling (sqrt r) ^. transformationMatrix         -- m is the matrix s.t. if we apply m to the unit circle centered at the origin, we         -- get the input circle. ---- | Helper to construct a IpeOut g Path, for when we already have an IpeOut g PathSegment-fromPathSegment    :: IpeOut g (PathSegment r) -> IpeOut g (Path r)-fromPathSegment io = IpeOut $ Path . S2.l1Singleton . asIpe io---ipePolygon :: IpeOut (Polygon t p r) (Path r)-ipePolygon = IpeOut $ io . first (const ())-  where-    io                       :: forall t r. Polygon t () r -> Path r-    io pg@(SimplePolygon _)  = pg^.re _asSimplePolygon-    io pg@(MultiPolygon _ _) = pg^.re _asMultiPolygon------------ ls = (ClosedLineSegment (ext origin) (ext (point2 1 1)))----- testzz :: IpeObject Integer--- testzz = asIpeObjectWith ipeLineSegment ls $ mempty <> attr SStroke (IpeColor "red")---+-- | Helper to construct a path from a singleton item+path :: PathSegment r -> Path r+path = Path . LSeq.fromNonEmpty . (:| []) --- test' :: Attributes (PathAttrElfSym1 Integer) (AttributesOf (Path Integer) (PathAttrElfSym1 Integer))--- -- test' :: RecApplicative (AttributesOf (Path Integer) (IpeObjectSymbolF (Path Integer)))--- --       => IpeAttributes (Path Integer)--- test' = mempty+pathSegment :: LineSegment 2 p r -> PathSegment r+pathSegment = PolyLineSegment . fromLineSegment . first (const ()) +-- | Draw a polygon+ipePolygon                          :: IpeOut (Polygon t p r) Path r+ipePolygon (first (const ()) -> pg) = case pg of+               (SimplePolygon _)  -> pg^.re _asSimplePolygon :+ mempty+               (MultiPolygon _ _) -> pg^.re _asMultiPolygon  :+ mempty  +--------------------------------------------------------------------------------+-- * Group Converters --- -- test' :: IpeObject Integer ('IpePath '[])--- test' = asIpeObject' ls emptyPathAttributes+ipeGroup    :: IpeOut [IpeObject r] Group r+ipeGroup xs = Group xs :+ mempty    --- emptyPathAttributes :: Rec (PathAttribute r) '[]--- emptyPathAttributes = RNil+--------------------------------------------------------------------------------
src/Data/Geometry/Ipe/PathParser.hs view
@@ -12,7 +12,6 @@ import           Data.Geometry.Transformation import           Data.Geometry.Vector import           Data.Ratio-import           Data.Semigroup import           Data.Text (Text) import qualified Data.Text as T import           Text.Parsec.Error (messageString, errorMessages)
src/Data/Geometry/Ipe/Reader.hs view
@@ -37,6 +37,8 @@ import           Data.Geometry.Ipe.ParserPrimitives (pInteger, pWhiteSpace) import           Data.Geometry.Ipe.PathParser import           Data.Geometry.Ipe.Types+import           Data.Geometry.Ipe.Value+import           Data.Geometry.Ipe.Color(IpeColor(..)) import           Data.Geometry.Point import           Data.Geometry.PolyLine import qualified Data.Geometry.Polygon as Polygon@@ -45,8 +47,7 @@ import qualified Data.List.NonEmpty as NE import           Data.Maybe (fromMaybe, mapMaybe) import           Data.Proxy-import qualified Data.Seq2 as S2-import           Data.Semigroup ((<>))+import qualified Data.LSeq as LSeq import           Data.Singletons import           Data.Text (Text) import qualified Data.Text as T@@ -210,7 +211,7 @@ dropRepeats = map head . L.group  instance (Coordinate r, Eq r) => IpeReadText (Path r) where-  ipeReadText = fmap (Path . S2.viewL1FromNonEmpty) . ipeReadText+  ipeReadText = fmap (Path . LSeq.fromNonEmpty) . ipeReadText  -------------------------------------------------------------------------------- -- Reading attributes
src/Data/Geometry/Ipe/Types.hs view
@@ -3,6 +3,16 @@ {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE QuasiQuotes #-} {-# LANGUAGE OverloadedStrings #-}+--------------------------------------------------------------------------------+-- |+-- Module      :  Data.Geometry.Ipe.Types+-- Copyright   :  (C) Frank Staals+-- License     :  see the LICENSE file+-- Maintainer  :  Frank Staals+--+-- Data type modeling the various elements in Ipe files.+--+-------------------------------------------------------------------------------- module Data.Geometry.Ipe.Types where  @@ -22,6 +32,7 @@ import           Data.Singletons.TH(genDefunSymbols)  import           Data.Geometry.Ipe.Literal+import           Data.Geometry.Ipe.Color import qualified Data.Geometry.Ipe.Attributes as AT import           Data.Geometry.Ipe.Attributes hiding (Matrix) import           Data.Text(Text)@@ -31,7 +42,7 @@   import qualified Data.List.NonEmpty as NE-import qualified Data.Seq2     as S2+import qualified Data.LSeq          as LSeq  -------------------------------------------------------------------------------- @@ -125,7 +136,7 @@   -- | A path is a non-empty sequence of PathSegments.-newtype Path r = Path { _pathSegments :: S2.ViewL1 (PathSegment r) }+newtype Path r = Path { _pathSegments :: LSeq.LSeq 1 (PathSegment r) }                  deriving (Show,Eq) makeLenses ''Path @@ -197,8 +208,7 @@   -- | A group is essentially a list of IpeObjects.-newtype Group r = Group { _groupItems :: [IpeObject r] }-                  deriving (Show,Eq)+newtype Group r = Group [IpeObject r] deriving (Show,Eq)  type instance NumType   (Group r) = r type instance Dimension (Group r) = 2@@ -238,23 +248,26 @@   deriving instance (Show r) => Show (IpeObject r)+-- deriving instance (Read r) => Read (IpeObject r) deriving instance (Eq r)   => Eq   (IpeObject r)  type instance NumType   (IpeObject r) = r type instance Dimension (IpeObject r) = 2  makePrisms ''IpeObject-makeLenses ''Group +groupItems :: Lens (Group r) (Group s) [IpeObject r] [IpeObject s]+groupItems = lens (\(Group xs) -> xs) (const Group)+ class ToObject i where-  ipeObject' :: i r -> IpeAttributes i r -> IpeObject r+  mkIpeObject :: IpeObject' i r -> IpeObject r -instance ToObject Group      where ipeObject' g a = IpeGroup     (g :+ a)-instance ToObject Image      where ipeObject' p a = IpeImage     (p :+ a)-instance ToObject TextLabel  where ipeObject' p a = IpeTextLabel (p :+ a)-instance ToObject MiniPage   where ipeObject' p a = IpeMiniPage  (p :+ a)-instance ToObject IpeSymbol  where ipeObject' s a = IpeUse       (s :+ a)-instance ToObject Path       where ipeObject' p a = IpePath      (p :+ a)+instance ToObject Group      where mkIpeObject = IpeGroup+instance ToObject Image      where mkIpeObject = IpeImage+instance ToObject TextLabel  where mkIpeObject = IpeTextLabel+instance ToObject MiniPage   where mkIpeObject = IpeMiniPage+instance ToObject IpeSymbol  where mkIpeObject = IpeUse+instance ToObject Path       where mkIpeObject = IpePath  instance Fractional r => IsTransformable (IpeObject r) where   transformBy t (IpeGroup i)     = IpeGroup     $ i&core %~ transformBy t@@ -264,8 +277,9 @@   transformBy t (IpeUse i)       = IpeUse       $ i&core %~ transformBy t   transformBy t (IpePath i)      = IpePath      $ i&core %~ transformBy t --+-- | Shorthand for constructing ipeObjects+ipeObject'     :: ToObject i => i r -> IpeAttributes i r -> IpeObject r+ipeObject' i a = mkIpeObject $ i :+ a  commonAttributes :: Lens' (IpeObject r) (Attributes (AttrMapSym1 r) CommonAttributes) commonAttributes = lens (Attrs . g) (\x (Attrs a) -> s x a)
+ src/Data/Geometry/Ipe/Value.hs view
@@ -0,0 +1,24 @@+{-# LANGUAGE OverloadedStrings #-}+--------------------------------------------------------------------------------+-- |+-- Module      :  Data.Geometry.Ipe.Value+-- Copyright   :  (C) Frank Staals+-- License     :  see the LICENSE file+-- Maintainer  :  Frank Staals+--+-- Data type for representing values in ipe.+--+--------------------------------------------------------------------------------+module Data.Geometry.Ipe.Value where++import GHC.Exts+import Data.Text++--------------------------------------------------------------------------------++-- | Many types either consist of a symbolc value, or a value of type v+data IpeValue v = Named Text | Valued v+  deriving (Show,Read,Eq,Ord,Functor,Foldable,Traversable)++instance IsString (IpeValue v) where+  fromString = Named . fromString
src/Data/Geometry/Ipe/Writer.hs view
@@ -1,9 +1,18 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE UndecidableInstances #-}+--------------------------------------------------------------------------------+-- |+-- Module      :  Data.Geometry.Ipe.Writer+-- Copyright   :  (C) Frank Staals+-- License     :  see the LICENSE file+-- Maintainer  :  Frank Staals+-- Description :  Converting data types into IpeTypes+--+-------------------------------------------------------------------------------- module Data.Geometry.Ipe.Writer where -import           Control.Lens ((^.),(^..),(.~),(&), to)+import           Control.Lens ((^.), (^..), (.~), (&)) import qualified Data.ByteString as B import qualified Data.ByteString.Char8 as C import           Data.Colour.SRGB (RGB(..))@@ -13,18 +22,20 @@ import           Data.Geometry.Box import           Data.Geometry.Ipe.Attributes import qualified Data.Geometry.Ipe.Attributes as IA+import           Data.Geometry.Ipe.Color (IpeColor(..)) import           Data.Geometry.Ipe.Types+import           Data.Geometry.Ipe.Value import           Data.Geometry.LineSegment import           Data.Geometry.Point import           Data.Geometry.PolyLine import           Data.Geometry.Polygon (Polygon, outerBoundary, holeList, asSimplePolygon) import qualified Data.Geometry.Transformation as GT import           Data.Geometry.Vector+import qualified Data.LSeq as LSeq+import           Data.List.NonEmpty (NonEmpty(..)) import           Data.Maybe (catMaybes, mapMaybe, fromMaybe) import           Data.Proxy import           Data.Ratio-import           Data.Semigroup-import qualified Data.Seq2 as S2 import           Data.Singletons import           Data.Text (Text) import qualified Data.Text as T@@ -35,6 +46,7 @@ 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,@@ -90,6 +102,11 @@ class IpeWrite t where   ipeWrite :: t -> Maybe (Node Text Text) +instance IpeWrite t => IpeWrite [t] where+  ipeWrite gs = case mapMaybe ipeWrite gs of+                  [] -> Nothing+                  ns -> (Just $ Element "group" [] ns)+ instance (IpeWrite l, IpeWrite r) => IpeWrite (Either l r) where   ipeWrite = either ipeWrite ipeWrite @@ -252,6 +269,7 @@ instance IpeWriteText r => IpeWriteText (PolyLine 2 () r) where   ipeWriteText pl = case pl^..points.traverse.core of     (p : rest) -> unlines' . map ipeWriteText $ MoveTo p : map LineTo rest+    _          -> error "ipeWriteText. absurd. no vertices polyline"     -- the polyline type guarantees that there is at least one point  instance IpeWriteText r => IpeWriteText (Polygon t () r) where@@ -269,6 +287,7 @@   ipeWriteText (PolyLineSegment p) = ipeWriteText p   ipeWriteText (PolygonPath     p) = ipeWriteText p   ipeWriteText (EllipseSegment  m) = ipeWriteText $ Ellipse m+  ipeWriteText _                   = error "ipeWriteText: PathSegment, not implemented yet."  instance IpeWriteText r => IpeWrite (Path r) where   ipeWrite p = (\t -> Element "path" [] [Text t]) <$> ipeWriteText p@@ -277,9 +296,7 @@   instance (IpeWriteText r) => IpeWrite (Group r) where-  ipeWrite (Group gs) = case mapMaybe ipeWrite gs of-                          [] -> Nothing-                          ns -> (Just $ Element "group" [] ns)+  ipeWrite (Group gs) = ipeWrite gs   instance ( AllSatisfy IpeAttrName rs@@ -389,7 +406,7 @@       -- TODO: Do something with the p's  fromPolyLine :: PolyLine 2 () r -> Path r-fromPolyLine = Path . S2.l1Singleton . PolyLineSegment+fromPolyLine = Path . LSeq.fromNonEmpty . (:| []) . PolyLineSegment   instance (IpeWriteText r) => IpeWrite (LineSegment 2 p r) where
src/Data/Geometry/KDTree.hs view
@@ -14,8 +14,8 @@ import qualified Data.List.NonEmpty as NonEmpty import           Data.Maybe (fromJust) import           Data.Proxy-import           Data.Seq (LSeq(..), ViewL(..))-import qualified Data.Seq as Seq+import           Data.LSeq (LSeq(..), pattern (:<|))+import qualified Data.LSeq as LSeq import           Data.Util import qualified Data.Vector.Fixed as FV import           GHC.TypeLits@@ -77,7 +77,7 @@  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+buildKDTree' = KDT . addBoxes . build (Coord 1) . toPointSet . LSeq.fromNonEmpty   where     -- compute one tree with bounding boxes, then merge them together     addBoxes t = let bbt = foldUpData (\l _ r -> boundingBoxList' [l,r])                                       (boundingBox . (^.core)) t@@ -94,7 +94,7 @@            => LSeq n (Point d r :+ p) -> PointSet (LSeq n) d p r toPointSet = FV.imap sort . FV.replicate   where-    sort i = Seq.unstableSortBy (compareOn $ 1 + i)+    sort i = LSeq.unstableSortBy (compareOn $ 1 + i)   compareOn       :: (Ord r, Arity d)@@ -166,13 +166,13 @@     -- i = traceShow (c,j) j      m = let xs = fromJust $ pts^?element' (i-1)-        in xs `Seq.index` (F.length xs `div` 2)+        in xs `LSeq.index` (F.length xs `div` 2)      -- Since the input seq has >= 2 elems, F.length xs / 2 >= 1. It follows     -- that the both sets thus have at least one elemnt.     -- f :: LSeq 2 _ -> (LSeq 1 _, LSeq 1 _)-    f = bimap Seq.promise Seq.promise-      . Seq.partition (\p -> compareOn i p m == LT)+    f = bimap LSeq.promise LSeq.promise+      . LSeq.partition (\p -> compareOn i p m == LT)      (l,r) = unzip' . fmap f $ pts @@ -180,8 +180,9 @@     unzip' = bimap vectorFromListUnsafe vectorFromListUnsafe . unzip . F.toList  -asSingleton   :: (1 <= 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 $ unsafeCoerce v-                  p :< _           -> Left p -- only one element+asSingleton v = case v^.element (C :: C 0) of+                  (p :<| s) | null s -> Left p -- only one lement+                  _                  -> Right $ unsafeCoerce v
src/Data/Geometry/Line.hs view
@@ -2,10 +2,20 @@ {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE UnicodeSyntax #-}+--------------------------------------------------------------------------------+-- |+-- Module      :  Data.Geometry.Line+-- Copyright   :  (C) Frank Staals+-- License     :  see the LICENSE file+-- Maintainer  :  Frank Staals+--+-- \(d\)-dimensional lines.+--+-------------------------------------------------------------------------------- module Data.Geometry.Line( module Data.Geometry.Line.Internal                          ) where -import           Control.Lens ((^.), re, bimap)+import           Control.Lens import           Data.Ext import           Data.Geometry.Boundary import           Data.Geometry.Box@@ -44,12 +54,14 @@   nonEmptyIntersection = defaultNonEmptyIntersection    line' `intersect` (Boundary rect)  = case asA' segP of-      [sl'] -> coRec . bimap id unVal $ sl'^.re _SubLine-      []    -> case nub' . map (fmap unVal) $ asA' pointP of+      [sl'] -> case fromUnbounded sl' of+        Nothing   -> error "intersect: line x boundary rect; unbounded line? absurd"+        Just sl'' -> coRec $ sl''^.re _SubLine+      []    -> case nub' $ asA' pointP of         [p]   -> coRec p         [p,q] -> coRec (p,q)         _     -> coRec NoIntersection-      _     -> error "intersect; ine x boundary rect; absurd"+      _     -> error "intersect; line x boundary rect; absurd"     where       (t,r,b,l) = sides' rect       ints = map (\s -> sl `intersect` toSL s) [t,r,b,l]@@ -58,18 +70,16 @@        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"+      toSL  :: LineSegment 2 p r -> SubLine 2 () (UnBounded r) r+      toSL s = s^._SubLine.re _unBounded.to dropExtra -      asA'    :: (t ∈ IntersectionOf (SubLine 2 () (UnBounded r))-                                     (SubLine 2 () (UnBounded r)))+      asA'    :: (t ∈ IntersectionOf (SubLine 2 () (UnBounded r) r)+                                     (SubLine 2 () (UnBounded r) r))               => proxy t -> [t]       asA' px = mapMaybe (asA px) ints -      segP   = Proxy :: Proxy (SubLine 2 () (UnBounded r))-      pointP = Proxy :: Proxy (Point 2      (UnBounded r))+      segP   = Proxy :: Proxy (SubLine 2 () (UnBounded r) r)+      pointP = Proxy :: Proxy (Point 2 r)   type instance IntersectionOf (Line 2 r) (Rectangle p r) =
src/Data/Geometry/Line/Internal.hs view
@@ -2,6 +2,16 @@ {-# LANGUAGE DeriveAnyClass  #-} {-# LANGUAGE ScopedTypeVariables  #-} {-# LANGUAGE UndecidableInstances #-}+--------------------------------------------------------------------------------+-- |+-- Module      :  Data.Geometry.Line.Internal+-- Copyright   :  (C) Frank Staals+-- License     :  see the LICENSE file+-- Maintainer  :  Frank Staals+--+-- \(d\)-dimensional lines.+--+-------------------------------------------------------------------------------- module Data.Geometry.Line.Internal where  import           Control.DeepSeq@@ -29,13 +39,22 @@  instance (Show r, Arity d) => Show (Line d r) where   show (Line p v) = concat [ "Line (", show p, ") (", show v, ")" ]-deriving instance (Eq r,   Arity d)   => Eq            (Line d r)++-- -- TODO:+-- instance (Read r, Arity d)   => Read (Line d r) where++++ deriving instance (NFData r, Arity d) => NFData        (Line d r) deriving instance Arity d             => Functor       (Line d) deriving instance Arity d             => F.Foldable    (Line d) deriving instance Arity d             => T.Traversable (Line d) +instance (Arity d, Eq r, Fractional r) => Eq (Line d r) where+  l@(Line p _) == m = l `isParallelTo` m && p `onLine` m + type instance Dimension (Line d r) = d type instance NumType   (Line d r) = r @@ -92,6 +111,29 @@ -- | 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+++-- | 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)+++-- | Given point p and a line (Line q v), Get the scalar lambda s.t.+-- p = q + lambda v. If p does not lie on the line this returns a Nothing.+toOffset              :: (Eq r, Fractional r, Arity d) => Point d r -> Line d r -> Maybe r+toOffset p (Line q v) = scalarMultiple (p .-. q) v+++-- | Given point p *on* a line (Line q v), Get the scalar lambda s.t.+-- p = q + lambda v. (So this is an unsafe version of 'toOffset')+--+-- pre: the input point p lies on the line l.+toOffset'             :: (Eq r, Fractional r, Arity d) => Point d r -> Line d r -> r+toOffset' p = fromJust' . toOffset p+  where+    fromJust' (Just x) = x+    fromJust' _        = error "toOffset: Nothing"   -- | The intersection of two lines is either: NoIntersection, a point or a line.
src/Data/Geometry/LineSegment.hs view
@@ -1,11 +1,15 @@ {-# 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+-- Copyright   :  (C) Frank Staals+-- License     :  see the LICENSE file+-- Maintainer  :  Frank Staals+--+-- Line segment data type and some basic functions on line segments+--+-------------------------------------------------------------------------------- module Data.Geometry.LineSegment( LineSegment                                 , pattern LineSegment                                 , pattern LineSegment'@@ -37,8 +41,6 @@ import           Data.Geometry.Transformation import           Data.Geometry.Vector import           Data.Ord (comparing)-import           Data.Semigroup-import           Data.UnBounded import           Data.Vinyl import           Data.Vinyl.CoRec import           GHC.TypeLits@@ -92,22 +94,21 @@   end = unLineSeg.end  -_SubLine :: (Fractional r, Eq r, Arity d) => Iso' (LineSegment d p r) (SubLine d p r)+_SubLine :: (Num r, Arity d) => Iso' (LineSegment d p r) (SubLine d p r r) _SubLine = iso segment2SubLine subLineToSegment {-# INLINE _SubLine #-} -segment2SubLine    :: (Fractional r, Eq r, Arity d)-                   => LineSegment d p r -> SubLine d p r-segment2SubLine ss = SubLine l (Interval s e)+segment2SubLine    :: (Num r, Arity d)+                   => LineSegment d p r -> SubLine d p r r+segment2SubLine ss = SubLine (Line p (q .-. p)) (Interval s e)   where-    l = supportingLine ss-    f = flip toOffset l-    (Interval p q)  = ss^.unLineSeg--    s = p&unEndPoint.core %~ f-    e = q&unEndPoint.core %~ f+    p = ss^.start.core+    q = ss^.end.core+    (Interval a b)  = ss^.unLineSeg+    s = a&unEndPoint.core .~ 0+    e = b&unEndPoint.core .~ 1 -subLineToSegment    :: (Num r, Arity d) => SubLine d p r -> LineSegment d p r+subLineToSegment    :: (Num r, Arity d) => SubLine d p r r -> LineSegment d p r subLineToSegment sl = let (Interval s' e') = (fixEndPoints sl)^.subRange                           s = s'&unEndPoint %~ (^.extra)                           e = e'&unEndPoint %~ (^.extra)@@ -125,8 +126,8 @@ deriving instance Arity d                   => Functor (LineSegment d p)  instance PointFunctor (LineSegment d p) where-  pmap f ~(LineSegment s e) = LineSegment (s&unEndPoint %~ first f)-                                          (e&unEndPoint %~ first f)+  pmap f ~(LineSegment s e) = LineSegment (s&unEndPoint.core %~ f)+                                          (e&unEndPoint.core %~ f)  instance Arity d => IsBoxable (LineSegment d p r) where   boundingBox l = boundingBox (l^.start.core) <> boundingBox (l^.end.core)@@ -174,14 +175,12 @@          (LineSegment 2 p r) `IsIntersectableWith` (Line 2 r) where   nonEmptyIntersection = defaultNonEmptyIntersection -  ~s@(LineSegment p q) `intersect` l = let f  = bimap (fmap Val) (const ())-                                           s' = LineSegment (p&unEndPoint %~ f)-                                                            (q&unEndPoint %~ f)-                                    in match ((s'^._SubLine) `intersect` (fromLine l)) $-         (H   coRec)-      :& (H $ coRec . fmap (_unUnBounded))-      :& (H $ const (coRec s))-      :& RNil+  s `intersect` l = let ubSL = s^._SubLine.re _unBounded.to dropExtra+                    in match (ubSL `intersect` (fromLine l)) $+                            (H   coRec)+                         :& (H $ coRec)+                         :& (H $ const (coRec s))+                         :& RNil  -- * Functions on LineSegments 
src/Data/Geometry/PlanarSubdivision.hs view
@@ -1,25 +1,36 @@ {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE PartialTypeSignatures #-} {-# LANGUAGE ScopedTypeVariables #-}+--------------------------------------------------------------------------------+-- |+-- Module      :  Data.Geometry.PlnarSubdivision+-- Copyright   :  (C) Frank Staals+-- License     :  see the LICENSE file+-- Maintainer  :  Frank Staals+--+-- Data type to represent a PlanarSubdivision+--+-------------------------------------------------------------------------------- module Data.Geometry.PlanarSubdivision( module Data.Geometry.PlanarSubdivision.Basic-                                      , fromPolygon, fromPolygons+                                      -- , module Data.Geometry.PlanarSubdivision.Build+                                      , fromPolygon                                       ) where  -- 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.Box import           Data.Geometry.PlanarSubdivision.Basic import           Data.Geometry.Polygon-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+import           Data.Proxy+import           Data.Util+import           Control.Lens+import           Data.Bitraversable+import qualified Data.Foldable as F+import qualified Data.Vector as V+import qualified Data.Vector.Mutable as MV +--------------------------------------------------------------------------------  -- | Construct a planar subdivision from a polygon. Since our PlanarSubdivision -- models only connected planar subdivisions, this may add dummy/invisible@@ -50,17 +61,7 @@   --- | 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@@ -98,10 +99,3 @@ getP            :: HoleData f p -> Maybe p getP (Outer _)  = Nothing getP (Hole _ p) = Just p---- | 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
@@ -2,60 +2,71 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE PartialTypeSignatures #-} {-# LANGUAGE ScopedTypeVariables #-}+--------------------------------------------------------------------------------+-- |+-- Module      :  Data.Geometry.PlnarSubdivision.Basic+-- Copyright   :  (C) Frank Staals+-- License     :  see the LICENSE file+-- Maintainer  :  Frank Staals+-- Description :  Basic data types to represent a PlanarSubdivision+--+-------------------------------------------------------------------------------- module Data.Geometry.PlanarSubdivision.Basic( VertexId', FaceId'-                                           , VertexData(VertexData), PG.vData, PG.location+                                            , VertexData(VertexData), PG.vData, PG.location -                                           , FaceData(FaceData), holes, fData+                                            , FaceData(FaceData), holes, fData -                                           , PlanarSubdivision(PlanarSubdivision)-                                           , Wrap+                                            , PlanarSubdivision(PlanarSubdivision)+                                            , Wrap -                                           , Component, ComponentId+                                            , Component, ComponentId -                                           , PolygonFaceData(..)-                                           , PlanarGraph-                                           , PlaneGraph-                                           , fromSimplePolygon-                                           , fromConnectedSegments-                                           , fromPlaneGraph, fromPlaneGraph'+                                            , PolygonFaceData(..)+                                            , PlanarGraph+                                            , PlaneGraph+                                            , fromSimplePolygon+                                            , fromConnectedSegments+                                            , fromPlaneGraph, fromPlaneGraph' -                                           , numVertices, numEdges, numFaces, numDarts-                                           , dual+                                            , numVertices, numEdges, numFaces, numDarts+                                            , dual -                                           , components, component-                                           , vertices', vertices-                                           , edges', edges-                                           , faces', faces, internalFaces-                                           , darts'+                                            , components, component+                                            , vertices', vertices+                                            , edges', edges+                                            , faces', faces, internalFaces+                                            , darts'+                                            -- , traverseVertices, traverseDarts, traverseFaces -                                           , headOf, tailOf, twin, endPoints+                                            , headOf, tailOf, twin, endPoints -                                           , incidentEdges, incomingEdges, outgoingEdges-                                           , nextIncidentEdge-                                           , neighboursOf+                                            , incidentEdges, incomingEdges, outgoingEdges+                                            , nextIncidentEdge+                                            , neighboursOf -                                           , leftFace, rightFace-                                           , outerBoundaryDarts, boundaryVertices, holesOf-                                           , outerFaceId-                                           , boundary'+                                            , leftFace, rightFace+                                            , outerBoundaryDarts, boundaryVertices, holesOf+                                            , outerFaceId+                                            , boundary' -                                           , locationOf-                                           , HasDataOf(..)+                                            , locationOf+                                            , HasDataOf(..) -                                           , endPointsOf, endPointData+                                            , endPointsOf, endPointData -                                           , edgeSegment, edgeSegments-                                           , rawFacePolygon, rawFaceBoundary-                                           , rawFacePolygons+                                            , edgeSegment, edgeSegments+                                            , rawFacePolygon, rawFaceBoundary+                                            , rawFacePolygons -                                           , VertexId(..), FaceId(..), Dart, World(..)+                                            , VertexId(..), FaceId(..), Dart, World(..)  -                                           , rawVertexData, rawDartData, rawFaceData-                                           , dataVal+                                            , rawVertexData, rawDartData, rawFaceData+                                            , vertexData, dartData, faceData+                                            , dataVal -                                           , dartMapping, Raw(..)-                                           ) where+                                            , dartMapping, Raw(..)+                                            ) where  import           Control.Lens hiding (holes, holesOf, (.=)) import           Data.Aeson@@ -67,11 +78,8 @@ 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           Data.PlanarGraph (isPositive, allDarts) import qualified Data.PlaneGraph as PG import           Data.PlaneGraph( PlaneGraph, PlanarGraph, dual                                 , Dart, VertexId(..), FaceId(..), twin@@ -110,17 +118,23 @@   Wrap s = Wrap' s  newtype ComponentId s = ComponentId { unCI :: Int }-  deriving (Show,Eq,Ord,Generic,Bounded,Enum)+  deriving (Show,Eq,Ord,Generic,Bounded,Enum,ToJSON,FromJSON)  -data Raw s ia a = Raw { _compId  :: {-# UNPACK #-} !(ComponentId s)-                      , _idxVal  :: {-# UNPACK #-} !ia+data Raw s ia a = Raw { _compId  :: !(ComponentId s)+                      , _idxVal  :: !ia                       , _dataVal :: !a-                      } deriving (Eq,Show,Functor,Foldable,Traversable)-makeLenses ''Raw+                      } deriving (Eq,Show,Functor,Foldable,Traversable,Generic) +instance (FromJSON ia, FromJSON a) => FromJSON (Raw s ia a)+instance (ToJSON ia, ToJSON a) => ToJSON (Raw s ia a) where+  toEncoding = genericToEncoding defaultOptions +-- | get the dataVal of a Raw+dataVal :: Lens (Raw s ia a) (Raw s ia b) a b+dataVal = lens (\(Raw _ _ x) -> x) (\(Raw c i _) y -> Raw c i y) + --------------------------------------------------------------------------------  -- | A connected component.@@ -147,7 +161,7 @@                     , _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)+                    } deriving (Show,Eq,Functor,Generic) makeLenses ''PlanarSubdivision  @@ -160,8 +174,14 @@  component    :: ComponentId s -> Lens' (PlanarSubdivision s v e f r)                                        (Component s r)-component ci = components.ix' (unCI ci)+component ci = components.singular (ix $ unCI ci) +-- instance (ToJSON v, ToJSON v, ToJSON e, ToJSON f, ToJSON r)+--          => ToJSON (PlanarSubdivision s v e f r) where+--   toEncoding = genericToEncoding defaultOptions+++ --------------------------------------------------------------------------------  -- | Constructs a planarsubdivision from a PlaneGraph@@ -196,10 +216,10 @@     (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)+    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'@@ -235,6 +255,27 @@                          -> PlanarSubdivision s (NonEmpty p) e () r fromConnectedSegments px = fromPlaneGraph . PG.fromConnectedSegments px +-- g1 = PG.fromConnectedSegments (Identity Test1) testSegs+-- ps1 = fromConnectedSegments (Identity Test1) testSegs++-- data Test1 = Test1++-- draw = V.filter isEmpty . rawFacePolygons+--   where+--     isEmpty (_,Left  p :+ _) = (< 3) . length . polygonVertices $ p+--     isEmpty (_,Right p :+ _) = (< 3) . length . polygonVertices $ p++-- testSegs = map (\(p,q) -> ClosedLineSegment (ext p) (ext q) :+ ())+--                    [ (origin, Point2 10 10)+--                    , (origin, Point2 12 10)+--                    , (origin, Point2 20 5)+--                    , (origin, Point2 13 20)+--                    , (Point2 10 10, Point2 12 10)+--                    , (Point2 10 10, Point2 13 20)+--                    , (Point2 12 10, Point2 20 5)+--                    ]++ --------------------------------------------------------------------------------  -- | Data type that expresses whether or not we are inside or outside the@@ -321,6 +362,9 @@ 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@@ -329,15 +373,42 @@                    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+-- | 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 = lens getF setF+  where+    getF     = V.imap (\i x -> (toEnum i, x^.dataVal)) . _rawDartData+    setF ps ds' = ps&rawDartData %~ mkDS' ds' +    -- create a new dartData vector to assign the values to+    mkDS' ds' ds = V.create $ do+                     v <- MV.new (V.length ds)+                     mapM_ (assignDart ds v) ds'+                     pure v +    assignDart ds v (d,x) = let i = fromEnum d+                                y = ds V.! i+                            in MV.write v i (y&dataVal .~ x)  +-- | Lens to the facedata of the faces themselves. The indices correspond to the faceIds+faceData :: Lens (PlanarSubdivision s v e f r) (PlanarSubdivision s v e f' r)+                 (V.Vector f)                  (V.Vector f')+faceData = lens getF setF+  where+    getF = fmap (^.dataVal) . _rawFaceData+    setF ps v' = ps&rawFaceData %~ V.zipWith (\x' x -> x&dataVal .~ x') v' +-- | Lens to the facedata of the vertexdata themselves. The indices correspond to the vertexId's+vertexData :: Lens (PlanarSubdivision s v e f r) (PlanarSubdivision s v' e f r)+                   (V.Vector v)                  (V.Vector v')+vertexData = lens getF setF+  where+    getF = fmap (^.dataVal) . _rawVertexData+    setF ps v' = ps&rawVertexData %~ V.zipWith (\x' x -> x&dataVal .~ x') v'++ -- | The tail of a dart, i.e. the vertex this dart is leaving from -- -- running time: \(O(1)\)@@ -453,7 +524,7 @@  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)+asLocalD d ps = let (Raw ci d' _) = ps^?!rawDartData.ix (fromEnum d)                 in (ci,d',ps^.component ci)  @@ -461,12 +532,12 @@  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+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+asLocalF (FaceId (VertexId f)) ps = let (Raw ci f' _) = ps^?!rawFaceData.ix f                                     in (ci,f',ps^.component ci)  @@ -476,11 +547,11 @@                            -> 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+    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)+    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)@@ -492,15 +563,15 @@ faceDataOf fi = lens getF setF   where     (FaceId (VertexId i)) = fi-    getF ps = let (Raw ci wfi x) = ps^.rawFaceData.ix' i+    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+    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+                 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@@ -508,14 +579,39 @@  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+  dataOf d = rawDartData.singular (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  +-- -- | Traverse the vertices+-- --+-- traverseVertices   :: Applicative m+--                    => (VertexId' s -> v -> m v')+--                    -> PlanarSubdivision s v e f r+--                    -> m (PlanarSubdivision s v' e f r)+-- traverseVertices f = itraverseOf (vertexData.itraversed) (\i -> f (VertexId i)) +-- -- | Traverses the darts+-- --+-- traverseDarts   :: Applicative m+--                 => (Dart s -> e -> m e')+--                 -> PlanarSubdivision s v e f r+--                 -> m (PlaneGraph s v e' f r)+-- traverseDarts f = traverseOf (dart) (PG.traverseDarts f)+++-- -- | Traverses the faces+-- --+-- traverseFaces   :: Applicative m+--                 => (FaceId' s  -> f -> m f')+--                 -> PlaneGraph s v e f r+--                 -> m (PlaneGraph s v e f' r)+-- traverseFaces f = traverseOf graph (PG.traverseFaces f)++ -- | Getter for the data at the endpoints of a dart -- -- running time: \(O(1)\)@@ -579,7 +675,7 @@ -- | 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+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@@ -595,4 +691,5 @@   +dartMapping    :: PlanarSubdivision s v e f r -> V.Vector (Dart (Wrap s), Dart s) dartMapping ps = ps^.component (ComponentId 0).PG.dartData
src/Data/Geometry/PlanarSubdivision/Draw.hs view
@@ -1,17 +1,54 @@ module Data.Geometry.PlanarSubdivision.Draw where -import           Data.Geometry.Ipe-import           Data.Ext import           Control.Lens+import           Data.Ext+import           Data.Geometry.Ipe+import           Data.Geometry.LineSegment+import           Data.Geometry.PlanarSubdivision+import           Data.Geometry.Polygon+import           Data.Maybe (mapMaybe) 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++drawColoredPlanarSubdivision  ::  IpeOut (PlanarSubdivision s v e (Maybe (IpeColor r)) r)+                                          Group r+drawColoredPlanarSubdivision ps = drawPlanarSubdivision+    (ps&vertexData.traverse  .~ Just mempty+       &dartData.traverse._2 .~ Just mempty+       &faceData.traverse    %~ fmap (attr SFill)+    )++-- | Draws only the values for which we have a Just attribute+drawPlanarSubdivision :: forall s r.+                         IpeOut (PlanarSubdivision s (Maybe (IpeAttributes IpeSymbol r))+                                                     (Maybe (IpeAttributes Path      r))+                                                     (Maybe (IpeAttributes Path      r))+                                r) Group r+drawPlanarSubdivision = drawPlanarSubdivisionWith fv fe ff   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+    fv                     :: (VertexId' s, VertexData r (Maybe (IpeAttributes IpeSymbol r)))+                           -> Maybe (IpeObject' IpeSymbol r)+    fv (_,VertexData p ma) = (\a -> defIO p ! a) <$> ma -- draws a point+    fe (_,s :+ ma)         = (\a -> defIO s ! a) <$> ma -- draw segment+    ff (_,f :+ ma)         = (\a -> defIO f ! a) <$> ma -- draw a face+++-- | Draw everything using the defaults+drawPlanarSubdivision'    :: forall s v e f r. IpeOut (PlanarSubdivision s v e f r) Group r+drawPlanarSubdivision' ps = drawPlanarSubdivision+  (ps&vertexData.traverse   .~ Just (mempty :: IpeAttributes IpeSymbol r)+     &dartData.traverse._2  .~ Just (mempty :: IpeAttributes Path      r)+     &faceData.traverse     .~ Just (mempty :: IpeAttributes Path      r))++type MIO g i r = g -> Maybe (IpeObject' i r)++drawPlanarSubdivisionWith            :: (ToObject vi, ToObject ei, ToObject fi)+                                     => MIO (VertexId' s, VertexData r v)          vi r+                                     -> MIO (Dart s,      LineSegment 2 v r :+ e)  ei r+                                     -> MIO (FaceId' s,   SomePolygon v r :+ f)    fi r+                                     -> IpeOut (PlanarSubdivision s v e f r) Group r+drawPlanarSubdivisionWith fv fe ff g = ipeGroup . concat $ [vs, es, fs]+  where+    vs = mapMaybe (fmap iO . fv) . V.toList . vertices        $ g+    es = mapMaybe (fmap iO . fe) . V.toList . edgeSegments    $ g+    fs = mapMaybe (fmap iO . ff) . V.toList . rawFacePolygons $ g
src/Data/Geometry/Point.hs view
@@ -1,11 +1,15 @@ {-# LANGUAGE ScopedTypeVariables  #-} {-# LANGUAGE UndecidableInstances #-}-{-|-Module    : Data.Geometry.Point-Description: \(d\)-dimensional points-Copyright : (c) Frank Staals-License : See LICENCE file--}+--------------------------------------------------------------------------------+-- |+-- Module      :  Data.Geometry.Point+-- Copyright   :  (C) Frank Staals+-- License     :  see the LICENSE file+-- Maintainer  :  Frank Staals+--+-- \(d\)-dimensional points.+--+-------------------------------------------------------------------------------- module Data.Geometry.Point where  import           Control.DeepSeq@@ -22,8 +26,11 @@ import           Data.Proxy import           GHC.Generics (Generic) import           GHC.TypeLits---------------------------------------------------------------------------------+import           Text.ParserCombinators.ReadP (ReadP, string,pfail)+import           Text.ParserCombinators.ReadPrec (lift)+import           Text.Read (Read(..),readListPrecDefault, readPrec_to_P,minPrec) + -------------------------------------------------------------------------------- -- $setup -- >>> :{@@ -43,6 +50,17 @@   show (Point v) = mconcat [ "Point", show $ F.length v , " "                            , show $ F.toList v                            ]+instance (Read r, Arity d) => Read (Point d r) where+  readPrec     = lift readPt+  readListPrec = readListPrecDefault++readPt :: forall d r. (Arity d, Read r) => ReadP (Point d r)+readPt = do let d = natVal (Proxy :: Proxy d)+            _  <- string $ "Point" <> show d <> " "+            rs <- readPrec_to_P readPrec minPrec+            case pointFromList rs of+              Just p -> pure p+              _      -> pfail  deriving instance (Eq r, Arity d)     => Eq (Point d r) deriving instance (Ord r, Arity d)    => Ord (Point d r)
src/Data/Geometry/PolyLine.hs view
@@ -6,23 +6,23 @@ import           Control.Lens import           Data.Bifunctor import           Data.Ext+import qualified Data.Foldable as F import           Data.Geometry.Box import           Data.Geometry.LineSegment import           Data.Geometry.Point import           Data.Geometry.Properties import           Data.Geometry.Transformation import           Data.Geometry.Vector+import           Data.LSeq (LSeq, pattern (:<|))+import qualified Data.LSeq as LSeq import qualified Data.List.NonEmpty as NE-import           Data.Semigroup-import qualified Data.Seq2 as S2-import qualified Data.Sequence as Seq import           GHC.TypeLits  -------------------------------------------------------------------------------- -- * d-dimensional Polygonal Lines (PolyLines) --- | A Poly line in R^d-newtype PolyLine d p r = PolyLine { _points :: S2.Seq2 (Point d r :+ p) }+-- | A Poly line in R^d has at least 2 vertices+newtype PolyLine d p r = PolyLine { _points :: LSeq 2 (Point d r :+ p) } makeLenses ''PolyLine  deriving instance (Show r, Show p, Arity d) => Show    (PolyLine d p r)@@ -53,7 +53,7 @@  -- | pre: The input list contains at least two points fromPoints :: [Point d r :+ p] -> PolyLine d p r-fromPoints = PolyLine . S2.fromList+fromPoints = PolyLine . LSeq.forceLSeq (C  :: C 2) . LSeq.fromList  -- | pre: The input list contains at least two points. All extra vields are -- initialized with mempty.@@ -66,19 +66,12 @@ fromLineSegment ~(LineSegment' p q) = fromPoints [p,q]  -- | Convert to a closed line segment by taking the first two points.-asLineSegment                              :: PolyLine d p r -> LineSegment d p r-asLineSegment (PolyLine (S2.Seq2 p mid q)) = ClosedLineSegment p (f $ Seq.viewl mid)-  where-    f Seq.EmptyL    = q-    f (q' Seq.:< _) = q'+asLineSegment                            :: PolyLine d p r -> LineSegment d p r+asLineSegment (PolyLine (p :<| q :<| _)) = ClosedLineSegment p q  -- | Stricter version of asLineSegment that fails if the Polyline contains more -- than two points.-asLineSegment'                            :: PolyLine d p r -> Maybe (LineSegment d p r)-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 )+asLineSegment'                :: PolyLine d p r -> Maybe (LineSegment d p r)+asLineSegment' (PolyLine pts) = case F.toList pts of+                                  [p,q] -> Just $ ClosedLineSegment p q+                                  _     -> Nothing
src/Data/Geometry/Polygon.hs view
@@ -1,10 +1,14 @@ {-# 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+-- Copyright   :  (C) Frank Staals+-- License     :  see the LICENSE file+-- Maintainer  :  Frank Staals+--+-- A Polygon data type and some basic functions to interact with them.+--+-------------------------------------------------------------------------------- module Data.Geometry.Polygon where  import           Control.DeepSeq@@ -26,7 +30,7 @@ import qualified Data.List.NonEmpty as NonEmpty import           Data.Maybe (mapMaybe) import           Data.Proxy-import           Data.Semigroup+import           Data.Semigroup(sconcat) import qualified Data.Sequence as Seq import           Data.Util import           Data.Vinyl.CoRec (asA)
src/Data/Geometry/Polygon/Convex.hs view
@@ -1,11 +1,15 @@ {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TemplateHaskell #-}-{-|-Module    : Data.Geometry.Polygon.Convex-Description: Convex Polygons-Copyright : (c) Frank Staals-License : See LICENCE file--}+--------------------------------------------------------------------------------+-- |+-- Module      :  Data.Geometry.Polygon.Convex+-- Copyright   :  (C) Frank Staals+-- License     :  see the LICENSE file+-- Maintainer  :  Frank Staals+--+-- Convex Polygons+--+-------------------------------------------------------------------------------- module Data.Geometry.Polygon.Convex( ConvexPolygon(..), simplePolygon                                    , merge                                    , lowerTangent, upperTangent@@ -41,8 +45,10 @@  -- import           Data.Geometry.Ipe -- import           Debug.Trace+ -------------------------------------------------------------------------------- +-- | Data Type representing a convex polygon newtype ConvexPolygon p r = ConvexPolygon {_simplePolygon :: SimplePolygon p r }                           deriving (Show,Eq,NFData) makeLenses ''ConvexPolygon
src/Data/Geometry/Properties.hs view
@@ -2,12 +2,17 @@ {-# 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+-- Copyright   :  (C) Frank Staals+-- License     :  see the LICENSE file+-- Maintainer  :  Frank Staals+--+-- Defines some generic geometric properties e.g. Dimensions, NumType, and+-- Intersection types.+--+-------------------------------------------------------------------------------- module Data.Geometry.Properties where  import Data.Maybe (isNothing)@@ -26,6 +31,8 @@  -- | A type family for types that have an associated numeric type. type family NumType t :: *++type instance NumType [t] = NumType t  -- | A simple data type expressing that there are no intersections data NoIntersection = NoIntersection deriving (Show,Read,Eq,Ord)
src/Data/Geometry/SegmentTree.hs view
@@ -1,18 +1,4 @@-{-# LANGUAGE TemplateHaskell #-} module Data.Geometry.SegmentTree( module Data.Geometry.SegmentTree.Generic                                 ) where --import           Data.Ext-import           Data.Semigroup-import           Control.Lens-import           Data.List.NonEmpty (NonEmpty)-import qualified Data.List.NonEmpty as NonEmpty-import qualified Data.List as List-import           Data.BinaryTree-import           Data.Range-import           Data.Geometry.Interval import           Data.Geometry.SegmentTree.Generic-import           Data.Geometry.Interval.Util-import           Data.Geometry.Properties-import           Data.Geometry.IntervalTree (IntervalLike(..))
src/Data/Geometry/SegmentTree/Generic.hs view
@@ -1,4 +1,13 @@ {-# LANGUAGE TemplateHaskell #-}+--------------------------------------------------------------------------------+-- |+-- Module      :  Data.Geometry.SegmentTree.Generic+-- Copyright   :  (C) Frank Staals+-- License     :  see the LICENSE file+-- Maintainer  :  Frank Staals+-- Description :  Implementation of SegmentTrees+--+-------------------------------------------------------------------------------- module Data.Geometry.SegmentTree.Generic( NodeData(..), splitPoint, range, assoc                                         , LeafData(..), atomicRange, leafAssoc @@ -19,14 +28,12 @@ import           Control.DeepSeq import           Control.Lens import           Data.BinaryTree-import           Data.Ext import           Data.Geometry.Interval 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.Semigroup import           GHC.Generics (Generic)  --------------------------------------------------------------------------------@@ -258,13 +265,16 @@ -------------------------------------------------------------------------------- -- * Counting the number of segments intersected -newtype Count = Count { getCount :: Int}+newtype Count = Count { getCount :: Word }               deriving (Show,Eq,Ord,Num,Integral,Enum,Real,Generic,NFData)  newtype C a = C { _unC :: a} deriving (Show,Read,Eq,Ord,Generic,NFData)  instance Semigroup Count where   a <> b = Count $ getCount a + getCount b+instance Monoid Count where+  mempty = 0+  mappend = (<>)  instance Measured Count (C i) where   measure _ = 1@@ -277,29 +287,29 @@ -------------------------------------------------------------------------------- -- * Testing stuff -test'' = fromIntervals' . NonEmpty.fromList $ test-test = [Interval (Closed (238 :+ ())) (Open (309 :+ ())), Interval (Closed (175 :+ ())) (Closed (269 :+ ())),Interval (Closed (255 :+ ())) (Open (867 :+ ())),Interval (Open (236 :+ ())) (Closed (863 :+ ())),Interval (Open (150 :+ ())) (Closed (161 :+ ())),Interval (Closed (35 :+ ())) (Closed (77 :+ ()))]+-- test'' = fromIntervals' . NonEmpty.fromList $ test+-- test = [Interval (Closed (238 :+ ())) (Open (309 :+ ())), Interval (Closed (175 :+ ())) (Closed (269 :+ ())),Interval (Closed (255 :+ ())) (Open (867 :+ ())),Interval (Open (236 :+ ())) (Closed (863 :+ ())),Interval (Open (150 :+ ())) (Closed (161 :+ ())),Interval (Closed (35 :+ ())) (Closed (77 :+ ()))]  --- q =        [78]+-- -- q =        [78] --- test = fromIntervals' . NonEmpty.fromList $ [ closedInterval 0 10---                                             , closedInterval 5 15---                                             , closedInterval 1 4---                                             , closedInterval 3 9---                                             ]-tst = fromIntervals' . NonEmpty.fromList $ [ closedInterval 1 6-                                           , closedInterval 2 6-                                           -- , Interval (Closed $ ext 0) (Open $ ext 1)-                                           ]+-- -- test = fromIntervals' . NonEmpty.fromList $ [ closedInterval 0 10+-- --                                             , closedInterval 5 15+-- --                                             , closedInterval 1 4+-- --                                             , closedInterval 3 9+-- --                                             ]+-- tst = fromIntervals' . NonEmpty.fromList $ [ closedInterval 1 6+--                                            , closedInterval 2 6+--                                            -- , Interval (Closed $ ext 0) (Open $ ext 1)+--                                            ]   -closedInterval a b = ClosedInterval (ext a) (ext b)+-- closedInterval a b = ClosedInterval (ext a) (ext b) -showT :: (Show r, Show v) => SegmentTree v r -> String-showT = drawTree . _unSegmentTree+-- showT :: (Show r, Show v) => SegmentTree v r -> String+-- showT = drawTree . _unSegmentTree  -test' :: (Show r, Num r, Ord r, Enum r) => SegmentTree [I (Interval () r)] r-test' = insert (I $ closedInterval 6 14) $ createTree (NonEmpty.fromList [2,4..20]) []+-- test' :: (Show r, Num r, Ord r, Enum r) => SegmentTree [I (Interval () r)] r+-- test' = insert (I $ closedInterval 6 14) $ createTree (NonEmpty.fromList [2,4..20]) []
src/Data/Geometry/Slab.hs view
@@ -121,11 +121,11 @@   -type instance IntersectionOf (SubLine 2 p r) (Slab o a r) =-  [NoIntersection, SubLine 2 () r]+type instance IntersectionOf (SubLine 2 p s r) (Slab o a r) =+  [NoIntersection, SubLine 2 () s r]  instance (Fractional r, Ord r, HasBoundingLines o) =>-         SubLine 2 a r `IsIntersectableWith` (Slab o a r) where+         SubLine 2 a r r `IsIntersectableWith` (Slab o a r) where    nonEmptyIntersection = defaultNonEmptyIntersection @@ -139,8 +139,7 @@                                  :& RNil)     :& RNil     where-      dropExtra sub = sub&subRange %~ bimap (const ()) id-      singleton p = let x = ext $ toOffset p l in SubLine l (ClosedInterval x x)+      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) =@@ -158,5 +157,5 @@   -test :: SubLine 2 () Double-test = (ClosedLineSegment (ext origin) (ext origin))^._SubLine+-- test :: SubLine 2 () Double Double+-- test = (ClosedLineSegment (ext origin) (ext origin))^._SubLine
src/Data/Geometry/SubLine.hs view
@@ -3,6 +3,7 @@ module Data.Geometry.SubLine where  import           Control.Lens+import           Data.Bifunctor import           Data.Ext import qualified Data.Foldable as F import           Data.Geometry.Interval@@ -15,39 +16,31 @@ import           Data.Vinyl import           Data.Vinyl.CoRec ++import           Data.Ratio+ --------------------------------------------------------------------------------  -- | 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-                             }--+data SubLine d p s r = SubLine { _line     :: Line d r+                               , _subRange :: Interval p s+                               } makeLenses ''SubLine -type instance Dimension (SubLine d p r) = d-type instance NumType   (SubLine d p r) = r--deriving instance (Show r, Show p, Arity d) => Show (SubLine d p r)-deriving instance (Eq r, Eq p, Arity d)     => Eq (SubLine d p r)-deriving instance Arity d                   => Functor (SubLine d p)-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)+type instance Dimension (SubLine d p s r) = d  --- | 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)-+deriving instance (Show r, Show s, Show p, Arity d) => Show (SubLine d p s r)+-- deriving instance (Read r, Read p, Arity d) => Read (SubLine d p r)+deriving instance (Eq r, Eq s, Fractional r, Eq p, Arity d)     => Eq (SubLine d p s r)+deriving instance Arity d                   => Functor (SubLine d p s)+deriving instance Arity d                   => F.Foldable (SubLine d p s)+deriving instance Arity d                   => T.Traversable (SubLine d p s)   -- | 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    :: (Num r, Arity d) => SubLine d p r r -> SubLine d (Point d r :+ p) r r fixEndPoints sl = sl&subRange %~ f   where     ptAt              = flip pointAt (sl^.line)@@ -55,29 +48,40 @@     f ~(Interval l u) = Interval (l&unEndPoint %~ label)                                  (u&unEndPoint %~ label) +-- | forget the extra information stored at the endpoints of the subline.+dropExtra :: SubLine d p s r -> SubLine d () s r+dropExtra = over subRange (first (const ())) --- | given point p on line (Line q v), Get the scalar lambda s.t.--- p = q + lambda v-toOffset              :: (Eq r, Fractional r, Arity d) => Point d r -> Line d r -> r-toOffset p (Line q v) = fromJust' $ scalarMultiple (p .-. q) v-  where-    fromJust' (Just x) = x-    fromJust' _        = error "toOffset: Nothing"+_unBounded :: Prism' (SubLine d p (UnBounded r) r) (SubLine d p r r)+_unBounded = prism' toUnbounded fromUnbounded -type instance IntersectionOf (SubLine 2 p r) (SubLine 2 q r) = [ NoIntersection-                                                               , Point 2 r-                                                               , SubLine 2 p r-                                                               ]+-- | Transform into an subline with a potentially unbounded interval+toUnbounded :: SubLine d p r r -> SubLine d p (UnBounded r) r+toUnbounded = over subRange (fmap Val) +-- | Try to make a potentially unbounded subline into a bounded one.+fromUnbounded               :: SubLine d p (UnBounded r) r -> Maybe (SubLine d p r r)+fromUnbounded (SubLine l i) = SubLine l <$> mapM unBoundedToMaybe i+ -- | 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+                          => Point d r -> SubLine d p r r -> Bool+onSubLine p (SubLine l r) = case toOffset p l of+                              Nothing -> False+                              Just x  -> x `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+onSubLineUB                   :: (Ord r, Fractional r)+                              => Point 2 r -> SubLine 2 p (UnBounded r) r -> Bool+p `onSubLineUB` (SubLine l r) = case toOffset p l of+                                  Nothing -> False+                                  Just x  -> Val x `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 r -> Bool p `onSubLine2` sl = d `inInterval` r   where     -- get the endpoints (a,b) of the subline@@ -87,11 +91,22 @@     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 ++-- | given point p, and a Subline l r such that p lies on line l, test if it+-- lies on the subline, i.e. in the interval r+onSubLine2UB        :: (Ord r, Fractional r)+                    => Point 2 r -> SubLine 2 p (UnBounded r) r -> Bool+p `onSubLine2UB` sl = p `onSubLineUB` sl+++type instance IntersectionOf (SubLine 2 p s r) (SubLine 2 q s r) = [ NoIntersection+                                                                   , Point 2 r+                                                                   , SubLine 2 p s r+                                                                   ]+ instance (Ord r, Fractional r) =>-         (SubLine 2 p r) `IsIntersectableWith` (SubLine 2 p r) where+         (SubLine 2 p r r) `IsIntersectableWith` (SubLine 2 p r r) where    nonEmptyIntersection = defaultNonEmptyIntersection @@ -107,16 +122,43 @@            )       :& RNil     where-      -- 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+          $ 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) (ClosedInterval (ext MinInfinity) (ext MaxInfinity))+instance (Ord r, Fractional r) =>+         (SubLine 2 p (UnBounded r) r) `IsIntersectableWith` (SubLine 2 p (UnBounded r) r) where+  nonEmptyIntersection = defaultNonEmptyIntersection +  sl@(SubLine l r) `intersect` sm@(SubLine m _) = match (l `intersect` m) $+         (H $ \NoIntersection -> coRec NoIntersection)+      :& (H $ \p@(Point _)    -> if onSubLine2UB p sl && onSubLine2UB p sm+                                 then coRec p+                                 else coRec NoIntersection)+      :& (H $ \_             -> match (r `intersect` s'') $+                                      (H $ \NoIntersection -> coRec NoIntersection)+                                   :& (H $ \i              -> coRec $ SubLine l i)+                                   :& RNil+           )+      :& RNil+    where+      -- convert to points, then convert back to 'r' values (but now w.r.t. l)+      s'  = getEndPointsUnBounded sm+      s'' = second (fmap f) s'+      f = flip toOffset' l +-- | Get the endpoints of an unbounded interval+getEndPointsUnBounded    :: (Num r, Arity d) => SubLine d p (UnBounded r) r+                         -> Interval p (UnBounded (Point d r))+getEndPointsUnBounded sl = second (fmap f) $ sl^.subRange+  where+    f = flip pointAt (sl^.line)++fromLine   :: Arity d => Line d r -> SubLine d () (UnBounded r) r+fromLine l = SubLine l (ClosedInterval (ext MinInfinity) (ext MaxInfinity))++ -- testL :: SubLine 2 () (UnBounded Rational) -- testL = SubLine (horizontalLine 0) (Interval (Closed (only 0)) (Open $ only 10)) @@ -125,3 +167,11 @@   -- test = (testL^.subRange) `intersect` (horL^.subRange)++-- toOffset (Point2 minInfinity minInfinity) (horizontalLine 0)+-- testzz = let f  = bimap (fmap Val) (const ())+--          in++testz :: SubLine 2 () Rational Rational+testz = SubLine (Line (Point2 0 0) (Vector2 10 0))+                (Interval (Closed (0 % 1 :+ ())) (Closed (1 % 1 :+ ())))
src/Data/Geometry/Transformation.hs view
@@ -8,6 +8,7 @@ module Data.Geometry.Transformation where  import           Control.Lens (lens,Lens',set)+import           Unsafe.Coerce(unsafeCoerce) import           Data.Geometry.Point import           Data.Geometry.Properties import           Data.Geometry.Vector@@ -16,6 +17,7 @@ import qualified Data.Vector.Fixed as FV import           GHC.TypeLits import           Linear.Matrix ((!*),(!*!))+import qualified Linear.Matrix as Lin  -------------------------------------------------------------------------------- -- * Matrices@@ -34,6 +36,23 @@ mult :: (Arity m, Arity n, Num r) => Matrix n m r -> Vector m r -> Vector n r (Matrix m) `mult` v = m !* v ++class Invertible n r where+  inverse' :: Matrix n n r -> Matrix n n r++instance Fractional r => Invertible 2 r where+  -- >>> inverse' $ Matrix $ Vector2 (Vector2 1 2) (Vector2 3 4.0)+  -- Matrix Vector2 [Vector2 [-2.0,1.0],Vector2 [1.5,-0.5]]+  inverse' (Matrix m) = Matrix . unsafeCoerce . Lin.inv22 . unsafeCoerce $ m++instance Fractional r => Invertible 3 r where+  -- >>> inverse' $ Matrix $ Vector3 (Vector3 1 2 4) (Vector3 4 2 2) (Vector3 1 1 1.0)+  -- Matrix Vector3 [Vector3 [0.0,0.5,-1.0],Vector3 [-0.5,-0.75,3.5],Vector3 [0.5,0.25,-1.5]]+  inverse' (Matrix m) = Matrix . unsafeCoerce . Lin.inv33 . unsafeCoerce $ m++instance Fractional r => Invertible 4 r where+  inverse' (Matrix m) = Matrix . unsafeCoerce . Lin.inv44 . unsafeCoerce $ m+ -------------------------------------------------------------------------------- -- * Transformations @@ -55,6 +74,17 @@ (|.|) :: (Num r, Arity (d + 1)) => Transformation d r -> Transformation d r -> Transformation d r (Transformation f) |.| (Transformation g) = Transformation $ f `multM` g ++-- if it exists?++-- | Compute the inverse transformation+--+-- >>> inverseOf $ translation (Vector2 (10.0) (5.0))+-- Transformation {_transformationMatrix = Matrix Vector3 [Vector3 [1.0,0.0,-10.0],Vector3 [0.0,1.0,-5.0],Vector3 [0.0,0.0,1.0]]}+inverseOf :: (Fractional r, Invertible (d + 1) r)+          => Transformation d r -> Transformation d r+inverseOf = Transformation . inverse' . _transformationMatrix+ -------------------------------------------------------------------------------- -- * Transformable geometry objects @@ -136,3 +166,16 @@ 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++--------------------------------------------------------------------------------+-- * 3D Rotations++-- | Given three new unit-length basis vectors (u,v,w) that map to (x,y,z),+-- construct the appropriate rotation that does this.+--+--+rotateTo                 :: Num r => Vector 3 (Vector 3 r) -> Transformation 3 r+rotateTo (Vector3 u v w) = Transformation . Matrix $ Vector4 (snoc u        0)+                                                             (snoc v        0)+                                                             (snoc w        0)+                                                             (Vector4 0 0 0 1)
src/Data/Geometry/Triangle.hs view
@@ -1,22 +1,38 @@+{-# LANGUAGE ScopedTypeVariables  #-} {-# 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+import           Control.Lens+import           Data.Bifunctor+import           Data.Either (partitionEithers)+import           Data.Ext+import           Data.Geometry.Ball (Disk, disk)+import           Data.Geometry.Boundary+import           Data.Geometry.HyperPlane+import           Data.Geometry.Line+import           Data.Geometry.LineSegment+import           Data.Geometry.Point+import           Data.Geometry.Properties+import           Data.Geometry.Transformation+import           Data.Geometry.Vector+import qualified Data.Geometry.Vector as V+import qualified Data.List as List+import           Data.Maybe (mapMaybe)+import           Data.Vinyl+import           Data.Vinyl.CoRec+import           GHC.TypeLits ++--------------------------------------------------------------------------------+ data Triangle d p r = Triangle (Point d r :+ p)                                (Point d r :+ p)                                (Point d r :+ p)  deriving instance (Arity d, Show r, Show p) => Show (Triangle d p r)+deriving instance (Arity d, Read r, Read p) => Read (Triangle d p r)+deriving instance (Arity d, Eq r, Eq p)     => Eq (Triangle d p r)  instance Arity d => Functor (Triangle d p) where   fmap f (Triangle p q r) = let f' = first (fmap f) in Triangle (f' p) (f' q) (f' r)@@ -32,6 +48,15 @@   transformBy = transformPointFunctor  +-- | convenience function to construct a triangle without associated data.+triangle'       :: Point d r -> Point d r -> Point d r -> Triangle d () r+triangle' p q r = Triangle (ext p) (ext q) (ext r)+++sideSegments                  :: Triangle d p r -> [LineSegment d p r]+sideSegments (Triangle p q r) =+  [ClosedLineSegment p q, ClosedLineSegment q r, ClosedLineSegment r p]+ -- | Compute the area of a triangle area   :: Fractional r => Triangle 2 p r -> r area t = doubleArea t / 2@@ -47,9 +72,144 @@     Point2 bx by = b^.core     Point2 cx cy = c^.core +-- | Checks if the triangle is degenerate, i.e. has zero area.+isDegenerateTriangle :: (Num r, Eq r) => Triangle 2 p r -> Bool+isDegenerateTriangle = (== 0) . doubleArea  -- | get the inscribed disk. Returns Nothing if the triangle is degenerate, -- i.e. if the points are colinear. inscribedDisk                  :: (Eq r, Fractional r)                                => Triangle 2 p r -> Maybe (Disk () r) inscribedDisk (Triangle p q r) = disk (p^.core) (q^.core) (r^.core)+++instance Num r => HasSupportingPlane (Triangle 3 p r) where+  supportingPlane (Triangle p q r) = from3Points (p^.core) (q^.core) (r^.core)+++-- | Given a point q and a triangle, q inside the triangle, get the baricentric+-- cordinates of q+toBarricentric                                 :: Fractional r+                                               => Point 2 r -> Triangle 2 p r+                                               -> Vector 3 r+toBarricentric (Point2 qx qy) (Triangle a b c) = Vector3 alpha beta gamma+  where+    Point2 ax ay = a^.core+    Point2 bx by = b^.core+    Point2 cx cy = c^.core++    dett  = (by - cy)*(ax - cx) + (cx - bx)*(ay - cy)++    alpha = ((by - cy)*(qx - cx) + (cx - bx)*(qy - cy)) / dett+    beta  = ((cy - ay)*(qx - cx) + (ax - cx)*(qy - cy)) / dett+    gamma = 1 - alpha - beta+    -- see https://en.wikipedia.org/wiki/Barycentric_coordinate_system#Conversion_between_barycentric_and_Cartesian_coordinates++-- | Given a vector of barricentric coordinates and a triangle, get the+-- corresponding point in the same coordinate sytsem as the vertices of the+-- triangle.+fromBarricentric                                  :: (Arity d, Num r)+                                                  => Vector 3 r -> Triangle d p r+                                                  -> Point d r+fromBarricentric (Vector3 a b c) (Triangle p q r) = let f = view (core.vector) in+    Point $ a *^ f p ^+^ b *^ f q ^+^ c *^ f r+++-- | Tests if a point lies inside a triangle, on its boundary, or outside the triangle+inTriangle     :: (Ord r, Fractional r)+                 => Point 2 r -> Triangle 2 p r -> PointLocationResult+inTriangle q t+    | all (`inRange` (OpenRange   0 1)) [a,b,c] = Inside+    | all (`inRange` (ClosedRange 0 1)) [a,b,c] = OnBoundary+    | otherwise                                 = Outside+  where+    Vector3 a b c = toBarricentric q t++-- | Test if a point lies inside or on the boundary of a triangle+onTriangle       :: (Ord r, Fractional r)+                 => Point 2 r -> Triangle 2 p r -> Bool+q `onTriangle` t = let Vector3 a b c = toBarricentric q t+                   in all (`inRange` (ClosedRange 0 1)) [a,b,c]+++-- myQ :: Point 2 Rational+-- myQ = read "Point2 [(-5985) % 16,(-14625) % 1]"+-- myTri :: Triangle 2 () Rational+-- myTri = read "Triangle (Point2 [(-15) % 1,0 % 1] :+ ()) (Point2 [225 % 2,0 % 1] :+ ()) (Point2 [135 % 1,0 % 1] :+ ())"++type instance IntersectionOf (Line 2 r) (Triangle 2 p r) =+  [ NoIntersection, Point 2 r, LineSegment 2 () r ]++instance (Fractional r, Ord r) => (Line 2 r) `IsIntersectableWith` (Triangle 2 p r) where+   nonEmptyIntersection = defaultNonEmptyIntersection++   l `intersect` (Triangle p q r) =+     case first List.nub . partitionEithers . mapMaybe collect $ sides of+       ([],[])   -> coRec NoIntersection+       (_, [s])  -> coRec $ first (const ()) s+       ([a],_)   -> coRec a+       ([a,b],_) -> coRec $ ClosedLineSegment (ext a) (ext b)+       (_,_)     -> error "intersecting a line with a triangle. Triangle is degenerate"+     where+       sides = [ClosedLineSegment p q, ClosedLineSegment q r, ClosedLineSegment r p]++       collect   :: LineSegment 2 p r -> Maybe (Either (Point 2 r) (LineSegment 2 p r))+       collect s = match (s `intersect` l) $+                        (H $ \NoIntersection           -> Nothing)+                     :& (H $ \(a :: Point 2 r)         -> Just $ Left a)+                     :& (H $ \(e :: LineSegment 2 p r) -> Just $ Right e)+                     :& RNil++++type instance IntersectionOf (Line 3 r) (Triangle 3 p r) =+  [ NoIntersection, Point 3 r, LineSegment 3 () r ]++instance (Fractional r, Ord r) => (Line 3 r) `IsIntersectableWith` (Triangle 3 p r) where+   nonEmptyIntersection = defaultNonEmptyIntersection++   l@(Line a v) `intersect` t@(Triangle (p :+ _) (q :+ _) (r :+ _)) =+       match (l `intersect` h) $+            (H $ \NoIntersection   -> coRec NoIntersection)+         :& (H $ \i@(Point3 _ _ _) -> if onTriangle' i then coRec i else coRec NoIntersection)+         :& (H $ \_                -> intersect2d)+         :& RNil+     where+       h@(Plane _ n) = supportingPlane t++       -- 2d triangle and the line in terms of 2d-coordinates wr.t. of a+       -- coordinate system in the supporting plane of t. The origin of this+       -- coordinate system corresponds to the second vertex of t (q)+       t' = Triangle (ext $ project p) (ext origin) (ext $ project r)+       l' = Line (project a) (project' v)++       -- test if the point in terms of its 2d coords lies in side the projected triangle+       onTriangle'                :: Point 3 r -> Bool+       onTriangle' i = (project i) `onTriangle` t'++       -- FIXME! these vectors may not be unit vectors. How do we deal with+       -- that? (and does that really matter here?)+       transf :: Transformation 3 r+       transf = let u = p .-. q+                in rotateTo (Vector3 u (n `cross` u) n) |.| translation ((-1) *^ (toVec q))+       -- inverse of the transformation above.+       invTrans :: Transformation 3 r+       invTrans = inverseOf transf+++       project :: Point 3 r -> Point 2 r+       project = projectPoint . transformBy transf+       project' :: Vector 3 r -> Vector 2 r+       project' = toVec . project . Point++       lift :: Point 2 r -> Point 3 r+       lift = Point . transformBy invTrans . flip V.snoc 0 . toVec+         -- lift a 2d point back into plane coordinates++       intersect2d :: Intersection (Line 3 r) (Triangle 3 p r)+       intersect2d = match (l' `intersect` t') $+            (H $ \NoIntersection    -> coRec NoIntersection)+         :& (H $ \i@(Point2 _ _)    -> coRec $ lift i)+         :& (H $ \(LineSegment s e) -> coRec $ LineSegment (s&unEndPoint.core %~ lift)+                                                           (e&unEndPoint.core %~ lift))+         :& RNil
src/Data/Geometry/Vector.hs view
@@ -1,3 +1,13 @@+--------------------------------------------------------------------------------+-- |+-- Module      :  Data.Geometry.Vector+-- Copyright   :  (C) Frank Staals+-- License     :  see the LICENSE file+-- Maintainer  :  Frank Staals+--+-- \(d\)-dimensional vectors.+--+-------------------------------------------------------------------------------- module Data.Geometry.Vector( module Data.Geometry.Vector.VectorFamily                            , module LV                            , C(..)@@ -8,17 +18,19 @@                            , scalarMultiple                            -- reexports                            , FV.replicate-                           , FV.imap,+                           , FV.imap+                           , xComponent, yComponent, zComponent                            ) where  import           Control.Applicative (liftA2)+import           Control.Lens(Lens') import qualified Data.Foldable as F import           Data.Geometry.Properties import           Data.Geometry.Vector.VectorFamily-import           Data.Geometry.Vector.VectorFixed(C(..))+import           Data.Geometry.Vector.VectorFixed (C(..)) import           Data.Maybe-import           Data.Semigroup import qualified Data.Vector.Fixed as FV+import           GHC.TypeLits import           Linear.Affine (Affine(..), qdA, distanceA) import           Linear.Metric (dot,norm,signorm) import           Linear.Vector as LV@@ -101,3 +113,19 @@     g No      = Nothing     g Maybe   = error "scalarMultiple': found a Maybe, which means the vectors either have length zero, or one of them is all Zero!"     g (Yes x) = Just x+++--------------------------------------------------------------------------------+-- * Helper functions specific to two and three dimensional vectors++xComponent :: (1 <= d, Arity d) => Lens' (Vector d r) r+xComponent = element (C :: C 0)+{-# INLINABLE xComponent #-}++yComponent :: (2 <= d, Arity d) => Lens' (Vector d r) r+yComponent = element (C :: C 1)+{-# INLINABLE yComponent #-}++zComponent :: (3 <= d, Arity d) => Lens' (Vector d r) r+zComponent = element (C :: C 2)+{-# INLINABLE zComponent #-}
src/Data/Geometry/Vector/VectorFamily.hs view
@@ -1,5 +1,17 @@ {-# LANGUAGE ScopedTypeVariables  #-} {-# LANGUAGE UndecidableInstances #-}+--------------------------------------------------------------------------------+-- |+-- Module      :  Data.Geometry.Vector.VectorFamily+-- Copyright   :  (C) Frank Staals+-- License     :  see the LICENSE file+-- Maintainer  :  Frank Staals+--+-- Implementation of \(d\)-dimensional vectors. The implementation+-- automatically selects an optimized representation for small (up to size 4)+-- vectors.+--+-------------------------------------------------------------------------------- module Data.Geometry.Vector.VectorFamily where  import           Control.DeepSeq@@ -14,7 +26,6 @@                                                         , VectorFamilyF                                                         , ImplicitArity                                                         )-import           Data.Semigroup import qualified Data.Vector.Fixed as V import           Data.Vector.Fixed.Cont (Peano) import           GHC.TypeLits@@ -24,7 +35,10 @@ import qualified Linear.V3 as L3 import qualified Linear.V4 as L4 import           Linear.Vector-+import           Text.ParserCombinators.ReadP (ReadP, string,pfail)+import           Text.ParserCombinators.ReadPrec (lift)+import           Text.Read (Read(..),readListPrecDefault, readPrec_to_P,minPrec)+import           Data.Proxy  -------------------------------------------------------------------------------- -- * d dimensional Vectors@@ -57,7 +71,10 @@  deriving instance Arity d => Additive (Vector d) deriving instance Arity d => Metric (Vector d)-deriving instance Arity d => Affine (Vector d)+instance Arity d => Affine (Vector d) where+  type Diff (Vector d) = Vector d+  u .-. v = u ^-^ v+  p .+^ v = p ^+^ v  instance Arity d => Ixed (Vector d r) where   ix = element'@@ -71,6 +88,18 @@   show v = mconcat [ "Vector", show $ F.length v , " "                    , show $ F.toList v ] +instance (Read r, Arity d) => Read (Vector d r) where+  readPrec     = lift readVec+  readListPrec = readListPrecDefault++readVec :: forall d r. (Arity d, Read r) => ReadP (Vector d r)+readVec = do let d = natVal (Proxy :: Proxy d)+             _  <- string $ "Vector" <> show d <> " "+             rs <- readPrec_to_P readPrec minPrec+             case vectorFromList rs of+               Just v -> pure v+               _      -> pfail+ deriving instance (FromJSON r, Arity d) => FromJSON (Vector d r) instance (ToJSON r, Arity d) => ToJSON (Vector d r) where   toJSON     = toJSON . _unV@@ -83,18 +112,23 @@  pattern Vector   :: VectorFamilyF (Peano d) r -> Vector d r pattern Vector v = MKVector (VectorFamily v)+{-# COMPLETE Vector #-}  pattern Vector1   :: r -> Vector 1 r pattern Vector1 x = (Vector (Identity x))+{-# COMPLETE Vector1 #-}  pattern Vector2     :: r -> r -> Vector 2 r pattern Vector2 x y = (Vector (L2.V2 x y))+{-# COMPLETE Vector2 #-}  pattern Vector3        :: r -> r -> r -> Vector 3 r pattern Vector3 x y z  = (Vector (L3.V3 x y z))+{-# COMPLETE Vector3 #-}  pattern Vector4         :: r -> r -> r -> r -> Vector 4 r pattern Vector4 x y z w = (Vector (L4.V4 x y z w))+{-# COMPLETE Vector4 #-}  -------------------------------------------------------------------------------- 
src/Data/Geometry/Vector/VectorFamilyPeano.hs view
@@ -9,13 +9,9 @@ -- 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           Data.Vector.Fixed.Cont (PeanoNum(..), Fun(..)) import           GHC.TypeLits import           Linear.Affine (Affine(..)) import           Linear.Metric
src/Data/Geometry/Vector/VectorFixed.hs view
@@ -10,7 +10,6 @@ import qualified Data.Vector.Fixed as V import           Data.Vector.Fixed (Arity) import           Data.Vector.Fixed.Boxed-import           Data.Vector.Fixed.Cont (Peano, PeanoNum(..)) import           GHC.Generics (Generic) import           GHC.TypeLits import           Linear.Affine (Affine(..))
+ src/Data/LSeq.hs view
@@ -0,0 +1,310 @@+{-# LANGUAGE ScopedTypeVariables #-}+--------------------------------------------------------------------------------+-- |+-- Module      :  Data.LSeq+-- Copyright   :  (C) Frank Staals+-- License     :  see the LICENSE file+-- Maintainer  :  Frank Staals+-- Description :  Wrapper around Data.Sequence with type level length annotation.+--+--------------------------------------------------------------------------------+module Data.LSeq( LSeq+                , toSeq+                , empty+                , fromList+                , fromNonEmpty+                , fromSeq+                , toNonEmpty++                , (<|), (|>)+                , (><)+                , eval++                , index+                , adjust+                , partition+                , mapWithIndex+                , take+                , drop+                , unstableSort, unstableSortBy+                , head, last+                , append++                , ViewL(..)+                , viewl+                , pattern (:<|)++                , pattern (:<<)+                , pattern EmptyL++                , ViewR(..)+                , viewr+                , pattern (:|>)+++                , promise+                , forceLSeq+                ) where++import           Control.DeepSeq+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 qualified Data.Sequence as S+import           GHC.Generics (Generic)+import qualified Data.Traversable as Tr+import           GHC.TypeLits+import           Prelude hiding (drop,take,head,last)++--------------------------------------------------------------------------------++-- $setup+-- >>> :{+-- import Data.Proxy+-- :}++++-- | LSeq n a certifies that the sequence has *at least* n items+newtype LSeq (n :: Nat) a = LSeq (S.Seq a)+                          deriving (Show,Read,Eq,Ord,Foldable,Functor,Traversable+                                   ,Generic,NFData)++toSeq          :: LSeq n a -> S.Seq a+toSeq (LSeq s) = s++instance Semigroup (LSeq n a) where+  (LSeq s) <> (LSeq s') = LSeq (s <> s')++instance Monoid (LSeq 0 a) where+  mempty = empty+  mappend = (<>)++++type instance Index   (LSeq n a) = Int+type instance IxValue (LSeq n a) = a+instance Ixed (LSeq n a) where+  ix i f s@(LSeq xs)+    | 0 <= i && i < S.length xs = f (S.index xs i) <&> \x -> LSeq $ S.update i x xs+    | otherwise                 = pure s++empty :: LSeq 0 a+empty = LSeq S.empty++(<|) :: a -> LSeq n a -> LSeq (1 + n) a+x <| xs = LSeq (x S.<| toSeq xs)++(|>)    :: LSeq n a -> a -> LSeq (1 + n) a+xs |> x = LSeq (toSeq xs S.|> x)++infixr 5 <|+infixl 5 |>++(><) :: LSeq n a -> LSeq m a -> LSeq (n + m) a+xs >< ys = LSeq (toSeq xs <> toSeq ys)++infix 5 ><+++eval :: forall proxy n m a. KnownNat n => proxy n -> LSeq m a -> Maybe (LSeq n a)+eval n (LSeq xs)+  | toInteger (S.length xs) >= natVal n = Just $ LSeq xs+  | otherwise                           = Nothing++++++-- | Promises that the length of this LSeq is actually n. This is not+-- checked.+--+-- This function should be a noop+promise :: LSeq m a -> LSeq n a+promise = LSeq . toSeq+++-- | Forces the first n elements of the LSeq+forceLSeq   :: KnownNat n => proxy n -> LSeq m a -> LSeq n a+forceLSeq n = promise . go (fromInteger $ natVal n)+  where+    -- forces the Lseq for n' positions+    go      :: Int -> LSeq m a -> LSeq m a+    go n' s | n' <= l    = s+            | otherwise  = error msg+      where+        l   = S.length . S.take n' . toSeq $ s+        msg = "forceLSeq: too few elements. expected " <> show n' <> " but found " <> show l++++toNonEmpty :: LSeq (1 + n) a -> NonEmpty.NonEmpty a+toNonEmpty = NonEmpty.fromList . F.toList++-- | appends two sequences.+--+append         :: LSeq n a -> LSeq m a -> LSeq (n + m) a+sa `append` sb = LSeq $ (toSeq sa) <> toSeq sb++--------------------------------------------------------------------------------++-- | get the element with index i, counting from the left and starting at 0.+-- O(log(min(i,n-i)))+index     :: LSeq n a -> Int -> a+index s i = fromJust $ s^?ix i++adjust       :: (a -> a) -> Int -> LSeq n a -> LSeq n a+adjust f i s = s&ix i %~ f+++partition   :: (a -> Bool) -> LSeq n a -> (LSeq 0 a, LSeq 0 a)+partition p = bimap LSeq LSeq . S.partition p . toSeq++mapWithIndex   :: (Int -> a -> b) -> LSeq n a -> LSeq n b+mapWithIndex f = wrapUnsafe (S.mapWithIndex f)++take   :: Int -> LSeq n a -> LSeq 0 a+take i = wrapUnsafe (S.take i)++drop   :: Int -> LSeq n a -> LSeq 0 a+drop i = wrapUnsafe (S.drop i)+++unstableSortBy   :: (a -> a -> Ordering) -> LSeq n a -> LSeq n a+unstableSortBy f = wrapUnsafe (S.unstableSortBy f)++unstableSort :: Ord a => LSeq n a -> LSeq n a+unstableSort = wrapUnsafe (S.unstableSort)+++wrapUnsafe :: (S.Seq a -> S.Seq b) -> LSeq n a -> LSeq m b+wrapUnsafe f = LSeq . f . toSeq++--------------------------------------------------------------------------------++fromSeq :: S.Seq a -> LSeq 0 a+fromSeq = LSeq++fromList :: Foldable f => f a -> LSeq 0 a+fromList = LSeq . S.fromList . F.toList++fromNonEmpty :: NonEmpty.NonEmpty a -> LSeq 1 a+fromNonEmpty = LSeq . S.fromList . F.toList+++--------------------------------------------------------------------------------++data ViewL n a where+  (:<) :: a -> LSeq n a -> ViewL (1 + n) a++infixr 5 :<++instance Semigroup (ViewL n a) where+  (x :< xs) <> (y :< ys) = x :< LSeq (toSeq xs <> (y S.<| toSeq ys))++deriving instance Show a => Show (ViewL n a)+instance Functor (ViewL n) where+  fmap = Tr.fmapDefault+instance Foldable (ViewL n) where+  foldMap = Tr.foldMapDefault+instance Traversable (ViewL n) where+  traverse f (x :< xs) = (:<) <$> f x <*> traverse f xs+instance Eq a => Eq (ViewL n a) where+  s == s' = F.toList s == F.toList s'+instance Ord a => Ord (ViewL n a) where+  s `compare` s' = F.toList s `compare` F.toList s'+++viewl :: LSeq (1 + n) a -> ViewL (1 + n) a+viewl xs = let ~(x S.:< ys) = S.viewl $ toSeq xs in x :< LSeq ys++viewl'    :: LSeq (1 + n) a -> (a, LSeq n a)+viewl' xs = let ~(x S.:< ys) = S.viewl $ toSeq xs in (x,LSeq ys)++infixr 5 :<|++pattern (:<|)    :: a -> LSeq n a -> LSeq (1 + n) a+pattern x :<| xs <- (viewl' -> (x,xs)) -- we need the coerce unfortunately+  where+    x :<| xs = x <| xs+{-# COMPLETE (:<|) #-}++++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)+viewLSeq (LSeq s) = case S.viewl s of+                      S.EmptyL    -> Nothing+                      (x S.:< xs) -> Just (x,LSeq xs)+++--------------------------------------------------------------------------------++data ViewR n a where+  (:>) :: LSeq n a -> a -> ViewR (1 + n) a++infixl 5 :>++instance Semigroup (ViewR n a) where+  (xs :> x) <> (ys :> y) = LSeq ((toSeq xs S.|> x) <> toSeq ys) :> y++deriving instance Show a => Show (ViewR n a)+instance Functor (ViewR n) where+  fmap = Tr.fmapDefault+instance Foldable (ViewR n) where+  foldMap = Tr.foldMapDefault+instance Traversable (ViewR n) where+  traverse f (xs :> x) = (:>) <$> traverse f xs <*> f x+instance Eq a => Eq (ViewR n a) where+  s == s' = F.toList s == F.toList s'+instance Ord a => Ord (ViewR n a) where+  s `compare` s' = F.toList s `compare` F.toList s'++viewr    :: LSeq (1 + n) a -> ViewR (1 + n) a+viewr xs = let ~(ys S.:> x) = S.viewr $ toSeq xs in LSeq ys :> x++viewr'    :: LSeq (1 + n) a -> (LSeq n a, a)+viewr' xs = let ~(ys S.:> x) = S.viewr $ toSeq xs in (LSeq ys, x)++infixl 5 :|>++pattern (:|>)    :: forall n a. LSeq n a -> a -> LSeq (1 + n) a+pattern xs :|> x <- (viewr' -> (xs,x))+  where+    xs :|> x = xs |> x+{-# COMPLETE (:|>) #-}++--------------------------------------------------------------------------------++-- | Gets the first element of the LSeq+--+-- >>> head $ forceLSeq (Proxy :: Proxy 3) $ fromList [1,2,3]+-- 1+head           :: LSeq (1 + n) a -> a+head (x :<| _) = x++-- s = let (x :< _) = viewl s in x++-- | Get the last element of the LSeq+--+-- >>> last $ forceLSeq (Proxy :: Proxy 3) $ fromList [1,2,3]+-- 3+last           :: LSeq (1 + n) a -> a+last (_ :|> x) = x++-- testL = (eval (Proxy :: Proxy 2) $ fromList [1..5])++-- testL' :: LSeq 2 Integer+-- testL' = fromJust testL++-- test            :: Show a => LSeq (1 + n) a -> String+-- test (x :<| xs) = show x ++ show xs
src/Data/OrdSeq.hs view
@@ -6,7 +6,6 @@ import           Data.FingerTree hiding (null, viewl, viewr) import qualified Data.Foldable as F import           Data.Maybe-import           Data.Semigroup  -------------------------------------------------------------------------------- 
src/Data/Permutation.hs view
@@ -1,6 +1,17 @@ {-# LANGUAGE TemplateHaskell #-}+--------------------------------------------------------------------------------+-- |+-- Module      :  Data.Permutation+-- Copyright   :  (C) Frank Staals+-- License     :  see the LICENSE file+-- Maintainer  :  Frank Staals+--+-- Data type for representing a Permutation+--+-------------------------------------------------------------------------------- module Data.Permutation where +import           Control.DeepSeq import           Control.Lens import           Control.Monad (forM) import           Control.Monad.ST (runST)@@ -11,6 +22,7 @@ import qualified Data.Vector.Generic as GV import qualified Data.Vector.Unboxed as UV import qualified Data.Vector.Unboxed.Mutable as UMV+import           GHC.Generics (Generic)  -------------------------------------------------------------------------------- @@ -24,9 +36,11 @@                                                -- implies that a is the j^th                                                -- item in the i^th orbit                                  }-                   deriving (Show,Eq)+                   deriving (Show,Eq,Generic) makeLenses ''Permutation +instance NFData a => NFData (Permutation a)+ instance Functor Permutation where   fmap = T.fmapDefault @@ -45,7 +59,7 @@  -- | The cycle containing a given item cycleOf        :: Enum a => Permutation a -> a -> Orbit a-cycleOf perm x = perm^.orbits.ix' (perm^.indexes.ix' (fromEnum x)._1)+cycleOf perm x = perm^?!orbits.ix (perm^?!indexes.ix (fromEnum x)._1)   -- | Next item in a cyclic permutation@@ -61,12 +75,12 @@ -- -- runnign time: \(O(1)\) lookupIdx        :: Enum a => Permutation a -> a -> (Int,Int)-lookupIdx perm x = perm^.indexes.ix' (fromEnum x)+lookupIdx perm x = perm^?!indexes.ix (fromEnum x)  -- | Apply the permutation, i.e. consider the permutation as a function. apply        :: Enum a => Permutation a -> a -> a apply perm x = let (c,i) = lookupIdx perm x-               in next (perm^.orbits.ix' c) i+               in next (perm^?!orbits.ix c) i   -- | Find the cycle in the permutation starting at element s@@ -108,13 +122,3 @@   where     f i c = zipWith (\x j -> (fromEnum x,(i,j))) c [0..]     ixes' = concat $ zipWith f [0..] os--------------------------------------------------------------------------------------- * Helper stuff---- | lens indexing into a vector-ix'   :: (GV.Vector v a, Index (v a) ~ Int, IxValue (v a) ~ a, Ixed (v a))-      => Int -> Lens' (v a) a-ix' i = singular (ix i)
src/Data/PlanarGraph.hs view
@@ -1,41 +1,65 @@ {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE OverloadedStrings #-}-module Data.PlanarGraph( Arc(..)+--------------------------------------------------------------------------------+-- |+-- Module      :  Data.PlanarGraph+-- Copyright   :  (C) Frank Staals+-- License     :  see the LICENSE file+-- Maintainer  :  Frank Staals+--+-- Data type for representing connected planar graphs+--------------------------------------------------------------------------------+module Data.PlanarGraph( -- $setup+                         -- * The Planar Graph type+                         PlanarGraph+                       , embedding, vertexData, dartData, faceData, rawDartData+                       , edgeData++                       , World(..)+                       , DualOf++                       -- * Representing edges: Arcs and Darts+                       , Arc(..)                        , Direction(..), rev                         , Dart(..), arc, direction                        , twin, isPositive -                       , World(..)--                       , DualOf+                       -- * Vertices                         , VertexId(..), VertexId' -                       , PlanarGraph-                       , embedding, vertexData, dartData, faceData, rawDartData-                       , edgeData+                       -- * Building a planar graph                         , planarGraph, planarGraph', fromAdjacencyLists                        , toAdjacencyLists                        , buildFromJSON +                       -- * Quering a planar graph+                        , numVertices, numDarts, numEdges, numFaces                        , darts', darts, edges', edges, vertices', vertices, faces', faces+                       , traverseVertices, traverseDarts, traverseFaces                         , tailOf, headOf, endPoints                        , incidentEdges, incomingEdges, outgoingEdges, neighboursOf                        , nextIncidentEdge, prevIncidentEdge +                       -- * Associated Data+                        , HasDataOf(..), endPointDataOf, endPointData                         , dual +                       -- * Faces+                        , FaceId(..), FaceId'-                       , leftFace, rightFace, boundary, boundary', boundaryVertices+                       , leftFace, rightFace+                       , boundaryDart, boundary, boundary', boundaryVertices                        , nextEdge, prevEdge +                       -- * Edge Oracle                         , EdgeOracle                        , edgeOracle, buildEdgeOracle@@ -47,6 +71,7 @@   import           Control.Applicative (Alternative(..))+import           Control.DeepSeq import           Control.Lens hiding ((.=)) import           Control.Monad.ST (ST) import           Control.Monad.State.Strict@@ -57,7 +82,6 @@ import qualified Data.Foldable as F import           Data.Maybe (catMaybes, isJust, fromJust, fromMaybe) import           Data.Permutation-import           Data.Semigroup (Semigroup(..)) import           Data.Traversable (fmapDefault,foldMapDefault) import           Data.Type.Equality (gcastWith, (:~:)(..)) import qualified Data.Vector as V@@ -65,20 +89,17 @@ import qualified Data.Vector.Mutable as MV import qualified Data.Vector.Unboxed as UV import qualified Data.Vector.Unboxed.Mutable as UMV+import           GHC.Generics (Generic) import           Unsafe.Coerce (unsafeCoerce)-- -- import           Data.Yaml.Util--- import           Debug.Trace ---------------------------------------------------------------------------------  -------------------------------------------------------------------------------- -- $setup -- >>> :{ -- 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 () Primal () String () --     myGraph = planarGraph [ [ (Dart aA Negative, "a-") --                             , (Dart aC Positive, "c+") --                             , (Dart aB Positive, "b+")@@ -97,21 +118,27 @@ --                             ] --                           ] -- :}---- This represents the following graph:+--+--+-- This represents the following graph. Note that the graph is undirected, the+-- arrows are just to indicate what the Positive direction of the darts is.+-- -- ![myGraph](docs/Data/PlanarGraph/testG.png)  --------------------------------------------------------------------------------  -- | An Arc is a directed edge in a planar graph. The type s is used to tie -- this arc to a particular graph.-newtype Arc s = Arc { _unArc :: Int } deriving (Eq,Ord,Enum,Bounded)+newtype Arc s = Arc { _unArc :: Int } deriving (Eq,Ord,Enum,Bounded,Generic,NFData)  instance Show (Arc s) where   show (Arc i) = "Arc " ++ show i +-- | Darts have a direction which is either Positive or Negative (shown as +1+-- or -1, respectively).+data Direction = Negative | Positive deriving (Eq,Ord,Bounded,Enum,Generic) -data Direction = Negative | Positive deriving (Eq,Ord,Bounded,Enum)+instance NFData Direction  instance Show Direction where   show Positive = "+1"@@ -130,13 +157,12 @@ -- | 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       :: {-#UNPACK #-} !(Arc s)-                   , _direction :: {-#UNPACK #-} !Direction-                   } deriving (Eq,Ord)+data Dart s = Dart { _arc       :: !(Arc s)+                   , _direction :: !Direction+                   } deriving (Eq,Ord,Generic) makeLenses ''Dart --+instance NFData (Dart s)  instance Show (Dart s) where   show (Dart a d) = "Dart (" ++ show a ++ ") " ++ show d@@ -157,8 +183,8 @@  instance Enum (Dart s) where   toEnum x-    | even x    = Dart (Arc $ x `div` 2)       Positive-    | otherwise = Dart (Arc $ (x `div` 2) + 1) Negative+    | even x    = Dart (Arc $ x `div` 2) Positive+    | otherwise = Dart (Arc $ x `div` 2) Negative   -- get the back edge by adding one    fromEnum (Dart (Arc i) d) = case d of@@ -174,10 +200,13 @@ -- | The world in which the graph lives data World = Primal | Dual deriving (Show,Eq) +-- | We can take the dual of a world. For the Primal this gives us the Dual,+-- for the Dual this gives us the Primal. type family DualOf (sp :: World) where   DualOf Primal = Dual   DualOf Dual   = Primal +-- | The Dual of the Dual is the Primal. dualDualIdentity :: forall w. DualOf (DualOf w) :~: w dualDualIdentity = unsafeCoerce Refl           -- manual proof:@@ -188,9 +217,10 @@ -- | 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,ToJSON,FromJSON)+                                deriving (Eq,Ord,Enum,ToJSON,FromJSON,Generic,NFData) -- VertexId's are in the range 0...|orbits|-1 +-- | Shorthand for vertices in the primal. type VertexId' s = VertexId s Primal  unVertexId :: Getter (VertexId s w) Int@@ -216,7 +246,7 @@                                                     , _rawDartData :: V.Vector e                                                     , _faceData    :: V.Vector f                                                     , _dual        :: PlanarGraph s (DualOf w) f e v-                                                    }+                                                    } deriving (Generic)  instance (Show v, Show e, Show f) => Show (PlanarGraph s w v e f) where   show (PlanarGraph e v r f _) = unwords [ "PlanarGraph"@@ -236,14 +266,22 @@   toJSON     = object . encodeJSON   toEncoding = pairs . mconcat . encodeJSON +++-- | Enclodes the planar graph as a JSON object.  note that every face is+-- stored together with a dart bounding the face. (and so that the face lies to+-- its right. Otherwise we cannot reconstruct the face data appropriately. 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)+encodeJSON g = [ "vertices"    .= ((\(v,x) -> v :+ x)             <$> vertices g)+               , "darts"       .= ((\(e,x) -> endPoints e g :+ x) <$> darts g)+               , "faces"       .= ((\(f,x) -> f :+ x)             <$> faces g)                , "adjacencies" .= toAdjacencyLists g                ]-+  -- where+  --   faces'' = withBoundaryDart  <$> faces g+  --   withBoundaryDart (f,x) = let d = boundaryDart f g+  --                            in (f, endPoints d g, x)  instance (FromJSON v, FromJSON e, FromJSON f)          => FromJSON (PlanarGraph s Primal v e f) where@@ -270,9 +308,7 @@     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+    -- TODO: do we have enough infor to reconstruct the face info?      -- make sure we order the data values appropriately     reorder v f = V.create $ do@@ -288,6 +324,8 @@  -- ** lenses and getters +-- | Get the embedding, reprsented as a permutation of the darts, of this+-- graph. embedding :: Getter (PlanarGraph s w v e f) (Permutation (Dart s)) embedding = to _embedding @@ -303,11 +341,17 @@                  (V.Vector f) (V.Vector f') faceData = lens _faceData (\g fD -> updateData id id (const fD) g) +-- | Get the dual graph of this graph. dual :: Getter (PlanarGraph s w v e f) (PlanarGraph s (DualOf w) f e v) dual = to _dual  +-- FIXME: So I guess the two darts associated with an edge can store different+-- data. This is useful. Make sure that works as expected.+ -- | 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 dD -> updateData id (const $ reorderEdgeData dD) id g)@@ -355,6 +399,55 @@                                     MV.write v (fromEnum d) x                                   pure v +-- | Traverse the vertices+--+-- (^.vertexData) <$> traverseVertices (\i x -> Just (i,x)) myGraph+-- Just [(VertexId 0,()),(VertexId 1,()),(VertexId 2,()),(VertexId 3,())]+-- >>> traverseVertices (\i x -> print (i,x)) myGraph >> pure ()+-- (VertexId 0,())+-- (VertexId 1,())+-- (VertexId 2,())+-- (VertexId 3,())+traverseVertices   :: Applicative m+                   => (VertexId s w -> v -> m v')+                   -> PlanarGraph s w v e f+                   -> m (PlanarGraph s w v' e f)+traverseVertices f = itraverseOf (vertexData.itraversed) (\i -> f (VertexId i))++-- | Traverses the darts+--+-- >>> traverseDarts (\d x -> print (d,x)) myGraph >> pure ()+-- (Dart (Arc 0) +1,"a+")+-- (Dart (Arc 0) -1,"a-")+-- (Dart (Arc 1) +1,"b+")+-- (Dart (Arc 1) -1,"b-")+-- (Dart (Arc 2) +1,"c+")+-- (Dart (Arc 2) -1,"c-")+-- (Dart (Arc 3) +1,"d+")+-- (Dart (Arc 3) -1,"d-")+-- (Dart (Arc 4) +1,"e+")+-- (Dart (Arc 4) -1,"e-")+-- (Dart (Arc 5) +1,"g+")+-- (Dart (Arc 5) -1,"g-")+traverseDarts   :: Applicative m+                => (Dart s -> e -> m e')+                -> PlanarGraph s w v e f+                -> m (PlanarGraph s w v e' f)+traverseDarts f = itraverseOf (rawDartData.itraversed) (\i -> f (toEnum i))++-- | Traverses the faces+--+-- >>> traverseFaces (\i x -> print (i,x)) myGraph >> pure ()+-- (FaceId 0,())+-- (FaceId 1,())+-- (FaceId 2,())+-- (FaceId 3,())+traverseFaces   :: Applicative m+                => (FaceId s w -> f -> m f')+                -> PlanarGraph s w v e f+                -> m (PlanarGraph s w v e f')+traverseFaces f = itraverseOf (faceData.itraversed) (\i -> f (FaceId $ VertexId i))+ -------------------------------------------------------------------------------- -- ** Constructing a Planar graph @@ -440,71 +533,7 @@ 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).---     -- if u > v. Don't assign anything.--- assignArcs                     :: (Ord v, Foldable f)---                                    => (v, f v)---                                    -> SP [(v, [v :+ Maybe Int])] Int---                                    -> SP [(v, [v :+ Maybe Int])] Int--- assignArcs (u,adjU) (SP acc i) = first (\adjU' -> (u,adjU'):acc)---                                    . foldr (assignArcs' u) (SP [] i)---                                    . F.toList $ adjU ---     -- Go through all edges that have u as one endpoint.--- assignArcs'   :: Ord v => v -> v -> SP [v :+ Maybe Int] Int---                                  -> SP [v :+ Maybe Int] Int--- assignArcs' u v (SP acc i)---       | u <= v    = SP ((v :+ Just i)  : acc) (i+1)---       | otherwise = SP ((v :+ Nothing) : acc) i---------- -- - 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 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 () () ()--- fromAdjacencyLists adjM = planarGraph' . toCycleRep n $ perm---   where---     n    = sum . fmap length $ adjM---     perm = trd' . foldr toOrbit (STR mempty 0 mempty) $ adjM-----     -- | 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))---                                 -> STR' s [[Dart s]]---                                 -> STR' s [[Dart s]]---     toOrbit (u,vs) (STR m a dss) =---       let (STR m' a' ds') = foldr (toDart . (u,)) (STR m a mempty) . C.toList $ vs---       in STR 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 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---                                     t'  = (min u v, max u v)---                                in case SM.lookup t' m of---       Just a' -> STR m                  a     (Dart (Arc a') dir : ds)---       Nothing -> STR (SM.insert t' a m) (a+1) (Dart (Arc a)  dir : ds)-- -------------------------------------------------------------------------------- -- ** Convenience functions @@ -592,10 +621,6 @@ edges = V.filter (isPositive . fst) . darts  ---- -- | The tail of a dart, i.e. the vertex this dart is leaving from -- -- running time: \(O(1)\)@@ -615,14 +640,12 @@ 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+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.@@ -650,7 +673,7 @@ 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+                       in next (perm^?!orbits.ix i) j   -- | Given a dart d that points into some vertex v, report the next dart in the@@ -660,7 +683,7 @@ 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+                       in previous (perm^?!orbits.ix i) j   --------------------------------------------------------------------------------@@ -676,15 +699,15 @@  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+  dataOf (VertexId i) = vertexData.singular (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)+  dataOf d = rawDartData.singular (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+  dataOf (FaceId (VertexId i)) = faceData.singular (ix i)   -- | Data corresponding to the endpoints of the dart@@ -734,10 +757,11 @@                         g  --- | A face+-- | The type to reprsent FaceId's newtype FaceId s w = FaceId { _unFaceId :: VertexId s (DualOf w) }-                   deriving (Eq,Ord,ToJSON,FromJSON)+                   deriving (Eq,Ord,Enum,ToJSON,FromJSON) +-- | Shorthand for FaceId's in the primal. type FaceId' s = FaceId s Primal  instance Show (FaceId s w) where@@ -796,6 +820,12 @@ prevEdge d = prevIncidentEdge d . _dual  +-- | Gets a dart bounding this face. I.e. a dart d such that the face lies to+-- the right of the dart.+boundaryDart   :: FaceId s w -> PlanarGraph s w v e f -> Dart s+boundaryDart f = V.head . boundary f+-- TODO: make sure that this is indeed to the right.+ -- | The darts bounding this face, for internal faces in clockwise order, for -- the outer face in counter clockwise order. --@@ -853,28 +883,28 @@ --                               ] --                             ] -data Test+-- 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..]   @@ -1016,41 +1046,39 @@  -------------------------------------------------------------------------------- -data TestG--+-- data Test -type Vertex = VertexId TestG Primal+-- type Vertex = VertexId Test Primal -testEdges :: [(Vertex,[Vertex])]-testEdges = map (\(i,vs) -> (VertexId i, map VertexId vs))-            [ (0, [1])-            , (1, [0,1,2,4])-            , (2, [1,3,4])-            , (3, [2,5])-            , (4, [1,2,5])-            , (5, [3,4])-            ]+-- testEdges :: [(Vertex,[Vertex])]+-- testEdges = map (\(i,vs) -> (VertexId i, map VertexId vs))+--             [ (0, [1])+--             , (1, [0,1,2,4])+--             , (2, [1,3,4])+--             , (3, [2,5])+--             , (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..]+-- 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,6 +1,18 @@ {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE OverloadedStrings #-}+--------------------------------------------------------------------------------+-- |+-- Module      :  Data.PlaneGraph+-- Copyright   :  (C) Frank Staals+-- License     :  see the LICENSE file+-- Maintainer  :  Frank Staals+--+-- Data type for planar graphs embedded in \(\mathbb{R}^2\). For functions that+-- export faces and edges etc, we assume the graph has a (planar) straight line+-- embedding.+--+-------------------------------------------------------------------------------- module Data.PlaneGraph( PlaneGraph(PlaneGraph), graph                       , PlanarGraph                       , VertexData(VertexData), vData, location, vtxDataToExt@@ -14,6 +26,7 @@                       , edges', edges                       , faces', faces, internalFaces, faces''                       , darts'+                      , traverseVertices, traverseDarts, traverseFaces                        , headOf, tailOf, twin, endPoints @@ -40,23 +53,24 @@                         , withEdgeDistances+                      , writePlaneGraph, readPlaneGraph                       ) where   import           Control.Lens hiding (holes, holesOf, (.=)) import           Data.Aeson-import           Data.ByteString (ByteString)+import qualified Data.ByteString as B import qualified Data.CircularSeq as C import           Data.Ext import qualified Data.Foldable as F import           Data.Function (on)+import           Data.Geometry.Box 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           Data.Geometry.Properties import qualified Data.List.NonEmpty as NonEmpty import qualified Data.Map as M import           Data.Ord (comparing)@@ -68,18 +82,20 @@                                  , FaceId', VertexId'                                  , HasDataOf(..)                                  )-import           Data.Semigroup import           Data.Util import qualified Data.Vector as V+import           Data.Version+import           Data.Yaml (ParseException)+import           Data.Yaml.Util 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)+                                 } deriving (Show,Eq,Ord,Generic+                                            ,Functor,Foldable,Traversable) makeLenses ''VertexData  vtxDataToExt                  :: VertexData r v -> Point 2 r :+ v@@ -100,7 +116,7 @@ -- | 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)+      deriving (Show,Eq,ToJSON,FromJSON,Generic) makeLenses ''PlaneGraph  type instance NumType   (PlaneGraph s v e f r) = r@@ -416,6 +432,7 @@                    -> V.Vector (VertexId' s) boundaryVertices f = PG.boundaryVertices f . _graph + -------------------------------------------------------------------------------- -- * Access data @@ -439,6 +456,57 @@   dataOf f = graph.dataOf f  +-- | Traverse the vertices+--+-- (^.vertexData) <$> traverseVertices (\i x -> Just (i,x)) myGraph+-- Just [(VertexId 0,()),(VertexId 1,()),(VertexId 2,()),(VertexId 3,())]+-- >>> traverseVertices (\i x -> print (i,x)) myGraph >> pure ()+-- (VertexId 0,())+-- (VertexId 1,())+-- (VertexId 2,())+-- (VertexId 3,())+traverseVertices   :: Applicative m+                   => (VertexId' s -> v -> m v')+                   -> PlaneGraph s v e f r+                   -> m (PlaneGraph s v' e f r)+traverseVertices f = itraverseOf (vertexData.itraversed) (\i -> f (VertexId i))++-- | Traverses the darts+--+-- >>> traverseDarts (\d x -> print (d,x)) myGraph >> pure ()+-- (Dart (Arc 0) +1,"a+")+-- (Dart (Arc 0) -1,"a-")+-- (Dart (Arc 1) +1,"b+")+-- (Dart (Arc 1) -1,"b-")+-- (Dart (Arc 2) +1,"c+")+-- (Dart (Arc 2) -1,"c-")+-- (Dart (Arc 3) +1,"d+")+-- (Dart (Arc 3) -1,"d-")+-- (Dart (Arc 4) +1,"e+")+-- (Dart (Arc 4) -1,"e-")+-- (Dart (Arc 5) +1,"g+")+-- (Dart (Arc 5) -1,"g-")+traverseDarts   :: Applicative m+                => (Dart s -> e -> m e')+                -> PlaneGraph s v e f r+                -> m (PlaneGraph s v e' f r)+traverseDarts f = traverseOf graph (PG.traverseDarts f)+++-- | Traverses the faces+--+-- >>> traverseFaces (\i x -> print (i,x)) myGraph >> pure ()+-- (FaceId 0,())+-- (FaceId 1,())+-- (FaceId 2,())+-- (FaceId 3,())+traverseFaces   :: Applicative m+                => (FaceId' s  -> f -> m f')+                -> PlaneGraph s v e f r+                -> m (PlaneGraph s v e f' r)+traverseFaces f = traverseOf graph (PG.traverseFaces f)++ -- | Getter for the data at the endpoints of a dart -- -- running time: \(O(1)\)@@ -526,16 +594,20 @@ -------------------------------------------------------------------------------- -- * 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+-- | Reads a plane graph from a bytestring+readPlaneGraph   :: (FromJSON v, FromJSON e, FromJSON f, FromJSON r)+                 => proxy s -> B.ByteString+                 -> Either ParseException (PlaneGraph s v e f r)+readPlaneGraph _ = decodeYaml +-- | Writes a plane graph to a bytestring+writePlaneGraph :: (ToJSON v, ToJSON e, ToJSON f, ToJSON r)+                => PlaneGraph s v e f r -> B.ByteString+writePlaneGraph = encodeYaml . Versioned planeGraphVersion --- writePlaneGraph :: (ToJSON v, ToJSON e, ToJSON f, ToJSON r)---                           => PlaneGraph s v e f r -> ByteString--- writePlaneGraph = YamlP.encodePretty YamlP.defConfig++planeGraphVersion :: Version+planeGraphVersion = makeVersion [1,0]  -------------------------------------------------------------------------------- 
src/Data/PlaneGraph/Draw.hs view
@@ -1,23 +1,18 @@ {-# LANGUAGE ScopedTypeVariables #-} module Data.PlaneGraph.Draw where -import Data.PlaneGraph-import           Data.Geometry.Ipe import           Data.Ext-import           Control.Lens+import           Data.Geometry.Ipe+import           Data.PlaneGraph 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+drawPlaneGraph   :: IpeOut (PlaneGraph s v e f r) Group r+drawPlaneGraph g = ipeGroup $ concatMap V.toList [vs, es, fs]   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+    vs = (\(_,VertexData p _) -> iO $ defIO p) <$> vertices g+    es = (\(_,s :+ _)         -> iO $ defIO s) <$> edgeSegments g+    fs = (\(_,f :+ _)         -> iO $ defIO f) <$> rawFacePolygons g   -- drawPlaneGraphWith :: (VertexId' s :+ v -> IpeObject r)
src/Data/Range.hs view
@@ -1,11 +1,16 @@ {-# LANGUAGE TemplateHaskell   #-} {-# LANGUAGE DeriveAnyClass  #-}-{-|-Module    : Data.Range-Description: Generic Ranges (Intervals)-Copyright : (c) Frank Staals-License : See LICENCE file--}+--------------------------------------------------------------------------------+-- |+-- Module      :  Data.Range+-- Copyright   :  (C) Frank Staals+-- License     :  see the LICENSE file+-- Maintainer  :  Frank Staals+--+-- Data type for representing Generic Ranges (Intervals) and functions that+-- work with them.+--+-------------------------------------------------------------------------------- module Data.Range( EndPoint(..)                  , isOpen, isClosed                  , unEndPoint@@ -27,6 +32,7 @@ import Control.DeepSeq  --------------------------------------------------------------------------------+-- * Representing Endpoints of a Range  -- | Endpoints of a range may either be open or closed. data EndPoint a = Open   !a@@ -49,7 +55,7 @@   where     f (Open _) a   = Open a     f (Closed _) a = Closed a-+{-# INLINE unEndPoint #-}  isOpen          :: EndPoint a -> Bool isOpen (Open _) = True@@ -60,6 +66,7 @@   --------------------------------------------------------------------------------+-- * The Range Data type  -- | Data type for representing ranges. data Range a = Range { _lower :: !(EndPoint a)@@ -85,8 +92,16 @@ {-# COMPLETE Range' #-}  +-- | Helper function to show a range in mathematical notation.+--+-- >>> prettyShow $ OpenRange 0 2+-- "(0,2)"+-- >>> prettyShow $ ClosedRange 0 2+-- "[0,2]"+-- >>> prettyShow $ Range (Open 0) (Closed 5)+-- "(0,5]" prettyShow             :: Show a => Range a -> String-prettyShow (Range l u) = concat [ lowerB, show (l^.unEndPoint), ", "+prettyShow (Range l u) = concat [ lowerB, show (l^.unEndPoint), ","                                 , show (u^.unEndPoint), upperB                                 ]   where@@ -213,17 +228,17 @@ -- | Shift a range x units to the left -- -- >>> prettyShow $ shiftLeft 10 (ClosedRange 10 20)--- "[0, 10]"+-- "[0,10]" -- >>> prettyShow $ shiftLeft 10 (OpenRange 15 25)--- "(5, 15)"+-- "(5,15)" shiftLeft   :: Num r => r -> Range r -> Range r shiftLeft x = shiftRight (-x)  -- | Shifts the range to the right -- -- >>> prettyShow $ shiftRight 10 (ClosedRange 10 20)--- "[20, 30]"+-- "[20,30]" -- >>> prettyShow $ shiftRight 10 (OpenRange 15 25)--- "(25, 35)"+-- "(25,35)" shiftRight   :: Num r => r -> Range r -> Range r shiftRight x = fmap (+x)
− src/Data/Seq.hs
@@ -1,236 +0,0 @@-{-# LANGUAGE ScopedTypeVariables #-}-module Data.Seq( LSeq-               , toSeq-               , empty-               , fromList-               , fromNonEmpty-               , fromSeq-               , toNonEmpty--               , (<|), (|>)-               , (><)-               , eval--               , index-               , adjust-               , partition-               , mapWithIndex-               , take-               , drop-               , unstableSortBy--               , ViewL(..)-               , viewl-               , pattern (:<|)--               , pattern (:<<)-               , pattern EmptyL--               , ViewR(..)-               , viewr-               , pattern (:|>)---               , promise-               ) where--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.Semigroup-import qualified Data.Sequence as S-import qualified Data.Traversable as Tr-import           GHC.TypeLits-import           Prelude hiding (drop,take)----- | LSeq n a certifies that the sequence has *at least* n items-newtype LSeq (n :: Nat) a = LSeq { toSeq :: S.Seq a}-                          deriving (Show,Read,Eq,Ord,Foldable,Functor,Traversable)--instance Semigroup (LSeq n a) where-  (LSeq s) <> (LSeq s') = LSeq (s <> s')--instance Monoid (LSeq 0 a) where-  mempty = empty-  mappend = (<>)--type instance Index   (LSeq n a) = Int-type instance IxValue (LSeq n a) = a-instance Ixed (LSeq n a) where-  ix i f s@(LSeq xs)-    | 0 <= i && i < S.length xs = f (S.index xs i) <&> \x -> LSeq $ S.update i x xs-    | otherwise                 = pure s--empty :: LSeq 0 a-empty = LSeq S.empty--(<|) :: a -> LSeq n a -> LSeq (1 + n) a-x <| xs = LSeq (x S.<| toSeq xs)--(|>)    :: LSeq n a -> a -> LSeq (1 + n) a-xs |> x = LSeq (toSeq xs S.|> x)--infixr 5 <|-infixl 5 |>--(><) :: LSeq n a -> LSeq m a -> LSeq (n + m) a-xs >< ys = LSeq (toSeq xs <> toSeq ys)--infix 5 ><---eval :: forall proxy n m a. KnownNat n => proxy n -> LSeq m a -> Maybe (LSeq n a)-eval n (LSeq xs)-  | toInteger (S.length xs) >= natVal n = Just $ LSeq xs-  | otherwise                           = Nothing-------- | Promises that the length of this LSeq is actually n. This is not--- checked.------ This function should be a noop-promise :: LSeq m a -> LSeq n a-promise = LSeq . toSeq--toNonEmpty :: LSeq (1 + n) a -> NonEmpty.NonEmpty a-toNonEmpty = NonEmpty.fromList . F.toList--------------------------------------------------------------------------------------- | get the element with index i, counting from the left and starting at 0.--- O(log(min(i,n-i)))-index     :: LSeq n a -> Int -> a-index s i = fromJust $ s^?ix i--adjust       :: (a -> a) -> Int -> LSeq n a -> LSeq n a-adjust f i s = s&ix i %~ f---partition   :: (a -> Bool) -> LSeq n a -> (LSeq 0 a, LSeq 0 a)-partition p = bimap LSeq LSeq . S.partition p . toSeq--mapWithIndex   :: (Int -> a -> b) -> LSeq n a -> LSeq n b-mapWithIndex f = wrapUnsafe (S.mapWithIndex f)--take   :: Int -> LSeq n a -> LSeq 0 a-take i = wrapUnsafe (S.take i)--drop   :: Int -> LSeq n a -> LSeq 0 a-drop i = wrapUnsafe (S.drop i)---unstableSortBy   :: (a -> a -> Ordering) -> LSeq n a -> LSeq n a-unstableSortBy f = wrapUnsafe (S.unstableSortBy f)---wrapUnsafe :: (S.Seq a -> S.Seq b) -> LSeq n a -> LSeq m b-wrapUnsafe f = LSeq . f . toSeq------------------------------------------------------------------------------------fromSeq :: S.Seq a -> LSeq 0 a-fromSeq = LSeq--fromList :: Foldable f => f a -> LSeq 0 a-fromList = LSeq . S.fromList . F.toList--fromNonEmpty :: NonEmpty.NonEmpty a -> LSeq 1 a-fromNonEmpty = LSeq . S.fromList . F.toList-------------------------------------------------------------------------------------data ViewL n a where-  (:<) :: a -> LSeq n a -> ViewL (1 + n) a--infixr 5 :<--instance Semigroup (ViewL n a) where-  (x :< xs) <> (y :< ys) = x :< LSeq (toSeq xs <> (y S.<| toSeq ys))--deriving instance Show a => Show (ViewL n a)-instance Functor (ViewL n) where-  fmap = Tr.fmapDefault-instance Foldable (ViewL n) where-  foldMap = Tr.foldMapDefault-instance Traversable (ViewL n) where-  traverse f (x :< xs) = (:<) <$> f x <*> traverse f xs-instance Eq a => Eq (ViewL n a) where-  s == s' = F.toList s == F.toList s'-instance Ord a => Ord (ViewL n a) where-  s `compare` s' = F.toList s `compare` F.toList s'---viewl :: LSeq (1 + n) a -> ViewL (1 + n) a-viewl xs = let ~(x S.:< ys) = S.viewl $ toSeq xs in x :< LSeq ys--infixr 5 :<|---- 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)-viewLSeq (LSeq s) = case S.viewl s of-                      S.EmptyL    -> Nothing-                      (x S.:< xs) -> Just (x,LSeq xs)-------------------------------------------------------------------------------------data ViewR n a where-  (:>) :: LSeq n a -> a -> ViewR (1 + n) a--infixl 5 :>--instance Semigroup (ViewR n a) where-  (xs :> x) <> (ys :> y) = LSeq ((toSeq xs S.|> x) <> toSeq ys) :> y--deriving instance Show a => Show (ViewR n a)-instance Functor (ViewR n) where-  fmap = Tr.fmapDefault-instance Foldable (ViewR n) where-  foldMap = Tr.foldMapDefault-instance Traversable (ViewR n) where-  traverse f (xs :> x) = (:>) <$> traverse f xs <*> f x-instance Eq a => Eq (ViewR n a) where-  s == s' = F.toList s == F.toList s'-instance Ord a => Ord (ViewR n a) where-  s `compare` s' = F.toList s `compare` F.toList s'--viewr :: LSeq (1 + n) a -> ViewR (1 + n) a-viewr xs = let ~(ys S.:> x) = S.viewr $ toSeq xs in LSeq ys :> x---infixl 5 :|>---- pattern (:|>) :: LSeq n a -> a -> LSeq (1 + n) a-pattern xs :|> x <- (viewr -> xs :> x)-  where-    xs :|> x = xs |> x-------------------------------------------------------------------------------------- testL = (eval (Proxy :: Proxy 2) $ fromList [1..5])---- testL' :: LSeq 2 Integer--- testL' = fromJust testL---- test            :: Show a => LSeq (1 + n) a -> String--- test (x :<| xs) = show x ++ show xs
− src/Data/Seq2.hs
@@ -1,221 +0,0 @@-module Data.Seq2 where--import           Control.Lens ((%~), (&), (<&>), (^?), Lens', lens)-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.Semigroup-import qualified Data.Sequence as S-import qualified Data.Traversable as T-import           Prelude hiding (foldr,foldl,head,tail,last,length)-------------------------------------------------------------------------------------- | Basically Data.Sequence but with the guarantee that the list contains at--- least two elements.-data Seq2 a = Seq2 a (S.Seq a) a-                deriving (Eq,Ord,Show)---instance T.Traversable Seq2 where-  -- Applicative f => (a -> f b) -> t a -> f (t b)-  traverse f ~(Seq2 l s r) = Seq2 <$> f l <*> T.traverse f s <*>  f r--instance Functor Seq2 where-  fmap = T.fmapDefault--instance F.Foldable Seq2 where-  foldMap = T.foldMapDefault-  length ~(Seq2 _ s _) = 2 + S.length s--instance Semigroup (Seq2 a) where-  l <> r = l >< r--type instance Index (Seq2 a)   = Int-type instance IxValue (Seq2 a) = a-instance Ixed (Seq2 a) where-  ix i f s@(Seq2 l m r)-    | i == 0      = f l                 <&> \a -> Seq2 a m r-    | i < 1 + mz  = f (S.index m (i-1)) <&> \a -> Seq2 l (S.update (i-1) a m) r-    | i == mz + 1 = f r                 <&> \a -> Seq2 l m a-    | otherwise   = pure s-      where-        mz = S.length m--duo     :: a -> a -> Seq2 a-duo a b = Seq2 a S.empty b---- | get the element with index i, counting from the left and starting at 0.--- O(log(min(i,n-i)))-index     :: Seq2 a -> Int -> a-index s i = fromJust $ s^?ix i--adjust       :: (a -> a) -> Int -> Seq2 a -> Seq2 a-adjust f i s = s&ix i %~ f--partition                :: (a -> Bool) -> Seq2 a -> (S.Seq a, S.Seq a)-partition p (Seq2 x s y) = let (l,r) = S.partition p s in case (p x, p y) of-    (False,False) -> ((x S.<| l) S.|> y, r)-    (False,_)     -> (x S.<| l,          r S.|> y)-    (True, False) -> (l S.|> y,          x S.<| r)-    _             -> (l,                 (x S.<| r) S.|> y)---(<|) :: a -> Seq2 a -> Seq2 a-x <| ~(Seq2 l s r) = Seq2 x (l S.<| s) r---(|>) :: Seq2 a -> a -> Seq2 a-~(Seq2 l s r) |> x = Seq2 l (s S.|> r) x----- | Concatenate two sequences. O(log(min(n1,n2)))-(><) :: Seq2 a -> Seq2 a -> Seq2 a-s >< l = fromSeqUnsafe $ toSeq s S.>< toSeq l----- | pre: the list contains at least two elements-fromList          :: [a] -> Seq2 a-fromList (a:b:xs) = F.foldl' (\s x -> s |> x) (duo a b) xs-fromList _        = error "Seq2.fromList: Not enough values"------ | fmap but with an index-mapWithIndex                  :: (Int -> a -> b) -> Seq2 a -> Seq2 b-mapWithIndex f s@(Seq2 a m b) = Seq2 (f 0 a) (S.mapWithIndex f' m) (f l b)-  where-    l    = F.length s - 1-    f' i = f (i+1)---take   :: Int -> Seq2 a -> S.Seq a-take i = S.take i . toSeq---drop   :: Int -> Seq2 a -> S.Seq a-drop i = S.drop i . toSeq---toSeq               :: Seq2 a -> S.Seq a-toSeq ~(Seq2 a m b) = ((a S.<| m) S.|> b)----- | Convert a Seq into a Seq2. It is not checked that the length is at least two-fromSeqUnsafe   :: S.Seq a -> Seq2 a-fromSeqUnsafe s = Seq2 a m b-  where-    ~(a S.:< s') = S.viewl s-    ~(m S.:> b)  = S.viewr s'-------------------------------------------------------------------------------------- | Left views--data ViewL2 a = a :<< ViewR1 a deriving (Show,Eq,Ord)---- | At least two elements-instance T.Traversable ViewL2 where-  traverse f ~(a :<< s) = (:<<) <$> f a <*> T.traverse f s--instance Functor ViewL2 where-  fmap = T.fmapDefault--instance F.Foldable ViewL2 where-  foldMap = T.foldMapDefault-  length ~(_ :<< s) = 1 + F.length s-------- | At least one element-data ViewL1 a = a :< S.Seq a deriving (Eq,Ord)--instance Show a => Show (ViewL1 a) where-  show (x :< xs) = concat [ show x, " :< ", show $ F.toList xs]--instance T.Traversable ViewL1 where-  traverse f ~(a :< s) = (:<) <$> f a <*> T.traverse f s--instance Functor ViewL1 where-  fmap = T.fmapDefault--instance F.Foldable ViewL1 where-  foldMap = T.foldMapDefault-  length ~(_ :< s) = 1 + S.length s---- | We throw away information here; namely that the combined list contains two elements.-instance Semigroup (ViewL1 a) where-  ~(a :< s) <> ~(b :< t) = a :< (s <> S.singleton b <> t)---headL1 :: Lens' (ViewL1 a) a-headL1 = lens (\(l :< _) -> l) (\(_ :< s) l -> l :< s)----toNonEmpty           :: ViewL1 a -> NonEmpty.NonEmpty a-toNonEmpty ~(a :< s) = (a NonEmpty.:| F.toList s)--viewL1FromNonEmpty                     :: NonEmpty.NonEmpty a -> ViewL1 a-viewL1FromNonEmpty ~(x NonEmpty.:| xs) = x :< S.fromList xs--viewL1FromSeq   :: S.Seq a -> ViewL1 a-viewL1FromSeq s = case S.viewl s of-  S.EmptyL    -> error "viewL1FromSeq: Empty seq"-  (x S.:< xs) -> x :< xs------ | O(1) get a left view-viewl                 :: Seq2 a -> ViewL2 a-viewl ~(Seq2 l s r) = l :<< (s :> r)---l1Singleton :: a -> ViewL1 a-l1Singleton = (:< S.empty)--viewL1toR1           :: ViewL1 a -> ViewR1 a-viewL1toR1 ~(l :< s) = let (s' S.:> r) = S.viewr (l S.<| s) in s' :> r-------------------------------------------------------------------------------------- | Right views---- | A view of the right end of the seq, with the guarantee that it--- has at least two elements-data ViewR2 a = ViewL1 a :>> a deriving (Show,Eq,Ord)--instance T.Traversable ViewR2 where-  traverse f ~(s :>> a) = (:>>) <$> T.traverse f s <*> f a--instance Functor ViewR2 where-  fmap = T.fmapDefault--instance F.Foldable ViewR2 where-  foldMap = T.foldMapDefault-  length (s :>> _) = 1 + F.length s---- | A view of the right end of the sequence, with the guarantee that it has at--- least one element.-data ViewR1 a = S.Seq a :> a deriving (Show,Read,Eq,Ord)--instance T.Traversable ViewR1 where-  traverse f ~(s :> a) = (:>) <$> T.traverse f s <*> f a--instance Functor ViewR1 where-  fmap = T.fmapDefault--instance F.Foldable ViewR1 where-  foldMap = T.foldMapDefault-  length (s :> _) = 1 + S.length s----- | O(1) get a right view-viewr                 :: Seq2 a -> ViewR2 a-viewr ~(Seq2 l s r) = (l :< s) :>> r--r1Singleton :: a -> ViewR1 a-r1Singleton = (S.empty :>)
src/Data/SlowSeq.hs view
@@ -7,7 +7,6 @@ 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 
+ src/Data/Tree/Util.hs view
@@ -0,0 +1,154 @@+module Data.Tree.Util where++import Data.Maybe(listToMaybe,maybeToList)+import Control.Lens+import Control.Monad((>=>))+import Data.Tree+import qualified Data.List as List++--------------------------------------------------------------------------------++-- $setup+-- >>> :{+-- let myTree = Node 0 [ Node 1 []+--                     , Node 2 []+--                     , Node 3 [ Node 4 [] ]+--                     ]+-- :}++--------------------------------------------------------------------------------+-- * Zipper on rose trees++-- | Zipper for rose trees+data Zipper a = Zipper { focus      :: Tree a+                       , ancestors  :: [([Tree a], a, [Tree a])] -- left siblings in reverse order+                       }+              deriving (Show,Eq)++-- | Create a new zipper focussiong on the root.+root :: Tree a -> Zipper a+root = flip Zipper []++-- | Move the focus to the parent of this node.+up               :: Zipper a -> Maybe (Zipper a)+up (Zipper t as) = case as of+                     []              -> Nothing+                     ((ls,p,rs):as') -> Just $ Zipper (Node p (reverse ls <> [t] <> rs)) as'++-- | Move the focus to the first child of this node.+--+-- >>> firstChild $ root myTree+-- Just (Zipper {focus = Node {rootLabel = 1, subForest = []}, ancestors = [([],0,[Node {rootLabel = 2, subForest = []},Node {rootLabel = 3, subForest = [Node {rootLabel = 4, subForest = []}]}])]})+firstChild                          :: Zipper a -> Maybe (Zipper a)+firstChild (Zipper (Node x chs) as) = case chs of+                                        []       -> Nothing+                                        (c:chs') -> Just $ Zipper c (([],x,chs'):as)++-- | Move the focus to the next sibling of this node+--+-- >>> (firstChild $ root myTree) >>= nextSibling+-- Just (Zipper {focus = Node {rootLabel = 2, subForest = []}, ancestors = [([Node {rootLabel = 1, subForest = []}],0,[Node {rootLabel = 3, subForest = [Node {rootLabel = 4, subForest = []}]}])]})+nextSibling               :: Zipper a -> Maybe (Zipper a)+nextSibling (Zipper t as) = case as of+                              []                  -> Nothing -- no parent+                              ((_,_,[]):_)        -> Nothing -- no next sibling+                              ((ls,p,(r:rs)):as') -> Just $ Zipper r ((t:ls,p,rs):as')++-- | Move the focus to the next sibling of this node+prevSibling               :: Zipper a -> Maybe (Zipper a)+prevSibling (Zipper t as) = case as of+                              []                  -> Nothing -- no parent+                              (([],_,_):_)        -> Nothing -- no prev sibling+                              (((l:ls),p,rs):as') -> Just $ Zipper l ((ls,p,t:rs):as')++-- | Given a zipper that focussses on some subtree t, construct a list with+-- zippers that focus on each child.+allChildren :: Zipper a -> [Zipper a]+allChildren = List.unfoldr ((\ch -> (ch, nextSibling ch)) <$>) . firstChild++-- | Given a zipper that focussses on some subtree t, construct a list with+-- zippers that focus on each of the nodes in the subtree of t.+allTrees   :: Zipper a -> [Zipper a]+allTrees r = r : concatMap allTrees (allChildren r)++-- | Creates a new tree from the zipper that thas the current node as root. The+-- ancestorTree (if there is any) forms the first child in this new root.+unZipperLocal                          :: Zipper a -> Tree a+unZipperLocal (Zipper (Node x chs) as) = Node x (maybeToList (constructTree as) <> chs)++-- | Constructs a tree from the list of ancestors (if there are any)+constructTree :: [([Tree a],a,[Tree a])] -> Maybe (Tree a)+constructTree = listToMaybe+              . foldr (\(ls,p,rs) tas -> [Node p (tas <> reverse ls <> rs)]) []+++--------------------------------------------------------------------------------++-- | Given a predicate on an element, find a node that matches the predicate, and turn that+-- node into the root of the tree.+--+-- running time: \(O(nT)\) where \(n\) is the size of the tree, and \(T\) is+-- the time to evaluate a predicate.+--+-- >>> findEvert (== 4) myTree+-- Just (Node {rootLabel = 4, subForest = [Node {rootLabel = 3, subForest = [Node {rootLabel = 0, subForest = [Node {rootLabel = 1, subForest = []},Node {rootLabel = 2, subForest = []}]}]}]})+-- >>> findEvert (== 5) myTree+-- Nothing+findEvert   :: (a -> Bool) -> Tree a -> Maybe (Tree a)+findEvert p = findEvert' (p . rootLabel)++-- | Given a predicate matching on a subtree, find a node that matches the predicate, and turn that+-- node into the root of the tree.+--+-- running time: \(O(nT(n))\) where \(n\) is the size of the tree, and \(T(m)\) is+-- the time to evaluate a predicate on a subtree of size \(m\).+findEvert'   :: (Tree a -> Bool) -> Tree a -> Maybe (Tree a)+findEvert' p = fmap unZipperLocal . listToMaybe . filter (p . focus) . allTrees . root++-- | Function to extract a path between a start node and an end node (if such a+--path exists). If there are multiple paths, no guarantees are given about+--which one is returned.+--+-- running time: \(O(n(T_p+T_s)\), where \(n\) is the size of the tree, and+-- \(T_p\) and \(T_s\) are the times it takes to evaluate the 'isStartingNode'+-- and 'isEndingNode' predicates.+--+--+-- >>> findPath (== 1) (==4) myTree+-- Just [1,0,3,4]+-- >>>  findPath (== 1) (==2) myTree+-- Just [1,0,2]+-- >>>  findPath (== 1) (==1) myTree+-- Just [1]+-- >>>  findPath (== 1) (==2) myTree+-- Just [1,0,2]+-- >>>  findPath (== 4) (==2) myTree+-- Just [4,3,0,2]+findPath               :: (a -> Bool) -- ^ is this node a starting node+                          -> (a -> Bool) -- ^ is this node an ending node+                          -> Tree a -> Maybe [a]+findPath isStart isEnd = findEvert isStart >=> findNode isEnd++-- | Given a predicate on a, find (the path to) a node that satisfies the predicate.+--+-- >>> findNode (== 4) myTree+-- Just [0,3,4]+findNode   :: (a -> Bool) -> Tree a -> Maybe [a]+findNode p = listToMaybe . findNodes (p . rootLabel)++-- | Find all paths to nodes that satisfy the predicate+--+-- running time: \(O(nT(n))\) where \(n\) is the size of the tree, and \(T(m)\) is+-- the time to evaluate a predicate on a subtree of size \(m\).+--+-- >>> findNodes ((< 4) . rootLabel) myTree+-- [[0],[0,1],[0,2],[0,3]]+-- >>> findNodes (even . rootLabel) myTree+-- [[0],[0,2],[0,3,4]]+-- >>> let size = length in findNodes ((> 1) . size) myTree+-- [[0],[0,3]]+findNodes   :: (Tree a -> Bool) -> Tree a -> [[a]]+findNodes p = go+  where+    go t = let mh = if p t then [[]] else []+           in map (rootLabel t:) $ mh <> concatMap go (children t)
src/Data/UnBounded.hs view
@@ -13,7 +13,7 @@ import           Control.Lens import qualified Data.Foldable as F import qualified Data.Traversable as T-+import           Data.Functor.Classes  -------------------------------------------------------------------------------- -- * Top and Bottom@@ -23,7 +23,7 @@ -- -- >>> data Top a = ValT a | Top newtype Top a = GTop { topToMaybe :: Maybe a }-                deriving (Eq,Functor,F.Foldable,T.Traversable,Applicative,Monad)+                deriving (Eq,Functor,F.Foldable,T.Traversable,Applicative,Monad,Eq1)  pattern ValT  :: a -> Top a pattern ValT x = GTop (Just x)@@ -31,11 +31,17 @@ pattern Top    :: Top a pattern Top    = GTop Nothing +{-# COMPLETE ValT, Top #-}+++instance Ord1 Top where+  liftCompare _   Top       Top       = EQ+  liftCompare _   _         Top       = LT+  liftCompare _   Top       _         = GT+  liftCompare cmp ~(ValT x) ~(ValT y) = x `cmp` y+ instance Ord a => Ord (Top a) where-  Top       `compare` Top      = EQ-  _         `compare` Top      = LT-  Top       `compare` _        = GT-  ~(ValT x) `compare` ~(ValT y) = x `compare` y+  compare = compare1  instance Show a => Show (Top a) where   show Top       = "Top"@@ -49,13 +55,15 @@ -- -- >>> data Bottom a = Bottom | ValB a newtype Bottom a = GBottom { bottomToMaybe :: Maybe a }-                 deriving (Eq,Ord,Functor,F.Foldable,T.Traversable,Applicative,Monad)+                 deriving (Eq,Ord,Functor,F.Foldable,T.Traversable,Applicative,Monad,Eq1,Ord1)  pattern Bottom :: Bottom a pattern Bottom = GBottom Nothing  pattern ValB   :: a -> Bottom a pattern ValB x = GBottom (Just x)++{-# COMPLETE Bottom, ValB #-}  instance Show a => Show (Bottom a) where   show Bottom    = "Bottom"
src/Data/Util.hs view
@@ -1,13 +1,37 @@+--------------------------------------------------------------------------------+-- |+-- Module      :  Data.Util+-- Copyright   :  (C) Frank Staals+-- License     :  see the LICENSE file+-- Maintainer  :  Frank Staals+--+-- Some basic types, mostly strict triples and pairs.+--+-------------------------------------------------------------------------------- module Data.Util where +import Control.DeepSeq import Control.Lens-import Data.Semigroup+import GHC.Generics (Generic)+import qualified Data.List as List +--------------------------------------------------------------------------------+-- * Strict Triples+ -- |  strict triple data STR a b c = STR { fst' :: !a, snd' :: !b , trd' :: !c}-               deriving (Show,Eq,Ord,Functor)+               deriving (Show,Eq,Ord,Functor,Generic) +instance (Semigroup a, Semigroup b, Semigroup c) => Semigroup (STR a b c) where+  (STR a b c) <> (STR d e f) = STR (a <> d) (b <> e) (c <> f) +instance (Semigroup a, Semigroup b, Semigroup c+         , Monoid a, Monoid b, Monoid c) => Monoid (STR a b c) where+  mempty = STR mempty mempty mempty+  mappend = (<>)++instance (NFData a, NFData b, NFData c) => NFData (STR a b c)+ instance Field1 (STR a b c) (STR d b c) a d where   _1 = lens fst' (\(STR _ b c) d -> STR d b c) @@ -17,16 +41,29 @@ instance Field3 (STR a b c) (STR a b d) c d where   _3 = lens trd' (\(STR a b _) d -> STR a b d) +-- | Generate All unique unordered triplets.+--+uniqueTriplets    :: [a] -> [STR a a a]+uniqueTriplets xs = [ STR x y z | (x:ys) <- nonEmptyTails xs, SP y z <- uniquePairs ys]  +--------------------------------------------------------------------------------+-- * Strict Pairs   -- | Strict pair-data SP a b = SP !a !b deriving (Show,Eq,Ord,Functor)+data SP a b = SP !a !b deriving (Show,Eq,Ord,Functor,Generic)  instance (Semigroup a, Semigroup b) => Semigroup (SP a b) where   (SP a b) <> (SP c d) = SP (a <> c) (b <> d) +instance (Semigroup a, Semigroup b, Monoid a, Monoid b) => Monoid (SP a b) where+  mempty = SP mempty mempty+  mappend = (<>)++instance (NFData a, NFData b) => NFData (SP a b)++ instance Field1 (SP a b) (SP c b) a c where   _1 = lens (\(SP a _) -> a) (\(SP _ b) c -> SP c b) @@ -36,5 +73,24 @@ instance Bifunctor SP where   bimap f g (SP a b) = SP (f a) (g b) +--------------------------------------------------------------------------------+-- | * Strict pair whose elements are of the same type.+ -- | Strict pair with both items the same type Two a = SP a a++pattern Two :: a -> a -> Two a+pattern Two a b = SP a b+{-# COMPLETE Two #-}++-- | Given a list xs, generate all unique (unordered) pairs.+--+--+uniquePairs    :: [a] -> [Two a]+uniquePairs xs = [ Two x y | (x:ys) <- nonEmptyTails xs, y <- ys ]++--------------------------------------------------------------------------------++-- | A version of List.tails in which we remove the emptylist+nonEmptyTails :: [a] -> [[a]]+nonEmptyTails = List.init . List.tails
src/Data/Yaml/Util.hs view
@@ -1,10 +1,34 @@-module Data.Yaml.Util where+{-# LANGUAGE OverloadedStrings #-}+--------------------------------------------------------------------------------+-- |+-- Module      :  Data.Yaml.Util+-- Copyright   :  (C) Frank Staals+-- License     :  see the LICENSE file+-- Maintainer  :  Frank Staals+-- Description :  Helper functions for working with yaml+--+--------------------------------------------------------------------------------+module Data.Yaml.Util( encodeYaml, encodeYamlFile+                     , decodeYaml, decodeYamlFile+                     , printYaml+                     , parseVersioned+                     , Versioned(Versioned), unversioned+                     ) where -import qualified Data.Yaml.Pretty as YamlP-import           Data.Yaml+import           Control.Applicative+import           Data.Aeson+import           Data.Aeson.Types (typeMismatch) import           Data.ByteString (ByteString)-import           Data.ByteString.Char8 as B+import qualified Data.ByteString.Char8 as B+import qualified Data.Text as T+import           Data.Version+import           Data.Yaml+import qualified Data.Yaml.Pretty as YamlP+import           GHC.Generics (Generic)+import           Text.ParserCombinators.ReadP (readP_to_S) +--------------------------------------------------------------------------------+ -- | Write the output to yaml encodeYaml :: ToJSON a => a -> ByteString encodeYaml = YamlP.encodePretty YamlP.defConfig@@ -20,3 +44,46 @@ -- | alias for reading a yaml file decodeYamlFile :: FromJSON a => FilePath -> IO (Either ParseException a) decodeYamlFile = decodeFileEither++-- | Encode a yaml file+encodeYamlFile    :: ToJSON a => FilePath -> a -> IO ()+encodeYamlFile fp = B.writeFile fp . encodeYaml+++-- | Data type for things that have a version+data Versioned a = Versioned { version :: Version+                             , content :: a+                             } deriving (Show,Read,Generic,Eq,Functor,Foldable,Traversable)++unversioned :: Versioned a -> a+unversioned = content++instance ToJSON a => ToJSON (Versioned a) where+  toJSON     (Versioned v x) = object [ "version" .= showVersion v, "content" .= x]+  toEncoding (Versioned v x) = pairs ("version" .= showVersion v <> "content" .= x)+++-- | Given a list of candidate parsers, select the right one+parseVersioned               :: [(Version -> Bool,Value -> Parser a)]+                             -> Value -> Parser (Versioned a)+parseVersioned ps (Object o) = do V v <- o .: "version"+                                  co  <- o .: "content"+                                  let ps' = map (\(_,p) -> Versioned v <$> p co)+                                          . filter (($ v) . fst) $ ps+                                      err = fail $ "no matching version found for version "+                                                   <> showVersion v+                                  foldr (<|>) err ps'+parseVersioned _ invalid     = typeMismatch "Versioned" invalid++-- instance (FromJSON a) => FromJSON (Versioned a) where+--   parseJSON (Object v) = Versioned <$> (unV <$> v .: "version")+--                                    <*> v .: "content"+--   parseJSON invalid    = typeMismatch "Versioned" invalid++newtype V = V Version++instance FromJSON V where+  parseJSON (String t) = case filter (null . snd) (readP_to_S parseVersion $ T.unpack t) of+     ((v,""):_) -> pure $ V v+     _          -> fail $ "parsing " <> show t <> " into a version failed"+  parseJSON invalid    = typeMismatch "Version" invalid
+ src/Graphics/Camera.hs view
@@ -0,0 +1,165 @@+{-# LANGUAGE TemplateHaskell  #-}+--------------------------------------------------------------------------------+-- |+-- Module      :  Graphics.Camera+-- Copyright   :  (C) Frank Staals+-- License     :  see the LICENSE file+-- Maintainer  :  Frank Staals+-- Description :  Data type to represent a camera and some functions for working with it.+--+--------------------------------------------------------------------------------+module Graphics.Camera( Camera(Camera)+                      , cameraPosition, rawCameraNormal, rawViewUp+                      , viewPlaneDepth, nearDist, farDist, screenDimensions++                      , cameraNormal, viewUp++                      , cameraTransform, worldToView++                      , toViewPort, perspectiveProjection, rotateCoordSystem+                      , flipAxes+                      ) where++import Data.Ext+import Control.Lens+import Data.Geometry.Point+import Data.Geometry.Vector+import Data.Geometry.Transformation+import Data.Geometry.Triangle++--------------------------------------------------------------------------------++-- | defines a basic camera+data Camera r = Camera { _cameraPosition   :: !(Point 3 r)+                       , _rawCameraNormal  :: !(Vector 3 r)+                         -- ^ unit vector from camera into center of the screen+                       , _rawViewUp        :: !(Vector 3 r)+                       -- ^ viewUp; assumed to be unit vector+                       , _viewPlaneDepth   :: !r+                       , _nearDist         :: !r+                       , _farDist          :: !r+                       , _screenDimensions :: !(Vector 2 r)+                       } deriving (Show,Eq,Ord)+makeLenses ''Camera++-- | Lens to get and set the Camera normal, makes sure that the vector remains+-- normalized.+cameraNormal :: Floating r => Lens' (Camera r) (Vector 3 r)+cameraNormal = lens _rawCameraNormal (\c n -> c { _rawCameraNormal = signorm n} )+++-- | Lens to get and set the viewUp vector. Makes sure the vector remains+-- normalized.+viewUp :: Floating r => Lens' (Camera r) (Vector 3 r)+viewUp = lens _rawViewUp (\c n -> c { _rawViewUp = signorm n})+++-- | Full transformation that renders the figure+cameraTransform   :: Fractional r => Camera r -> Transformation 3 r+cameraTransform c =  toViewPort c+                 |.| perspectiveProjection c+                 |.| worldToView c++-- | Translates world coordinates into view coordinates+worldToView   :: Fractional r => Camera r -> Transformation 3 r+worldToView c =  rotateCoordSystem c+             |.| (translation $ (-1) *^ c^.cameraPosition.vector)++-- | Transformation into viewport coordinates+toViewPort   :: Fractional r => Camera r -> Transformation 3 r+toViewPort c = Transformation . Matrix+             $ Vector4 (Vector4 (w/2) 0     0     0)+                       (Vector4 0     (h/2) 0     0)+                       (Vector4 0     0     (1/2) (1/2))+                       (Vector4 0     0     0     1)+  where+    Vector2 w h = c^.screenDimensions+++-- | constructs a perspective projection+perspectiveProjection   :: Fractional r => Camera r -> Transformation 3 r+perspectiveProjection c = Transformation . Matrix $+    Vector4 (Vector4 (-n/rx) 0       0              0)+            (Vector4 0       (-n/ry) 0              0)+            (Vector4 0       0       (-(n+f)/(n-f)) (-2*n*f/(n-f)))+            (Vector4 0       0       1              0)+  where+    n = c^.nearDist+    f = c^.farDist+    Vector2 rx ry = (/2) <$> c^.screenDimensions++-- | Rotates coordinate system around the camera, such that we look in the negative z+-- direction+rotateCoordSystem   :: Num r => Camera r -> Transformation 3 r+rotateCoordSystem c = rotateTo $ Vector3 u v n+  where+    u = (c^.rawViewUp) `cross` n+    v = n `cross` u+    n = (-1) *^ c^.rawCameraNormal -- we need the normal from the scene *into* the camera+++++-- transformBy' (Transformation m) (Vector3 x y z) = m `mult` (Vector4 x y z (-z))++-- | Flips the y and z axis.+flipAxes :: Num r => Transformation 3 r+flipAxes = Transformation . Matrix+             $ Vector4 (Vector4 1 0 0 0)+                       (Vector4 0 0 1 0)+                       (Vector4 0 1 0 0)+                       (Vector4 0 0 0 1)++--------------------------------------------------------------------------------++myCamera :: Camera Rational+myCamera = Camera (Point3 50 0 50)+                  (Vector3 0 0 (-1))+                  (Vector3 0 1 0)+                  10+                  15+                  55+                  (Vector2 800 600)+++myCamera1 :: Camera Double+myCamera1 = Camera origin+                  (Vector3 0 0 (-1))+                  (Vector3 0 1 0)+                  10+                  10+                  50 -- we can see up to the origin+                  (Vector2 60 40)++testProjection   :: Camera Double -> [Vector 3 Double]+testProjection c = map (transformBy t) [Vector3 30 30 (-10), Vector3 (30*50/10) 30 (-50)]+  where+    u = (c^.rawViewUp) `cross` n+    v = n `cross` u+    n = (-1) *^ c^.rawCameraNormal -- we need the normal from the scene *into* the camera+    t = perspectiveProjection c+++myT :: Triangle 3 () Rational+myT = Triangle (ext $ Point3 1  1  10)+               (ext $ Point3 20 1  10)+               (ext $ Point3 20 30 10)++++testToWorld   :: Camera Double -> [Vector 3 Double]+testToWorld c = map (transformBy t) [u, v, n, Vector3 80 20 40]+  where+    u = (c^.rawViewUp) `cross` n+    v = n `cross` u+    n = (-1) *^ c^.rawCameraNormal -- we need the normal from the scene *into* the camera+    t = worldToView c+++testRotate   :: Camera Double -> [Vector 3 Double]+testRotate c = map (transformBy t) [u, v, n]+  where+    u = (c^.rawViewUp) `cross` n+    v = n `cross` u+    n = (-1) *^ c^.rawCameraNormal -- we need the normal from the scene *into* the camera+    t = rotateCoordSystem c
src/Test/QuickCheck/HGeometryInstances.hs view
@@ -1,6 +1,16 @@ {-# LANGUAGE UndecidableInstances  #-} {-# LANGUAGE ScopedTypeVariables #-} {-# OPTIONS_GHC -fno-warn-orphans #-}+--------------------------------------------------------------------------------+-- |+-- Module      :  Test.QuickCheck.HGeometryInstances+-- Copyright   :  (C) Frank Staals+-- License     :  see the LICENSE file+-- Maintainer  :  Frank Staals+--+-- Arbitrary instances for most geometry types in HGeometry+--+-------------------------------------------------------------------------------- module Test.QuickCheck.HGeometryInstances where  import           Control.Lens@@ -8,12 +18,12 @@ import           Data.Ext import           Data.Geometry hiding (vector) import           Data.Geometry.Box+import           Data.PlanarGraph+import qualified Data.PlanarGraph as PlanarGraph 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 qualified Data.LSeq as LSeq import           GHC.TypeLits import           Test.QuickCheck @@ -25,9 +35,6 @@ 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@@ -43,8 +50,8 @@                               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')+instance (KnownNat n, Arbitrary a) => Arbitrary (LSeq.LSeq n a) where+  arbitrary = (\s s' -> LSeq.promise . LSeq.fromList $ s <> s')             <$> vector (fromInteger . natVal $ (Proxy :: Proxy n))             <*> arbitrary @@ -85,10 +92,21 @@   arbitrary = GInterval <$> arbitrary  -instance (Arbitrary r, Arbitrary p, Arity d, Ord r, Ord p, Num r)-         => Arbitrary (SubLine d p r) where+instance (Arbitrary r, Arbitrary p, Arbitrary s, Arity d, Ord r, Ord s, Ord p, Num r)+         => Arbitrary (SubLine d p s r) where   arbitrary = SubLine <$> arbitrary <*> arbitrary   instance (Arbitrary r, Arbitrary p, Arity d) => Arbitrary (LineSegment d p r) where   arbitrary = LineSegment <$> arbitrary <*> arbitrary++++instance Arbitrary (Arc s) where+  arbitrary = Arc <$> (arbitrary `suchThat` (>= 0))++instance Arbitrary Direction where+  arbitrary = (\b -> if b then PlanarGraph.Positive else Negative) <$> arbitrary++instance Arbitrary (Dart s) where+  arbitrary = Dart <$> arbitrary <*> arbitrary
+ test/Algorithms/Geometry/ClosestPair/ClosestPairSpec.hs view
@@ -0,0 +1,45 @@+module Algorithms.Geometry.ClosestPair.ClosestPairSpec where++import qualified Algorithms.Geometry.ClosestPair.DivideAndConquer as DivideAndConquer+import qualified Algorithms.Geometry.ClosestPair.Naive as Naive+import           Control.Lens+import           Data.Ext+import           Data.Geometry.Point+import           Data.LSeq (LSeq)+import qualified Data.LSeq as LSeq+import           Data.Util+import           Test.Hspec+import           Test.Hspec.QuickCheck+import           Test.QuickCheck+import           Test.QuickCheck.HGeometryInstances ()+import           Test.QuickCheck.Instances ()+++spec :: Spec+spec = do+    describe "ClosestPairSpec Algorithms" $ do+      modifyMaxSuccess (const 1000) $+        it "Naive and DivideAnd Conquer report same closest pair distance (quickcheck)" $+          property $ \pts ->+            (squaredEuclideanDist' $ Naive.closestPair pts)+            ==+            (squaredEuclideanDist' $ DivideAndConquer.closestPair pts)+      it "Naive and DivideAnd Conquer report same closest pair distance (manual)" $ do+        let myPts = toLSeq myTest in+          (squaredEuclideanDist' $ Naive.closestPair myPts)+          `shouldBe`+          (squaredEuclideanDist' $ DivideAndConquer.closestPair myPts)+++squaredEuclideanDist'                         :: Two (Point 2 Rational :+ ()) -> Rational+squaredEuclideanDist' (Two (p :+ _) (q :+ _)) = squaredEuclideanDist p q+++-- LSeq {toSeq = fromList [Point2 [(-33759522867779) % 7496802324005,10839434579010 % 8710408063243] :+ (),Point2 [27010230067287 % 7207136323822,(-3164483769031) % 742671498890] :+ (),Point2 [16411948329569 % 7616584565141,12511394381428 % 2834373835667] :+ (),Point2 [(-327606334581) % 728344280722,(-33692910597997) % 8003329261050] :+ (),Point2 [(-15920889254819) % 4416206444274,31639684978225 % 4753346825613] :+ ()]}+++toLSeq :: [a] -> LSeq 2 a+toLSeq = LSeq.promise . LSeq.fromList++myTest :: [Point 2 Rational :+ ()]+myTest = read "[Point2 [146640303144371 % 4224053853937,101854287495663 % 611897639578] :+ (),Point2 [40638737917185 % 6880564569878,266207821342347 % 5620065708622] :+ (),Point2 [(-22768678067038) % 4099605651011,63425313194697 % 3004649322800] :+ (),Point2 [(-79043128684637) % 1637661769455,(-295977300701107) % 9093457570027] :+ (),Point2 [(-73583019410059) % 7397585905521,(-132085857579544) % 3023721689783] :+ (),Point2 [110730624564935 % 3206669900528,(-134126355694632) % 1030756818019] :+ (),Point2 [375473877556369 % 5688548958491,(-61990694642620) % 8334329062977] :+ (),Point2 [113637651255443 % 7393857491411,60345369766453 % 1970866530039] :+ (),Point2 [18099493254552 % 6747283329067,(-104898261130768) % 6685232742229] :+ (),Point2 [(-99452695817779) % 9671436420976,(-15569270478765) % 353842993324] :+ (),Point2 [(-307985949779841) % 8267832155219,(-104994723690859) % 937448083071] :+ (),Point2 [5298565527551 % 9166217911857,361269627209233 % 6403545389662] :+ (),Point2 [(-53286482779806) % 163082999159,32112688900059 % 718598733692] :+ (),Point2 [(-107690491383153) % 5350356516874,(-335465470420443) % 9259993302154] :+ (),Point2 [(-1431112842609) % 2908633300498,(-6394060822783) % 6674992423] :+ (),Point2 [(-297096490651238) % 8936478049895,88152403947309 % 6679373739130] :+ (),Point2 [(-69377170752544) % 423340544261,85249651585993 % 1566182413847] :+ (),Point2 [(-76831240905987) % 7713729889276,(-161201413608815) % 3632380150759] :+ (),Point2 [120510849091594 % 469904179619,(-172736649495640) % 5333925170989] :+ (),Point2 [(-188872871543069) % 1898068101049,355493261879401 % 7036186201752] :+ (),Point2 [(-255393995322931) % 1103177446757,265927198927640 % 3105872402029] :+ (),Point2 [(-69257424852911) % 283924670424,157163114450212 % 6947926872911] :+ (),Point2 [160793284019169 % 4243291855883,136543247038343 % 663996934927] :+ (),Point2 [349183720690751 % 69082861367,27899563589967 % 984451034746] :+ (),Point2 [(-6729975907016) % 287613226363,(-132751704193606) % 884101426259] :+ (),Point2 [158419738815649 % 1684813345364,(-232301201438133) % 2251322747338] :+ (),Point2 [53058623626229 % 834280423049,11416530634139 % 5498459429949] :+ (),Point2 [153130827172836 % 3179759716621,(-247386168772091) % 6720178879120] :+ (),Point2 [(-255140791023605) % 6181407399187,(-58852369239783) % 1447725941071] :+ (),Point2 [(-35688634701875) % 8985183678917,162916031022373 % 4757510120717] :+ ()]"
test/Algorithms/Geometry/ConvexHull/ConvexHullSpec.hs view
@@ -1,6 +1,6 @@ module Algorithms.Geometry.ConvexHull.ConvexHullSpec where -import qualified Algorithms.Geometry.ConvexHull.DivideAndConqueror as DivideAndConqueror+import qualified Algorithms.Geometry.ConvexHull.DivideAndConquer as DivideAndConquer import qualified Algorithms.Geometry.ConvexHull.GrahamScan as GrahamScan import           Control.Lens import           Data.CircularSeq (isShiftOf)@@ -12,7 +12,6 @@ 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@@ -27,11 +26,11 @@ spec = do     describe "ConvexHull Algorithms" $ do       modifyMaxSize (const 1000) . modifyMaxSuccess (const 1000) $-        it "GrahamScan and DivideAnd Conqueror are the same" $+        it "GrahamScan and DivideAnd Conquer are the same" $           property $ \pts ->             (PG $ GrahamScan.convexHull pts)             ==-            (PG $ DivideAndConqueror.convexHull pts)+            (PG $ DivideAndConquer.convexHull pts)  newtype PG = PG (ConvexPolygon () Rational) deriving (Show) 
test/Algorithms/Geometry/DelaunayTriangulation/DTSpec.hs view
@@ -1,7 +1,7 @@ {-# LANGUAGE LambdaCase #-} module Algorithms.Geometry.DelaunayTriangulation.DTSpec where -import qualified Algorithms.Geometry.DelaunayTriangulation.DivideAndConqueror as DC+import qualified Algorithms.Geometry.DelaunayTriangulation.DivideAndConquer as DC import qualified Algorithms.Geometry.DelaunayTriangulation.Naive as Naive import           Algorithms.Geometry.DelaunayTriangulation.Types import           Control.Lens@@ -28,7 +28,7 @@  spec :: Spec spec = do-  describe "Testing Divide and Conqueror Algorithm for Delaunay Triangulation" $ do+  describe "Testing Divide and Conquer Algorithm for Delaunay Triangulation" $ do     it "singleton " $ do       dtEdges (take' 1 myPoints) `shouldBe` []     toSpec (TestCase "myPoints" myPoints)@@ -69,7 +69,7 @@  sameAsNaive       :: (Fractional r, Ord r, Show p, Show r)                   => String -> NonEmpty.NonEmpty (Point 2 r :+ p) -> Spec-sameAsNaive s pts = it ("Divide And Conqueror same answer as Naive on " ++ s) $+sameAsNaive s pts = it ("Divide And Conquer same answer as Naive on " ++ s) $                       (Naive.delaunayTriangulation pts                        `sameEdges`                        DC.delaunayTriangulation pts) `shouldBe` True
test/Algorithms/Geometry/WellSeparatedPairDecomposition/WSPDSpec.hs view
@@ -8,7 +8,7 @@ import qualified Data.Foldable as F import           Data.Geometry import qualified Data.List.NonEmpty as NonEmpty-import qualified Data.Seq2 as S2+import qualified Data.LSeq as LSeq import qualified Data.Set as Set import qualified Data.Vector as V import           Test.Hspec@@ -58,9 +58,9 @@ --     output = v2 (f [ origin :+ 0, point2 1 1 :+ 1, point2 5 5 :+ 2 ]) --                 (f [ point2 1 1 :+ 1, point2 5 5 :+ 2, origin :+ 0 ]) ---     f = S2.viewL1FromNonEmpty . NonEmpty.fromList . map (&extra %~ ext)+--     f =  LSeq.fromNonEmpty . NonEmpty.fromList . map (&extra %~ ext) -ptSeq = S2.viewL1FromNonEmpty . NonEmpty.fromList . map (&extra %~ ext)+ptSeq = LSeq.fromNonEmpty . NonEmpty.fromList . map (&extra %~ ext)  -- coversAll 
+ test/Data/Geometry/ArrangementSpec.hs view
@@ -0,0 +1,102 @@+{-# LANGUAGE OverloadedStrings #-}+module Data.Geometry.ArrangementSpec where++import           Control.Lens+import qualified Data.ByteString as B+import           Data.Ext+import           Data.Geometry+import           Data.Geometry.Arrangement+import           Data.Geometry.Arrangement.Draw+import           Data.Geometry.Ipe+import           Test.Hspec+import           Util(runOnFile)++spec :: Spec+spec = testCases "test/Data/Geometry/arrangement.ipe"+++testCases    :: FilePath -> Spec+testCases fp = runIO (readInputFromFile fp) >>= \case+    Left e    -> it "reading arrangement file" $+                   expectationFailure $ "Failed to read ipe file " ++ show e+    Right tcs -> mapM_ toSpec tcs+++--   ipeF <- beforeAll $ readInputFromFile "tests/Data/Geometry/pointInPolygon.ipe"+--   describe "Point in Polygon tests" $ do+--     it "returns the first element of a list" $ do+--       head [23 ..] `shouldBe` (23 :: Int)+++data TestCase r = TestCase { _lines      :: [Line 2 r :+ ()]+                           , _outFile    :: FilePath -- ^ filename of the output arrangement,+                                                     -- as an ipe file+                           }+                  deriving (Show)++data Test = Test++drawArr    :: [Line 2 Rational :+ a] -> B.ByteString+drawArr ls = let arr = constructArrangement (Identity Test) ls+                 out = [ iO $ drawArrangement arr ]+                 Just bs = toIpeXML . singlePageFromContent $ out+             in bs+++toSpec                       :: TestCase Rational -> Spec+toSpec (TestCase ls outFile) = do+    runOnFile "test drawing arrangement"  outFile (pure $ drawArr ls)++-- toSingleSpec poly r q = it msg $ (q `inPolygon` poly) `shouldBe` r+--   where+--     msg = "Point in polygon test with " ++ show q++++-- toSpec (TestCase poly is bs os) = do+--                                     describe "inside tests" $+--                                       mapM_ (toSingleSpec poly Inside) is+--                                     describe "on boundary tests" $+--                                       mapM_ (toSingleSpec poly OnBoundary) bs+--                                     describe "outside tests" $+--                                       mapM_ (toSingleSpec poly Outside) os++readInputFromFile    :: FilePath -> IO (Either ConversionError [TestCase Rational])+readInputFromFile fp = fmap f <$> readSinglePageFile fp+  where+    f      :: IpePage Rational -> [TestCase Rational]+    f page = [ TestCase [ ext $ supportingLine s+                        | (s :+ _ats) <- segs+                        ]+                        (fp <> ".out.ipe")+             ]+      where+        segs = page^..content.traverse._withAttrs _IpePath _asLineSegment+    -- f page = [ TestCase poly+    --                     [ s^.symbolPoint | s <- myPoints ats, isInsidePt  s ]+    --                     [ s^.symbolPoint | s <- myPoints ats, isBorderPt  s ]+    --                     [ s^.symbolPoint | s <- myPoints ats, isOutsidePt s ]+    --          | (poly :+ ats) <- polies+    --          ]+    --   where+    --     polies = page^..content.traverse._withAttrs _IpePath _asSimplePolygon+    --     syms   = page^..content.traverse._IpeUse+++    --     myPoints polyAts = [s | (s :+ ats) <- syms, belongsToPoly ats polyAts ]++    --     -- We test a point/polygon combination if they have the same color+    --     belongsToPoly symAts polyAts =+    --         lookupAttr colorP symAts == lookupAttr colorP polyAts++    --     -- A point i inside if it is a disk+    --     isInsidePt   :: IpeSymbol r -> Bool+    --     isInsidePt s = s^.symbolName == "mark/disk(sx)"++    --     -- Boxes are on the boundary+    --     isBorderPt s = s^.symbolName == "mark/box(sx)"++    --     -- crosses are outside the polygon+    --     isOutsidePt s = s^.symbolName == "mark/cross(sx)"++    --     colorP = Proxy :: Proxy Stroke
test/Data/Geometry/IntervalSpec.hs view
@@ -12,7 +12,6 @@ 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           Test.Hspec
test/Data/Geometry/Ipe/ReaderSpec.hs view
@@ -25,8 +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 (Named \"black\"))}, GAttr {_getAttr = Nothing}, GAttr {_getAttr = Nothing}, GAttr {_getAttr = Just (IpeSize (Named \"normal\"))}}})"-+        "Right (Attrs {NoAttr, NoAttr, NoAttr, NoAttr, Attr IpeColor (Named \"black\"), NoAttr, NoAttr, Attr IpeSize (Named \"normal\")})"     describe "IpeRead" $ do       it "parses a Symbol" $         fromIpeXML' useTxt
test/Data/Geometry/KDTreeSpec.hs view
@@ -6,7 +6,7 @@ import           Data.Geometry import           Data.Geometry.Box import           Data.Geometry.KDTree-import qualified Data.Seq as Seq+import qualified Data.LSeq as LSeq import qualified Data.Set as Set import           GHC.TypeLits import           Test.QuickCheck.HGeometryInstances()@@ -32,22 +32,22 @@               []     -> True               (x:xs) -> all (== x) xs --- newtype Pts n d r = Pts (PointSet (Seq.LSeq n) d () r)+-- newtype Pts n d r = Pts (PointSet (LSeq.LSeq n) d () r) -- deriving instance (Arity d, Show r) => Show (Pts n d r)  -- instance (KnownNat n, Arity d, KnownNat d, Arbitrary r, Ord r) => Arbitrary (Pts n d r) where---   arbitrary = Pts . toPointSet . Seq.toNonEmpty <$> arbitrary+--   arbitrary = Pts . toPointSet . LSeq.toNonEmpty <$> arbitrary   spec :: Spec spec = do   describe "splitOn" $ do     it "quickheck: left set same points" $-      property $ \c (pts :: Seq.LSeq 2 (Point 2 Int :+ ())) ->+      property $ \c (pts :: LSeq.LSeq 2 (Point 2 Int :+ ())) ->                    let (l,_,_) = splitOn (toEnum c) (toPointSet pts)                    in allSame . fmap (Set.fromList . F.toList) $ l     it "quickheck: right set same points" $-      property $ \c (pts :: Seq.LSeq 2 (Point 2 Int :+ ())) ->+      property $ \c (pts :: LSeq.LSeq 2 (Point 2 Int :+ ())) ->                    let (_,_,r) = splitOn (toEnum c) (toPointSet pts)                    in allSame . fmap (Set.fromList . F.toList) $ r   describe "Same as Naive" $ do
test/Data/Geometry/LineSegmentSpec.hs view
@@ -1,16 +1,20 @@ {-# LANGUAGE ScopedTypeVariables #-} module Data.Geometry.LineSegmentSpec where -import           Data.Ext-import           Data.Geometry-import           Test.Hspec-import           Test.QuickCheck.HGeometryInstances ()+import Data.Ext+import Data.Geometry+import Data.Vinyl.CoRec+import Test.Hspec+import Test.QuickCheck.HGeometryInstances ()  spec :: Spec spec =-  describe "onSegment" $+  describe "onSegment" $ do     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+      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+    it "intersecting line segment and line" $ do+      let s = ClosedLineSegment (ext $ origin) (ext $ Point2 10 (0 :: Rational))+      (s `intersect` horizontalLine (0 :: Rational)) `shouldBe` coRec s
test/Data/Geometry/PlanarSubdivisionSpec.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE PartialTypeSignatures #-} module Data.Geometry.PlanarSubdivisionSpec where  @@ -26,6 +27,10 @@ import           Data.Maybe (fromJust) import           Data.PlaneGraph.Draw +import Data.Geometry.LineSegment+import Data.Geometry.Interval+import Data.Range+import Data.Ratio  data Test = Test data Id a = Id a@@ -62,6 +67,7 @@     it "outerFace tests" $       let [d] = toList $ holesOf (outerFaceId triangle) triangle       in leftFace d triangle `shouldBe` (outerFaceId triangle)+    noEmptyFacesSpec     testSpec testPoly     testSpec testPoly2     testSpec testPoly3@@ -199,18 +205,18 @@ -- test = asIpe drawPlaneGraph testPolygPlaneG mempty  printMP = mapM_ printAsIpeSelection-        . map (asIpeObject' mempty . (^.core) . snd)+        . map (iO' . (^.core) . snd)         . toList . rawFacePolygons $ monotonePs    printP = mapM_ printAsIpeSelection-       . map (asIpeObject' mempty . (^.core) . snd)+       . map (iO' . (^.core) . snd)        . toList . PG.rawFacePolygons $ test'   printPPX = mapM_ printAsIpeSelection-        . map (asIpeObject' mempty . (^.core) . snd)+        . map (iO' . (^.core) . snd)         . toList . rawFacePolygons  printPP = printPPX test@@ -219,3 +225,70 @@        . lefts . map ((^.core) . snd) . toList . rawFacePolygons $ monotonePs  parts'' = lefts . map ((^.core) . snd) . toList . rawFacePolygons $ monotonePs+++--------------------------------------------------------------------------------++noEmptyFacesSpec :: Spec+noEmptyFacesSpec = describe "fromConnectedSegments, correct handling of high degree vertex" $ do+    it "ps1" $+      draw' testSegs `shouldBe` mempty+    it "ps5" $+      draw' testSegs2 `shouldBe` mempty+    it "ps3" $+      draw' testSegs3 `shouldBe` mempty+    -- segs4 <- runIO $ readFromIpeFile "test/Data/Geometry/connectedsegments_simple2.ipe"+    -- it "connected_simple2.ipe" $+    --   draw' segs4 `shouldBe` mempty+    -- segs2 <- runIO $ readFromIpeFile "test/Data/Geometry/connectedsegments_simple.ipe"+    -- it "connected_simple.ipe" $+    --   draw' segs2 `shouldBe` mempty+    -- segs3 <- runIO $ readFromIpeFile "test/Data/Geometry/connectedsegments.ipe"+    -- it "connectedsegments.ipe" $+    --   draw' segs3 `shouldBe` mempty+  where+    draw' = draw . fromConnectedSegments (Identity Test1)++readFromIpeFile    :: FilePath -> IO [LineSegment 2 () Rational :+ _]+readFromIpeFile fp = do Right page <- readSinglePageFile fp+                        pure $+                           page^..content.traverse._withAttrs _IpePath _asLineSegment++data Test1 = Test1++testX = do segs <- readFromIpeFile "test/Data/Geometry/connectedsegments_simple2.ipe"+           let ps = fromConnectedSegments (Identity Test1) segs+           print $ draw ps+++draw = V.filter isEmpty . rawFacePolygons+  where+    isEmpty (_,Left  p :+ _) = (< 3) . length . polygonVertices $ p+    isEmpty (_,Right p :+ _) = (< 3) . length . polygonVertices $ p++testSegs = map (\(p,q) -> ClosedLineSegment (ext p) (ext q) :+ ())+                   [ (origin, Point2 10 10)+                   , (origin, Point2 12 10)+                   , (origin, Point2 20 5)+                   , (origin, Point2 13 20)+                   , (Point2 10 10, Point2 12 10)+                   , (Point2 10 10, Point2 13 20)+                   , (Point2 12 10, Point2 20 5)+                   ]++testSegs2 = map (\(p,q) -> ClosedLineSegment (ext p) (ext q) :+ ())+                   [ (Point2 160 192, Point2 80 112)+                   , (Point2 80 112, Point2 192 96)+                   , (Point2 192 96, Point2 160 192)+                   ]+++testSegs3 = map (\(p,q) -> ClosedLineSegment (ext p) (ext q) :+ ())+                   [ (origin, Point2 10 0)+                   , (Point2 10 0, Point2 10 10)+                   , (origin, Point2 10 10)++                   , (origin, Point2 (-10) 0)+                   , (Point2 (-10) 0, Point2 (-10) (-10))+                   , (origin, Point2 (-10) (-10))+                   ]
test/Data/Geometry/PointSpec.hs view
@@ -2,12 +2,18 @@  import Data.Ext import Data.Geometry.Point+import Data.Geometry.Vector import Test.Hspec import qualified Data.CircularList as C   spec :: Spec spec = do+  describe "Add vector to point" $ do+    it "2d" $+      origin .+^ Vector2 1 2 `shouldBe` Point2 1 2+    it "3d" $+      origin .+^ Vector3 1 2 3 `shouldBe` Point3 1 2 3   describe "Sort Arround a Point test" $ do     it "Sort around origin" $       sortArround (ext origin) (map ext [ point2 (-3) (-3)
test/Data/Geometry/SubLineSpec.hs view
@@ -30,15 +30,21 @@     `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')+    let mySeg :: LineSegment 2 () Rational+        mySeg    = ClosedLineSegment (ext origin) (ext $ Point2 14 0)+        myLine :: SubLine 2 () (UnBounded Rational) Rational+        myLine   = fromLine $ lineThrough (Point2 0 0) (Point2 10 0)+        myAnswer :: Interval () (UnBounded Rational)+        myAnswer = ClosedInterval (ext $ Val 0) (ext . Val $ 7 % 5)+    in (myLine `intersect` (mkSL mySeg))        `shouldBe`-       coRec (myLine&subRange .~ ClosedInterval (ext $ Val 0) (ext . Val $ 7 % 5))+       coRec (myLine&subRange .~ myAnswer)  +mkSL  :: (Num r, Arity d) => LineSegment d () r -> SubLine d () (UnBounded r) r+mkSL s = s^._SubLine.re _unBounded + seg :: LineSegment 2 () Rational seg = ClosedLineSegment (ext (Point2 1 1)) (ext (Point2 5 5)) @@ -46,5 +52,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+                          => Point d r -> SubLine d p r r -> Bool+onSubLineOrig p (SubLine l r) = toOffset' p l `inInterval` r
+ test/Data/Geometry/TriangleSpec.hs view
@@ -0,0 +1,107 @@+{-# LANGUAGE OverloadedStrings #-}+module Data.Geometry.TriangleSpec where++import Data.Traversable(traverse)+import Data.Ext+import Control.Lens+import Control.Applicative+import Data.Geometry+import Data.Geometry.Triangle+import Data.Geometry.Boundary+import Data.Geometry.Ipe+import Data.Proxy+import Test.Hspec+import Data.Ratio+import Data.Vinyl.CoRec++spec :: Spec+spec = do testCases "test/Data/Geometry/pointInTriangle.ipe"+          describe "intersection tests" $ do+            it "intersecting Line 2 with Triangle 2 " $ do+              let t :: Triangle 2 () Rational+                  t = Triangle (ext origin) (ext $ Point2 10 0) (ext $ Point2 10 10)+                  hor :: Rational -> Line 2 Rational+                  hor = horizontalLine+              (hor 3 `intersect` t)+                `shouldBe` (coRec $ ClosedLineSegment (ext $ Point2 10 (3 :: Rational))+                                                      (ext $ Point2 3  (3 :: Rational)))+              (hor 10 `intersect` t)+                `shouldBe` (coRec $ Point2 10 (10 :: Rational))+              (hor 11 `intersect` t)+                `shouldBe` (coRec NoIntersection)+++testCases    :: FilePath -> Spec+testCases fp = runIO (readInputFromFile fp) >>= \case+    Left e    -> it "reading point in triangle file" $+                   expectationFailure $ "Failed to read ipe file " ++ show e+    Right tcs -> mapM_ toSpec tcs+++--   ipeF <- beforeAll $ readInputFromFile "tests/Data/Geometry/pointInPolygon.ipe"+--   describe "Point in Polygon tests" $ do+--     it "returns the first element of a list" $ do+--       head [23 ..] `shouldBe` (23 :: Int)+++data TestCase r = TestCase { _triangle   :: Triangle 2 () r+                           , _inside     :: [Point 2 r]+                           , _onBoundary :: [Point 2 r]+                           , _outside    :: [Point 2 r]+                           }+                  deriving (Show)+++toSingleSpec poly r q = it msg $ (q `inTriangle` poly) `shouldBe` r+  where+    msg = "Point in triangle test with " ++ show q+++toSpec                          ::  (Show r, Ord r, Fractional r)+                                =>  TestCase r -> Spec+toSpec (TestCase poly is bs os) = do+                                    describe "inside tests" $+                                      mapM_ (toSingleSpec poly Inside) is+                                    describe "on boundary tests" $+                                      mapM_ (toSingleSpec poly OnBoundary) bs+                                    describe "outside tests" $+                                      mapM_ (toSingleSpec poly Outside) os++++readInputFromFile    :: FilePath -> IO (Either ConversionError [TestCase Rational])+readInputFromFile fp = fmap f <$> readSinglePageFile fp+  where+    f page = [ TestCase poly+                        [ s^.symbolPoint | s <- myPoints ats, isInsidePt  s ]+                        [ s^.symbolPoint | s <- myPoints ats, isBorderPt  s ]+                        [ s^.symbolPoint | s <- myPoints ats, isOutsidePt s ]+             | (poly :+ ats) <- polies+             ]+      where+        polies = page^..content.traverse._withAttrs _IpePath _asTriangle+        syms   = page^..content.traverse._IpeUse+++        myPoints polyAts = [s | (s :+ ats) <- syms, belongsToPoly ats polyAts ]++        -- We test a point/polygon combination if they have the same color+        belongsToPoly symAts polyAts =+            lookupAttr colorP symAts == lookupAttr colorP polyAts++        -- A point i inside if it is a disk+        isInsidePt   :: IpeSymbol r -> Bool+        isInsidePt s = s^.symbolName == "mark/disk(sx)"++        -- Boxes are on the boundary+        isBorderPt s = s^.symbolName == "mark/box(sx)"++        -- crosses are outside the polygon+        isOutsidePt s = s^.symbolName == "mark/cross(sx)"++        colorP = Proxy :: Proxy Stroke+++++-- main = readInputFromFile "tests/Data/Geometry/pointInPolygon.ipe"
+ test/Data/Geometry/arrangement.ipe view
@@ -0,0 +1,296 @@+<?xml version="1.0"?>+<!DOCTYPE ipe SYSTEM "ipe.dtd">+<ipe version="70107" creator="Ipe 7.2.2">+<info created="D:20180731094955" modified="D:20180731094955"/>+<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 560 m+368 800 l+</path>+<path stroke="black">+160 768 m+416 608 l+</path>+<path stroke="black">+80 624 m+400 672 l+</path>+<path matrix="0.857143 0 0 1.3 32 -172.8" stroke="black">+224 576 m+336 736 l+</path>+</page>+</ipe>
+ test/Data/Geometry/arrangement.ipe.out.ipe view
@@ -0,0 +1,274 @@+<?xml version="1.0" encoding="UTF-8"?>+<ipe version="70005" creator="HGeometry"><ipestyle name="basic">+<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 0.745 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 0.663 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 0.827 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"/>+<pen name="heavier" value="0.8"/>+<pen name="fat" value="1.2"/>+<pen name="ultrafat" value="2"/>+<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"/>+<symbolsize name="small" value="2"/>+<symbolsize name="tiny" value="1.1"/>+<symbolsize name="large" value="5"/>+<arrowsize name="small" value="5"/>+<arrowsize name="tiny" value="3"/>+<arrowsize name="large" value="10"/>+<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"/>+<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/arc(spx)">+<path pen="sym-pen" stroke="sym-stroke" fill="sym-stroke">+0 0 m -1.0 0.333 l -1.0 -0.333 l h</path></symbol>+<symbol name="arrow/farc(spx)">+<path pen="sym-pen" stroke="sym-stroke" fill="white">+0 0 m -1.0 0.333 l -1.0 -0.333 l h</path></symbol>+<symbol name="arrow/ptarc(spx)">+<path pen="sym-pen" stroke="sym-stroke" fill="sym-stroke">+0 0 m -1.0 0.333 l -0.8 0 l -1.0 -0.333 l h</path></symbol>+<symbol name="arrow/fptarc(spx)">+<path pen="sym-pen" stroke="sym-stroke" fill="white">+0 0 m -1.0 0.333 l -0.8 0 l -1.0 -0.333 l h</path></symbol>+<symbol name="arrow/fnormal(spx)">+<path pen="sym-pen" stroke="sym-stroke" fill="white">+0 0 m -1.0 0.333 l -1.0 -0.333 l h</path></symbol>+<symbol name="arrow/pointed(spx)">+<path pen="sym-pen" stroke="sym-stroke" fill="sym-stroke">+0 0 m -1.0 0.333 l -0.8 0 l -1.0 -0.333 l h</path></symbol>+<symbol name="arrow/fpointed(spx)">+<path pen="sym-pen" stroke="sym-stroke" fill="white">+0 0 m -1.0 0.333 l -0.8 0 l -1.0 -0.333 l h</path></symbol>+<symbol name="arrow/linear(spx)">+<path pen="sym-pen" stroke="sym-stroke">+-1.0 0.333 m 0 0 l -1.0 -0.333 l</path></symbol>+<symbol name="arrow/fdouble(spx)">+<path pen="sym-pen" stroke="sym-stroke" fill="white">+0 0 m -1.0 0.333 l -1.0 -0.333 l h+-1 0 m -2.0 0.333 l -2.0 -0.333 l h+</path></symbol>+<symbol name="arrow/double(spx)">+<path pen="sym-pen" stroke="sym-stroke" fill="sym-stroke">+0 0 m -1.0 0.333 l -1.0 -0.333 l h+-1 0 m -2.0 0.333 l -2.0 -0.333 l h+</path></symbol>+<tiling name="falling" angle="-60" width="1" step="4"/>+<tiling name="rising" angle="30" width="1" step="4"/>+<textstyle name="center" begin="\begin{center}" end="\end{center}"/>+<textstyle name="itemize" begin="\begin{itemize}" end="\end{itemize}"/>+<textstyle name="item" begin="\begin{itemize}\item{}" end="\end{itemize}"/>+</ipestyle><page><group><use pos="172.658536585365 637.048780487804" name="mark/disk(sx)"/><use pos="172.658536585365 637.215447154471" name="mark/disk(sx)"/><use pos="172.658536585365 637.898780487804" name="mark/disk(sx)"/><use pos="172.658536585365 746.000060937506" name="mark/disk(sx)"/><use pos="173.658536585365 638.048780487804" name="mark/disk(sx)"/><use pos="195.199902499989 746.000060937506" name="mark/disk(sx)"/><use pos="252.176396921200 637.048780487804" name="mark/disk(sx)"/><use pos="256.914285714285 707.428571428571" name="mark/disk(sx)"/><use pos="258.512437254286 650.776865588142" name="mark/disk(sx)"/><use pos="278.447793072843 693.970129329472" name="mark/disk(sx)"/><use pos="302.000073125007 745.000060937506" name="mark/disk(sx)"/><use pos="302.461611663469 746.000060937506" name="mark/disk(sx)"/><use pos="303.200073125007 746.000060937506" name="mark/disk(sx)"/><use pos="330.322580645161 661.548387096774" name="mark/disk(sx)"/><use pos="331.322580645161 637.048780487804" name="mark/disk(sx)"/><use pos="331.322580645161 660.923387096774" name="mark/disk(sx)"/><use pos="331.322580645161 661.698387096774" name="mark/disk(sx)"/><use pos="331.322580645161 746.000060937506" name="mark/disk(sx)"/><path>172.658536585365 637.215447154471 m+173.658536585365 638.048780487804 l+</path><path>173.658536585365 638.048780487804 m+256.914285714285 707.428571428571 l+</path><path>256.914285714285 707.428571428571 m+302.000073125007 745.000060937506 l+</path><path>302.000073125007 745.000060937506 m+303.200073125007 746.000060937506 l+</path><path>195.199902499989 746.000060937506 m+256.914285714285 707.428571428571 l+</path><path>256.914285714285 707.428571428571 m+278.447793072843 693.970129329472 l+</path><path>278.447793072843 693.970129329472 m+330.322580645161 661.548387096774 l+</path><path>330.322580645161 661.548387096774 m+331.322580645161 660.923387096774 l+</path><path>172.658536585365 637.898780487804 m+173.658536585365 638.048780487804 l+</path><path>173.658536585365 638.048780487804 m+258.512437254286 650.776865588142 l+</path><path>258.512437254286 650.776865588142 m+330.322580645161 661.548387096774 l+</path><path>330.322580645161 661.548387096774 m+331.322580645161 661.698387096774 l+</path><path>252.176396921200 637.048780487804 m+258.512437254286 650.776865588142 l+</path><path>258.512437254286 650.776865588142 m+278.447793072843 693.970129329472 l+</path><path>278.447793072843 693.970129329472 m+302.000073125007 745.000060937506 l+</path><path>302.000073125007 745.000060937506 m+302.461611663469 746.000060937506 l+</path><path>172.658536585365 746.000060937506 m+195.199902499989 746.000060937506 l+</path><path>195.199902499989 746.000060937506 m+302.461611663469 746.000060937506 l+</path><path>302.461611663469 746.000060937506 m+303.200073125007 746.000060937506 l+</path><path>303.200073125007 746.000060937506 m+331.322580645161 746.000060937506 l+</path><path>331.322580645161 746.000060937506 m+331.322580645161 661.698387096774 l+</path><path>331.322580645161 661.698387096774 m+331.322580645161 660.923387096774 l+</path><path>331.322580645161 660.923387096774 m+331.322580645161 637.048780487804 l+</path><path>331.322580645161 637.048780487804 m+252.176396921200 637.048780487804 l+</path><path>252.176396921200 637.048780487804 m+172.658536585365 637.048780487804 l+</path><path>172.658536585365 637.048780487804 m+172.658536585365 637.215447154471 l+</path><path>172.658536585365 637.215447154471 m+172.658536585365 637.898780487804 l+</path><path>172.658536585365 637.898780487804 m+172.658536585365 746.000060937506 l+</path><path>252.176396921200 637.048780487804 m+331.322580645161 637.048780487804 l+331.322580645161 660.923387096774 l+331.322580645161 661.698387096774 l+331.322580645161 746.000060937506 l+303.200073125007 746.000060937506 l+302.461611663469 746.000060937506 l+195.199902499989 746.000060937506 l+172.658536585365 746.000060937506 l+172.658536585365 637.898780487804 l+172.658536585365 637.215447154471 l+172.658536585365 637.048780487804 l+h++252.176396921200 637.048780487804 m+331.322580645161 637.048780487804 l+331.322580645161 660.923387096774 l+331.322580645161 661.698387096774 l+331.322580645161 746.000060937506 l+303.200073125007 746.000060937506 l+302.461611663469 746.000060937506 l+195.199902499989 746.000060937506 l+172.658536585365 746.000060937506 l+172.658536585365 637.898780487804 l+172.658536585365 637.215447154471 l+172.658536585365 637.048780487804 l+h+</path><path>172.658536585365 637.215447154471 m+173.658536585365 638.048780487804 l+258.512437254286 650.776865588142 l+252.176396921200 637.048780487804 l+172.658536585365 637.048780487804 l+h+</path><path>172.658536585365 637.898780487804 m+173.658536585365 638.048780487804 l+172.658536585365 637.215447154471 l+h+</path><path>172.658536585365 746.000060937506 m+195.199902499989 746.000060937506 l+256.914285714285 707.428571428571 l+173.658536585365 638.048780487804 l+172.658536585365 637.898780487804 l+h+</path><path>256.914285714285 707.428571428571 m+278.447793072843 693.970129329472 l+258.512437254286 650.776865588142 l+173.658536585365 638.048780487804 l+h+</path><path>302.461611663469 746.000060937506 m+302.000073125007 745.000060937506 l+256.914285714285 707.428571428571 l+195.199902499989 746.000060937506 l+h+</path><path>258.512437254286 650.776865588142 m+330.322580645161 661.548387096774 l+331.322580645161 660.923387096774 l+331.322580645161 637.048780487804 l+252.176396921200 637.048780487804 l+h+</path><path>302.000073125007 745.000060937506 m+278.447793072843 693.970129329472 l+256.914285714285 707.428571428571 l+h+</path><path>278.447793072843 693.970129329472 m+330.322580645161 661.548387096774 l+258.512437254286 650.776865588142 l+h+</path><path>302.000073125007 745.000060937506 m+303.200073125007 746.000060937506 l+331.322580645161 746.000060937506 l+331.322580645161 661.698387096774 l+330.322580645161 661.548387096774 l+278.447793072843 693.970129329472 l+h+</path><path>302.461611663469 746.000060937506 m+303.200073125007 746.000060937506 l+302.000073125007 745.000060937506 l+h+</path><path>331.322580645161 661.698387096774 m+331.322580645161 660.923387096774 l+330.322580645161 661.548387096774 l+h+</path></group></page></ipe>
+ test/Data/Geometry/pointInTriangle.ipe view
@@ -0,0 +1,310 @@+<?xml version="1.0"?>+<!DOCTYPE ipe SYSTEM "ipe.dtd">+<ipe version="70107" creator="Ipe 7.2.2">+<info created="D:20150923215046" modified="D:20180808120020"/>+<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"/>+<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="darkblue">+304 720 m+224 592 l+48 736 l+h+</path>+<use name="mark/disk(sx)" pos="128 704" size="normal" stroke="darkblue"/>+<use name="mark/disk(sx)" pos="192 672" size="normal" stroke="darkblue"/>+<use name="mark/disk(sx)" pos="192 720" size="normal" stroke="darkblue"/>+<use name="mark/box(sx)" pos="304 688" size="normal" stroke="black"/>+<use name="mark/cross(sx)" pos="352 736" size="normal" stroke="darkblue"/>+<use name="mark/cross(sx)" pos="352 704" size="normal" stroke="darkblue"/>+<path stroke="orange">+496 736 m+432 624 l+512 608 l+h+</path>+<use name="mark/box(sx)" pos="432 624" size="normal" stroke="orange"/>+<use name="mark/box(sx)" pos="512 608" size="normal" stroke="orange"/>+<use name="mark/box(sx)" pos="496 736" size="normal" stroke="orange"/>+<use name="mark/disk(sx)" pos="496 656" size="normal" stroke="orange"/>+<use name="mark/disk(sx)" pos="480 640" size="normal" stroke="orange"/>+<use name="mark/disk(sx)" pos="464 656" size="normal" stroke="orange"/>+<use name="mark/cross(sx)" pos="368 608" size="normal" stroke="orange"/>+<use name="mark/cross(sx)" pos="384 592" size="normal" stroke="orange"/>+<use name="mark/cross(sx)" pos="336 576" size="normal" stroke="orange"/>+<use name="mark/disk(sx)" pos="496 624" size="normal" stroke="orange"/>+<use name="mark/cross(sx)" pos="528 624" size="normal" stroke="orange"/>+<use name="mark/cross(sx)" pos="384 624" size="normal" stroke="orange"/>+<use name="mark/cross(sx)" pos="368 640" size="normal" stroke="orange"/>+<use name="mark/cross(sx)" pos="336 688" size="normal" stroke="darkblue"/>+<use name="mark/disk(sx)" pos="256 688" size="normal" stroke="darkblue"/>+<use name="mark/disk(sx)" pos="224 688" size="normal" stroke="darkblue"/>+</page>+</ipe>
test/Data/PlanarGraphSpec.hs view
@@ -1,16 +1,22 @@+{-# LANGUAGE ScopedTypeVariables #-} module Data.PlanarGraphSpec where  -import           Data.Util-import           Data.PlanarGraph-import           Data.Permutation(toCycleRep)-import           Test.Hspec+import           Data.Bifunctor+import qualified Data.ByteString.Char8 as B import qualified Data.Foldable as F+import qualified Data.Map.Strict as SM+import           Data.Permutation (toCycleRep)+import           Data.PlanarGraph+import qualified Data.PlanarGraph as PlanarGraph import qualified Data.Set as S+import           Data.Util import qualified Data.Vector as V-import qualified Data.Map.Strict as SM-import           Data.Semigroup-+import           Data.Yaml (prettyPrintParseException)+import           Data.Yaml.Util+import           Test.Hspec+import           Test.QuickCheck+import           Test.QuickCheck.HGeometryInstances ()   data TestG@@ -33,13 +39,21 @@       it "Missing edges from h in g" $           (missingAdjacencies h g) `shouldBe` [] --- spec :: Spec-spec = sameGraphs "testEdges" (fromAdjacencyLists testEdges) (fromAdjacencyListsOld testEdges)--+spec = do+    describe "PlanarGraph spec" $ do+      sameGraphs "testEdges" (fromAdjacencyLists testEdges) (fromAdjacencyListsOld testEdges)+    it "quickheck Dart:  (toEnum (fromEnum d)) = d" $+      property $ \(d :: Dart TestG) -> toEnum (fromEnum d) `shouldBe` d+    it "quickheck Dart: fromEnum (toEnum i) = i" $+      property $ \(NonNegative i) -> fromEnum ((toEnum i) :: Dart TestG) `shouldBe` i+    it "encode yaml test" $ do+      b <- B.readFile "test/Data/myGraph.yaml"+      encodeYaml (fromAdjacencyLists testEdges) `shouldBe` b+    it "decode yaml test" $ do+      (first prettyPrintParseException <$> decodeYamlFile "test/Data/myGraph.yaml")+      `shouldReturn`+      (Right $ fromAdjacencyLists testEdges)   testEdges :: [(Vertex,[Vertex])]@@ -52,6 +66,11 @@             , (5, [3,4])             ] +-- testGraph = fromAdjacencyLists testEdges++-- enccode = let g =+--           in encodeYamlFile+ --------------------------------------------------------------------------------  @@ -90,7 +109,7 @@     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+    toDart (u,v) (STR m a ds) = let dir = if u < v then PlanarGraph.Positive else Negative                                     t'  = (min u v, max u v)                                in case SM.lookup t' m of       Just a' -> STR m                  a     (Dart (Arc a') dir : ds)
+ test/Data/PlaneGraphSpec.hs view
@@ -0,0 +1,72 @@+{-# LANGUAGE PartialTypeSignatures #-}+module Data.PlaneGraphSpec where+++import           Control.Lens+import           Data.Bifunctor+import qualified Data.ByteString as B+import           Data.Ext+import           Data.Geometry.LineSegment+import           Data.Geometry.Point+import           Data.Geometry.Polygon+import           Data.PlaneGraph+import           Data.Util+import qualified Data.Vector as V+import           Data.Yaml (prettyPrintParseException)+import           Data.Yaml.Util+import           Test.Hspec+--------------------------------------------------------------------------------++spec :: Spec+spec = describe "PlaneGraph tests" $ do+         it "fromConnectedSegments, correct handling of high degree vertex" $ do+           draw test `shouldBe` mempty+           draw test2 `shouldBe` mempty+         it "encode yaml test" $ do+           b <- B.readFile "test/Data/myPlaneGraph.yaml"+           encodeYaml myGraph `shouldBe` b+         -- it "decode yaml test" $ do+         --   (first prettyPrintParseException+         --     <$> decodeYamlFile "test/Data/myPlaneGraph.yaml")+         --   `shouldReturn`+         --   (Right myGraph)+        -- the result is the same up to renumbering it seems. That is fine.+  where+    myGraph = fromConnectedSegments (Identity Test1) testSegs+++data Test1 = Test1++draw  :: PlaneGraph s p e extra r -> V.Vector (FaceId' s, Polygon 'Simple p r :+ extra)+draw = V.filter isEmpty . rawFacePolygons+  where+    isEmpty (_,p :+ _) = (< 3) . length . polygonVertices $ p++test :: PlaneGraph Test1 _ () () Integer+test = fromConnectedSegments (Identity Test1) testSegs++test2 :: PlaneGraph Test1 _ () () Integer+test2 = fromConnectedSegments (Identity Test1) testSegs2++testSegs :: [LineSegment 2 () Integer :+ ()]+testSegs = map (\(p,q) -> ClosedLineSegment (ext p) (ext q) :+ ())+                   [ (origin, Point2 10 10)+                   , (origin, Point2 12 10)+                   , (origin, Point2 20 5)+                   , (origin, Point2 13 20)+                   , (Point2 10 10, Point2 12 10)+                   , (Point2 10 10, Point2 13 20)+                   , (Point2 12 10, Point2 20 5)+                   ]+testSegs2 :: [LineSegment 2 () Integer :+ ()]+testSegs2 = map (\(p,q) -> ClosedLineSegment (ext p) (ext q) :+ ())+                   [ (origin, Point2 10 0)+                   , (Point2 10 0, Point2 10 10)+                   , (origin, Point2 10 10)++                   , (origin, Point2 (-10) 0)+                   , (Point2 (-10) 0, Point2 (-10) (-10))+                   , (origin, Point2 (-10) (-10))+                   ]++-- segs2 =
+ test/Data/myGraph.yaml view
@@ -0,0 +1,98 @@+adjacencies:+- - 0+  - - 1+- - 1+  - - 0+    - 2+    - 4+- - 2+  - - 1+    - 3+    - 4+- - 3+  - - 2+    - 5+- - 4+  - - 1+    - 2+    - 5+- - 5+  - - 3+    - 4+faces:+- extra: []+  core: 0+- extra: []+  core: 1+- extra: []+  core: 2+darts:+- extra: []+  core:+  - 0+  - 1+- extra: []+  core:+  - 1+  - 0+- extra: []+  core:+  - 1+  - 2+- extra: []+  core:+  - 1+  - 4+- extra: []+  core:+  - 2+  - 1+- extra: []+  core:+  - 2+  - 3+- extra: []+  core:+  - 2+  - 4+- extra: []+  core:+  - 3+  - 2+- extra: []+  core:+  - 3+  - 5+- extra: []+  core:+  - 4+  - 1+- extra: []+  core:+  - 4+  - 2+- extra: []+  core:+  - 4+  - 5+- extra: []+  core:+  - 5+  - 3+- extra: []+  core:+  - 5+  - 4+vertices:+- extra: []+  core: 0+- extra: []+  core: 1+- extra: []+  core: 2+- extra: []+  core: 3+- extra: []+  core: 4+- extra: []+  core: 5
+ test/Data/myPlaneGraph.yaml view
@@ -0,0 +1,131 @@+adjacencies:+- - 0+  - - 4+    - 2+    - 1+    - 3+- - 1+  - - 2+    - 3+    - 0+- - 2+  - - 1+    - 0+    - 4+- - 3+  - - 0+    - 1+- - 4+  - - 2+    - 0+faces:+- extra: []+  core: 0+- extra: []+  core: 1+- extra: []+  core: 2+- extra: []+  core: 3+darts:+- extra: []+  core:+  - 0+  - 4+- extra: []+  core:+  - 0+  - 2+- extra: []+  core:+  - 0+  - 1+- extra: []+  core:+  - 0+  - 3+- extra: []+  core:+  - 1+  - 2+- extra: []+  core:+  - 1+  - 3+- extra: []+  core:+  - 1+  - 0+- extra: []+  core:+  - 2+  - 1+- extra: []+  core:+  - 2+  - 0+- extra: []+  core:+  - 2+  - 4+- extra: []+  core:+  - 3+  - 0+- extra: []+  core:+  - 3+  - 1+- extra: []+  core:+  - 4+  - 2+- extra: []+  core:+  - 4+  - 0+vertices:+- extra:+    extra:+    - []+    - []+    - []+    - []+    core:+    - 0+    - 0+  core: 0+- extra:+    extra:+    - []+    - []+    - []+    core:+    - 10+    - 10+  core: 1+- extra:+    extra:+    - []+    - []+    - []+    core:+    - 12+    - 10+  core: 2+- extra:+    extra:+    - []+    - []+    core:+    - 13+    - 20+  core: 3+- extra:+    extra:+    - []+    - []+    core:+    - 20+    - 5+  core: 4
test/Util.hs view
@@ -1,13 +1,23 @@ module Util where -import Data.Vinyl-import Data.Geometry.Ipe-import Data.Proxy-import Data.Ext-import Data.Function(on)+import           Control.Exception.Base (bracket)+import           Control.Monad (when)+import qualified Data.ByteString as B+import qualified Data.ByteString.Lazy as LB+import           Data.Ext+import           Data.Function (on)+import           Data.Geometry.Ipe import qualified Data.List as L-import Data.Singletons(Apply)+import           Data.Proxy+import           Data.Singletons (Apply)+import           Data.Vinyl+import           System.Directory (removeFile, getTemporaryDirectory)+import           System.FilePath (takeExtension)+import           System.IO (hClose,openTempFile, Handle)+import           Test.Hspec +--------------------------------------------------------------------------------+ 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@@ -30,3 +40,52 @@  instance Eq a => Eq (NaiveSet a) where   (NaiveSet xs) == (NaiveSet ys) = L.null $ difference xs ys+++-- | Given a file with some file contents and a procedure that produces a+-- bytestring. Verify that the bytestring that we produce is the same as the+-- one stored in the file. If not, the output is stored in a temporary file so+-- that we can later look at the details.+runOnFile             :: String    -- ^ the description+                      -> FilePath  -- ^ the expected output file+                      -> IO B.ByteString -- ^ the algorithm to run.+                      -> Spec+runOnFile s expFP alg = runOnFile' s expFP (\h -> alg >>= B.hPut h)+++data Res = Res Bool FilePath FilePath+         | True' deriving (Show)++instance Eq Res where+  Res b _ _ == _ = b+  True'     == _ = True++-- | Given a file with some file contents and a procedure that produces a+-- bytestring. Verify that the bytestring that we produce is the same as the+-- one stored in the file. If not, the output is stored in a temporary file so+-- that we can later look at the details.+runOnFile'                 :: String    -- ^ the description+                           -> FilePath  -- ^ the expected output file+                           -> (Handle -> IO ()) -- ^ the algorithm to run.+                           -> Spec+runOnFile' descr expFP alg = it descr $ do+                               runAlgo `shouldReturn` True'+  where+    runAlgo = do+                dir <- getTemporaryDirectory+                outFP <- bracket (openTempFile dir outFPName)+                                 (hClose . snd)+                                 (\(fp,h) -> do+                                     alg h+                                     pure fp)+                res <- sameFile expFP outFP+                when res $ removeFile outFP+                pure $ Res res expFP outFP+    outFPName = "hgeometry_runOnFile_algo" <> takeExtension expFP+++-- | Test if two files are the same. Warning: uses lazy IO.+sameFile       :: FilePath -> FilePath -> IO Bool+sameFile fa fb = do a <- LB.readFile fa+                    b <- LB.readFile fb+                    pure $ a == b