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 +6/−4
- benchmark/Algorithms/Geometry/ClosestPair/Bench.hs +48/−0
- benchmark/Algorithms/Geometry/ConvexHull/Bench.hs +2/−2
- benchmark/Benchmarks.hs +1/−1
- benchmark/Data/Geometry/Vector/VectorFamily6.hs +0/−1
- changelog.md +10/−0
- docs/Data/PlanarGraph/testG.png binary
- doctests.hs +33/−20
- examples/Demo/Delaunay.hs +2/−2
- examples/Demo/DrawGPX.hs +1/−1
- examples/Demo/GPXParser.hs +1/−2
- examples/Demo/MinDisk.hs +5/−14
- examples/Demo/TriangulateWorld.hs +16/−22
- examples/Demo/WriteEnsemble.hs +1/−4
- hgeometry.cabal +80/−38
- src/Algorithms/Geometry/ClosestPair/DivideAndConquer.hs +129/−0
- src/Algorithms/Geometry/ClosestPair/Naive.hs +48/−0
- src/Algorithms/Geometry/ConvexHull/DivideAndConquer.hs +38/−0
- src/Algorithms/Geometry/ConvexHull/DivideAndConqueror.hs +0/−27
- src/Algorithms/Geometry/ConvexHull/GrahamScan.hs +0/−1
- src/Algorithms/Geometry/DelaunayTriangulation/DivideAndConquer.hs +296/−0
- src/Algorithms/Geometry/DelaunayTriangulation/DivideAndConqueror.hs +0/−296
- src/Algorithms/Geometry/DelaunayTriangulation/Types.hs +8/−5
- src/Algorithms/Geometry/EuclideanMST/EuclideanMST.hs +14/−5
- src/Algorithms/Geometry/LineSegmentIntersection/BentleyOttmann.hs +0/−1
- src/Algorithms/Geometry/LineSegmentIntersection/Naive.hs +0/−1
- src/Algorithms/Geometry/LineSegmentIntersection/Types.hs +1/−1
- src/Algorithms/Geometry/PolyLineSimplification/DouglasPeucker.hs +25/−19
- src/Algorithms/Geometry/PolygonTriangulation/MakeMonotone.hs +3/−4
- src/Algorithms/Geometry/PolygonTriangulation/Triangulate.hs +2/−1
- src/Algorithms/Geometry/PolygonTriangulation/TriangulateMonotone.hs +0/−1
- src/Algorithms/Geometry/PolygonTriangulation/Types.hs +0/−1
- src/Algorithms/Geometry/SmallestEnclosingBall/Naive.hs +17/−6
- src/Algorithms/Geometry/SmallestEnclosingBall/RandomizedIncrementalConstruction.hs +12/−1
- src/Algorithms/Geometry/SmallestEnclosingBall/Types.hs +11/−1
- src/Algorithms/Geometry/Sweep.hs +23/−3
- src/Algorithms/Geometry/WellSeparatedPairDecomposition/Types.hs +12/−3
- src/Algorithms/Geometry/WellSeparatedPairDecomposition/WSPD.hs +26/−23
- src/Algorithms/Util.hs +0/−20
- src/Data/BinaryTree.hs +18/−5
- src/Data/BinaryTree/Zipper.hs +0/−1
- src/Data/CircularSeq.hs +0/−1
- src/Data/Ext.hs +18/−10
- src/Data/Geometry.hs +13/−6
- src/Data/Geometry/Arrangement.hs +25/−0
- src/Data/Geometry/Arrangement/Draw.hs +24/−0
- src/Data/Geometry/Arrangement/Internal.hs +328/−0
- src/Data/Geometry/Ball.hs +10/−6
- src/Data/Geometry/Box.hs +10/−6
- src/Data/Geometry/Box/Internal.hs +17/−3
- src/Data/Geometry/HalfLine.hs +8/−13
- src/Data/Geometry/HyperPlane.hs +94/−0
- src/Data/Geometry/Interval.hs +1/−1
- src/Data/Geometry/Ipe.hs +14/−6
- src/Data/Geometry/Ipe/Attributes.hs +44/−22
- src/Data/Geometry/Ipe/Color.hs +110/−0
- src/Data/Geometry/Ipe/FromIpe.hs +42/−15
- src/Data/Geometry/Ipe/IpeOut.hs +126/−152
- src/Data/Geometry/Ipe/PathParser.hs +0/−1
- src/Data/Geometry/Ipe/Reader.hs +4/−3
- src/Data/Geometry/Ipe/Types.hs +28/−14
- src/Data/Geometry/Ipe/Value.hs +24/−0
- src/Data/Geometry/Ipe/Writer.hs +24/−7
- src/Data/Geometry/KDTree.hs +12/−11
- src/Data/Geometry/Line.hs +22/−12
- src/Data/Geometry/Line/Internal.hs +43/−1
- src/Data/Geometry/LineSegment.hs +28/−29
- src/Data/Geometry/PlanarSubdivision.hs +21/−27
- src/Data/Geometry/PlanarSubdivision/Basic.hs +165/−68
- src/Data/Geometry/PlanarSubdivision/Draw.hs +48/−11
- src/Data/Geometry/Point.hs +25/−7
- src/Data/Geometry/PolyLine.hs +12/−19
- src/Data/Geometry/Polygon.hs +11/−7
- src/Data/Geometry/Polygon/Convex.hs +12/−6
- src/Data/Geometry/Properties.hs +13/−6
- src/Data/Geometry/SegmentTree.hs +0/−14
- src/Data/Geometry/SegmentTree/Generic.hs +30/−20
- src/Data/Geometry/Slab.hs +6/−7
- src/Data/Geometry/SubLine.hs +94/−44
- src/Data/Geometry/Transformation.hs +43/−0
- src/Data/Geometry/Triangle.hs +169/−9
- src/Data/Geometry/Vector.hs +31/−3
- src/Data/Geometry/Vector/VectorFamily.hs +37/−3
- src/Data/Geometry/Vector/VectorFamilyPeano.hs +1/−5
- src/Data/Geometry/Vector/VectorFixed.hs +0/−1
- src/Data/LSeq.hs +310/−0
- src/Data/OrdSeq.hs +0/−1
- src/Data/Permutation.hs +18/−14
- src/Data/PlanarGraph.hs +195/−167
- src/Data/PlaneGraph.hs +87/−15
- src/Data/PlaneGraph/Draw.hs +7/−12
- src/Data/Range.hs +27/−12
- src/Data/Seq.hs +0/−236
- src/Data/Seq2.hs +0/−221
- src/Data/SlowSeq.hs +0/−1
- src/Data/Tree/Util.hs +154/−0
- src/Data/UnBounded.hs +15/−7
- src/Data/Util.hs +59/−3
- src/Data/Yaml/Util.hs +71/−4
- src/Graphics/Camera.hs +165/−0
- src/Test/QuickCheck/HGeometryInstances.hs +28/−10
- test/Algorithms/Geometry/ClosestPair/ClosestPairSpec.hs +45/−0
- test/Algorithms/Geometry/ConvexHull/ConvexHullSpec.hs +3/−4
- test/Algorithms/Geometry/DelaunayTriangulation/DTSpec.hs +3/−3
- test/Algorithms/Geometry/WellSeparatedPairDecomposition/WSPDSpec.hs +3/−3
- test/Data/Geometry/ArrangementSpec.hs +102/−0
- test/Data/Geometry/IntervalSpec.hs +0/−1
- test/Data/Geometry/Ipe/ReaderSpec.hs +1/−2
- test/Data/Geometry/KDTreeSpec.hs +5/−5
- test/Data/Geometry/LineSegmentSpec.hs +13/−9
- test/Data/Geometry/PlanarSubdivisionSpec.hs +76/−3
- test/Data/Geometry/PointSpec.hs +6/−0
- test/Data/Geometry/SubLineSpec.hs +13/−7
- test/Data/Geometry/TriangleSpec.hs +107/−0
- test/Data/Geometry/arrangement.ipe +296/−0
- test/Data/Geometry/arrangement.ipe.out.ipe +274/−0
- test/Data/Geometry/pointInTriangle.ipe +310/−0
- test/Data/PlanarGraphSpec.hs +33/−14
- test/Data/PlaneGraphSpec.hs +72/−0
- test/Data/myGraph.yaml +98/−0
- test/Data/myPlaneGraph.yaml +131/−0
- test/Util.hs +65/−6
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.+-- --  -------------------------------------------------------------------------------- -- | 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