1 
    2 
    3 
    4 
    5 
    6 
    7 
    8 
    9 
   10 module Mandel where
   11 import Complex -- 1.3
   12 import PortablePixmap
   13 default ()
   14 
   15 
   16 
   17 
   18 
   19 
   20 
   21 
   22 
   23 
   24 
   25 
   26 
   27 
   28 
   29 
   30 
   31 
   32 
   33 
   34 
   35 
   36 
   37 
   38 
   39 
   40 
   41 
   42 
   43 
   44 
   45 
   46 
   47 
   48 mandel::(Num a) => a -> [a]
   49 mandel c = infiniteMandel
   50            where
   51                 infiniteMandel = c : (map (\z -> z*z +c) infiniteMandel)
   52 
   53 
   54 
   55 
   56 
   57 
   58 
   59 
   60 
   61 
   62 
   63 
   64 
   65 
   66 
   67 
   68 
   69 
   70 
   71 
   72 
   73 
   74 
   75 
   76 
   77 
   78 
   79 
   80 
   81 
   82 
   83 
   84 
   85 
   86 
   87 
   88 whenDiverge::  Int -> Double -> Complex Double -> Int
   89 whenDiverge limit radius c
   90   = walkIt (take limit (mandel c))
   91   where
   92      walkIt []     = 0                         -- Converged
   93      walkIt (x:xs) | diverge x radius  = 0            -- Diverged
   94                    | otherwise          = 1 + walkIt xs -- Keep walking
   95 
   96 
   97 
   98 
   99 
  100 
  101 
  102 
  103 
  104 
  105 
  106 
  107 
  108 -- VERY IMPORTANT FUNCTION: sits in inner loop
  109 
  110 diverge::Complex Double -> Double -> Bool
  111 diverge cmplx radius =  magnitude cmplx > radius
  112 
  113 
  114 
  115 
  116 
  117 
  118 
  119 
  120 
  121 
  122 parallelMandel:: [Complex Double] -> Int -> Double -> [Int]
  123 parallelMandel mat limit radius
  124    = map (whenDiverge limit radius) mat
  125 
  126 
  127 
  128 
  129 
  130 
  131 
  132 
  133 
  134 
  135 
  136 
  137 
  138 
  139 
  140 
  141 
  142 
  143 
  144 
  145 
  146 
  147 
  148 
  149 mandelset::Double ->       -- Minimum X viewport
  150            Double ->            -- Minimum Y viewport
  151            Double ->            -- Maximum X viewport
  152            Double ->      -- maximum Y viewport
  153            Integer ->                 -- Window width
  154            Integer ->                 -- Window height
  155            Int ->             -- Window depth
  156            PixMap               -- result pixmap
  157 mandelset x y x' y' screenX screenY lIMIT
  158    = createPixmap screenX screenY lIMIT (map prettyRGB result)
  159    where
  160 
  161 
  162 
  163 
  164 
  165 
  166 
  167 
  168       windowToViewport s t
  169            = ((x + (((coerce s) * (x' - x)) / (fromInteger screenX))) :+
  170               (y + (((coerce t) * (y' - y)) / (fromInteger screenY))))
  171 
  172       coerce::Integer -> Double
  173       coerce  s   = encodeFloat (toInteger s) 0
  174 
  175 
  176 
  177 
  178       result = parallelMandel
  179                   [windowToViewport s t | t <- [1..screenY] , s<-[1..screenX]]
  180                   lIMIT
  181                   ((max (x'-x) (y'-y)) / 2.0)
  182 
  183       prettyRGB::Int -> (Int,Int,Int)
  184       prettyRGB s = let t = (lIMIT - s) in (s,t,t)
  185