Figure 2.10: Images produced by the
wave
painter, with respect to four different frames. The
frames, shown with dotted lines, are not part of the images.
Figure 2.10: Images produced by the
wave
painter, with respect to four different frames. The frames,
shown with dotted lines, are not part of the images.
Figure 2.11: Images
of William Barton Rogers, founder and first president of MIT,
painted with
respect to the same four frames as in figure 2.10 (original image reprinted with the permission of
the MIT Museum).
Figure 2.11: Images of William Barton Rogers, founder and first president of MIT, painted with
respect to the same four frames as in figure 2.10 (original image reprinted with the permission of the
MIT Museum).
Figure 2.12 shows the drawing of a painter called
wave4
that is built up in two stages starting from
wave
:
(define wave2 (beside wave (flip-vert wave)))
(define wave4 (below wave2 wave2))
(define wave2 (define wave4
(beside wave (flip-vert wave))) (below wave2 wave2))
Figure 2.12: Creating a complex figure,
starting from the
wave
painter of figure 2.10.
Figure 2.12: Creating a complex figure, starting from the
wave
painter of figure 2.10.
In building up a complex image in this manner we are exploiting the fact that painters are closed under
the language’s means of combination. The
beside
or
below
of two painters is itself a painter;
therefore, we can use it as an element in making more complex painters. As with building up list
structure using
cons
, the closure of our data under the means of combination
is crucial to the ability
to create complex structures while using only a few operations.
Once we can combine painters, we would like to be able to abstract typical patterns of combining
painters. We will implement the painter operations as Scheme procedures. This means that we don’t
need a special abstraction mechanism in the picture language: Since the means of combination are
ordinary Scheme procedures, we automatically have the capability to do anything with painter
operations that we can do with procedures. For example, we can abstract the pattern in
wave4
as
(define (flipped-pairs painter)
(let ((painter2 (beside painter (flip-vert painter))))
(below painter2 painter2)))
and define
wave4
as an instance of this pattern:
(define wave4 (flipped-pairs wave))
We can also define recursive operations. Here’s one that makes painters split and branch towards the
right as shown in figures 2.13 and 2.14:
(define (right-split painter n)
(if (= n 0)
painter
(let ((smaller (right-split painter (- n 1))))
(beside painter (below smaller smaller)))))
right-split n corner-split n
Figure 2.13: Recursive plans for
right-split
and
corner-split
.
Figure 2.13: Recursive plans for
right-split
and
corner-split
.
We can produce balanced patterns by branching upwards as well as towards the right (see
exercise 2.44 and figures 2.13 and 2.14):
(define (corner-split painter n)
(if (= n 0)
painter
(let ((up (up-split painter (- n 1)))
(right (right-split painter (- n 1))))
(let ((top-left (beside up up))
(bottom-right (below right right))
(corner (corner-split painter (- n 1))))
(beside (below painter top-left)
(below bottom-right corner))))))
(right-split wave 4) (right-split rogers 4)
(corner-split wave 4) (corner-split rogers 4)
Figure 2.14: The recursive operations
right-split
and
corner-split
applied to the
painters
wave
and
rogers
. Combining four
corner-split
figures produces symmetric
square-limit
designs as shown in figure 2.9.
Figure 2.14: The recursive operations
right-split
and
corner-split
applied to the painters
wave
and
rogers
. Combining four
corner-split
figures produces symmetric
square-limit
designs as shown in figure 2.9.
By placing four copies of a
corner-split
appropriately, we obtain a pattern called
square-limit
, whose application to
wave
and
rogers
is shown in figure 2.9:
(define (square-limit painter n)
(let ((quarter (corner-split painter n)))
(let ((half (beside (flip-horiz quarter) quarter)))
(below (flip-vert half) half))))
Exercise 2.44. Define the procedure
up-split
used by
corner-split
. It is similar to
right-split
, except that it switches the roles of
below
and
beside
.