2016-04-02 21 views
0

我創建了一個程序,其目的是繪製一個分形集(manderbrot集合),它不包含任何語法錯誤,但只有一個像素出現,而不是集合。在haskell中設置mandelbrot的邏輯錯誤

這裏是我的程序:

module Main where 

import Graphics.UI.Gtk 
import Graphics.UI.Gtk.Builder() 
import Graphics.Rendering.Cairo as C 
import Control.Monad (when) 


main :: IO() 
main = do 
    _ <- initGUI 
    builder <- builderNew 
    builderAddFromFile builder "09-mandelbrot.ui" 

    window <- builderGetObject builder castToWindow "Figure de Mandelbrot" 
    canvas <- builderGetObject builder castToDrawingArea "drawingarea1" 
    _ <- onExpose canvas $ const (updateCanvas canvas) 

    widgetShowAll window 
    mainGUI 


updateCanvas :: DrawingArea -> IO Bool 
updateCanvas canvas = do 
    win <- widgetGetDrawWindow canvas 
    (width, height) <- widgetGetSize canvas 
    renderWithDrawable win $ example (fromIntegral width) (fromIntegral height) 
    return True 

k=100 

mandelbrot :: Double -> Double -> Bool 
mandelbrot a b = 
    let 
    mandelrec :: Double -> Double -> Int -> Bool 
    mandelrec x y i 
     | (x * x + y * y > 4) = False 
     | (i==k) && (x * x + y * y <= 4) = True 
     | otherwise = mandelrec x' y' (i+1) 
      where x' = x * x - y * y + a 
        y' = 2 * x * y + b 
    in mandelrec 0 0 0 

affiche :: (Double, Double) -> Render() 
affiche (a, b) = when (mandelbrot a b) $ C.rectangle a b 1 1 

colonnes w = [ t/w*4-2 | t<-[0..(w-1)] ] 
lignes h = [ t/h*4-2 | t<-[0..(h-1)] ] 


example :: Double -> Double -> C.Render() 
example width height = do 
    setSourceRGB 0 0 0 
    setLineWidth 1 

    mapM_ affiche (zip (colonnes width) (lignes height)) 
    stroke 

如果需要的話我可以給你解釋。 我已經測試了函數lignes & colonnes,看起來沒問題。

回答

1

好吧,它現在有效。

我沒有收集範圍[-2..2] [ - 2..2]中的所有點,但只收集了放置在對角線上的所有點。

這裏是一個有效的代碼:

module Main where 

import Graphics.UI.Gtk 
import Graphics.UI.Gtk.Builder() 
import Graphics.Rendering.Cairo as C 
import Control.Monad (when) 


main :: IO() 
main = do 
    _ <- initGUI 
    builder <- builderNew 
    builderAddFromFile builder "09-mandelbrot.ui" 

    window <- builderGetObject builder castToWindow "Figure de Mandelbrot" 
    canvas <- builderGetObject builder castToDrawingArea "drawingarea1" 
    _ <- onExpose canvas $ const (updateCanvas canvas) 

    widgetShowAll window 
    mainGUI 


updateCanvas :: DrawingArea -> IO Bool 
updateCanvas canvas = do 
    win <- widgetGetDrawWindow canvas 
    (width, height) <- widgetGetSize canvas 
    renderWithDrawable win $ example (fromIntegral width) (fromIntegral height) 
    return True 

k :: Int 
k=100 

mandelbrot :: Double -> Double -> Bool 
mandelbrot a b = 
    let 
    mandelrec :: Double -> Double -> Int -> Bool 
    mandelrec x y i 
     | (x * x + y * y > 4) = False 
     | (i==k) && (x * x + y * y <= 4) = True 
     | otherwise = mandelrec x' y' (i+1) 
      where x' = x * x - y * y + a 
        y' = 2 * x * y + b 
    in mandelrec 0 0 0 

affiche2 :: Double -> Double -> Render() 
affiche2 a b = do 
    C.rectangle a b 1 1 
    stroke 

affiche :: ((Double,Double), (Double,Double)) -> Render() 
affiche ((a0,a), (b0,b)) = when (mandelbrot a b) $ affiche2 a0 b0 

colonnes w = [ (t,t/w*4-2) | t<-[0..(w-1)] ] 
lignes h = [ (t,t/h*4-2) | t<-[0..(h-1)] ] 
points w h = [ (colonne,ligne)| colonne <- colonnes w,ligne <- lignes h] 

example :: Double -> Double -> C.Render() 
example width height = do 
    setSourceRGB 0 0 0 
    setLineWidth 1 

    mapM_ affiche (points width height) 
    stroke