SICP Exercise 2.49

Question

Use segments->painter to define the following primitive painters:

  1. The painter that draws the outline of the designated frame.
  2. The painter that draws “X” by connecting opposite corners of the frame.
  3. The painter that draws a diamond shape by connecting the midpoints of the sides of the frame.
  4. The wave painter.

Answer

Let’s define some kind of frame first:

(define o (make-vect 100 100))
(define e1 (make-vect 50 100))
(define e2 (make-vect 200 50))
(define f (make-frame o e1 e2))

And then we need the different segment-list​s. Warning, this is going to be long:

; test 1
(define outline-segments
  (list
    (make-segment (make-vect 0 0) (make-vect 0 1))
    (make-segment (make-vect 0 1) (make-vect 1 1))
    (make-segment (make-vect 1 1) (make-vect 1 0))
    (make-segment (make-vect 1 0) (make-vect 0 0))))

; test 2
(define x-segments
  (list
    (make-segment (make-vect 0 0) (make-vect 1 1))
    (make-segment (make-vect 0 1) (make-vect 1 0))))

; test 3
(define diamond-segments
  (list
    (make-segment (make-vect 0.5 0) (make-vect 0 0.5))
    (make-segment (make-vect 0 0.5) (make-vect 0.5 1))
    (make-segment (make-vect 0.5 1) (make-vect  1 0.5))
    (make-segment (make-vect 1 0.5) (make-vect 0.5 0))))

; test 4
(define wave-segments
 (list
  (make-segment
   (make-vect 0.006 0.840) (make-vect 0.155 0.591))
  (make-segment
   (make-vect 0.006 0.635) (make-vect 0.155 0.392))
  (make-segment
   (make-vect 0.304 0.646) (make-vect 0.155 0.591))
  (make-segment
   (make-vect 0.298 0.591) (make-vect 0.155 0.392))
  (make-segment
   (make-vect 0.304 0.646) (make-vect 0.403 0.646))
  (make-segment
   (make-vect 0.298 0.591) (make-vect 0.354 0.492))
  (make-segment
   (make-vect 0.403 0.646) (make-vect 0.348 0.845))
  (make-segment
   (make-vect 0.354 0.492) (make-vect 0.249 0.000))
  (make-segment
   (make-vect 0.403 0.000) (make-vect 0.502 0.293))
  (make-segment
   (make-vect 0.502 0.293) (make-vect 0.602 0.000))
  (make-segment
   (make-vect 0.348 0.845) (make-vect 0.403 0.999))
  (make-segment
   (make-vect 0.602 0.999) (make-vect 0.652 0.845))
  (make-segment
   (make-vect 0.652 0.845) (make-vect 0.602 0.646))
  (make-segment
   (make-vect 0.602 0.646) (make-vect 0.751 0.646))
  (make-segment
   (make-vect 0.751 0.646) (make-vect 0.999 0.343))
  (make-segment
   (make-vect 0.751 0.000) (make-vect 0.597 0.442))
  (make-segment
   (make-vect 0.597 0.442) (make-vect 0.999 0.144))))

And then we can call the function like this:

((segments->painter outline-segments) f)

And we receive the following images.

Outline:

X:

Diamond:

Wave: