【问题标题】:How frames are used in the picture language in SICP?SICP中的图片语言是如何使用帧的?
【发布时间】:2013-03-20 11:36:53
【问题描述】:

我似乎无法理解 SICP 中框架的实现。

书上说

我们将使用单位正方形 (0

图像如何表示为坐标?我能想到的唯一解释是,所有图像,作为线条,只能映射到边界不能超过单位正方形的框架。但我对此表示怀疑,因为书中的下一行解释了“框架坐标图”,说

地图通过将向量 v = (x,y) 映射到向量和 Origin(Frame) + x*Edge1(Frame) + y*Edge2(Frame) 将单位正方形转换为框架

向量 (0,0) 被映射到框架的原点,而 (1,1) 被映射到与原点对角对角的顶点,这只会增加我的困惑。这些向量是什么?图片的来源还是什么?

我无法理解这一点,它阻止了我进一步深入正文,因为之后讨论的所有内容都建立在这个概念之上。如果我能详细解释读过这本书的人是如何理解这个想法的,我会觉得非常有帮助。

【问题讨论】:

    标签: scheme image sicp


    【解决方案1】:

    您对图像的解释是正确的。图像由单位正方形中的线段组成,原点 (0, 0) 为左下角,(1, 1) 为右上角。

    画家使用问题中给出的转换将图像映射到框架中。上面的einsten 图像是在默认框架(单位正方形)中绘制的,因此看起来很正常。

    您可以通过三个步骤使用The SICP Picture Language 创建和显示图像:

    • 定义线段列表
    • 根据这些线段创建线段绘制器
    • 使用新的段绘制器调用绘制

    我通过博客帖子SICP 2.49: Defining Primitive Painters 中的几张简单图片来做到这一点。这是一个仅使用两条线段的简单示例:

    ; The painter that draws an 'X' by connecting opposite corners of the frame.
    (define x-segments
     (list
      (make-segment
       (make-vect 0.0 0.0)
       (make-vect 0.99 0.99))
      (make-segment
       (make-vect 0.0 0.99)
       (make-vect 0.99 0.0))))
    
    (define x-painter (segments->painter x-segments))
    
    (paint x-painter)
    

    这是我在 DrRacket 中运行最后一条命令时的结果:

    您可以通过创建要绘制的新框架来翻转和旋转图像。

    一帧由三个向量定义:

    • 起源
    • 底边 (edge1)
    • 左边缘(edge2)

    您可以使用transform-painter 函数given in the text(在标题为转换和组合painters的部分中)使用新的原点和边缘来转换现有的segmentpainter。

    (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)))))))
    

    例如,如果我想绘制向左旋转 45 度的原始爱因斯坦图像,我只需将 einstein 分段绘制器连同新的原点、底部边缘和左侧边缘传递给 transform-painter 和它将返回一个新的段画家。换句话说,我需要告诉transform-painter在哪里绘制图像的左下角、右下角和左上角,它会完成原始线段绘制器中所有线段的转换工作。

    ; rotate an image 45 degrees to the left
    (define (rotate-45 painter)
      ((transform-painter (make-vect 0.5 0.0)
                          (make-vect 1.0 0.5)
                          (make-vect 0.0 0.5))
       painter))
    

    您可以执行命令(paint (rotate-45 einstein))查看旋转后的图像。

    【讨论】:

    • 非常感谢比尔。我现在明白了。顺便说一句,你博客的粉丝。
    • @user2190496 谢谢!我很快就会再次更新它。
    【解决方案2】:

    据我所知,这些帧是用相对于单位正方形的坐标定义的矢量图,并且可以从那里缩放、映射并通常转换到具有给定坐标系的坐标系中产地和大小。这一切都在“frames”部分下的book 中。

    您可以正确地假设所有图像都包含在单位正方形中,事实就是如此。然而,这根本不是一个限制——单位正方形中有无限数量的坐标点,你可以想象的任何图像都适合在那里。定义坐标在 [0, 1] 范围内,这只是一个约定问题;如果它们在 [1, 1000] 范围内,则相同,您可以通过移动小数点从一个坐标系映射到另一个坐标系。

    【讨论】:

    • 书中说“单位正方形中的坐标(0Edge1(Frame) + yEdge2(Frame)" 我的理解是,所有图像都有尺寸不超过一个单位平方,但我们可以使用框架来放大和缩小它们。我认为这是不对的。这很困难,因为我觉得我在某个地方使用了一个误解来填补一个完全让我失望的空白。
    • @user2190496 你是对的,假设所有图像都包含在单位正方形中,就是这样。但是,这根本不是限制,单位正方形中有无数个坐标点,您可以梦想的任何图像都适合在那里。这只是一个约定问题,定义坐标在 [0, 1] 范围内。如果它们在 [1, 1000] 范围内也是一样的,您可以通过移动小数点从一个映射到另一个
    • 那么让我看看我是否有这个权利。由于单位正方形内有无限数量的点,并且所有图像都可以在其中表示,因此一帧只不过是单位正方形边界的表示,在其中我们可以将任何图像移动和缩放到任意程度。是这样吗?
    • @user2190496 完全正确!你明白了!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-19
    • 2020-07-26
    • 2023-03-04
    相关资源
    最近更新 更多