2

I created a working program displaying the Mandelbrot set, but the whole set is displayed after all is computed; I wonder which changes of the code I must do in order to have a points displayed as soon as it's known if it belongs to the set or not.

Here is my program; the beginning is not very important, it's more or less common to all programs using Gtk:

module Main where

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


main :: IO()
main = do
    _ <- initGUI

    window <- windowNew
    windowSetPosition window WinPosCenter
    windowSetDefaultSize window 500 350
    set window [windowTitle := "Ensemble de Mandelbrot"]
    on window objectDestroy mainQuit

    canvas <- drawingAreaNew
    canvas `on` sizeRequest $ return (Requisition 450 300)
    window `containerAdd` canvas

    _ <- onExpose canvas $ const (updateCanvas canvas)

    widgetShowAll window
    mainGUI


updateCanvas :: DrawingArea -> IO Bool
updateCanvas canvas = do
  win <- widgetGetDrawWindow canvas
  (width, height) <- widgetGetSize canvas
  _ <- mapM_ (affiche win)  (points (fromIntegral width) (fromIntegral height))

  return True

k :: Int
k=100 -- 100 : after launching, u must wait less than 10s

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 :: DrawWindow -> Double -> Double -> IO()
affiche2 win a b = renderWithDrawable win $ do
    setSourceRGB 0 0 0
    setLineWidth 1
    C.rectangle a b 1 1 
    stroke


affiche :: DrawWindow -> ((Double,Double), (Double,Double)) -> IO ()
affiche win ((a0,a), (b0,b)) = when (mandelbrot a b) $ postGUIAsync (affiche2 win a0 b0)

colonnes :: Double -> [(Double, Double)]
colonnes w = [ (t,t/w*4-2) | t<-[0..(w-1)] ]

lignes :: Double -> [(Double, Double)]
lignes h = [ (t,t/h*4-2) | t<-[0..(h-1)] ]

points :: Double -> Double -> [((Double, Double), (Double, Double))]
points w h = [ (colonne,ligne)| colonne <- colonnes w,ligne <- lignes h]
leftaroundabout
  • 117,950
  • 5
  • 174
  • 319
lolveley
  • 1,659
  • 2
  • 18
  • 34
  • 1
    Are you trying to draw the entire Mandelbrot in the `expose` event? If so, you are blocking the GTK+ main loop and not allowing other events to occur until after the Mandelbrot is finished. What you could do is calculate the points in another thread and send them back to the GUI thread via the `gdk_threads_add_idle()` function, which then calls `gtk_widget_queue_draw_area()` to request a re-expose of the given pixel. (How to store the pixel values for redraw is up to you.) I don't know how that's used from Haskell though, sorry. – andlabs Apr 03 '16 at 00:01
  • hello, unfortunately, it's not sufficient enough to allow me to finish my program. I'm not enough experimented in haskell to modify it, but I found something interesting at https://wiki.haskell.org/Gtk2Hs/Tutorials/ThreadedGUIs, if someone could show me how to modify that would be nice! – lolveley Apr 03 '16 at 10:21
  • @andlabs isn't the function you gave me a C function? I mean, I won't be able to insert it to my haskell code, no? please have a look at my new code, but if I well understood you, the problem comes from the "expose" call. Can you help me more? – lolveley Apr 04 '16 at 12:44
  • 1
    They are C functions, but those give you the hint as to what to look for. You will need to check your Haskell documentation to see what the equivalent is. I don't know Haskell; sorry. – andlabs Apr 04 '16 at 14:05
  • So, you you update _this_ to not need a ui file? And, try to avoid code duplication. – leftaroundabout Apr 04 '16 at 16:23
  • hello, nothing new? I tried to put onExpose as the first argument of mapM_, in order to get rid of the sessions which are created at each call to onExpose, but in this code nothing appears in the canvas... I am desperate. – lolveley Apr 05 '16 at 15:07

0 Answers0