Blob


1 ;; The first three lines of this file were inserted by DrScheme. They record metadata
2 ;; about the language level of this file in a form that our tools can easily process.
3 #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")))))
4 ;The minimum area before the approximating triangle of the Bezier curve is drawn.
5 (define MINAREA 10)
7 ;bezier : posn posn posn symbol -> true
8 ;Draw a smooth curve from p1 to p3, viewed from p2. In the trivial case, where the area of the triangle is very small, simply draw the triangle. When the triangle is not small, partition the larger triangle into two smaller triangles, where the first triangle is composed of p1, the midpoint of p1 and p2 (termed r2), and the midpoint between r2 and the midpoint between p2 and p3 (termed q2). The second triangle is composed of p3, q2, and the midpoint between r2 and q2. Repeat bezier on these successive triangles.
10 (define (bezier p1 p2 p3 color)
11 (local ((define r2 (midpoint p1 p2))
12 (define q2 (midpoint p2 p3))
13 (define m (midpoint r2 q2)))
14 (cond
15 [(small-enough? p1 p2 p3) (draw-triangle p1 p2 p3 color)]
16 [else (and (bezier p1 r2 m color)
17 (bezier m q2 p3 color))])))
19 ;small-enough? : posn posn posn -> boolean
20 ;Determine if the triangle is small enough to draw.
22 (define (small-enough? a b c)
23 (< (area-of-triangle a b c) MINAREA))
25 ;distance : posn posn -> number
26 ;Given p1, p2, determine the distance between two points.
28 (define (distance p1 p2)
29 (sqrt (+ (sqr (- (posn-x p2) (posn-x p1)))
30 (sqr (- (posn-y p2) (posn-y p1))))))
32 ;midpoint : posn posn -> posn
33 ;Given a, b, find the midpoint of the two posns.
35 (define (midpoint a b)
36 (make-posn (/ (+ (posn-x a) (posn-x b)) 2)
37 (/ (+ (posn-y a) (posn-y b)) 2)))
39 ;draw-triangle : posn posn posn -> true
40 ;Draw the triangle that contains a, b, and c as vertices.
42 (define (draw-triangle a b c color)
43 (and (draw-solid-line a b color)
44 (draw-solid-line b c color)
45 (draw-solid-line c a color)))
47 ;area-of-triangle : posn posn posn -> number
48 ;Given a, b, c, determine the area of the triangle. (uses Heron's formula)
50 (define (area-of-triangle a b c)
51 (local ((define A (distance b c))
52 (define B (distance a c))
53 (define C (distance a b))
54 (define semiperimeter (/ (+ A B C) 2)))
55 (sqrt (* semiperimeter
56 (- semiperimeter A)
57 (- semiperimeter B)
58 (- semiperimeter C)))))
60 (define x1 (make-posn 300 300))
61 (define x2 (make-posn 400 500))
62 (define x3 (make-posn 500 200))
64 (define p1 (make-posn 50 50))
65 (define p2 (make-posn 150 150))
66 (define p3 (make-posn 250 100))
68 (start 1000 1000)
69 (bezier x1 x2 x3 'blue)
70 (bezier p1 p2 p3 'purple)