我在Haskell中有这个函数(我使用的是Haskell-SDL库):
pixel :: Surface -> Int16 -> Int16 -> Pixel -> IO Bool
pixel screen x y color
我想用它来获取一个二维数组(或其他类型的数据结构),并将其绘制到屏幕上,一次绘制一个像素。我考虑过用forM_来做这件事,但是想不出如何让它对x和y参数进行操作。
一般来说,我对Haskell和函数式编程都很陌生。我正在学习另一个Haskell教程,但是这个问题把我难住了。
如果它与解决方案相关,我正在尝试编写一个raytracer。它必须对每个像素执行计算,然后将该像素写入屏幕。
发布于 2011-02-12 01:59:33
您需要在这里拆分两个问题。首先,你需要计算像素值。这应该是场景的纯函数,以及要发射到场景中的光线的坐标。然后,您需要将该像素值写入屏幕。
所以首先你需要一个函数:
type Coord = (Int, Int)
raytrace :: Scene -> Coord -> (Coord, Colour)
-- You will see why it returns this pair in a few lines然后,您希望为曲面中的每个像素调用该函数,以获得坐标-颜色对的列表:
allCoords :: Int -> Int -> [Coord]
allCoords width height = [(x,y) | x <- [0..width], y <- [0..height]]
allPixels :: Scene -> Int -> Int -> [(Coord, Colour)]
allPixels scene w h = map (raytrace scene) (allCoords w h)最后使用您的“像素”函数将像素列表放到显示表面上。
writeScene :: Surface -> Scene -> Int -> Int -> IO ()
writeScene surface scene w h = mapM_ writePixel (allPixels scene w h)
where writePixel ((x,y),c) = pixel surface x y c唯一的问题是,你的“像素”函数返回一个"IO Bool“。我不知道为什么,所以我用"mapM_“而不是"mapM”忽略了它。
这看起来像是它构建了一个极其低效的坐标-颜色对列表,然后遍历它来绘制图片。但事实上,由于Haskell的懒惰特性,它实际上编译成一个循环,生成每种颜色,然后在结果上调用“像素”。
发布于 2011-02-11 13:04:58
如果您使用的是嵌套列表,请执行以下操作:
import Control.Monad
plot :: Surface -> [[Pixel]] -> IO ()
plot surf = zipWithM_ (\ y -> zipWithM_ (\ x c -> pixel surf x y c) [0..]) [0..]发布于 2011-02-11 17:48:39
Haskell有各种各样的实数组。对我来说,你似乎在做一些效率很低的事情,你想创建一个像素缓冲区并将其blit到另一个缓冲区吗?创建一个新的SDL表面(您可以为其获取/设置像素)并将其blit到另一个表面/屏幕,或者创建一个实际的像素数组并使用创建SDL表面,然后使用SDL的blit例程,这将更加有效。如果你解释一下你想做什么,我想我们可以告诉你一个更好的方法。
https://stackoverflow.com/questions/4965640
复制相似问题