Skip to content

Instantly share code, notes, and snippets.

@mmitou
Created December 25, 2012 10:53
Show Gist options
  • Select an option

  • Save mmitou/4372629 to your computer and use it in GitHub Desktop.

Select an option

Save mmitou/4372629 to your computer and use it in GitHub Desktop.
HaskellとOpenGLでマンデルブロ集合
import Data.Complex
import Graphics.Gnuplot.Simple (linearScale)
import Control.Monad (forM_)
import Data.Maybe (isJust)
import qualified Graphics.Rendering.OpenGL as GL
import qualified Graphics.UI.GLUT as GLUT
import Data.IORef
f :: Complex Double -> Complex Double -> Complex Double
f c z = z * z + c
findIndexWithLimitIndex :: (a -> Bool) -> Int -> [a] -> Maybe Int
findIndexWithLimitIndex f limit xs = findIndex' (map f xs) 0
where
findIndex' [] n = Just n
findIndex' (y:ys) n | n == limit = Nothing
| otherwise = if y == True
then Just n
else findIndex' ys (n + 1)
isDivergent :: Complex Double -> Bool
isDivergent c = (magnitude z) > 2.0
where
zs = iterate (f c) 0
z = zs !! 50
allPoints = filter (\(_, _, i) -> isJust i)
[(0.5 * x, 0.5 * y, findIndexWithLimitIndex (\z -> (magnitude z) > 2.0) 64 $ iterate (f (x :+ y)) 0)
| x <- linearScale 2000 (-2,2)
, y <- linearScale 2000 (-2,2)]
drawMandelbrot = GL.renderPrimitive GL.Points $ mapM_ drawColoredPoints allPoints
where
drawColoredPoints (x, y, Just i) = do
GL.color $ GL.Color3 (fromIntegral i / fromIntegral 64) (0.0 :: GL.GLfloat) 0.0
GL.vertex $ GL.Vertex3 x y 0
display = do
GL.clear [GL.ColorBuffer] -- make the window black
GL.loadIdentity -- reset any transformation
GL.preservingMatrix drawMandelbrot
GLUT.swapBuffers -- refresh screen
main = do
-- GLUT need to be initialized
(progname,_) <- GLUT.getArgsAndInitialize
-- We will use the double buffered mode (GL constraint)
GLUT.initialDisplayMode GL.$= [GLUT.DoubleBuffered]
-- We create a window with some title
GLUT.createWindow "Mandelbrot Set with Haskell and OpenGL"
-- Each time we will need to update the display
-- we will call the function 'display'
GLUT.displayCallback GL.$= display
-- We enter the main loop
GLUT.mainLoop
@romanenko

Copy link
Copy Markdown

I have an error when compiling:

[1 of 1] Compiling Main             ( Main.hs, dist/build/opengl-demo/opengl-demo-tmp/Main.o )

Main.hs:32:55:
    No instance for (GLUT.VertexComponent Double)
      arising from a use of ‘drawColoredPoints’
    In the first argument of ‘mapM_’, namely ‘drawColoredPoints’
    In the second argument of ‘($)’, namely
      ‘mapM_ drawColoredPoints allPoints’
    In the expression:
      GLUT.renderPrimitive GLUT.Points
      $ mapM_ drawColoredPoints allPoints

I'm pretty new to Haskell and I can't figure out what's wrong. Do you have any ideas?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment