我一直在做SICP图片语言示例练习2.51的第一部分。以下是我的解决方案和我得到的结果。
#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)
我希望通过这段代码,爱因斯坦图像将在练习器请求时呈现以下对角线阴影。在代码中可见,第一个画家用于转换,将原点移动到(0,0.5),第一个边缘移动到(1,0.5),第二个边缘移动到(0,1),它们与底部相对应图像。然而第二位画家就在那里!可能我错过了一些非常明显的东西,但我不明白它为什么会以相反的方式表现。有人可以向我解释我做错了什么吗?
答案 0 :(得分:1)
可能是y轴指向上方吗?
如果我们更改transform-painter
以显示新的来源和框架:
(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)))))))
您的示例的输出是:
((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)
我们可以从输出中看到两个来源已被交换。
奖励信息:此处提供了sicp图片语言的重新实现。重新实现支持更大的图像,颜色等。
https://raw.githubusercontent.com/sicp-lang/sicp/master/sicp-pict2/sicp.rkt
将文件保存在磁盘上,然后将此爱因斯坦图像保存在同一文件夹中。
https://github.com/sicp-lang/sicp/blob/master/sicp-pict2/einstein2.jpg