module Data.QuadEdge.Base where
import Prelude hiding (flip)
type Index = Int
data Edge a = Edge { edgeTable :: EdgeTable,
attributes :: a } deriving (Eq, Show, Read)
type EdgeRef = (Index, Direction, Orientation)
type EdgeTable = (EdgeRef, EdgeRef, EdgeRef, EdgeRef)
data Direction = Rot0 | Rot1 | Rot2 | Rot3 deriving (Eq, Ord, Enum, Show, Read)
data Orientation = Normal | Flipped deriving (Eq, Ord, Enum, Show, Read)
incrDir, decrDir :: Direction -> Direction
incrDir x = case x of { Rot0 -> Rot1; Rot1 -> Rot2;
Rot2 -> Rot3; Rot3 -> Rot0 }
decrDir x = case x of { Rot0 -> Rot3; Rot1 -> Rot0;
Rot2 -> Rot1; Rot3 -> Rot2 }
edgesET :: EdgeTable -> [EdgeRef]
edgesET (a,b,c,d) = [a,b,c,d]
emptyET :: Index -> EdgeTable
emptyET i = (mk Rot0, mk Rot3, mk Rot2, mk Rot1)
where mk r = (i, r, Normal)
lookupET :: Direction -> EdgeTable -> EdgeRef
lookupET Rot0 (x,_,_,_) = x
lookupET Rot1 (_,x,_,_) = x
lookupET Rot2 (_,_,x,_) = x
lookupET Rot3 (_,_,_,x) = x
updateET :: EdgeTable -> Direction -> EdgeRef -> EdgeTable
updateET (_,b,c,d) Rot0 v = (v,b,c,d)
updateET (a,_,c,d) Rot1 v = (a,v,c,d)
updateET (a,b,_,d) Rot2 v = (a,b,v,d)
updateET (a,b,c,_) Rot3 v = (a,b,c,v)
isPrimal, isDual :: EdgeRef -> Bool
isPrimal (_, r, _) = r == Rot0 || r == Rot2
isDual (_, r, _) = r == Rot1 || r == Rot3
isFlipped :: EdgeRef -> Bool
isFlipped (_, _, f) = f == Flipped
rot, sym, rotInv, flip :: EdgeRef -> EdgeRef
rot (e, r, Normal) = (e, incrDir r, Normal)
rot (e, r, Flipped) = (e, decrDir r, Flipped)
rotInv (i, r, Normal) = (i, decrDir r, Normal)
rotInv (i, r, Flipped) = (i, incrDir r, Flipped)
sym = rot . rot
flip (e, r, Normal) = (e, r, Flipped)
flip (e, r, Flipped) = (e, r, Normal)