import Data.Complex import System.Environment(getArgs) type C = Complex(Double) mandelbrot_eval::Int->C->Int mandelbrot_eval max_iter c = length $ (takeWhile (\z -> (magnitude z) < 2)) $ (take max_iter) $ (iterate (\z -> z*z+c) (0:+0) ) -- half_width_pixels::Int -- half_width_pixels = 10240 -- at 12800: 9162 seconds (153 minutes) -- at 10240: 99m 44s scaling:: Int -> Double->Int->Double scaling half_width_pixels width = (* (width /(fromIntegral half_width_pixels))) . fromIntegral range:: Int -> Double->[Double] range half_width_pixels width= map (scaling half_width_pixels width) [1-half_width_pixels .. half_width_pixels] -- the "28" was discovered by trial and error for zoom 6. -- Also consider zoom 5.42 if only the center section is going to be cut out to create a rectangular image iterations::Int iterations = 100000; -- 310+28 -- 310; -- perl -plwe 'next unless /^\d+$/;if($_>255){$_=255}' fileout | xloadimage stdin -- perl -plwe 'next unless /^-?\d+$/;if($_>255){$_=255}elsif($_<0){$_=0}' fileout | xloadimage stdin truncrange :: Int -> Int truncrange i = if (i>255) then 255 else if (i<0) then 0 else i; color :: Int -> Int -> [Int]; color max_iter i = if i==max_iter then [0,0,0] else [i-55,i-55,i] -- (\i -> [i-55-28,i-55-28,i-28]) -- (\i -> [i-55,i-55,i]) main::IO () main = do args <- getArgs let half_width_pixels :: Int half_width_pixels = read $ args !! 1 s = show $ 2*half_width_pixels putStrLn ("P3\n"++s++" "++s++"\n"++"255"); let side::Double side = exp(-(read (head args))) the_range :: [Double] the_range = range half_width_pixels side putStr $ unlines $ map (show.truncrange) $ concatMap ((color iterations) . (mandelbrot_eval iterations) . (+ center) ) $ [x:+y | x<- the_range, y<- the_range] center::C center = 0.4245127190 :+ 0.2075302281 -- Fenway House is looking for new residents!