reanimate-0.3.2.0: src/Reanimate/Math/DCEL.hs
{-# 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
-}