Extended Exercise: Moving Circles and Rectangles

Implementing a computer game often requires that a picture move across a computer monitor. In figure~#figmoving#5471>, for example, a simplistic face is moved from the left part of the canvas toward the right border. We can easily imagine more complex situations.
rawhtml14 <#5472#>Figure: A moving face<#5472#>
For simplicity, our pictures consist of many colored circles and rectangles. Here we learn to move these basic shapes across a canvas. From section~#sectrafficdraw#5474>, we already know, for example, how to draw and erase a circle. Here we learn to translate a circle, that is, to move its representation in a particular direction. In sections~#secmoveshape#5475>, #secmovefig#5476>, and~#secabsmoving#5477> we learn to move entire pictures with compact programs.

<#5479#>A First Note on Iterative Refinement<#5479#>:\ This method of developing large programs is our first taste of <#61262#><#5480#>ITERATIVE REFINEMENT<#5480#><#61262#>. The basic idea behind iterative refinement is to start with a simple version of the program, that is, a version that deals with the most important part of the problem. Here we start with functions that move the most basic shapes: circles and rectangles. Then we refine the program to deal with more and more complex situations. For example, in section~#secmovefig#5481> we learn to deal with pictures that consist of an arbitrary number of circles and rectangles. Once we have a complete program, we edit it so that others can easily read and modify it, too. Section~#secabsmoving#5482> covers this aspect of the ``moving pictures'' example. Refining a program in this manner is the most prevalent method of designing complex programs. Of course, we must know the eventual goal for this method to succeed, and we must always keep it in mind. It is therefore a good idea to write down an action plan, and to re-consider the plan after each refinement step. We will discuss this process again in section~#secfiles#5483>.~<#61263#><#61263#> Following the design recipe, we start with structure and data definitions, then move on to templates, and finally write the necessary functions. The first sequence of exercises covers circles; the second one is about rectangles.
<#5488#>Exercise 6.6.1<#5488#> Provide a structure definition and a data definition for representing colored circles. A <#5490#>circle<#5490#> is characterized by three pieces of information: its center, its radius, and the color of its perimeter. The first is a <#61264#><#5491#>posn<#5491#><#61264#> structure, the second a number, and the third a color defined by the teachpack <#5492#>draw.ss<#5492#>. Develop the template <#61265#><#5493#>fun-for-circle<#5493#><#61265#>, which outlines a function that consumes <#61266#><#5494#>circle<#5494#><#61266#>s and produces different classes of data.~ external Solution<#61267#><#61267#> <#5500#>Exercise 6.6.2<#5500#> Use the template <#61268#><#5503#>fun-for-circle<#5503#><#61268#> to develop the function <#61269#><#5504#>draw-a-circle<#5504#><#61269#>. It consumes a <#61270#><#5505#>circle<#5505#><#61270#> structure and draws the corresponding circle on the screen. Use <#61271#><#5506#>(start<#5506#>\ <#5507#>200<#5507#>\ <#5508#>200)<#5508#><#61271#> to create the canvas before testing.~ external Solution<#61272#><#61272#> <#5514#>Exercise 6.6.3<#5514#> Use the template <#61273#><#5516#>fun-for-circle<#5516#><#61273#> to develop <#61274#><#5517#>in-circle?<#5517#><#61274#>. The function consumes a <#61275#><#5518#>circle<#5518#><#61275#> structure and a <#61276#><#5519#>posn<#5519#><#61276#> and determines whether or not the pixel is inside the circle. All pixels whose distance to the center is less or equal to the radius are inside the circle; the others are outside. Consider the circle in figure~#figgeoin#5520>. The circle's center is <#61277#><#5521#>(make-posn<#5521#>\ <#5522#>6<#5522#>\ <#5523#>2)<#5523#><#61277#>, its radius is <#61278#><#5524#>1<#5524#><#61278#>. The pixel labeled <#61279#><#5525#>A<#5525#><#61279#>, located at <#61280#><#5526#>(make-posn<#5526#>\ <#5527#>6<#5527#>\ <#5528#>1.5)<#5528#><#61280#>, is inside the circle. The pixel labeled <#61281#><#5529#>B<#5529#><#61281#>, located at <#61282#><#5530#>(make-posn<#5530#>\ <#5531#>8<#5531#>\ <#5532#>6)<#5532#><#61282#>, is outside.~ external Solution<#61283#><#61283#> <#5538#>Exercise 6.6.4<#5538#> Use the template <#61284#><#5540#>fun-for-circle<#5540#><#61284#> to develop <#61285#><#5541#>translate-circle<#5541#><#61285#>. The function consumes a <#61286#><#5542#>circle<#5542#><#61286#> structure and a number <#61287#><#5543#>delta<#5543#><#61287#>. The result is a <#61288#><#5544#>circle<#5544#><#61288#> whose center is <#61289#><#5545#>delta<#5545#><#61289#> pixels to the right of the input. Note that the function has no effect on the canvas.

<#5546#>Translation<#5546#>:\ Moving a geometric shape along a straight line is referred to as a <#5547#>translation<#5547#>.~ external Solution<#61290#><#61290#> <#5553#>Exercise 6.6.5<#5553#> Use the template <#61291#><#5556#>fun-for-circle<#5556#><#61291#> to develop <#61292#><#5557#>clear-a-circle<#5557#><#61292#>. The function consumes a <#61293#><#5558#>circle<#5558#><#61293#> structure and clears the corresponding circle on the canvas.~ external Solution<#61294#><#61294#> <#5564#>Exercise 6.6.6<#5564#> Define the function <#61295#><#5566#>draw-and-clear<#5566#><#61295#>, which draws a <#61296#><#5567#>circle<#5567#><#61296#> structure, waits for a short time, and clears it. To implement a waiting period, the teachpack <#5568#>draw.ss<#5568#> provides the function <#61297#><#5569#>sleep-for-a-while<#5569#><#61297#>. It consumes a number and puts the program to sleep for that many seconds; its result is <#61298#><#5570#>true<#5570#><#61298#>. For example, <#61299#><#5571#>(sleep-for-a-while<#5571#>\ <#5572#>1)<#5572#><#61299#> waits for one second.~ external Solution<#61300#><#61300#> Here is a function for moving circles across a canvas:

<#70767#>;; <#61301#><#5582#>move-circle<#5582#> <#5583#>:<#5583#> <#5584#>number<#5584#> <#5585#>circle<#5585#> <#5586#><#5586#><#5587#>-;SPMgt;<#5587#><#5588#><#5588#> <#5589#>circle<#5589#><#61301#><#70767#>
<#70768#>;; to draw and clear a circle and then to move it by <#61302#><#5590#>delta<#5590#><#61302#> pixels<#70768#> 
<#5591#>(d<#5591#><#5592#>efine<#5592#> <#5593#>(move-circle<#5593#> <#5594#>delta<#5594#> <#5595#>a-circle)<#5595#> 
  <#5596#>(c<#5596#><#5597#>ond<#5597#> 
    <#5598#>[<#5598#><#5599#>(draw-and-clear<#5599#> <#5600#>a-circle)<#5600#> <#5601#>(translate-circle<#5601#> <#5602#>a-circle<#5602#> <#5603#>delta)]<#5603#> 
    <#5604#>[<#5604#><#5605#>else<#5605#> <#5606#>a-circle]<#5606#><#5607#>))<#5607#> 
The function <#61303#><#5611#>move-circle<#5611#><#61303#> always produces the new <#61304#><#5612#>circle<#5612#><#61304#> structure so that we can move a circle across a canvas as follows:
<#5617#>(start<#5617#> <#5618#>200<#5618#> <#5619#>100)<#5619#>
<#5620#>(d<#5620#><#5621#>raw-a-circle<#5621#> 
  <#5622#>(m<#5622#><#5623#>ove-circle<#5623#> <#5624#>10<#5624#> 
    <#5625#>(m<#5625#><#5626#>ove-circle<#5626#> <#5627#>10<#5627#> 
      <#5628#>(m<#5628#><#5629#>ove-circle<#5629#> <#5630#>10<#5630#> 
        <#5631#>(move-circle<#5631#> <#5632#>10<#5632#> <#5633#>...<#5633#> <#5634#>a<#5634#> <#5635#>circle<#5635#> <#5636#>...)))))<#5636#> 
This expression moves the circle four times, by 10 pixels each, and also shows this movement on the canvas. The last <#61305#><#5640#>draw-a-circle<#5640#><#61305#> is necessary because we wouldn't otherwise see the last move on the screen.
<#72325#>#tex2html_wrap72774#<#72325#> <#5675#>Figure: Circles, rectangles, and pixels<#5675#>
<#5677#>Exercise 6.6.7<#5677#> Provide a structure definition and a data definition for representing colored rectangles. A <#5679#>rectangle<#5679#> is characterized by four pieces of information: its upper-left corner, its width, its height, and its fill color. The first is a <#61334#><#5680#>posn<#5680#><#61334#> structure, the second and third quantities are plain numbers, and the last one is a color. Develop the template <#61335#><#5681#>fun-for-rect<#5681#><#61335#>, which outlines a function that consumes <#61336#><#5682#>rectangle<#5682#><#61336#>s and produces different classes of data.~ external Solution<#61337#><#61337#> <#5688#>Exercise 6.6.8<#5688#> Use the template <#61338#><#5691#>fun-for-rect<#5691#><#61338#> to develop <#61339#><#5692#>draw-a-rectangle<#5692#><#61339#>. The function consumes a <#61340#><#5693#>rectangle<#5693#><#61340#> structure and draws the corresponding rectangle on the screen. In contrast to circles, the entire rectangle is painted in the matching color. Remember to use <#61341#><#5694#>(start<#5694#>\ <#5695#>num<#5695#>\ <#5696#>num)<#5696#><#61341#> to create the canvas.~ external Solution<#61342#><#61342#> <#5702#>Exercise 6.6.9<#5702#> Use the template <#61343#><#5704#>fun-for-rect<#5704#><#61343#> to develop <#61344#><#5705#>in-rectangle?<#5705#><#61344#>. The function consumes a <#61345#><#5706#>rectangle<#5706#><#61345#> structure and a <#61346#><#5707#>posn<#5707#><#61346#> and determines whether or not the pixel is inside the rectangle. A pixel is within a rectangle if its horizontal and vertical distances to the upper-left corner are positive and smaller than the width and height of the rectangle. Consider the rectangle in figure~#figgeoin#5708>. This rectangle's key parameters are <#61347#><#5709#>(make-posn<#5709#>\ <#5710#>2<#5710#>\ <#5711#>3)<#5711#><#61347#>, <#61348#><#5712#>3<#5712#><#61348#>, and <#61349#><#5713#>2<#5713#><#61349#>. The pixel labeled <#61350#><#5714#>C<#5714#><#61350#> is inside of the rectangle, <#61351#><#5715#>B<#5715#><#61351#> is outside.~ external Solution<#61352#><#61352#> <#5721#>Exercise 6.6.10<#5721#> Use the template <#61353#><#5723#>fun-for-rect<#5723#><#61353#> to develop <#61354#><#5724#>translate-rectangle<#5724#><#61354#>. The function consumes a <#61355#><#5725#>rectangle<#5725#><#61355#> structure and a number <#61356#><#5726#>delta<#5726#><#61356#>. The result is a <#61357#><#5727#>rectangle<#5727#><#61357#> whose center is <#61358#><#5728#>delta<#5728#><#61358#> pixels to the right of the input.~ external Solution<#61359#><#61359#> <#5734#>Exercise 6.6.11<#5734#> Use the template <#61360#><#5737#>fun-for-rect<#5737#><#61360#> to develop <#61361#><#5738#>clear-a-rectangle<#5738#><#61361#>. The function consumes a <#61362#><#5739#>rectangle<#5739#><#61362#> structure and clears the corresponding rectangle on the canvas.~ external Solution<#61363#><#61363#> <#5745#>Exercise 6.6.12<#5745#> Develop the function <#61364#><#5748#>move-rectangle<#5748#><#61364#>. It consumes a number (<#61365#><#5749#>delta<#5749#><#61365#>) and a <#61366#><#5750#>rectangle<#5750#><#61366#> structure. The function draws the given rectangle, waits for one second, and clears the rectangle. If these actions produce <#61367#><#5751#>true<#5751#><#61367#>, <#61368#><#5752#>move-rectangle<#5752#><#61368#> translates the rectangle by <#61369#><#5753#>delta<#5753#><#61369#> pixels and returns this new value as a result. <#5754#>Hint:<#5754#> \ If the actions fail to produce <#61370#><#5755#>true<#5755#><#61370#>, they generate an error. Use the given rectangle for the answer of this <#61371#><#5756#>cond<#5756#><#61371#>-line. Also see the definition of <#61372#><#5757#>move-circle<#5757#><#61372#> and its uses.~ external Solution<#61373#><#61373#>