SICP – Section 2.2.4   Leave a comment

This section is a powerful demonstration of abstraction, using a “picture language”. For this section I used the sicp package from the PLaneT repository in DrScheme. Normally, I just use mzscheme and vim, but apparently you need DrScheme open to use that particular (graphical) package. Anyway, I found it pretty enjoyable, and even made some fractals with it.

;;Exercise 2.44

They could have made this one a little tougher ;)
Telling us to flip the arguments to right-split took any challenge out of it…

(define (up-split painter n)
  (if (= n 0)
      painter
      (let ((smaller (up-split painter (- n 1))))
        (below painter (beside smaller smaller)))))

;;Exercise 2.45

We follow the usual patter of making abstractions.

(define (split op1 op2)
  (define (rec painter n)
    (if (= n 0)
        painter
        (let ((smaller (rec painter (- n 1))))
          (op1 painter (op2 smaller smaller)))))
  rec)

(define up-split (split below beside))
(define right-split (split beside below))

;;Exercise 2.46

Not much to it, I used a list, but a cons would do fine too, however, I decided on list, because perhaps we’ll want to add a z coordinate for 3D vectors.

(define (make-myvect x y)
  (list x y))
(define (xcor-myvect vect)
  (car vect))
(define (ycor-myvect vect)
  (cadr vect))

(define (add-myvect a b)
  (make-myvect (+ (xcor-myvect a) (xcor-myvect b))
             (+ (ycor-myvect a) (ycor-myvect b))))

(define (sub-myvect a b)
  (make-myvect (- (xcor-myvect a) (xcor-myvect b))
             (- (ycor-myvect a) (ycor-myvect b))))

(define (scale-myvect s v)
  (make-myvect (* s (xcor-myvect v))
             (* s (ycor-myvect v))))

;;Exercise 2.47

First definition

(define (make-myframe origin edge1 edge2)
  (list origin edge1 edge2))

(define (origin-myframe f) (car f))

(define (edge1-myframe f) (cadr f))

(define (edge2-myframe f) (caddr f))

Second definition

(define (make-myframe origin edge1 edge2)
  (cons origin (cons edge1 edge2)))

(define (origin-myframe f) (car f))

(define (edge1-myframe f) (cadr f))

(define (edge2-myframe f) (cddr f))

;;Exercise 2.48

(define (make-mysegment start end) (cons start end))

(define (start-mysegment seg) (car seg))

(define (end-mysegment seg) (cdr seg))

;;Exercise 2.49


;;a.  The painter that draws the outline of the designated frame.
(define outline (segments->painter (list
  (make-segment (make-vect 0 0)
                (make-vect 0 1))
  (make-segment (make-vect 0 0)
                (make-vect 1 0))
  (make-segment (make-vect .99 0)
                (make-vect .99 1))
  (make-segment (make-vect 0 .99)
                (make-vect 1 .99)))))

;;b.  The painter that draws an ``X'' by connecting opposite corners of the frame.
(define X (segments->painter (list
  (make-segment (make-vect 0 0)
                (make-vect 1 1))
  (make-segment (make-vect 1 0)
                (make-vect 0 1)))))

;;c.  The painter that draws a diamond shape by connecting the midpoints of the sides of the frame.
(define diamond (segments->painter (list
  (make-segment (make-vect 0 .5)
                (make-vect .5 0))
  (make-segment (make-vect .5 0)
                (make-vect 1 .5))
  (make-segment (make-vect 1 .5)
                (make-vect .5 1))
  (make-segment (make-vect .5 1)
                (make-vect 0 .5)))))

;;d.  The wave painter.
(define wave (segments->painter (list
  (make-segment (make-vect 0 .84) (make-vect .13 .6))
  (make-segment (make-vect .13 .6) (make-vect .3 .66))
  (make-segment (make-vect .3 .66) (make-vect .4 .66))
  (make-segment (make-vect .4 .66) (make-vect .36 .84))
  (make-segment (make-vect .36 .84) (make-vect .4 1))
  (make-segment (make-vect .6 1) (make-vect .64 .84))
  (make-segment (make-vect .64 .84) (make-vect .6 .66))
  (make-segment (make-vect .6 .66) (make-vect .71 .66))
  (make-segment (make-vect .71 .66) (make-vect 1 .34))
  (make-segment (make-vect 1 .16) (make-vect .6 .44))
  (make-segment (make-vect .6 .44) (make-vect .74 0))
  (make-segment (make-vect .6 0) (make-vect .5 .3))
  (make-segment (make-vect .5 .3) (make-vect .4 0))
  (make-segment (make-vect .24 0) (make-vect .34 .5))
  (make-segment (make-vect .34 .5) (make-vect .3 .6))
  (make-segment (make-vect .3 .6) (make-vect .14 .4))
  (make-segment (make-vect .14 .4) (make-vect 0 .64)))))

;;Exercise 2.50
The key to figuring these out is to draw a diagram of the unit square, draw the original picture, and then draw the rotated one, and note the coordinates of the origin, edge1, and edge2.

(define (myflip-horiz painter)
  ((transform-painter (make-vect 1 0)
                      (make-vect 0 0)
                      (make-vect 1 1)) painter))

(define (rotate-90 painter)
  ((transform-painter (make-vect 1 0)
                     (make-vect 1 1)
                     (make-vect 0 0)) painter))

(define (rotate-180 painter)
  ((transform-painter (make-vect 1 1)
                      (make-vect 0 1)
                      (make-vect 1 0)) painter))

(define (rotate-270 painter)
  ((transform-painter (make-vect 0 1)
                      (make-vect 0 0)
                      (make-vect 1 1)) painter))

;;Exercise 2.51

(define (my-below painter1 painter2)
  (let ((split-point (make-vect 0 .5)))
    (let ((paint-top
           ((transform-painter split-point
                               (make-vect 1 .5)
                               (make-vect 0 1)) painter1))
          (paint-bottom
           ((transform-painter (make-vect 0 0)
                               (make-vect 1 0)
                               split-point) painter2)))
      (lambda (frame)
        (paint-top frame)
        (paint-bottom frame)))))

(define (my-below2 painter1 painter2)
  (rotate-90 (beside (rotate-270 painter1) (rotate-270 painter2))))

Okay, this has been a pretty boring article… lack of pictures, &c. However, I do have a couple pictures of some nice fractals that I generated with some functions I wrote in this picture language.

The sierpinski painter generates a sierpinski triangle with n iterations using an MRCM (Multiple Reduction Copy Machine) process. This is based on the idea from the book, Computational Beauty of Nature.

(define (sierpinski painter n)
  (if (= n 0)
      painter
            (let ((top ((transform-painter (make-vect .25 0)
                      (make-vect .75 0)
                      (make-vect .25 1))
                      painter)))
        (sierpinski (below (beside painter painter) top) (- n 1))))) 

And here it is generating it with the einstein painter.

There’s also another neat fractal, which is defined as

(define (crystal painter n)
  (if (= n 0)
      painter
            (let ((top ((transform-painter (make-vect .25 0)
                      (make-vect .75 0)
                      (make-vect .25 1))
                      painter)))
        (crystal (below (beside (rotate-90 painter)
                                   (rotate-270 painter))
                           top)
                    (- n 1))))) 

And looks like

As you can see, it’s pretty easy to define MRCM fractals using this picture language.

Advertisements

Posted 24/04/2010 by Emmanuel Jacyna in Code, Scheme, SICP

Tagged with , , , ,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: