Question

I can't seem to get my head around the implementation of frames in SICP.

The book states

We will use coordinates in the unit square (0< x,y< 1) to specify images

How are images expressed as coordinates? The only interpretation I can muster is that all images, being lines, can only be mapped to a frame whose boundary can not exceed that of a unit square. But I doubt that because the next line in the book, explaining a "frame coordinate map", says

The map transforms the unit square into the frame by mapping the vector v = (x,y) to the vector sum Origin(Frame) + x*Edge1(Frame) + y*Edge2(Frame)

The vector (0,0) being mapped to the origin of the frame and (1,1) to the vertex diagonally opposite the origin, only adds to my confusion. What are these vectors? The origin of the image or what?

I can't make sense of this and it's preventing me from moving further into the text as everything discussed after builds on this concept. I'd find it very helpful if I could get a detailed explanation of how any one who's read the book understood this idea.

Was it helpful?

Solution 2

As far as I remember, the frames are vector images defined with coordinates relative to the unit square, and from there they can be scaled, mapped and in general transformed into a coordinate system with a given origin and size. It's all in the book under the "frames" section.

You can correctly assume that all images are contained in the unit square, that's how it is. However, this is not a limitation at all - there's an infinite number of coordinate points in the unit square, and any image you can dream of fits in there. Defining that the coordinates are in the range [0, 1] it's just a matter of convention; it'd be the same if they were in the range [1, 1000], you can map from one coordinate system to the other by moving the decimal point.

OTHER TIPS

Your interpretation of images is correct. Images are made up of line segments in a unit square where the origin (0, 0) is the bottom left corner and (1, 1) is the top right corner.

Einstein drawn in the default frame

A painter maps the image into a frame using the transformation given in the question. The einsten image above is drawn in the default frame (the unit square) so it appears normal.

You can create and display an image using The SICP Picture Language in three steps:

  • define a list of line segments
  • create a segment painter from those line segments
  • call paint with the new segment painter

I do this with several simple images in by blog post SICP 2.49: Defining Primitive Painters. Here's one simple example using just two line segments:

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

Here's the result when I run that last command in DrRacket:

simple painter

You can flip and rotate an image by creating new frames for it to be drawn in.

A frame is defined by three vectors:

  • the origin
  • the bottom edge (edge1)
  • the left edge (edge2)

enter image description here

You can use the transform-painter function given in the text (in the section titled Transforming and combining painters) to transform an existing segment painter using a new origin and edges.

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

For example, if I want to draw the original Einstein image rotated 45 degrees to the left, I just need to pass the einstein segment painter along with a new origin, bottom edge, and left edge to transform-painter and it will return a new segment painter. In other words, I need to tell transform-painter where to draw the bottom left, bottom right, and top left corners of the image, and it will do the work of transforming all of the line segments in the original segment 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))

You can execute the command (paint (rotate-45 einstein)) to see the rotated image.

Einstein rotated 45 degrees

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top