;;; Scheme Recursive Art Contest Entry ;;; ;;; Please do not include your name or personal info in this file. ;;; ;;; Title: Parentheses Out For Harambe ;;; ;;; Description: ;;; ;;; Cincinnati Zoo. ;;; He was just a gorilla. ;;; But now, he's a god. ; If you are interested in rendering this, I would recommend lowering NUM_CUTS ; and then doing something else, like passing spring semester courses, before ; coming back to check if this has finished. ; Rendering instructions: ; 1. Be very, very, very, (define (f n) (if (> n 0) (begin (print "very, ") (f (- n 1)))))(f 1000000000) very patient. ; 2. Repeat the previous step a few billion times. ; 3. Write out the next few billion steps following the template "Repeat the previous step a few billion times.". ; 7. Write out the next few billion steps following the template "Repeat the previous step a few billion times.". ; 7. Write out the next few billion steps following the template "Repeat the previous step a few billion times.". ; 8. We're now at depth 3. Repeat until depth is roughly a few billion. ; 9. Assuming the universe has not ended yet, invent a time machine, and start at 1 again, loop through the steps a few billion times for good measure. ; 10. Hopefully it's finished now (it will almost certainly take upwards of a few hours). If not, please wait a bit longer. ; 11. The screenshot provided uses (define NUM_CUTS 50). This takes an absurd amount of time to render (read: days-weeks). ; This number represents how many line segments each bezier curve is broken up into; for a much faster render (with less smooth curves), ; you can reduce this from 50 to 4-5. Do still expect to wait a long time; rendering with NUM_CUTS=4 on derby took hours. ; It's also possible to parallelize the drawing process a bit if desired: edit tscheme_pixel in scheme_primitives.py to print out (pixel X Y COLOR) ; instead of drawing it, then change START/END to be, say, 0/131071 for the first instance, and 131072/262143 for the second instance. ; Pipe the output to a single file, and then combine and run with the standard pixel instruction to draw. ; How many cuts to break each bezier curve into. ; I would suggest not lowering this beyond 4-5, as that's ; the point where the figure is no longer recognizable. ; Above 20 or so, and you're looking at days-weeks of render time. (define NUM_CUTS 50) ; START index (0 <= START < END) (define START 0) ; END index (START < END < 262144 = 2^9*2^9 - 1) (define END 262143) (define (draw) (hideturtle) (speed 0) (define (clamp t) (cond ((< t 0) 0) ((> t 1) 1) (else t))) (define (here-be-memes curves i) (define (distance point p1) (hypot (- (car point) (car p1)) (- (cdr point) (cdr p1)))) (define (memes x t last point sum sumweight) (define (bezier s n) (+ (* (car s) (expt (- 1 t) 3)) (* (car (cdr s)) 3 (expt (- 1 t) 2) t) (* (car (cdr (cdr s))) 3 (- 1 t) t t) (* (car (cdr (cdr (cdr s)))) t t t))) (if (null? x) (let ((L (/ sum sumweight))) (define (cmp p) (clamp (+ L (* p (- 1 (abs (+ L L -1))))))) (pixel (+ 50 (car point)) (+ 50 (cdr point)) (rgb (cmp -.49) (cmp 0) (cmp .49))) (forward 0)) (let ((next (cons (bezier (car (car x)) 3) (bezier (cdr (car x)) 3))) (lx (car last)) (ly (cdr last))) (define (dot c) (+ (* (- (car c) lx) (- (car next) lx)) (* (- (cdr c) ly) (- (cdr next) ly)))) (define (closest-segment-point) (let ((t (/ (dot point) (dot next)))) (cons (+ lx (* (- (car next) lx) (clamp t))) (+ ly (* (- (cdr next) ly) (clamp t)))))) (if (> t 1) (memes (cdr x) 0 next point sum sumweight) (if (zero? t) (memes x (+ t (/ 1 NUM_CUTS)) next point sum sumweight) (let ((source (closest-segment-point))) (define dps (distance point source)) (define fsdps (* 4 (sqrt dps))) (define wave-dps (* (exp (* dps -0.02)) (cos fsdps))) (let ((phi1 (atan2 (- (* -0.02 wave-dps fsdps) (* 8 (exp (* -0.02 dps)) (sin fsdps))) fsdps))) (define (light-source x y z) ; does anyone recognize the spherical law of cosines? (let ((phi (atan2 (distance point (cons x y)) (- z wave-dps)))) (abs (+ (* (sin phi1) (sin phi) (cos (- (atan2 (- (cdr point) (cdr source)) (- (car point) (car source))) (atan2 (- y (cdr point)) (- x (car point)))))) (* (cos phi1) (cos phi)))))) (define L1 (light-source -250 600 100)) (define L2 (light-source -150 600 100)) (define L3 (light-source -50 600 100)) (define L4 (light-source 50 600 100)) (define L5 (light-source 150 600 100)) (define L6 (light-source 256 600 100)) (define L7 (light-source 356 600 100)) (define L8 (light-source 456 600 100)) (define L9 (light-source 556 600 100)) (define LA (light-source 656 600 100)) (define LB (light-source 756 600 100)) (define L (/ (+ L1 L2 L3 L4 L5 L6 L7 L8 L9 LA LB) 11)) (memes x (+ t (/ 1 NUM_CUTS)) next point (+ sum (/ (* 1000000 L) (* dps dps dps dps))) (+ sumweight (/ 1000000 (* dps dps dps dps))))))))))) (memes curves 0 (cons (modulo i 512) (quotient i 512)) (cons (modulo i 512) (quotient i 512)) 0 0) (if (= i START) () (here-be-memes curves (- i 1)))) ; here be the bezier curves. changing things will change the curve drawn. ; here is also where all those tokens went. (here-be-memes '(((147.1 -138.2 650.2 364.9) . (399.1 -74.30000000000001 -74.30000000000001 399.1)) ((147.1 223.6 288.4 364.9) . (399.1 435.1 435.1 399.1)) ((147.1 144.39999999999998 367.6 364.9) . (399.1 486.4 486.4 399.1)) ((210.1 219.1 292.9 301.9) . (349.6 360.4 360.4 349.6)) ((120.1 82.29999999999998 429.70000000000005 391.9) . (347.8 310.9 310.9 347.8)) ((163.3 191.2 256 256) . (326.2 189.39999999999998 276.7 324.4)) ((348.7 320.8 256 256) . (326.2 189.39999999999998 276.7 324.4)) ((213.7 268.6 115.6 256) . (253.3 213.7 138.1 152.5)) ((298.3 243.4 396.4 256) . (253.3 213.7 138.1 152.5)) ((256 256 238.9 236.2) . (193.9 228.1 217.3 216.4)) ((256 256 273.1 275.8) . (193.9 228.1 217.3 216.4)) ((236.2 235.3 242.5 256) . (216.4 210.1 189.39999999999998 194.8)) ((275.8 276.7 269.5 256) . (216.4 210.1 189.39999999999998 194.8))) END) (exitonclick)) (draw)