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.
Square
s. 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
Graphic
s 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 2006
Maintained by Brian Howard
(bhoward@depauw.edu
).
Last updated