Affine Transformations, Part II - psholtz/MIT-SICP GitHub Wiki

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 above, and again in terms of "beside" and suitable rotation operations (from Exercise 2.50).

Solution

As with the previous exercise, this problem can be stated (and solved) largely in the language of affine transformations.

We really have two linear transformations here, one that will transform the "bottom" painter, and the second which will transform the "top" painter. In other words, we have something like:

http://farm9.staticflickr.com/8339/8277165032_2d7e20cc47_o.jpg

Bottom Painter

The first (i.e., bottom) transformation is given simply by "squishing" the painter down into the lower half of the unit square:

http://farm9.staticflickr.com/8216/8276106109_2cf5c2ace3_o.jpg

Taking our three frame-defining vectors:

http://farm9.staticflickr.com/8498/8275789131_c1f37c7384_o.jpg

these are carried by the linear transformation into:

http://farm9.staticflickr.com/8340/8276106097_8528b340b2_o.jpg

Top Painter

The second (i.e., top) transformation is given by "squishing" the painter down to the same dimensions as previously, but then also translating the paint upwards by half a unit (i.e., add the vector (0,0.5)):

http://farm9.staticflickr.com/8204/8277165002_9fd0f162ce_o.jpg

In this case, the three frame-defining vectors are carried by the linear transformation into:

http://farm9.staticflickr.com/8496/8276133789_a30380e7e8_o.jpg

These results agree with what we programmed in the Scheme code.

;; first definition
(define (below painter1 painter2)
 (let ((split-point (make-vect 0.0 0.5)))
  (let ((paint-bottom
         (transform-painter painter1
                            (make-vect 0.0 0.0)
                            (make-vect 1.0 0.0)
                            split-point))
        (paint-top
         (transform-painter painter2
                            split-point
                            (make-vect 1.0 0.5)
                            (make-vect 0.0 1.0))))
   (lambda (frame)
    (paint-bottom frame)
    (paint-top frame)))))
;; second definition
(define (below painter1 painter2)
 (rotate270 (beside (rotate90 painter2) (rotate90 painter1))))

http://farm9.staticflickr.com/8482/8266751172_4fe901a84a_o.jpg