| Overview | Schedule | Resources | Assignments | Home |
By working through the steps in this handout, you will develop a HasCl program to draw a picture made up of many overlapping squares of different sizes and colors.
data Graphic = Square(Num, Num, Num, Color) | Over(Graphic, Graphic) | BlankThis says that a
Graphic value is either a
single square or the combination of one
Graphic over another, or nothing at all. A
square needs four parameters--the value Square(x, y,
w, c) describes a square whose lower-left corner is
at the point (x,
y), with width w and color c. The first three parameters,
x, y, and w, are all numbers expressing
positions or distances relative to the coordinate system of
the graphics window: the lower-left corner is at (- 50, - 50), and the upper-right
corner is at (50, 50), regardless
of the actual size of the window. The color, c, is specified as a value of
the following data type, which is also defined in the
Graphics module:
data Color = RGB(Num, Num, Num)The value
RGB(r, g, b) specifies a color with
red, green, and blue components given by the numbers r, g, and b, respectively, where each
component ranges from 0 (completely absent) to 255 (full
strength). The Graphics module also defines some useful
constants of type Color; for example,
red is the value RGB(255,0,0)
(look in the module browser in Funnie to see what other
colors are defined).
Square(10, 20, 30, RGB(0, 255, 0)). If you
type this in, the system should pop-up a graphics window
containing the square.
For testing, it will be convenient to define some sample squares. Enter each of the following in a separate definition window:
redGiant = Square(-20, -10, 50, RGB(255, 0, 0)) whiteDwarf = Square(10, 30, 20, RGB(255, 255, 255)) purpleMedium = Square(0, -20, 35, RGB(128, 0, 128))Now you can easily draw a square by entering its name, e.g.,
redGiant, in
a Funnie expression window. However, this only lets you
draw one square at a time. To combine several squares in
one picture, we need the Over constructor of
the Graphic data type, as follows:
Over(redGiant, whiteDwarf). Notice how the
squares are combined, and see what happens if you reverse
the order of the squares.
Squares. We will
need a function which takes a list of squares and combines
them all into a single Graphic. As usual when
working with a list of things, we will define the function
by recursion. Here is the base case, which uses the special
value Blank to produce a blank picture:
showSquareList([ ]) = BlankThe recursive case will have the following form:
showSquareList([s : ss]) =When this pattern matches,
s will be the first
square on the list, and ss will be a list of
the remaining squares. Write an appropriate right-hand side
for this case of the function. The square s is
already a Graphic; you will need to use
showSquareList to produce another
Graphic from ss. These two
Graphics will then need to be combined into
one with Over. When you have defined the
function, try it out with showSquareList([redGiant,
whiteDwarf]).
diagonalSquares(x, y, d, rgb, 0) = [ ]
diagonalSquares(x, y, d, rgb, n) = [Square(x, y, d, rgb) :
diagonalSquares(x+d/2, y+d/2, d, rgb, n-1)]
After entering this function, evaluate
showSquareList(diagonalSquares(-30, -30, 10, white,
9)). The cases for this function mean that
diagonalSquares(x, y, d, rgb, n) will produce
a list of n squares (because the list is empty
when n is 0, and it gets one
extra element for each recursive call as n
counts down to 0). The first one will have its
corner at (x,y), with width d and
color rgb. Succeeding squares will be offset
by adding d/2 to the x and
y coordinates of the corner; the effect will
be that each square will be centered on the upper-right
corner of the previous one. You should get a picture that
looks like a white staircase.
vanishingSquares which is similar to
diagonalSquares except replace the size argument
d in the recursive call (to
vanishingSquares, of course) with the expression
d*3/4. To try this out, you will probably want
to start with a larger initial square; something like this
should work: showSquareList(vanishingSquares(-30, -30,
20, white, 7))++. Here is a skeleton of the code for you to
fill in:
squareDesign(x, y, d, rgb, 0) =
squareDesign(x, y, d, rgb, n) = [Square(x, y, d, rgb) :
squareDesign(x-d/4, y-d/4, d/2, rgb, n-1) ++
squareDesign(x-d/4, y+3*d/4, d/2, rgb, n-1) ++
squareDesign( ) ++
squareDesign( )]
When you have successfully compiled the finished function,
try evaluating the following expression:
showSquareList(squareDesign(-20, -20, 40, white,
4)). You can change the 4 to
5 to draw one more level, but it will take too
long if you try to do 6 or more levels (each level has four
times as many squares, so there are 1024 squares at level
6).
lessRed and
lessGreen, each of type (Color) ->
Color. Here is one:
lessRed(RGB(r, g, b)) = RGB(r/2, g, b)You will need to enter this and a similar definition for
lessGreen, then write a new function similar
to squareDesign that calls these functions in
the appropriate places. Call this new function
colorDesign, and test it.
2; for
example, if you modify colorDesign, then your
new function should be named colorDesign2.| Overview | Schedule | Resources | Assignments | Home |
![]()
DePauw
University, Computer Science
Department, Spring 2005
Maintained by Brian Howard (bhoward@depauw.edu).
Last updated