Reputation: 169
I have been doing the first part of exercise 2.51 of the SICP picture language example. Following is my solution and the result that I got.
#lang sicp
(#%require sicp-pict)
(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
(vector-sub (m corner1) new-origin)
(vector-sub (m corner2) new-origin)))))))
(define (below painter1 painter2)
(let ((split-point (make-vect 0.0 0.5)))
(let ((paint-bottom
(transform-painter painter1
split-point
(make-vect 1.0 0.5)
(make-vect 0.0 1.0)))
(paint-top
(transform-painter painter2
(make-vect 0.0 0.0)
(make-vect 1.0 0.0)
split-point)))
(lambda (frame)
(paint-top frame)
(paint-bottom frame)))))
(define einstein-below-diagonal-shading (below einstein diagonal-shading))
(paint einstein-below-diagonal-shading)
I expect with this code that the einstein image will be rendered below the diagonal shading as the excercise requests. As visible in the code the first painter is used in the transformation that moves the origin to the (0, 0.5), the first edge to (1, 0.5) and the second edge to (0, 1) which correspongs to the bottom part of the image. Yet the second painter is placed there! Probably I am missing something very obvious but I don't understand why is it behaving in the opposite way. Can someone explain to me what am I doing wrong?
Upvotes: 1
Views: 111
Reputation: 31145
Could it be that the y-axis points upwards?
If we change transform-painter
to display the new origin and frames:
(define (transform-painter painter origin corner1 corner2)
(lambda (frame)
(let ((m (frame-coord-map frame)))
(let ((new-origin (m origin)))
(display (list origin corner1 corner2)) (newline)
(display new-origin) (newline)
(display (vector-sub (m corner1) new-origin)) (newline)
(display (vector-sub (m corner2) new-origin)) (newline)
(painter
(make-frame new-origin
(vector-sub (m corner1) new-origin)
(vector-sub (m corner2) new-origin)))))))
The output of your example is:
((0.0 . 0.0) (1.0 . 0.0) (0.0 . 0.5))
(0.0 . 0.0) ; <- new origin for top
(128.0 . 0.0)
(0.0 . 64.0)
((0.0 . 0.5) (1.0 . 0.5) (0.0 . 1.0))
(0.0 . 64.0) ; <- new origin for botton
(128.0 . 0.0)
(0.0 . 64.0)
We can see from the output, that the two origins have been swapped.
Bonus info: There is an reimplementation of the sicp picture language available here. The reimplementation supports larger images, colors and more.
https://raw.githubusercontent.com/sicp-lang/sicp/master/sicp-pict2/sicp.rkt
Save the file on your disk, then save this image of einstein in the same folder.
https://github.com/sicp-lang/sicp/blob/master/sicp-pict2/einstein2.jpg
Upvotes: 1