Hatena::Grouphaskell

mokeheheの日記

2009-11-09

マンデルブロ集合

f:id:mokehehe:20091109152525p:image

なんの凝ったものもなく、Haskellでマンデルブロ集合を書いてみる。結果は標準出力にppm3で吐き出す:

import Complex
import System.Environment

main = do
	args <- getArgs
	let centerx = read $ getOption args 0 "0.0"
	let centery = read $ getOption args 1 "0.0"
	let scale = read $ getOption args 2 "2.0"
	let depth = read $ getOption args 3 "32"
	let w = read $ getOption args 4 "512"
	let h = read $ getOption args 5 "512"

	let dx = scale + (scale / (toEnum w))
	let dy = scale * (toEnum h) / (toEnum w) + (scale / (toEnum w))

	let img = mandelbrot w h (centerx - dx) (centery - dy) (centerx + dx) (centery + dy) depth
	saveppm w h img

mandelbrot w h minx miny maxx maxy depth =
	[calcPixelColor x y w h minx miny maxx maxy depth | y <- [0 .. h-1], x <- [0 .. w-1]]

calcPixelColor x y w h minx miny maxx maxy depth =
	if n == depth
		then (0,0,0)
		else hsv (n * 67)
	where
		n = calcDepth depth (px :+ py)
		px = ((toEnum x + 0.5) / toEnum w) * (maxx - minx) + minx
		py = ((toEnum y + 0.5) / toEnum h) * (maxy - miny) + miny

calcDepth max c = length $ takeWhile (not . diverge) $ take max $ iterate (\z -> z * z + c) czero

hsv h =
	case (h `div` 255 `mod` 6) of
		0 -> (255, t, 0)
		1 -> (255 - t, 255, 0)
		2 -> (0, 255, t)
		3 -> (0, 255 - t, 255)
		4 -> (t, 0, 255)
		5 -> (255, 0, 255 - t)
	where
		t = h `mod` 255

squareMagnitude c = (realPart c ** 2) + (imagPart c ** 2)
--squareMagnitude c = (realPart c ** 2) * (imagPart c ** 2)

diverge c = squareMagnitude c >= 4

getOption args idx defaultValue =
	if (length args) <= idx
		then defaultValue
		else args !! idx

saveppm w h img = do
	putStrLn "P3"
	putStrLn $ show w ++ " " ++ show h
	putStrLn "255"
	mapM_ (\(r,g,b) -> putStr $ (show r) ++ " " ++ (show g) ++ " " ++ (show b) ++ " ") img

czero = 0.0 :+ 0.0

複素数の長さの計算を間違って、

squareMagnitude c = (realPart c ** 2) * (imagPart c ** 2)  -- '+' と '*' を間違えた

としたら変わった絵ができた:

f:id:mokehehe:20091109152522p:image

概観は変わらないけどトゲトゲしたものになった。どういうこっちゃ!?面白い!

ゲスト



トラックバック - http://haskell.g.hatena.ne.jp/mokehehe/20091109