Skip to content

2.51

; 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).
#lang racket
(require (planet "sicp.ss" ("soegaard" "sicp.plt" 2 1)))

; Helpers
(define (xcor-vect v) (car v))
(define (ycor-vect v) (cdr v))
(define (sub-vect v1 v2)
    (make-vect 
        (- (xcor-vect v1) (xcor-vect v2))
        (- (ycor-vect v1) (ycor-vect v2))))

(define (transform-painter painter origin corner1 corner2)
  (lambda (frame)
    (let ((m (frame-coord-map frame)))
      (let ((new-origin (m origin)))
        (painter (make-frame
                   new-origin
                   (sub-vect (m corner1) new-origin)
                   (sub-vect (m corner2) new-origin)))))))

; (i) Below procedure analogous to `beside`
(define (below painter1 painter2)
  (let ((split-point (make-vect 0 0.5)))
    (let ((paint-bottom (transform-painter
            painter1
            (make-vect 0 0)
            (make-vect 1 0)
            split-point))
          (paint-top
           (transform-painter
            painter2
            split-point
            (make-vect 1 0.5)
            (make-vect 0 1))))
      (lambda (frame) (paint-bottom frame) (paint-top frame)))))

; Test 
(define f1-list (list (make-segment (make-vect 0.3 0.3) (make-vect 0.5 0.7))
                      (make-segment (make-vect 0.5 0.7) (make-vect 0.8 0.3))))
(define f1 (segments->painter f1-list))
(display "\nFrame 1\n")
(paint f1)

(display "\nBelow Frame1 & Frame1\n")
(paint (below f1 f1))

; (ii) Below procedure using beside and rotation
(define (below2 painter1 painter2)
  (rotate270 (beside (rotate90 painter2) (rotate90 painter1))))

; Test
(display "\nBelow Frame1 & Frame1\n")
(paint (below2 f1 f1))