Lab 3


This lab will focus on creating simple abstract data types and operating on lists. Additionally, we now know just enough Scheme to start using abstractions and abstract data types provided by external libraries to do interesting things.

A position is an abstract data type provided by Dr.Scheme (actually the Mr.Ed graphics subsystem).  A position represents a pixel on the screen as an x,y pair similar to a Cartesian point. As we discussd in class, a position has a creator and several selectors:
    (define p (make-posn 5 7)) --> Constructor creates a position p representing the point 5,7
    (posn-x p) --> 5
    (posn-y p) --> 7 are selectors giving the x and y values, respectively.

 

DrScheme provides the graphics teachpack draw.ss, which introduces simple graphics operations including
draw-circle, which consumes three arguments: a posn structure for the center of the circle, a number for the radius, and a color.

Every graphics operation produces true, if it succeeds in changing the canvas as specified. We refer to the action to the canvas as an EFFECT, but we will ignore studying the precise nature of effects until Chapter 3. Also, if anything goes wrong with the operation, it stops the evaluation with an error.

Each drawing operation also comes with a matching clear- operation:  clear-circle. If these functions are applied to the same arguments as their matching draw- function, they clear the corresponding shapes of the canvas.

Drawing operations on computers interpret the screen as follows:

[curriculum1aa-Z-G-17.gif]
First, the origin of the plane is in the upper-left corner. Second, y coordinates grow in the downwards direction. Understanding the difference between this picture and the more conventional Cartesian plane is critical for drawing shapes with programs.

Exercise 1.   (nothing to turn in) Use Language Intermediate Student with Lambda. Load the teachpack draw.ss, [Menubar: Language --> Add Teachpack --> select file teachpacks/htdp/draw.ss] Evaluate the following expressions in order:
  1. (start 300 300), which opens a canvas;

  2. (draw-circle (make-posn 110 30) 30 'yellow), which draws a yellow circle of radius 30 centered at the upper right corner of the rectangle;

  3. (stop), which closes the canvas.

Note the little quote tick in front of the word 'yellow: that means yellow is a symbol, as we briefly discussed Thursday. You can guess at the other colors such as 'red 'blue 'green 'orange and so on. If a color doesn't exist, you'll get an appropriate error message.

Exercise 2.   Provide an abstract  data type (constructor and three selectors) for representing colored circles. A circle is characterized by three pieces of information: its center, its radius, and the color of its perimeter. The first is a posn structure, the second a number, and the third a (color) symbol.

Exercise 3.   Write draw-a-circle. The function consumes a circle structure and draws the corresponding circle on the screen. Remember to do something like (start 300 300) by hand to create the canvas before testing the function.   

 

Exercise 4.   Write translate-circle. The function consumes a circle structure and a number delta. The result is a circle whose center is delta pixels to the right of the input. The function has no visual effect on the canvas.

 

Exercise 5.   Write clear-a-circle. The function consumes a circle structure and clears the corresponding circle on the canvas.  

 

Exercise 6.   Define the function draw-and-clear-circle, which draws a circle structure, waits for a short time, and clears it. To implement a waiting period, the teachpack draw.ss provides the function sleep-for-a-while. It consumes a number and puts the program to sleep for that many seconds; its result is true. For example, (sleep-for-a-while 1) waits for one second.   Hint: all the graphics operators return TRUE if they suceed. the Scheme operator AND takes a list of clauses and evaluates them one at a time as long as they return TRUE.

The following function is the key ingredient for moving a circle across a canvas, one step at a time: 

;; move-circle : number circle  ->  circle
;; to draw and clear a circle, translate it by delta pixels
(define (move-circle delta a-circle)
(cond
((draw-and-clear-circle a-circle) (translate-circle a-circle delta))
(else a-circle)))

It draws and clears the circle on the canvas and then produces the new circle structure so that another draw-and-clear effect displays the circle at a new position:

(start 200 100)

(draw-a-circle
(move-circle 10
(move-circle 10
(move-circle 10
(move-circle 10 ... a circle ...)))))
This expression moves the circle four times, by 10 pixels each, and also shows this movement on the canvas. The last draw-a-circle is necessary because we wouldn't otherwise see the last move on the screen.

Exercise 6.   Define the function my-andmap, which takes a predicate, a list, and determines if the predicate holds for every element on the list:
;; my-andmap : (X  ->  boolean) (listof X)  ->  boolean
;; to determine whether p holds for every item on alox
;; that is, (my-andmap p (list x-1 ... x-n)) = (and (p x-1) (and ... (p x-n)))
(define (my-andmap p alox) ...)
As you may suspect, andmap is actually a builtin Scheme function, another of the useful abstract operators on lists. It may be useful in completing some of the remaining excercises.

Exercise 7.   We might represent a more complex drawing as a list of  circles (loc's). Use Scheme's map and andmap to define draw-loc, clear-loc, and translate-loc. Hint: use andmap, noticing that these are just abstractions of the functions you already wrote!

Exercise 8.   Define move-loc. (hint: analogous to move-circle)

Exercise 9.   Load teachpack arrow.ss which provides the function
control-left-right : shape number move draw -> true 
It consumes a shape, a number, a move function and a draw function. Comment out any calls to sleep-for-a-while as they will not be needed with the controller in place. Demonstrate that the following works to move a multi-circle shape left and right:
(define a (make-circle (make-posn 100 100) 10 'red))
(define a1 (make-circle (make-posn 92 92) 6 'green))
(define a2 (make-circle (make-posn 108 92) 6 'green))
(define m (list a a1 a2))
(start 300 300)
(control-left-right m 10 move-loc draw-loc)