Comp210
Due: 98.Oct.05 (Mon.) in class
A Shape is - (make-circle <posn> <number>) - (make-rectangle <posn> <number> <number>) - (make-line <posn> <posn>)where we have defined the new types
(define-struct circle (center radius)) (define-struct rectangle (nw width height)) (define-struct line (start stop))where radius, width, height are positive integers ("int+"), and center, nw, start, stop are
posn
s.
We'll throw in one more data definition:
A Color is one of
{ BLUE , RED , GREEN , BLACK , YELLOW , WHITE }
.
Finally, note that you really can draw shapes on the screen. Select library "teach/draw-lib.ss" to get the functions
;draw-solid-line: Posn,Posn,Color --> #t ; Start- and end-points. ;draw-solid-disk: Posn,int+,Color --> #t ; Center and radius. ;draw-solid-rect: Posn,int+,int+,Color --> #t ; nw corner, width, height. ; Before drawing, you must open the pasteboard with a specified size. ; Example: (start 400 500) (draw-solid-disk (make-posn 40 50) 20 BLUE) = #t (draw-solid-rect (make-posn 40 50) 20 20 RED) = #tIf you want to draw two things with a single expression (each drawing call returning
#t
),
it follows you can use and
to sequence them (sneaky!):
(and (draw-solid-rect (make-posn 40 50) 30 30) (draw-solid-disk (make-posn 40 50) 20 BLUE)) = #tOf course, the second expression could also be a (recursive) function call which draws something(s) and then returns
#t
.
It is a little strange that we are calling functions not for their
return value, but actually for their side-effect of drawing on the screen.
area: Shape --> number
.
inscribe: Shape --> Shape
.inscribe
returns the inscribed rectangle
(a square).inscribe
return the inscribed circleinscribe
returns the same line.truncate
or round
when needed.
(Relatedly, you can experiment with functions quotient
and remainder.)
draw: Shape, Color --> #t
.
Note that this follows quickly from the Shape template,
since the drawing library's arguments happen to be
the same as the info we are storing in the structure.
A happy coincidence.
bullseye
,
which takes a center position and an initial size,
and draws concentric circles,
each with a radius one pixel smaller than the previous,
until a radius-zero circle has been drawn.
What argument should bullseye
recur on?
What is the template for that argument's type?
(Boringly, the function always returns #t
.)
bullseye
,
but which takes one additional
argument -- a Color -- and does the real work.
next-color: Color --> Color
,
to help alternate between (say)
RED
and WHITE
.
(If you encapsulate color-changing inside this function,
note how easily you can later make your bullseye be three-colored.)
bullseye
, so that
it takes another argument radius-decrement:
how much smaller is the radius of each successive circle,
(instead of always being 1).
What should the stopping-condition be?
If you want to ensure the center is always RED
,
what color should you start with?
bullseye-inscribed
,
which takes a shape and a number n,
and draws n successively inscribed Shapes.
bullseye-inscribed
to
start with only a Shape (no number n),
and have it keep drawing smaller figures until their
area is less than some positive constant TEENY
(which you define).
A philisophical aside:
This code is no longer based on a template.
We will see later, how functions w/o templates are not
always guaranteed to terminate.
If we didn't have to convert to integers, would
bullseye-inscribed
always stop,
for all possible inputs?
Can you prove that it stops?
(An easy proof, at least if you've had Math 321.
Note that the proof would mirror the data definiton
and program. Coincidence?)
Does this conclusion actually hold,
since we are converting some results to integers?