Подтвердить что ты не робот

Библиотека графического рисования для Haskell?

Я работаю над программой Haskell для игры в пространственные игры: у меня есть график группы людей, играющих дилемму заключенных, но только с их ближайшими соседями и копированием стратегий людей, которые делают лучше всего.

Я достиг точки, где мне нужно нарисовать образ мира, и именно здесь я столкнулся с проблемами. Две из возможных геометрий легки: если у людей есть четыре или восемь соседей каждый, я представляю каждый в виде заполненного квадрата (с цветом, соответствующим стратегии), и разбиваем плоскость с ними. Однако у меня также есть ситуация, когда люди имеют шесть соседей (шестиугольников) или трех соседей (треугольники).

Итак, мой вопрос: какая хорошая библиотека Haskell для создания образов и рисования фигур на них?. Я бы предпочел, чтобы он создавал PNG, но я не невероятно придирчив. Первоначально я использовал Graphics.GD, но он только экспортирует привязки к функциям для рисования точек, линий, дуг, эллипсов и невращающихся прямоугольников, что недостаточно для моих целей (если я не хочу рисовать шестиугольники по пикселям *). Я просмотрел с помощью foreign import, но это доказывает немного хлопот (отчасти потому, что для функции рисования многоугольника требуется массив структур gdPoint), и учитывая, что мои требования могут расти, было бы неплохо использовать -Haskell, и не нужно гадать с FFI (хотя, если толчок наступает, я готов это сделать). Любые предложения?

* Это тоже вариант, на самом деле; любые советы о том, как это сделать, также будут оценены, хотя я думаю, что библиотека будет проще.

РЕДАКТИРОВАТЬ: Спасибо вам большое за ваши предложения. К сожалению, мне не удалось собрать все необходимые библиотеки gtk2hs, что исключало множество решений. По целому ряду причин, после того как я попробовал все ваши ответы, не удалось установить несколько библиотек и обнаружил, что другие не могут делать то, что я хотел, я решил просто экспортировать больше FFI для libgd и использовал это вместо.

4b9b3361

Ответ 1

Диаграммы выглядят здорово, но если вы хотите избежать фиксации и оставаться в суперлегком весе, вы можете напрямую сгенерировать 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

[email protected][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 [email protected](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, экспортировано png http://img30.imageshack.us/img30/2245/93715707.png

Ответ 2

Я использовал HOpenGL раньше, но проблема в том, что (насколько я могу судить) он не может отображать файл, но только экран; то же самое (опять же, насколько Я могу сказать), похоже, относится к SDL и Wx. Я посмотрю в Каир, хотя.

По какой-то причине я не могу ответить на этот пост, поэтому я должен его процитировать. Вы ошибаетесь в отношении GL и SDL, вы можете создавать внеэкранную поверхность/буфер или визуализацию для текстуры. Эти библиотеки не нуждаются в такой функции (и это тоже не имеет особого смысла), потому что вы можете сделать это самостоятельно довольно легко, обратившись к пикселам в буфере и сами их записывая, даже с помощью буферов экрана вы можете получить доступ к пиксельным данным.

На днях я показал кому-то, как это сделать с привязками SDK Haskell:

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

Используйте библиотеку, которая может записывать файлы .PNG, они, скорее всего, возьмут необработанный указатель на буфер пикселей, который вы можете получить из SDL/GL, или скопируйте его в формат, который требуется библиотеке.

Я только что нашел привязку Haskell для библиотеки DevIL, которая может выводить файлы .PNG. Проверьте функцию с именем writeImageFromPtr

Ответ 3

Cairo - хорошая ставка, если вы хотите сгенерировать PNG. Wumpus также выглядит многообещающим, хотя я никогда не использовал его. Если вам просто нужно увидеть его на экране, graphics-drawingcombinators - это простой интерфейс для OpenGL, который будет делать то, что вам нужно, в нескольких строках (см. example.hs в распределении).

Ответ 5

какая хорошая библиотека Haskell для создания образов и рисования на них?

У вас есть несколько вариантов, на мой взгляд, следующие были используемые для игр:

Это самые распространенные, и вы можете просто выбрать, основываясь на особенностях/знакомстве.