为什么我在 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