import Graphics.Rendering.OpenGL import Graphics.UI.GLUT import Data.Complex import Data.Char import qualified Data.Map as Map import Data.List import Control.Applicative maxR :: GLfloat maxR = 4.0 maxCount :: GLint maxCount = 20 maxX :: GLfloat maxX = 2.0 maxY :: GLfloat maxY = 2.0 convergeSequence :: GLint -> [(Complex GLfloat)] -> (Complex GLfloat) -> (Complex GLfloat) -> GLint convergeSequence count zs z c |(magnitude z) >= maxR = count |count >= maxCount = count |otherwise = let newZ = (calcPolynominal zs z) + c in convergeSequence (count+1) zs newZ c type ColorConst = (GLint , GLint , GLint) colorD :: ColorConst -> GLint -> (Color3 GLfloat) colorD (x , y, z) ex = let ex1 = (ex * x) `mod` 1000 ex2 = (ex * y) `mod` 1000 ex3 = (ex * z) `mod` 1000 ex1f = (fromIntegral ex1) * 0.001 ex2f = (fromIntegral ex2) * 0.001 ex3f = (fromIntegral ex3) * 0.001 in (Color3 ex1f ex2f ex3f) complexPlane :: [(Complex GLfloat)] complexPlane = [x :+ y | x <- [(- maxX) , ((-maxX) + 0.004) .. (maxX)] , y <- [(- maxY) , ((-maxY) + 0.004).. (maxY)]] transComplexVertex :: (Complex GLfloat) -> Vertex2 GLfloat transComplexVertex z = let x = realPart z y = imagPart z in Vertex2 (x / maxX) (y / maxY) display :: ColorConst -> [(Complex GLfloat)] -> IO () display cC cs = do clearColor $= (Color4 0.4 0.5 0.5 1.0) clear [ColorBuffer] loadIdentity renderPrimitive Points $ do mapM_ (vertexAndColor cC cs) complexPlane flush swapBuffers vertexAndColor :: ColorConst -> [(Complex GLfloat)] -> (Complex GLfloat) -> IO () vertexAndColor cC cs z = let vt= transComplexVertex z in do color (colorD cC (convergeSequence 0 cs 0 z)) vertex vt keyboardMouse :: Key -> KeyState -> Modifiers -> Position -> IO() keyboardMouse key keystate modifier position = do if (keystate == Down) && (key == (Char 'c')) then actionOnWindowClose $=! Exit else return () main = do (progname,_) <- getArgsAndInitialize putStrLn "Input ColorConstant --- a,a,a :: GLint" cC <- getLine putStrLn "Input Coefficient List --- a,.. :: Complex GLfloat" polyC <- getLine initialDisplayMode $= [DoubleBuffered] createWindow "Mandelbrot" windowSize $= (Size 900 900) keyboardMouseCallback $= Just (keyboardMouse ) displayCallback $= display (listToTupple3 (map read (splitList ',' cC))) (map (read . compensateCompexNotation) (splitList ',' polyC)) mainLoop ------------------•â• splitList :: (Eq a) => a -> [a] -> [[a]] splitList c xs = case (elemIndex c xs) of Nothing -> [xs] Just i -> (take i xs) : (splitList c (drop (i + 1) xs)) ---------- listToTupple3 :: [a] -> (a , a , a) listToTupple3 (x:y:z:zs) = (x , y , z) listToTupple3 (x:y:zs) = (x , y , y) listToTupple3 (x:zs) = (x , x , x) -----‘½€Ž®ŒvŽZ calcPolynominal :: (Num a) => [a] -> a -> a calcPolynominal xs z = sum $ getZipList $ (*) <$> (ZipList [z^i | i <- [1..]]) <*> (ZipList xs) -----Complex‚Ì•\‹L‚ð•â³‚·‚é compensateCompexNotation :: String -> String compensateCompexNotation str = if ':' `elem` str then str else str ++ ":+ 0"