;; The first three lines of this file were inserted by DrScheme. They record metadata ;; about the language level of this file in a form that our tools can easily process. #reader(lib "htdp-intermediate-lambda-reader.ss" "lang")((modname |27.1|) (read-case-sensitive #t) (teachpacks ((lib "draw.ss" "teachpack" "htdp") (lib "arrow.ss" "teachpack" "htdp") (lib "gui.ss" "teachpack" "htdp"))) (htdp-settings #(#t constructor repeating-decimal #f #t none #f ((lib "draw.ss" "teachpack" "htdp") (lib "arrow.ss" "teachpack" "htdp") (lib "gui.ss" "teachpack" "htdp"))))) ;; sierpinski : posn posn posn symbol -> true ;; Given a, b, and c (posns), draw the triangle specified by the 3 posns and color and then use generative recursion to draw the nested triangles. Return true once the triangles become too small to draw. (define (sierpinski a b c color) (local ((define a-b (midpoint a b)) (define a-c (midpoint a c)) (define b-c (midpoint b c))) (cond [(too-small? a b c) true] [else (and (draw-triangle (round-posn a) (round-posn b) (round-posn c) color) (sierpinski a a-b a-c color) (sierpinski b a-b b-c color) (sierpinski c a-c b-c color))]))) ;round-posn : posn -> posn ;Rounds a posn x to the nearest integer (define (round-posn p) (make-posn (inexact->exact (round (posn-x p))) (inexact->exact (round (posn-y p))))) ;draw-triangle : posn posn posn -> true ;Draw the triangle that contains a, b, and c as vertices. (define (draw-triangle a b c color) (and (draw-solid-line a b color) (draw-solid-line b c color) (draw-solid-line c a color))) ;midpoint : posn posn -> posn ;Given a, b, find the midpoint of the two posns. (define (midpoint a b) (make-posn (/ (+ (posn-x a) (posn-x b)) 2) (/ (+ (posn-y a) (posn-y b)) 2))) ;too-small? : posn posn posn -> boolean ;Given a, b, c, determine if the triangle is too small. A triangle is too small if the area of the given triangle is less than MINAREA. (define MINAREA 5) (define (too-small? a b c) (< (area-of-triangle a b c) MINAREA)) ;area-of-triangle : posn posn posn -> number ;Given a, b, c, determine the area of the triangle. (uses Heron's formula) (define (area-of-triangle a b c) (local ((define A (distance b c)) (define B (distance a c)) (define C (distance a b)) (define semiperimeter (/ (+ A B C) 2))) (sqrt (* semiperimeter (- semiperimeter A) (- semiperimeter B) (- semiperimeter C))))) ;distance : posn posn -> number ;Given p1, p2, determine the distance between two points. (define (distance p1 p2) (sqrt (+ (sqr (- (posn-x p2) (posn-x p1))) (sqr (- (posn-y p2) (posn-y p1)))))) (define CENTER (make-posn 200 200)) (define RADIUS 200) ;;circle-pt : number -> posn ;;Given angle-ratio (ie, 120/360, 240/360, 360/360), find a position on the circle with CENTER and RADIUS as defined above. (define (circle-pt angle-ratio) (local ((define theta (* angle-ratio 2 pi))) (make-posn (+ (posn-x CENTER) (* RADIUS (cos theta))) (- (posn-y CENTER) (* RADIUS (sin theta)))))) (define A (circle-pt 120/360)) (define B (circle-pt 240/360)) (define C (circle-pt 360/360)) #| (define WIDTH 400) (define HEIGHT 400) (start WIDTH HEIGHT) (draw-circle CENTER RADIUS 'black) (draw-solid-disk A 5 'green) (draw-solid-disk B 5 'blue) (draw-solid-disk C 5 'purple) |# (define WIDTH 1000) (define HEIGHT 1000) (define x1 (make-posn 0 (round (inexact->exact HEIGHT)))) (define x2 (make-posn (round (inexact->exact WIDTH)) (round (inexact->exact HEIGHT)))) (define x3 (make-posn (round (inexact->exact (/ WIDTH 2))) (round (inexact->exact (* HEIGHT (- 1 (/ (sqrt 3) 2))))))) (start WIDTH HEIGHT) (sierpinski x1 x2 x3 'black)