2 Posts Tagged 'Mandelbrot'
More Clojure Mandelbrot Goodness
After my brief stint in the world of fractal geometry and Clojure, I decided to make a real Mandelbrot set viewer. The resulting source code is here. Here's a simple output (click for bigger version):
It's a pretty naive implementation, barely 100 lines of code, but even with my brute-force approach, given a liberal sprinkling of type hints it runs fast enough. Programming Swing from Clojure couldn't be easier (though I doubt programming Swing from any language is ever really enjoyable, it's a painful bunch of libraries).
There's a discussion of different coloring algorithms on Wikipedia, but even after reading that, getting this thing to look good was difficult. I don't know enough math for it. I ended up cheating and I colored a couple of them in the GIMP, so I could use them as desktop wallpapers.
There are some more PNGS over here including one that's 16000x16000 (producing it almost melted my CPU last night).
Clojure: ASCII Mandelbrot Set
Did you know there's this neat Lisp message board where from time to time someone posts a short problem similar in spirit to the infamous RubyQuiz?
Not a lot of people have participated so far, hopefully that changes. I participated this time; the problem is to render the Mandelbrot Set in ASCII. Here's my Clojure version (based loosely on this one).
(ns mandelbrot
(:refer-clojure :exclude [+ * <])
(:use (clojure.contrib complex-numbers)
(clojure.contrib.generic [arithmetic :only [+ *]]
[comparison :only [<]]
[math-functions :only [abs]])))
(defn- mandelbrot-seq [x y]
(let [z (complex x y)]
(iterate #(+ z (* % %)) z)))
(defn- mandelbrot-char [x y]
(loop [c 126
m (mandelbrot-seq x y)]
(if (and (< (abs (first m)) 2)
(> c 32))
(recur (dec c) (rest m))
(char c))))
(defn- mandelbrot-line [xs y]
(apply str (map #(mandelbrot-char % y) xs)))
(defn- m-range [min max num-steps]
(range min
max
(/ (+ (abs min)
(abs max))
num-steps)))
(defn mandelbrot [rmin rmax imin imax]
(let [rows 30
cols 50
xs (m-range rmin rmax cols)
ys (m-range imin imax rows)]
(dorun (map #(println (mandelbrot-line xs %)) ys))))
(comment
;Example run:
(mandelbrot -2.0 1.0 -1.5 1.5)
"
~~~~~~~~~~~~}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
~~~~~~~~~~~~}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
~~~~~~~~~~}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
~~~~~~~~~}}}}}}}}}}}}|||||||||}}}}}}}}}}}}}}}}}}}}
~~~~~~~}}}}}}}}|||||||||||||||||||||}}}}}}}}}}}}}}
~~~~~~}}}}}||||||||||||||{{{{zlxz{{{||||}}}}}}}}}}
~~~~~}}}}|||||||||||||{{{{{zzyxpvlz{{{||||}}}}}}}}
~~~~}}}|||||||||||||{{{{{{zzyxvnpwyzz{{{||||}}}}}}
~~~}}|||||||||||||{{{{{{zzyyws .vyzzz{{|||||}}}}
~~~}||||||||||||{{{{{zzxwwwvus muvxyywz{|||||}}}
~~}|||||||||||{{{zzzzyyu= p oteqpz{|||||}}
~~||||||||||{zzzzzzyyyvtm oxz{{|||||}
~}|||||{{{zyvwxxxxxxxwrG vuz{|||||}
~||{{{{{zzzywsMsqRovvs pxz{{|||||
~|{{{{{zzzyxsq pj `xz{{|||||
~{{{{yyyxwsrp wyz{{|||||
~?:3 3 # ovxzz{{|||||
~{{{{yyyxwsrp wyz{{|||||
~|{{{{{zzzyxsq pj `xz{{|||||
~||{{{{{zzzywsMsqRovvs pxz{{|||||
~}|||||{{{zyvwxxxxxxxwrG vuz{|||||}
~~||||||||||{zzzzzzyyyvtm oxz{{|||||}
~~}|||||||||||{{{zzzzyyu= p oteqpz{|||||}}
~~~}||||||||||||{{{{{zzxwwwvus muvxyywz{|||||}}}
~~~}}|||||||||||||{{{{{{zzyyws .vyzzz{{|||||}}}}
~~~~}}}|||||||||||||{{{{{{zzyxvnpwyzz{{{||||}}}}}}
~~~~~}}}}|||||||||||||{{{{{zzyxpvlz{{{||||}}}}}}}}
~~~~~~}}}}}||||||||||||||{{{{zlxz{{{||||}}}}}}}}}}
~~~~~~~}}}}}}}}|||||||||||||||||||||}}}}}}}}}}}}}}
~~~~~~~~~}}}}}}}}}}}}|||||||||}}}}}}}}}}}}}}}}}}}}
~~~~~~~~~~}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
"
)
And here's some obligatory Jonathan Coulton.
