首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >haskell & Gtk2hs :画布中没有显示任何点(并行绘图)

haskell & Gtk2hs :画布中没有显示任何点(并行绘图)
EN

Stack Overflow用户
提问于 2016-04-04 12:16:18
回答 1查看 78关注 0票数 0

我编写了一个小程序,它必须使用Gtk2Hs在haskell中显示mandelbrot集。

虽然没有编译错误,但画布中没有显示任何内容(点被着色的组件).

你能帮我调试这个逻辑错误吗?

我的代码:

代码语言:javascript
复制
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
    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
  _ <- mapM_ (affiche win)  (points (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 :: DrawWindow -> Double -> Double -> IO()
affiche2 win a b = do
  renderWithDrawable win $ setSourceRGB 0 1 0
  renderWithDrawable win $ setLineWidth 1
  renderWithDrawable win $ C.rectangle a b 1 1 
  renderWithDrawable win 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]

main()没什么意思,我敢肯定,它很管用。update_canvas获取一些值(宽度、高度、win),并调用副作用函数affiche,提供在“点”中的值(点包含好的值,即两个轴的-2..2之间的点的坐标)。曼德尔布罗特很好,因为我成功地画出了曼德尔布洛特集(但所有的点都画在一起了)。我认为如果有问题,它可能来自于affiche或affiche2,但我对Gtk编程还不熟悉。

谢谢。

编辑

好吧,它适用于你的零钱,但为什么?我还有另外一个问题:如果我把参数k提高到1000,在启动程序后17秒钟就会显示这个集合,并且显示得非常快;但这不是我想要的:我希望在计算出这些点之后立即绘制它们。你知道我必须做什么改变吗?

编辑2

下面是一个工作的代码:它在<10s中显示图像--不使用任何UI或GLADE文件--在计算完之后,绘制点

代码语言:javascript
复制
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]

奥利维尔

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-04-04 12:19:46

虽然我还没有使用过Gtk2Hs,但我想问题在affiche2中。尝试将其更改为:

代码语言:javascript
复制
affiche2 win a b = do
  renderWithDrawable win $ do
    setSourceRGB 0 1 0
    setLineWidth 1
    C.rectangle a b 1 1 
    stroke
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36402378

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档