--
import Draw import Region import SOEGraphics hiding (Region) import qualified SOEGraphics as G (Region) data Picture = Region Color Region | Picture `Over` Picture | EmptyPic deriving Show -- The Color type is imported from SOEGraphics -- and Exported from Picture -- data Color = Black | Blue | Green | Cyan -- | Red | Magenta | Yellow | White ------ Changes here -------- drawRegionInWindow::Window -> Color -> Region -> IO () drawRegionInWindow w c r = drawInWindow w (withColor c (drawRegion (regionToGRegion r))) ----------- End Changes ------------------ drawPic :: Window -> Picture -> IO () drawPic w (Region c r) = drawRegionInWindow w c r drawPic w (p1 `Over` p2) = do { drawPic w p2 ; drawPic w p1 } drawPic w EmptyPic = return () -- First a little side trip data NewRegion = Rect Side Side -- Abstracts G.Region regToNReg1 :: Region -> NewRegion regToNReg1 (Shape (Rectangle sx sy)) = Rect sx sy regToNReg1 (Scale (x,y) r) = regToNReg1 (scaleReg (x,y) r) where scaleReg (x,y) (Shape (Rectangle sx sy)) = Shape (Rectangle (x*sx) (y*sy)) scaleReg (x,y) (Scale s r) = Scale s (scaleReg (x,y) r) reverse1 [] = [] reverse1 (x:xs) = (reverse1 xs) ++ [x] where [] ++ zs = zs (y:ys) ++ zs = y : (ys ++ zs) reverse2 xs = revhelp xs [] where revhelp [] zs = zs revhelp (x:xs) zs = revhelp xs (x:zs) regToNReg2 :: Region -> NewRegion regToNReg2 r = rToNR (1,1) r where rToNR :: (Float,Float) -> Region -> NewRegion rToNR (x1,y1) (Shape (Rectangle sx sy)) = Rect (x1*sx) (y1*sy) rToNR (x1,y1) (Scale (x2,y2) r) = rToNR (x1*x2,y1*y2) r --- Return from side trip regToGReg1 :: Vector -> Vector -> Region -> G.Region regToGReg1 trans sca (Shape s) = shapeToGRegion trans sca s regToGReg1 (x,y) sca (Translate (u,v) r) = regToGReg1 (x+u, y+v) sca r regToGReg1 trans (x,y) (Scale (u,v) r) = regToGReg1 trans (x*u, y*v) r regToGReg1 trans sca Empty = createRectangle (0,0) (0,0) regToGReg1 trans sca (r1 `Union` r2) = let gr1 = regToGReg1 trans sca r1 gr2 = regToGReg1 trans sca r2 in orRegion gr1 gr2 ---------- Changes here ------------ primGReg trans sca r1 r2 op = let gr1 = regToGReg trans sca r1 gr2 = regToGReg trans sca r2 in op gr1 gr2 regToGReg :: Vector -> Vector -> Region -> G.Region regToGReg (trans @ (x,y)) (sca @ (a,b)) shape = case shape of (Shape s) -> shapeToGRegion trans sca s (Translate (u,v) r) -> regToGReg (x+u, y+v) sca r (Scale (u,v) r) -> regToGReg trans (a*u, b*v) r (Empty) -> createRectangle (0,0) (0,0) (r1 `Union` r2) -> primGReg trans sca r1 r2 orRegion (r1 `Intersect` r2) -> primGReg trans sca r1 r2 andRegion (Complement r) -> primGReg trans sca winRect r diffRegion where winRect :: Region winRect = Shape (Rectangle (pixelToInch xWin) (pixelToInch yWin)) regionToGRegion :: Region -> G.Region regionToGRegion r = regToGReg (0,0) (1,1) r ----------- End Changes ----------------- xWin2 = xWin `div` 2 yWin2 = yWin `div` 2 shapeToGRegion1 :: Vector -> Vector -> Shape -> G.Region shapeToGRegion1 (lx,ly) (sx,sy) (Rectangle s1 s2) = createRectangle (trans(-s1/2,-s2/2)) (trans (s1/2,s2/2)) where trans (x,y) = ( xWin2 + inchToPixel ((x+lx)*sx), yWin2 - inchToPixel ((y+ly)*sy) ) shapeToGRegion1 (lx,ly) (sx,sy) (Ellipse r1 r2) = createEllipse (trans (-r1,-r2)) (trans ( r1, r2)) where trans (x,y) = ( xWin2 + inchToPixel ((x+lx)*sx), yWin2 - inchToPixel ((y+ly)*sy) ) shapeToGRegion1 (lx,ly) (sx,sy) (Polygon pts) = createPolygon (map trans pts) where trans (x,y) = ( xWin2 + inchToPixel ((x+lx)*sx), yWin2 - inchToPixel ((y+ly)*sy) ) shapeToGRegion1 (lx,ly) (sx,sy) (RtTriangle s1 s2) = createPolygon (map trans [(0,0),(s1,0),(0,s2)]) where trans (x,y) = ( xWin2 + inchToPixel ((x+lx)*sx), yWin2 - inchToPixel ((y+ly)*sy) ) shapeToGRegion (lx,ly) (sx,sy) s = case s of Rectangle s1 s2 -> createRectangle (trans (-s1/2,-s2/2)) (trans (s1/2,s2/2)) Ellipse r1 r2 -> createEllipse (trans (-r1,-r2)) (trans ( r1, r2)) Polygon pts -> createPolygon (map trans pts) RtTriangle s1 s2 -> createPolygon (map trans [(0,0), (s1,0), (0,s2)]) where trans (x,y) = ( xWin2 + inchToPixel ((x+lx)*sx), yWin2 - inchToPixel ((y+ly)*sy) ) -- IMPORTANT that the WHERE be indented less than the patterns -- of the case. Because it then attaches to the last clause of -- the case rather than the defining equation. Since the Draw -- defines a trans function (with the right type) but the wrong -- functionality, the other clauses of the case appear well defined -- but do very strange things. draw :: Picture -> IO () draw p = runGraphics ( do w <- openWindow "Region Test" (xWin,yWin) drawPic w p spaceClose w ) r1 = Shape (Rectangle 3 2) r2 = Shape (Ellipse 1 1.5) r3 = Shape (RtTriangle 3 2) r4 = Shape (Polygon [(-2.5,2.5), (-3.0,0), (-1.7,-1.0), (-1.1,0.2), (-1.5,2.0)] ) reg1 = r3 `Union` --RtTriangle r1 `Intersect` -- Rectangle Complement r2 `Union` -- Ellispe r4 -- Polygon pic1 = Region Cyan reg1 main1 = draw pic1 reg2 = let circle = Shape (Ellipse 0.5 0.5) square = Shape (Rectangle 1 1) in (Scale (2,2) circle) `Union` (Translate (2,1) square) `Union` (Translate (-2,0) square) pic2 = Region Yellow reg2 main2 = draw pic2 pic3 = pic2 `Over` pic1 main3 = draw pic3 oneCircle = Shape (Ellipse 1 1) manyCircles = [ Translate (x,0) oneCircle | x <- [0,2..] ] fiveCircles = foldr Union Empty (take 5 manyCircles) pic4 = Region Magenta (Scale (0.25,0.25) fiveCircles) main4 = draw pic4 x0 = Region Magenta oneCircle x1 = Region Magenta (Scale (0.25,0.25) oneCircle) ---- Ordering Pictures pictToList :: Picture -> [(Color,Region)] pictToList EmptyPic = [] pictToList (Region c r) = [(c,r)] pictToList (p1 `Over` p2) = pictToList p1 ++ pictToList p2 pic6 = pic4 `Over` pic2 `Over` pic1 `Over` pic3 zz = pictToList pic6 -- [(Magenta,?), (yellow,?),(Cyan,?),(Cyan,?)] adjust :: [(Color,Region)] -> Vertex -> (Maybe (Color,Region), [(Color,Region)]) adjust [] p = (Nothing, []) adjust ((c,r):regs) p = if r `containsR` p then (Just (c,r), regs) else let (hit, rs) = adjust regs p in (hit, (c,r) : rs) adjust2 regs p = case (break (\(_,r) -> r `containsR` p) regs) of (top,hit:rest) -> (Just hit, top++rest) (_,[]) -> (Nothing, []) loop :: Window -> [(Color,Region)] -> IO () loop w regs = do clearWindow w sequence [ drawRegionInWindow w c r | (c,r) <- reverse regs ] (x,y) <- getLBP w print "Before adjust\n" case (adjust2 regs (pixelToInch (x - xWin2), pixelToInch (yWin2 - y) )) of (Nothing, _ ) -> do { print "Nothing"; closeWindow w } (Just hit, newRegs) -> do { print "after adjust" ; loop w (hit : newRegs) } draw2 :: Picture -> IO () draw2 pic = runGraphics ( do w <- openWindow "Picture demo" (xWin,yWin) loop w (pictToList pic)) p1,p2,p3,p4 :: Picture p1 = Region Magenta r1 p2 = Region Cyan r2 p3 = Region Green r3 p4 = Region Yellow r4 pic :: Picture pic = foldl Over EmptyPic [p1,p2,p3,p4] main5 = draw2 pic loop2 w regs = do clearWindow w sequence [ drawRegionInWindow w c r | (c,r) <- reverse regs ] (x,y) <- getLBP w let aux (_,r) = r `containsR` ( pixelToInch (x-xWin2), pixelToInch (yWin2-y) ) case (break aux regs) of (_,[]) -> closeWindow w (top,hit:bot) -> loop w (hit : (top++bot)) draw3 :: Picture -> IO () draw3 pic = runGraphics ( do w <- openWindow "Picture demo" (xWin,yWin) loop2 w (pictToList pic) ) main6 = draw3 pic --