module Data.PlanarGraph.Persistent where import Data.HashMap.Strict import Control.Monad.State type HalfEdge = Int type Vertex = Int type Face = Int -- PlanarGraphs have vertices, edges, and faces. -- Invariant: The half-edge of a boundary vertex is interior, twin is exterior. data PlanarGraph = PlanarGraph { PlanarGraph -> HalfEdge pgNextHalfEdgeId :: HalfEdge , PlanarGraph -> HalfEdge pgNextVertexId :: Vertex , PlanarGraph -> HalfEdge pgNextFaceId :: Face , PlanarGraph -> HashMap HalfEdge HalfEdge pgNext :: HashMap HalfEdge HalfEdge , PlanarGraph -> HashMap HalfEdge HalfEdge pgVertex :: HashMap HalfEdge Vertex , PlanarGraph -> HashMap HalfEdge HalfEdge pgFace :: HashMap HalfEdge Face , PlanarGraph -> HashMap HalfEdge HalfEdge pgHalfEdgeFromVertex :: HashMap Vertex HalfEdge , PlanarGraph -> HashMap HalfEdge HalfEdge pgHalfEdgeFromFace :: HashMap Face HalfEdge } -- data PlaneGraph r = PlaneGraph PlanarGraph (HashMap Vertex (Point 2 r)) new :: Int -> PlanarGraph new :: HalfEdge -> PlanarGraph new = HalfEdge -> PlanarGraph forall a. HasCallStack => a undefined -- O(log n) -- vertexHalfEdge :: Vertex -> PlanarGraph -> HalfEdge -- O(k log n) -- vertexOutgoingHalfEdges :: Vertex -> PlanarGraph -> [HalfEdge] -- O(k log n) -- vertexIncomingHalfEdges :: Vertex -> PlanarGraph -> [HalfEdge] -- vertexAdjacentVertices :: Vertex -> PlanarGraph -> [Vertex] -- vertexAdjacentFaces :: Vertex -> PlanarGraph -> [Face] halfEdgeNext :: HalfEdge -> PlanarGraph -> HalfEdge halfEdgeNext :: HalfEdge -> PlanarGraph -> HalfEdge halfEdgeNext = HalfEdge -> PlanarGraph -> HalfEdge forall a. HasCallStack => a undefined halfEdgeNextM :: MonadState PlanarGraph m => HalfEdge -> m HalfEdge halfEdgeNextM :: HalfEdge -> m HalfEdge halfEdgeNextM = (PlanarGraph -> HalfEdge) -> m HalfEdge forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a gets ((PlanarGraph -> HalfEdge) -> m HalfEdge) -> (HalfEdge -> PlanarGraph -> HalfEdge) -> HalfEdge -> m HalfEdge forall b c a. (b -> c) -> (a -> b) -> a -> c . HalfEdge -> PlanarGraph -> HalfEdge halfEdgeNext -- halfEdgeNext :: HalfEdge -> PlanarGraph -> HalfEdge -- halfEdgeVertex :: HalfEdge -> PlanarGraph -> Vertex -- halfEdgeTwin :: HalfEdge -> PlanarGraph -> HalfEdge -- halfEdgeTailVertex :: HalfEdge -> PlanarGraph -> Vertex -- halfEdgeTipVertex :: HalfEdge -> PlanarGraph -> Vertex -- halfEdgeFace :: HalfEdge -> PlanarGraph -> Face -- halfEdgeIsInterior -- faceHalfEdge :: Face -> PlanarGraph -> HalfEdge -- faceIsInterior -- faceIsBoundary -- faceAdjacentVertices :: -- faceAdjaventFaces :: Face -> PlanarGraph -> [Face] -- connectVertices :: HalfEdge -> HalfEdge -> PlanarGraph -> PlanarGraph -- splitHalfEdge :: HalfEdge -> PlanarGraph -> (PlanarGraph, Vertex) -- Use cases: -- Triangulate polygon. -- Create PlanarGraph from polygon. Holes have unique faces. -- Update with [LineSegment 2 Vertex r] -- Update Face ids at the end. -- Cut planar graph in two. -- Re-triangulate part of graph. -- Mesh smoothing. -- 1. Keep vertex positions separate. Can update without changing the graph. -- 2. Swap edges. HalfEdge+Twin. Find next of each. Delete original half-edges. -- Then insert half-edges to next.