Note: this wiki is now retired and will no longer be updated!

The static final versions of the pages are left as a convenience for readers. Note that meta-pages such as "discussion," "history," etc., will not work.

SICP exercise 2.51

From Drewiki
Jump to: navigation, search
Comment The solution for this exercise requires the use of the PLT Scheme DrScheme graphical environment. Ensure the DrScheme language is set to Module before running the program.
Comment The picture language implemented by the PLT Scheme SICP picture package is slightly different than the picture language described in the text. The PLT package lacks the wave and rogers pictures; the solution provided here will use the diagonal-shading and einstein pictures provided by the PLT package instead. Also, painters in the PLT picture package don't know how to draw themselves. In order to draw a painter in the DrScheme graphical environment, use the paint procedure: it takes a single argument, the painter to draw, e.g.,

(paint einstein)

The (require ...) expression at the beginning of the program automatically loads the PLT picture package from the DrScheme web site. It may not work if you're attempting to run the program from behind a proxy or outbound firewall.

For more information on the PLT SICP picture package, see here.

Problem

Define the below operation for painters. below takes two painters as arguments. The resulting painter, given a frame, draws with the first painter in the bottom of the frame and with the second painter in the top. Define below in two different ways -- first by writing a procedure that is analogous to the beside procedure given in the text, and again in terms of beside and suitable rotation operations (from exercise 2.50).

Solution

Comment The PLT DrScheme picture language provides its own implementation of below. To avoid a conflict with it, our solution will use the name my-below.

Additionally, the PLT DrScheme version of transform-painter takes only 3 arguments -- the coordinates of the transformed frame -- and returns a procedure which takes a single argument, the painter to be transformed. This definition is slightly different than the definition given in the text, in which transform-painter takes the painter as an additional argument. We'll use the PLT version in our solution, so the general form and use of transformations given here will look slightly different than those in the text.

Here's a definition of my-below that's analogous to the definition of beside given in the text. It defines the "split point" half-way up the y-axis, then uses it as edge 2 of the bottom image and the origin of the top image.

#lang scheme
(require (planet "sicp.ss" ("soegaard" "sicp.plt" 2 1)))
 
(define (my-below painter1 painter2)
  (let ((split-point (make-vect 0.0 0.5)))
    (let ((paint-bottom
           ((transform-painter (make-vect 0.0 0.0)
                               (make-vect 1.0 0.0)
                               split-point)
            painter1))
          (paint-top
           ((transform-painter split-point
                               (make-vect 1.0 0.5)
                               (make-vect 0.0 1.0))
            painter2)))
      (lambda (frame)
        (paint-bottom frame)
        (paint-top frame)))))

Test:

(paint (my-below einstein diagonal-shading))

Ex2.51-below.png


Here's the alternate definition of my-below, using rotations and the beside procedure. We take the painter created by putting the first painter beside the second and rotate it 90 degrees counter-clockwise:

;;; incomplete definition!
(define (my-below2 painter1 painter2)
  (rotate90 (beside painter1 painter2)))

Test:

(paint (my-below2 einstein diagonal-shading))

Ex2.51-incomplete-below.png

All that's left to do now is to rotate the individual painters so that they have the correct orientation in the final image. We can do that by undoing the counter-clockwise 90 degree rotation of whole image, i.e., a clockwise 90 degree rotation, which is equivalent to a 270 degree counter-clockwise rotation. Here's the final alternate definition:

(define (my-below2 painter1 painter2)
  (rotate90 (beside (rotate270 painter1) (rotate270 painter2))))

Test:

(paint (my-below2 einstein diagonal-shading))

Ex2.51-below.png

Personal tools