; Draws Sierpinski Triangle and other fractals ; Using the Chaos Game. ; Takes one argument with is a vector of the ; verticies of a polygon inside a unit square. (define pi 3.141592654) (define ChaosGame (lambda (vertexVector) (define drawWidth 700) (define drawHeight 720) (define scale 1) (define x 0) (define y 0) (define border 10) (define idx 0) (define vertexCount (vector-length vertexVector)) ;;================================================= (define getX (lambda (idx) (vector-ref (vector-ref vertexVector idx) 0) ) ) ;;================================================= ;;================================================= (define getY (lambda (idx) (vector-ref (vector-ref vertexVector idx) 1) ) ) ;;================================================= (define getScreenX (lambda (x) (+ (floor (* x scale)) border) ) ) (define getScreenY (lambda (y) (+ (floor (* y scale)) border) ) ) ;;================================================= (define getPen (lambda (idx) (vector-ref penVector idx) ) ) ;;================================================= ;;================================================= (define penVector (vector (instantiate pen% ("RoyalBlue" 4 'solid)) (instantiate pen% ("DarkOrchid" 4 'solid)) (instantiate pen% ("MediumSeaGreen" 4 'solid)) (instantiate pen% ("Crimson" 4 'solid)) (instantiate pen% ("OrangeRed" 4 'solid)) )) (define pen-black (instantiate pen% ("Black" 1 'solid)) ) ;;================================================= ;;================================================= (define frame (instantiate frame% ("Chaos Game") (width drawWidth) (height drawHeight) ) ) ;;================================================= ;;================================================= (define plot (lambda (dc x y idx) (send dc set-pen (getPen idx)) (send dc draw-point (getScreenX x) (getScreenX y) ) ) ) ;;================================================= ;;================================================= (define plot-ball (lambda (dc x y idx) (send dc set-pen (getPen idx)) (send dc draw-ellipse (- (getScreenX x) 3) (- (getScreenY y) 3) 7 7) ) ) ;;================================================= ;;================================================= (define DrawVertexies (lambda (dc) (do ((i 0 (+ i 1))) ((>= i vertexCount)) (plot-ball dc (getX i) (getY i) i) (send dc set-pen pen-black) (let ((ii (modulo (+ i 1) vertexCount))) (send dc draw-line (getScreenX (getX i)) (getScreenY (getY i)) (getScreenX (getX ii)) (getScreenY (getY ii)) ) ) ) )) ;;================================================= ;; Make the drawing area with a paint callback (define canvas (instantiate canvas% (frame) (paint-callback (lambda (canvas dc) (drawEverything dc)) ) ) ) ;;================================================= (define (drawEverything dc) (define drawSize (call-with-values (lambda () (send canvas get-client-size)) (lambda z z) ) ) (set! drawWidth (car drawSize)) (set! drawHeight (car (cdr drawSize))) (send dc set-background (make-object color% 255 255 255) ) (send dc clear) (send dc set-smoothing 'smoothed) (set! scale (- (- (min drawWidth drawHeight) border ) border) ) (DrawVertexies dc) (set! x (random)) (set! y (random)) (do ((i 0 (+ i 1))) ((>= i 50000)) ;(sleep 1) (set! idx (inexact->exact (floor (* (random) vertexCount)))) (set! x (/ (+ x (getX idx)) 2)) (set! y (/ (+ y (getY idx)) 2)) (plot dc x y idx) ;(plot-ball dc x y idx) ) ) ;; Show the frame (send frame show #t) )) ;;================================================= ;;Vertices of equilateral triangle (ChaosGame (vector (vector 0.0 1.0) (vector 1.0 1.0) (vector 0.5 (- 1.0 (sin (/ pi 3.0)))) ) ) ;(ChaosGame ; (vector (vector 0.0 0.0) ; (vector 1.0 1.0) ; (vector 0.0 1.0) ; ) ;) ;;================================================= ;; Vertices of regular pentagon ;(ChaosGame ; (vector (vector 0.5 0.951056516) ; (vector 0.0 0.587785252) ; (vector 0.190983006 0.0) ; (vector 0.809016994 0.0) ; (vector 1.0 0.587785252) ; ) ;)