J.P. Larocque (jp_larocque) wrote,
J.P. Larocque
jp_larocque

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

    Error

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.
  • 4 comments