module Math ( mandlebrot ) where import Graphics.UI.GLUT import Data.Complex iterations = 10 x // y = fromIntegral x / fromIntegral y -- Divides [a] into [[a], [a], ...] with each sublist of length n, -- except the last sublist which has length <= n chunkify n [] = [] chunkify n xs = let (xs', rest) = splitAt n xs in xs' : chunkify n rest -- Converts a coordinate in screen space to a vertex. pix2vert (Size w h) (x, y) = Vertex2 ((3 // w * fromIntegral x) - 2.0) ((2 // h * fromIntegral y) - 1.0) -- List of all the vertices that represent screen pixels. vertices :: IO [Vertex2 GLfloat] vertices = get windowSize >>= \(Size w h) -> return $ [pix2vert (Size w h) (x, y) | x <- [0..w-1], y <- [0..h-1]] -- Gets the color for a number of iterations. getcolor :: Int -> Color3 Float getcolor iter | iter == iterations = Color3 0 0 0 | otherwise = Color3 (amt * 0.5) amt (amt * 0.5) where amt = iter // iterations -- Returns the number of iterations <= the maximum iterations of the Mandlebrot set at the given vertex mandel (Vertex2 r i) = length . takeWhile (\z -> magnitude z <= 2) . take iterations $ iterate (\z -> z^2 + (r :+ i)) 0 -- plots one point. drawVert v = do color . getcolor $ mandel v vertex v -- draws all th vertices in slices (to update the display while drawing). display' chunks = do mapM_ (\vs -> do renderPrimitive Points $ mapM_ drawVert vs flush) chunks displayCallback $= display display = do clear [ ColorBuffer ] displayCallback $= (vertices >>= display' . chunkify 256) get currentWindow >>= postRedisplay mandlebrot = do getArgsAndInitialize initialDisplayMode $= [ SingleBuffered, RGBMode ] --initialWindowSize $= Size 1200 1024 --initialWindowPosition $= Position 100 100 createWindow "Mandlebrot" clearColor $= Color4 0 0 0 0 matrixMode $= Projection loadIdentity --ortho (-3) 1 (-1) 1 (-1) 1 --ortho (-2) 1 (-1) 1 (-1) 1 ortho (-3) 1 (-1) 1 (-1) 1 displayCallback $= display mainLoop