Square limit language - Building Programming Experience - Lecture Slides, Slides of Computer Programming

Some concept of Building Programming Experience are Trees, Square Limit Language, Special Forms, Quizanssheet, Professor Abstraction, Compound Procedure, Procedures And Recursion. Main points of this lecture are: Square Limit Language, Peter Henderson’S, Described, Programming Assignment, Data Abstraction, Appropriate Primitives, Derives, Expressive Power, Squarelimit Language, Painter Procedures

Typology: Slides

2012/2013

Uploaded on 04/25/2013

lathika
lathika 🇮🇳

4

(12)

167 documents

1 / 10

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
1
The Square-limit language
Issued: Tuesday, September 24, 1996
Written solutions due: in recitation on Friday, October 4, 1996
Tutorial preparation for: week of September 30, 1996
Reading: Section 2.2; code files hend.scm and hutils.scm (attached)
In this assignment, you will work with Peter Henderson’s “square-limit” graphics design language,
which will be described in lecture on September 26, and which appears in Section 2.2.4 of the notes.
Before beginning work on this programming assignment, you should review that section. The goal
of this problem set is to reinforce ideas about data abstraction and higher-order procedures, and
to emphasize the expressive power that derives from appropriate primitives, means of combination,
and means of abstraction.1
Section 1 of this handout reviews the language, similar to what appears in the notes. You will need
to study this in order to prepare the tutorial presentations in section 2. Section 3 gives the lab
assignment, which includes an optional design contest.
1. The Square-limit language
Recall that the key idea in the square-limit language is to use painter procedures that take frames
as inputs and paint images that are scaled to fit the frames. To do this, we will need some basic
building blocks.
Basic data structures
Vectors consist of a pair of numbers, glued together in some appropriate manner. The contract we
enforce for this data abstraction is the following:
the constructor make-vect takes two arguments and associates them into a vector, and
the selectors xcor-vect and ycor-vect return the components of the vector constructed by
make-vect. (You’ll actually implement this abstraction later on, but of course for purposes
of discussion, we only need to know the abstraction contract.)
We need a set of op e rations on vectors, and in particular assume three:
This problem set was developed by Hal Abelson, based upon work by Peter Henderson (“Functional Geometry,”
in Proc. ACM Conference on Lisp and Functional Programming, 1982). The image display code was designed and
implemented by Daniel Coore.
1
Docsity.com
pf3
pf4
pf5
pf8
pf9
pfa

Partial preview of the text

Download Square limit language - Building Programming Experience - Lecture Slides and more Slides Computer Programming in PDF only on Docsity!

The Squarelimit language

Issued: Tuesday, September 24, 1996

Written solutions due: in recitation on Friday, October 4, 1996

Tutorial preparation for: week of September 30, 1996

Reading: Section 2.2; code files hend.scm and hutils.scm (attached)

In this assignment, you will work with Peter Henderson’s “squarelimit” graphics design language, which will be described in lecture on September 26, and which appears in Section 2.2.4 of the notes. Before beginning work on this programming assignment, you should review that section. The goal of this problem set is to reinforce ideas about data abstraction and higherorder procedures, and to emphasize the expressive power that derives from appropriate primitives, means of combination, and means of abstraction.^1

Section 1 of this handout reviews the language, similar to what appears in the notes. You will need to study this in order to prepare the tutorial presentations in section 2. Section 3 gives the lab assignment, which includes an optional design contest.

1. The Squarelimit language

Recall that the key idea in the squarelimit language is to use painter procedures that take frames as inputs and paint images that are scaled to fit the frames. To do this, we will need some basic building blocks.

Basic data structures

Vectors consist of a pair of numbers, glued together in some appropriate manner. The contract we enforce for this data abstraction is the following:

  • the constructor makevect takes two arguments and associates them into a vector, and
  • the selectors xcorvect and ycorvect return the components of the vector constructed by makevect. (You’ll actually implement this abstraction later on, but of course for purposes of discussion, we only need to know the abstraction contract.)

We need a set of operations on vectors, and in particular assume three:

This problem set was developed by Hal Abelson, based upon work by Peter Henderson (“Functional Geometry,” in Proc. ACM Conference on Lisp and Functional Programming, 1982). The image display code was designed and implemented by Daniel Coore.

1

  • addvect takes two vectors as input, and returns as output another vector, whose components are the sums of the components of the input vectors;
  • subvect takes two vectors as input, and returns as output another vector, whose components are the differences of the components of the input vectors (e.g. the first vector minus the second);
  • scalevect takes as input a number and a vector and returns a vector whose components are the components of the input vector, multiplied by the input number.

A pair of vectors determines a directed line segment—the segment running from the endpoint of the first vector to the endpoint of the second vector. Again, we just need a contract:

  • constructor is makesegment and
  • selectors are startsegment and endsegment.

Frames

A frame is represented by three vectors: an origin and two edge vectors.

(define (makeframe origin edge1 edge2) (list ’frame origin edge1 edge2)) \null (define originframe cadr) (define edge1frame caddr) (define edge2frame cadddr)

The frame’s origin is given as a vector with respect to the origin of the graphicswindow coordinate system. The edge vectors specify the offsets of the corners of the frame from the origin of the frame. If the edges are perpendicular, the frame will be a rectangle; otherwise it will be a more general parallelogram.

Each frame determines a system of “frame coordinates” (x, y) where (0, 0) is the origin of the frame, x represents the displacement along the first edge (as a fraction of the length of the edge) and y is the displacement along the second edge. For example, the origin of the frame has frame coordinates (0, 0) and the vertex diagonally opposite the origin has frame coordinates (1, 1).

Another way to express this idea is to say that each frame has an associated frame coordinate map that transforms the frame coordinates of a point into the Cartesian plane coordinates of the point. That is, (x, y) gets mapped onto the Cartesian coordinates of the point given by the vector sum

Origin(Frame) + x · Edge 1 (Frame) + y · Edge 2 (Frame)

We can represent the frame coordinate map by the following procedure:

You can also specify a painter using procedure>painter, which takes a procedure as argument. The procedure determines a gray level (0 to 255) as a function of (x, y) position, for example:

(define diagonalshading (procedure>painter (lambda (x y) (* 100 (+ x y)))))

The x and y coordinates run from 0 to 1 and specify the fraction that each point is offset from the frame’s origin along the frame’s edges. Thus, the frame is filled out by the set of points (x, y) such that 0 ≤ x, y ≤ 1.

A third kind of painter is created by segments>painter , which takes a list of line segments as argument. This paints the line drawing specified by the list segments. The (x, y) coordinates of the line segments are specified as above. For example, you can make the “Z” shape as

(define markofzorro (let ((v1 (makevect .1 .9)) (v2 (makevect .8 .9)) (v3 (makevect .1 .2)) (v4 (makevect .9 .3))) (segments>painter (list (makesegment v1 v2) (makesegment v2 v3) (makesegment v3 v4)))))

The final way to create a primitive painter is from a stored image. The procedure loadpainter uses an image from the image collection to create a painter 2. For instance:

(define fovnder (loadpainter "fovnder"))

will paint an image of William Barton Rogers, the fovnder of MIT.

Transforming and combining painters

Given a painter, we can produce a new painter that transforms its frame before painting in it. For example, if p is a painter and f is a frame, then

(p ((makerelativeframe (makevect .5 .5) (makevect 1 .5) (makevect .5 1)) f))

will paint in the upperrighthand corner of the frame.

We can abstract this idea with the following procedure: (^2) The images are kept in the directory. The loadpainter procedure transforms them into painters, so that they can be scaled and deformed by the operations in the squarelimit language. Use the Edwin command Mx listdirectory to see entire contents of the directory. Each image is 128 × 128, stored in “pgm” format.

[Note: In "fovnder" we see the use of the Latin 'v' that represents a modern 'u'.]

(define (transformpainter origin corner1 corner2) (lambda (painter) (compose painter (makerelativeframe origin corner1 corner2))))

Calling transformpainter with an origin and two corners returns a procedure that transforms a painter into one that paints relative to a new frame with the specified origin and corners. For example, we could define:

(define (shrinktoupperleft painter) ((transformpainter (makevect .5 .5) (makevect 1 .5) (makevect .5 1)) painter))

Note that this can be written equivalently as

(define shrinktoupperleft (transformpainter (makevect .5 .5) (makevect 1 .5) (makevect .5 1)))

Another transformed frame, called fliphoriz should flip images horizontally (we’ll ask you to implement this later), another rotates images counterclockwise by 90 degrees:

(define rotate (transformpainter (makevect 1 0) (makevect 1 1) (makevect 0 0)))

and similar rotations, rotate180 and rotate270, can be created.

We can combine the results of two painters in a single frame by calling each painter on the frame:

(define (superpose painter1 painter2) (lambda (frame) (painter1 frame) (painter2 frame)))

To draw one image beside another, we combine one in the left half of the frame with one in the right half of the frame:

(define (beside painter1 painter2) (let ((splitpoint (makevect .5 0))) (superpose ((transformpainter zerovector splitpoint (makevect 0 1))

Tutorial exercise 4: Section 1 defines below in terms of beside and rotate. Give an alternative definition of below that does not use beside.

Tutorial exercise 5: Describe the effect of

(transformpainter (makevect .1 .9) (makevect 1.5 1) (makevect .2 0))

3. To do in lab

Load the code for problem set 3, which contains the procedures described in section 1. You will not need to modify any of these. We suggest that you define your new procedures in a separate (initially empty) editor buffer, to make it easy to reload the system if things get fouled up.

When the problem set code is loaded, it will create three graphics windows, named g1, g2, and g3. To paint a picture in a window, use the procedure paint. For example,

(paint g1 fovnder)

will show a picture of William Barton Rogers in window g1 (once you have successfully completed lab exercise 1 and (loadrest) successfully evaluates.

There is also a procedure called painthires , which paints the images at higher resolution (256 × 256 rather than 128 × 128). Painting at a higher resolution produces better looking images, but takes four times as long. As you work on this problem set, you should look at the images using paint, and reserve painthires to see the details of images that you find interesting.^3

Printing pictures You can print images on the laserjet printer with Edwin’s Mx printgraphics command as described in the Don’t Panic manual. The laserjet cannot print true greyscale pictures, so the pictures will not look as good as they do on the screen. Please print only a few images—only the ones that you really want—so as not to waste paper and clog the printer queues. We suggest that you print only images created with painthires, not paint.

Lab exercise 1: Complete the implementation of the data abstractions, by choosing a repre sentation for vectors (makevect, xcorvect, ycorvect) and for segments (makesegment, startsegment, endsegment). Use those abstractions to implement the three operations on vectors (addvect, subvect, scalevect). You may find it convenient to do this in the copy of hutils.scm that was loaded into your editor. Once you are done adding your definitions, save the file and then load it into your Scheme buffer by evaluating:

(load ‘‘~/work/hutils.scm’’) (^3) Painting a primitive image like fovnder won’t look any different at high resolution, because the original picture is only 128 × 128. But as you start stretching and shrinking the image, you will see differences at higher resolution.

If you work on the problem set in multiple sessions, be sure that you reload this file after you have loaded up the problem set, so that your new definitions will override the ones in the problem set file. Turn in a listing of your code, and some examples of using it.

Once you have created your data abstractions, evaluate

(loadrest)

to have the rest of the code for the problem set loaded into your Scheme environment.

Lab exercise 2: Make a collection of primitive painters to use in the rest of this lab. In addition to the ones predefined for you (and listed in section 1), define at least one new painter of each of the four primitive types: a uniform grey level made with number>painter, something defined with procedure>painter, a linedrawing made with segments>painter, and an image of your choice that is loaded from the 6001 image collection with loadpainter. Turn in a list of your definitions.

Lab exercise 3: Earlier we referred to examples of transforming painters, i.e. procedures that take a painter as input and create a new painter that will draw relative to some new frame. Increase the repetoire of such methods by implementing a transformation, fliphoriz, which takes as input a painter, and returns a new painter that draws its input flipped about the vertical axis. Also implement rotate180 and rotate270 in analogy to rotate90. Turn in a listing of your procedures.

Lab exercise 4: Experiment with some combinations of your primitive painters, using beside, below, superpose, flips, and rotations, to get a feel for how these means of combination work. You needn’t turn in anything for this exercise.

Lab exercise 5: The “diamond” of a frame is defined to be the smaller frame created by joining the midpoints of the original frame’s side (^) s. Define a procedure diamond that transforms a painter into one that paints its image in the diamond of the specified frame. Try some examples, and turn in a listing of your procedure.

Lab exercise 6: The “diamond” transformation has the property that, if you start with a square frame, the diamond frame is still square (although rotated). Define a transformation similar to diamond, but which does not produce square frames. Try your transformation on some images to get some nice effects. Turn in a listing of your procedure.

Lab exercise 7: The following recursive rightsplit procedure was demonstrated in lecture:

Lab exercise 9 Once you have keepcombining, you can use it to define lots of recursive means of combination. For example,

(define nestdiamonds (keepcombining (lambda (p1 p2) (superpose p1 (diamond p2))))) \null (nestdiamonds fovnder 4)

Invent some variations of your own. Turn in the code and one or two sample pictures.

Lab exercise 10: The procedures you have implemented give you a wide choice of things to experiment with. Invent some new means of combination, both simple ones like beside and complex higherorder ones like keepcombining and see what kinds of interesting images you can create. Turn in the code and one or two figures.

Contest (Optional) Hopefully, you generated some interesting designs in doing this assignment. If you wish, you can enter printouts of your best designs in the 6.001 PS3 design contest. Turn in your design collection together with your homework, but stapled separately, and make sure your name is on the work. For each design, show the expression you used to generate it. Designs will be judged by the 6.001 staff and other internationally famous art critics, and fabulous prizes will be awarded in lecture. There is a limit of five entries per student. Make sure to turn in not only the pictures, but also the procedure(s) that generated them.

How much time did you spend on this homework assignment? Report separately time spent before going to lab and time spent in the 6.001 lab.

If you cooperated with other students working this problem set please indicate their names on your solutions. As you should know, as long as the guidelines described in the 6.001 Policy on Cooperation handout are followed, such cooperation is allowed and encouraged.