为什么我在 SICP 图片语言中执行的以下程序表现异常?
Why my below procedure implementation in the SICP picture language is behaving strangely?
我一直在做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),这对应于底部的图像。然而第二个画家被放在那里!可能我遗漏了一些非常明显的东西,但我不明白为什么它会以相反的方式表现。有人可以向我解释我做错了什么吗?
难道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
我一直在做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),这对应于底部的图像。然而第二个画家被放在那里!可能我遗漏了一些非常明显的东西,但我不明白为什么它会以相反的方式表现。有人可以向我解释我做错了什么吗?
难道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