J.P. Larocque ([info]jp_larocque) wrote,
@ 2008-01-04 06:47:00
Previous Entry  Add to memories!  Tell a Friend  Next Entry
Diversions: character Mandelbrot in Common Lisp

Mandelbrot in Common Lisp, rendered with textual characters:

Snoopy swearing

(defun mandelbrot (width height x-offset y-offset x-scale y-scale)
  (declare (optimize speed (space 0) (compilation-speed 0)))
  (labels ((mandelbrot (x-coord y-coord)
             (let ((max-iter 100))
               (loop for x = x-coord then next-x
                     for y = y-coord then next-y
                     for next-x = (+ (* x x) (* -1 y y) x-coord)
                     for next-y = (+ (* 2 x y) y-coord)
                     for iter from 0 below max-iter
                     unless (< (+ (* x x) (* y y)) 4)
                     doing (return (color iter))
                     finally (return #\Space))))
           (color (iter)
             (let ((iter-mixed (if (evenp iter) (1+ iter) (1- iter))))
               (code-char (+ 33 (mod iter-mixed 94)))))
           (draw (width height)
             (let* ((type 'float)
                    (x-offset (coerce (- x-offset (/ 1 x-scale 2)) type))
                    (y-offset (coerce (- y-offset (/ 1 y-scale 2)) type))
                    (x-res (coerce (/ 1 width x-scale) type))
                    (y-res (coerce (/ 1 height y-scale) type))
                    (crosshair-x (round (/ width 2)))
                    (crosshair-y (round (/ height 2))))
               (loop for y from y-offset by y-res
                     for y-px from 0 below height
                     doing (fresh-line)
                     doing (loop for x from x-offset by x-res
                                 for x-px from 0 below width
                                 doing (princ (cond ((and (= y-px crosshair-y)
                                                          (= x-px (1- crosshair-x)))
                                                     #\[)
                                                    ((and (= y-px crosshair-y)
                                                          (= x-px crosshair-x))
                                                     #\+)
                                                    ((and (= y-px crosshair-y)
                                                          (= x-px (1+ crosshair-x)))
                                                     #\])
                                                    (t (mandelbrot x y)))))))))
    (declare (inline mandelbrot color))
    (draw (* width 2) height)
    (values)))



(4 comments) - (Post a new comment)


[info]souterrain
2008-01-04 08:31 pm UTC (link)
shiny.

(Reply to this)


[info]two_pi_r
2008-01-05 07:54 pm UTC (link)
That's kind of disturbing. I like it.

(Reply to this)


(Anonymous)
2008-01-06 02:41 am UTC (link)

What's a good initial value for the function?

(Reply to this) (Thread)

Documentation? Pfft.
[info]jp_larocque
2008-01-07 06:10 pm UTC (link)
width and height specify the size of the canvas, in characters. So, try 20 for instance. (width is first multiplied by 2, to make the "pixel" aspect ratio roughly 1:1.) Start with x-offset and y-offset at 0, and x-scale and y-scale at 1.

(Reply to this) (Parent)


(4 comments) - (Post a new comment)

Create an Account
Forgot your login or password?
Login w/ OpenID
English • Español • Deutsch • Русский…