;;; Draw a sierpinski triangle using the IFS. ;;; This code uses only the barest rudiments of the X11 protocol; ;;; it relies on the server supplying backing store, so you get no ;;; expose events other than the initial one(s). This is ok on Mac OS X. ;;; Example: (sierpinski 820 '(10 100 1000 10000 100000)) ;;; - 820 seems like a good size on the 11 inch PB. (in-package :cl-user) (require 'clx) (defun sierpinski (w nn &optional (host "")) (let* ((h (round (* w 0.5 (sqrt 3.0)))) (width (+ 10 w)) (height (+ 10 h)) (xx (vector 5 (- width 5) (+ 5 (round (/ w 2))))) (yy (vector (- height 5) (- height 5 5) 5)) (display (xlib:open-display host)) (screen (first (xlib:display-roots display))) (black (xlib:screen-black-pixel screen)) (white (xlib:screen-white-pixel screen)) (root (xlib:screen-root screen)) (gc (xlib:create-gcontext :drawable root :foreground white :background black)) (window (xlib:create-window :parent root :x 0 :y 0 :width width :height height :background black :event-mask (xlib:make-event-mask :exposure :button-press)))) (xlib:map-window window) (xlib:event-case (display :force-output-p t :discard-p t) (:exposure (count) nil) (:button-press (code) (cond ((and (equal code 1) nn) (loop for x = (random width) then (ash (+ x (aref xx c)) -1) and y = (random height) then (ash (+ y (aref yy c)) -1) and c = (random 3) repeat (pop nn) do (xlib:draw-point window gc x y))) ((equal code 3) t) (t nil)))) (xlib:destroy-window window) (xlib:close-display display)))