{-# LANGUAGE RecordWildCards #-} module Reanimate.Math.DCEL where {- import Control.Applicative import Data.List.Split import Data.Vector (Vector) import qualified Data.Vector as V import Linear.Matrix import Linear.V2 import Linear.V3 import Text.Printf import Reanimate.Math.Common type EdgeIdx = Int type VertexIdx = Int type FaceIdx = Int data DCEL = DCEL { dcelFaces :: Vector EdgeIdx , dcelVertices :: Vector EdgeIdx , dcelEdges :: Vector Edge , dcelPoints :: Vector P } deriving (Show) data Edge = Edge { edgeVertex :: VertexIdx , edgeFace :: FaceIdx , edgeTwin :: EdgeIdx , edgeNext :: EdgeIdx , edgePrev :: EdgeIdx } deriving (Show) getPoint :: Int -> DCEL -> P getPoint i DCEL{..} = dcelPoints V.! (i `mod` V.length dcelPoints) dcelSize :: DCEL -> Int dcelSize DCEL{..} = V.length dcelPoints isValidDCEL :: DCEL -> Maybe String isValidDCEL DCEL{..} = foldr (<|>) empty $ [ V.all (< V.length dcelEdges) dcelFaces ~> "Bad face" , V.all (< V.length dcelEdges) dcelVertices ~> "Bad vertice" , V.all (< V.length dcelEdges) (V.map edgeNext dcelEdges) ~> "Bad next" , V.all (< V.length dcelEdges) (V.map edgePrev dcelEdges) ~> "Bad prev" , V.all (< V.length dcelEdges) (V.map edgeTwin dcelEdges) ~> "Bad twin" , V.all (< V.length dcelPoints) (V.map edgeVertex dcelEdges) ~> "Bad edge vertex" , V.all (< V.length dcelFaces) (V.map edgeFace dcelEdges) ~> "Bad edge face" , V.length dcelVertices == V.length dcelPoints ~> "Vertex/Point mismatch" ] where infix 0 ~> True ~> _ = Nothing False ~> msg = Just msg ppDCEL :: DCEL -> String ppDCEL DCEL{..} = unlines [ "Faces: Edge" , unlines [ printf "%3d: %3d" face edge | (face, edge) <- zip [0::Int .. ] (V.toList dcelFaces) ] , "Vertices: Edge" , unlines [ printf "%3d: %3d" vertex edge | (vertex, edge) <- zip [0::Int ..] (V.toList dcelVertices) ] , "Edges: Vertex Face Twin Next Prev" , unlines [ printf "%3d: %3d %3d %3d %3d %3d" edge edgeVertex edgeFace edgeTwin edgeNext edgePrev | (edge, Edge{..}) <- zip [0::Int ..] (V.toList dcelEdges) ] , "Points:" , unlines [ printf "%3d: " (idx*chunkSize) ++ unwords [ printf "<%.1f,%.1f>" x y | V2 x y <- chunk ] | (idx, chunk) <- zip [0::Int ..] (chunksOf chunkSize (V.toList dcelPoints)) ] ] where chunkSize = 5 emptyDCEL :: DCEL emptyDCEL = undefined {- faces: [0,1] -- 0 is outside, 1 is inside. vertices: [0..n-1] edges: i: vertex=i face=1 twin=i+n next=(i+1)%n prev=(i-1)%n i: j=i-n vertex=edge[j].prev.vertex face=0 twin=j next=(j-1)%n + i prev=(j+1)%n +i points: pts -} fromSimplePolygon :: [V2 Double] -> DCEL fromSimplePolygon [] = error "empty polygon" fromSimplePolygon pts | not (isCCW $ V.fromList pts) = error "Polygon not counter-clockwise" fromSimplePolygon pts = DCEL { dcelFaces = V.fromList [0,1] , dcelVertices = V.fromList [0..n-1] , dcelEdges = V.fromList $ [ Edge { edgeVertex = i , edgeFace = 1 , edgeTwin = i+n , edgeNext = (i+1) `mod` n , edgePrev = (i-1) `mod` n } | i <- [0..n-1] ] ++ [ Edge { edgeVertex = (i-1) `mod` n , edgeFace = 0 , edgeTwin = i , edgeNext = (i-1) `mod` n + i , edgePrev = (i-1) `mod` n + i } | i <- [0..n-1] ] , dcelPoints = V.fromList pts } where n = length pts -- addEdge :: VertexIdx -> VertexIdx -> DCEL -> DCEL -> -- addEdge a b dcel = -- add edge, vertex=a, face=a -- add twin -}