J.P. Larocque (jp_larocque) wrote,

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)))
  • Post a new comment

    Error

    default userpic

    Your IP address will be recorded 

  • 4 comments