代码之家  ›  专栏  ›  技术社区  ›  Antal Spector-Zabusky

Haskell的图像绘图库?

  •  22
  • Antal Spector-Zabusky  · 技术社区  · 14 年前

    我正在开发一个用于玩空间游戏的haskell程序:我有一张图,上面是一群“个人”在玩囚徒困境,但只和他们的近邻一起玩,并模仿那些做得最好的人的策略。

    我已经到了需要描绘世界形象的地步,而这正是我遇到问题的地方。两种可能的几何图形很简单:如果每个人有四个或八个邻居,那么我将每个邻居表示为一个填充的正方形(颜色与策略对应),并用这些来平铺平面。但是,我也有一种情况,人们有六个邻居(六边形)或三个邻居(三角形)。

    那么,我的问题是: 有什么好的haskell库可以在上面创建图像和绘制形状? 我更希望它能制造PNG,但我不是特别挑剔。我最初使用 Graphics.GD ,但它只将绑定导出到用于绘制点、线、弧、椭圆和非旋转矩形的函数,这对于我的目的来说是不够的(除非我想逐像素绘制六边形*)。我想用 foreign import ,但这证明有点麻烦(部分原因是polygon drawing函数需要一个数组 gdPoint 考虑到我的需求可能会增长,最好使用in-haskell解决方案,而不必在ffi上浪费时间(尽管如果遇到困难,我愿意这么做)。有什么建议吗?

    *那 实际上,这也是一个选择;任何关于如何做到这一点的建议也会很受欢迎,尽管我认为图书馆会更容易。

    编辑: 非常感谢你们的建议。不幸的是,我无法获得所有gtk2h所需的库来构建,这排除了很多解决方案。由于种种原因,在我尝试了你所有的答案,未能安装一些库,并发现其他人不能做我想做的事,我最终决定只是出口更多的外国金融机构的libgd和使用。

    5 回复  |  直到 14 年前
        1
  •  11
  •   ja.    14 年前

    图表看起来很酷,但是如果您想避免提交并保持超轻量,可以直接生成svg。从康拉德·巴斯基那里偷东西 http://www.lisperati.com/haskell/

    type Point     = (Float,Float)
    type Color     = (Int,Int,Int)
    type Polygon   = [Point]
    
    writePoint :: Point -> String 
    writePoint (x,y) = (show x)++","++(show y)++" "
    
    writePolygon :: (Color,Polygon) -> String 
    writePolygon ((r,g,b),p) = "<polygon points=\""++(concatMap writePoint p)++"\" style=\"fill:#cccccc;stroke:rgb("++(show r)++","++(show g)++","++(show b)++");stroke-width:2\"/>"
    
    writePolygons :: [(Color,Polygon)] -> String 
    writePolygons p = "<svg xmlns=\"http://www.w3.org/2000/svg\">"++(concatMap writePolygon p)++"</svg>"
    
    colorize :: Color -> [Polygon] -> [(Color,Polygon)] 
    colorize = zip.repeat
    
    rainbow@[red,green,blue,yellow,purple,teal] = map colorize [(255,0,0),(0,255,0),(0,0,255),(255,255,0),(255,0,255),(0,255,255)]
    
    t0 = writeFile "tut0.svg" $ writePolygons (blue [[(100,100),(200,100),(200,200),(100,200)],[(200,200),(300,200),(300,300),(200,300)]])
    
    hexagon c r = translateTo c basicHexagon where
      basicHexagon =  top ++ (negate r, 0):bottom 
      top          =  [(r,0),(r * cos 1,(r * sin 1)),(negate (r * cos 1), r * (sin 1))]
      bottom       =  map (\(x,y)->(x,negate y)) (reverse top)
    
    translateTo (x,y) poly = map f poly where f (a,b)= ((a+x),(b+y))
    
    t1 = writeFile "t1.svg" $ writePolygons (blue [hexagon (100,100) 50] )
    
    hexField r n m = let 
         mkHex n = hexagon (1.5*n*(r*2),(r*2)) r
         row n = map mkHex [1..n]
         aRow = row n
      in concat [map (offset (r*x)) aRow |x<-[1..m]]
    
    offset r polys = map (oh r) polys where
      oh r pt@(x,y) = (x+(1.5*r),y+(r*sin 1))
    
    t2 = writeFile "t2.svg" $ writePolygons (blue $ hexField 50 4 5 )
    

    运行t2并将文件加载到firefox或其他支持svg的程序中。

    t2.svg ,exported png http://img30.imageshack.us/img30/2245/93715707.png

        2
  •  6
  •   snk_kid    14 年前

    我以前用过hopengl,但是 问题是(据我所知) 它不能呈现给文件,而只能 屏幕;同样的 我可以说,SDL似乎是正确的。 和WX。我会去看看开罗, 不过。

    由于某种原因,我不能回复这个帖子,所以我不得不引用它。你对GL和SDL不正确,你可以做一个屏幕外的表面/缓冲区或渲染到纹理。这些库不需要这样的功能(也不太有意义),因为您可以通过访问缓冲区中的像素并自己编写出来,甚至可以使用可以访问像素数据的屏幕缓冲区来轻松地完成这项功能。

    就在前几天,我给别人演示了如何使用haskell sdl绑定:

    http://hpaste.org/fastcgi/hpaste.fcgi/view?id=25047

    使用一个可以对PNG文件进行写入的库,它们很可能会将原始指针指向可以从SDL获得的像素缓冲区,或者将其复制到库需要的格式。

    我刚发现 Haskell binding for the library DevIL 可以输出.pNG文件。检查调用的函数 writeImageFromPtr

        3
  •  5
  •   luqui    14 年前

    Cairo 如果你想生成PNG,这是个不错的选择。 Wumpus 看起来也很有前途,虽然我从来没有用过。如果你只是想在屏幕上看到它, graphics-drawingcombinators 是一个简单的opengl接口,可以在几行中完成您需要的工作(请参见 example.hs 在发行版中)。

        4
  •  3
  •   Arthur Clemens    13 年前
        5
  •  2
  •   Don Stewart    14 年前

    有什么好的haskell库可以在上面创建图像和绘制形状?

    你有很多选择,在我看来 used for games :

    这些是最常见的,您可以根据功能/熟悉程度进行选择。