; Project 2: visualize fractals
; This project uses big-bang to visualize
; various fractals at different depths.
;
; Due: 10 p.m. December 2nd on MarkUs
; (require net/sendurl)
; (send-url “https://markus.teach.cs.toronto.edu/csc104-2016-09”)
;
; You will need to look up some of the documentation,
; devise the required functions, and come up with
; check-expect expressions for each function.
;
; The portions that need your input are marked with
; ###
;
; This project is somewhat open-ended. The function
; implementations are up to you, provided they work
; as described. You get to choose a third fractal,
; beyond sierpinski and sierpinski-carpet. You will
; probably need to check documentation for big-bang,
; on-key, and to-draw.
;
; The last 5% of this project is for an improvement. You
; may find that some fractals render slowly once the
; depth gets beyond 6 or 8. If you decide to improve this
; behaviour you must:
; 1. Write a short paragraph or two (commented out) in this
; file, describing how you aim to fix the problem
; 2. Modify the code so that the rendering is significantly
; faster.
(require picturing-programs)
; fractal is a struct that has:
; kind: string representing kind of fractal
; depth: number representing complexity
(define-struct fractal (kind depth))
; ###
; Write two check-expect expressions for sierpinski.
; The first check-expect is for (sierpinski 0)
; and it involves no recursion.
; The second check-expect is for (sierpinski 1)
; and it should be a Full Design check-expect that
; uses (sierpinski 0) in its body.
(check-expect (sierpinski 0)
(triangle 1024 ‘solid ‘green))
(check-expect (sierpinski 1)
(let ((sub (sierpinski 0)))
(scale 0.5 (above sub
(beside sub sub)))))
; ###
; Write the function definition for sierpinski.
; sierpinski : number -> image
; Produce sierpinski’s triangle of depth n
; 1024 pixels wide.
;
; You can see similar code to what you need in
; the triangle video:
; (require net/sendurl)
; (send-url “http://www.teach.cs.toronto.edu/~heap/Racket/recursion.html”)
;(image-width (sierpinski 4))
; ###
; Write check-expect expressions for (sierpinski-carpet 0)
; and (sierpinski-carpet 1).
; The check-expect for (sierpinski-carpet 0) involves no
; recursion.
; The check-expect for (sierpinski-carpet 1) should be a
; Full-Design check-expect that uses (sierpinski 0) in its
; body.
;
; ###
; Write the function definition for sierpinski-carpet
; sierpinski-carpet : number -> image[
; Produce sierpinski’s carpet of depth n
; 1024 pixels wide.
;
; You can see images of sierpinski carpets, and find out
; them at:
; (require net/sendurl)
; (send-url “https://en.wikipedia.org/wiki/Sierpinski_carpet”
; ###
; Develop a definition for a third fractal of your choice.
; It must be 1024 pixels wide at all depths. You may
; choose the koch snowflake or some other fractal.
; Your development should include two check-expect expressions
; similar to those for sierpinski and sierpinski-carpet
(check-expect (koch 0)
(line 1024 0 “black”))
(check-expect (koch 1)
(let ((sub (koch 0)))
(let ((res (beside/align “bottom” sub (rotate 60 sub) (rotate -60 sub) sub)))
(scale (/ 1024 (image-width res)) res))))
;;; My improvement for the last 5% of this project
;;; I use let syntax to compute subproblem as local variable
;;; thus it avoids computing the subproblem several times,
;;; and so making the program much faster.
; ###
; Add [question answer] pairs to the cond in function change
; to allow you to use the additional fractal you choose.
;
; change : world string -> world
; Produce new world w based on string a-key.
(define (change w a-key)
(cond
[(key=? a-key “up”) (make-fractal (fractal-kind w) (add1 (fractal-depth w)))]
[(key=? a-key “down”)
(make-fractal (fractal-kind w)
(max (sub1 (fractal-depth w)) 0))]
[(key=? a-key “t”)
(make-fractal “sierpinski” (fractal-depth w))]
[(key=? a-key “c”)
(make-fractal “sierpinski-carpet” (fractal-depth w))]
[(key=? a-key “k”)
(make-fractal “koch” (fractal-depth w))]
[else w]))
; ###
; Add [question answer] pair to the cond in render-fractal
; so that it will draw the appropriate fractal
;
; Until you have implemented the definitions of fractals, this
; code will generate errors, so you should leave it commented
; out until you’re ready.
;
; render-fractal : world -> image
; Produce an image of a fractal based on world w.
; (define (render-fractal w)
; (cond
; [(string=? (fractal-kind w) “sierpinski”)
; (sierpinski (fractal-depth w))]
; [(string=? (fractal-kind w) “sierpinski-carpet”)
; (sierpinski-carpet (fractal-depth w))]
; [else (triangle 10 “solid” “black”)]))
;
(define (render-fractal w)
(cond
[(string=? (fractal-kind w) “sierpinski”)
(sierpinski (fractal-depth w))]
[(string=? (fractal-kind w) “sierpinski-carpet”)
(sierpinski-carpet (fractal-depth w))]
[(string=? (fractal-kind w) “koch”)
(koch (fractal-depth w))]
[else (triangle 10 “solid” “black”)]))
; Leave big-bang commented out until you have
; completed functions change and render-fractal
; (big-bang (make-fractal “sierpinski” 0)
; (on-key change)
; (to-draw render-fractal 1024 1024))
;
;
(big-bang (make-fractal “sierpinski” 0)
(on-key change)
(to-draw render-fractal 1024 1024))