{-# LANGUAGE ScopedTypeVariables #-} module Main where import Data.QuadTree import Math.Geometry import Render ( init_display , new_viewer , view_rendering ) import Control.Monad import Data.Maybe ( maybe ) import Graphics.Rendering.OpenGL as GL import Graphics.UI.GLUT import System.Random.Mersenne import System.Random.Utils q :: QuadTree Boundary = empty e0 = Boundary (1.0, 1.0) 2.0 e1 = Boundary (0.0, 0.0) 0.5 main = do (viewer, _) <- new_viewer let q' = insert e0 q let q'' = insert e1 q' gen <- newMTGen Nothing (rq, gen) <- random_quadtree gen q 2000 view_quadtree viewer gen rq return () random_quadtree gen q 0 = return (q, gen) random_quadtree gen q n = do x :: Double <- randomRange (-10.0) 10.0 gen y :: Double <- randomRange (-10.0) 10.0 gen s :: Double <- randomRange 0.001 1.0 gen let e = Boundary (x, y) s let q' = insert e q random_quadtree gen q' (n - 1) view_quadtree viewer gen q = do view_rendering viewer $ display_quadtree gen q mainLoop display_quadtree gen q@(QuadTree _ (Boundary (bx, by) bsize) _) = do clearColor $= Color4 1.0 1.0 1.0 0.0 clear [ColorBuffer] matrixMode $= Modelview 0 loadIdentity -- First set the display to have the extents (0,0) and (1,1) translate $ Vector3 (-1.0 :: Double) (-1.0) 0.0 scale (2.0 :: Double) 2.0 0.0 -- Scale the entire quadtree to the display. scale (1.0 / bsize) (1.0 / bsize) 1.0 translate $ Vector3 (-bx) (-by) 0.0 mondrian_quadtree gen q lineWidth $= 2.0 maybe_outline_quadtree gen q flush outline_quadtree q = do color $ Color3 (0.0 :: Float) 0.0 0.0 polygonMode $= (Line, Line) renderPrimitive Quads $ outline_quadtree' q where outline_quadtree' (QuadTree _ b (cq0, cq1, cq2, cq3)) = do mapM_ (maybe (return ()) $ \cq -> outline_quadtree' cq) [cq0, cq1, cq2, cq3] render_boundary b maybe_outline_quadtree gen q = do color $ Color3 (0.0 :: Float) 0.0 0.0 polygonMode $= (Line, Line) renderPrimitive Lines $ outline_quadtree' q where outline_quadtree' (QuadTree _ b (cq0, cq1, cq2, cq3)) = do mapM_ (maybe (return ()) $ \cq -> outline_quadtree' cq) [cq0, cq1, cq2, cq3] mapM_ maybe_render_edge (boundary_edges b) maybe_render_edge ((x0,y0), (x1,y1)) = do p <- flip randomElement gen $ True : replicate 6 False if p then vertex (Vertex2 x0 y0) >> vertex (Vertex2 x1 y1) else return () outline_elements q = do color $ Color3 (1.0 :: Float) 0.0 0.0 polygonMode $= (Line, Line) renderPrimitive Quads $ outline_elements' q where outline_elements' (QuadTree bs _ (cq0, cq1, cq2, cq3)) = do mapM_ (maybe (return ()) $ \cq -> outline_elements' cq) [cq0, cq1, cq2, cq3] mapM_ render_boundary bs mondrian_quadtree gen q = do polygonMode $= (Fill, Line) renderPrimitive Quads $ mondrian_quadtree' gen q where mondrian_quadtree' gen (QuadTree bs bounds (cq0, cq1, cq2, cq3)) = do p <- flip randomElement gen $ True : replicate 2 False r :: Double <- randomRange 0.0 1.0 gen g :: Double <- randomRange 0.0 1.0 gen b :: Double <- randomRange 0.0 1.0 gen if p then color $ Color3 r g b else color $ Color3 (1.0 :: Double) 1.0 1.0 render_boundary bounds mapM_ (maybe (return ()) $ \cq -> mondrian_quadtree' gen cq) [cq0, cq1, cq2, cq3] random_color_gen gen = sequence $ repeat $ do r :: Double <- randomRange 0.0 1.0 gen g :: Double <- randomRange 0.0 1.0 gen b :: Double <- randomRange 0.0 1.0 gen return $ Color3 r g b render_boundary (Boundary (x,y) size) = do vertex $ Vertex2 x y vertex $ Vertex2 (x + size) y vertex $ Vertex2 (x + size) (y + size) vertex $ Vertex2 x (y + size)