twentefp-0.4: examples/RBgraphics.hs
module RBgraphics where
-- Grafische weergave van rood-zwart bomen. Werkt alleen voor *binaire* bomen.
--
-- Jan Kuper, 5 mei 2008
-- ============================================================================
import FPPrac.Graphics
import Prelude
data RbTreeG = RBnode Color String [RbTreeG]
deriving Eq
---------------schalingsfactoren----------------------------------------------
letterheight = 2
nodewidth = 30
hfactor = 1
---------------aspecten ve boom berekenen-------------------------------------
verticalstep (RBnode _ "" _) = 25
verticalstep (RBnode _ _ _ ) = 30
nodespace (RBnode _ "" _) = nodewidth / 4
nodespace (RBnode _ _ _ ) = nodewidth+1
ycrd m y t | colour t == red && m = y
| otherwise = y - verticalstep t
leftTree (RBnode _ _ [t0,_]) = t0
rightTree (RBnode _ _ [_,t1]) = t1
subtrees (RBnode _ _ ts) = ts
colour (RBnode c _ _ ) = c
treeheight _ (RBnode _ _ []) = 0
treeheight m (RBnode _ _ ts) | not m = 1 + maximum (map (treeheight m) ts)
| otherwise = maximum [ if (colour t == red) then
(treeheight m t) else
(1 + treeheight m t)
| t <- ts
]
treewidth :: RbTreeG -> Float
treewidth (RBnode c a ts) = sum (map treewidth ts) + nodespace (RBnode c a ts)
xPosleft x t | subtrees t /= [] = x - treewidth (rightTree t) - nodespace t
| otherwise = x - nodespace t
xPosright x t | subtrees t /= [] = x + treewidth (leftTree t) + nodespace t
| otherwise = x + nodespace t
---------------graphics-------------------------------------------------------
drawnode :: Color -> (Float,Float) -> String -> Picture
drawnode c (x,y) a | a /= "" = Pictures
[ Translate xcentre y $ Color c $ circleSolid rbig
, Translate xlabel (y-h) $ Scale 0.1 0.1 $ Color (if (c == black) then white else black) $ Text a
]
| otherwise = Translate xcentre y $ Color c $ circleSolid rsmall
where
xcentre = hfactor * x
xlabel = hfactor * (x - 3 * (fromIntegral $ length a))
rbig = hfactor*nodewidth/2
rsmall = hfactor*nodewidth/5
h = letterheight/1.5
drawrootedge (x,y) = Color black $ Line [(hfactor*x,y), (hfactor*x,y+hfactor*nodewidth)]
drawedge :: (Float,Float) -> (Float,Float) -> Picture
drawedge (x,y) (x1,y1) = Color red $ Line [(hfactor*x,y), (hfactor*x1,y1)]
drawbridge :: (Float,Float) -> (Float,Float) -> Picture
drawbridge (x,y) (x1,y1) = Color red $ Line (map (\(x,y)->(hfactor*x,y)) [(x,y), (x+d, yh), (x1-d,yh), (x1,y1)])
where
d = (x1-x)/3
yh = y+hfactor*nodewidth/1.5
drawTree :: Bool -> ((Float,Float) , RbTreeG) -> Picture
drawTree m ((x,y), (RBnode c a [ ] )) = drawnode c (x,y) a
drawTree m ((x,y), (RBnode c a [tl,tr]))
= Pictures $
[ drawGenEdgeL (x,y) (xleft , yleft )
, drawGenEdgeR (x,y) (xright, yright)
, drawTree m ((xleft ,yleft ) , tl)
, drawTree m ((xright,yright) , tr)
, drawnode c (x,y) a
]
where
xleft = xPosleft x tl
xright = xPosright x tr
yleft = ycrd m y tl
yright = ycrd m y tr
drawGenEdgeL | m &&
colour tl == red &&
subtrees tl /= [] &&
colour (rightTree tl) == red = drawbridge
| otherwise = drawedge
drawGenEdgeR | m
&& colour tr == red
&& subtrees tr /= []
&& colour (leftTree tr) == red = drawbridge
| otherwise = drawedge
drawTrees :: Bool -> Float -> [RbTreeG] -> Picture
drawTrees m y0 [] = Blank
drawTrees m y0 (t:ts) = Pictures
[ drawrootedge (x0,y0)
, drawTree m ((x0,y0), t)
, drawTrees m (y0 - (treeheight m t + 1) * verticalstep t) ts
]
where
x0 = xcoordMainRoot t
drawTreesTxts :: Bool -> Float -> [String] -> [RbTreeG] -> Picture
drawTreesTxts m y0 [] [] = Blank
drawTreesTxts m y0 (str:strs) (t:ts) = Pictures
[ drawrootedge (x0,y0)
, drawTree m ((x0,y0), t)
, Translate (-150) y0 $ Scale 0.1 0.1 $ Color black $ Text str
, drawTreesTxts m (y0 - (treeheight m t + 1) * verticalstep t) strs ts
]
where
x0 = xcoordMainRoot t
xcoordMainRoot (RBnode c a [tl,tr]) = (treewidth tl - treewidth tr)/2
xcoordMainRoot t = 0