5.2 Making Many Movements: An Introduction to Looping

Eventually we want to make some complex figures that require many movements on the part of the turtle. In order to make these go faster, we can turn off some of the turtle graphing by wrapping the desired movements in turtle_do(). See Figure 5.8 for the results of the following code.

turtle_init()
turtle_do({
  turtle_move(10)
  turtle_turn(45)
  turtle_move(15)
})
After final movement.

Figure 5.8: After final movement.

(turtle_turn() turns to the left by default.) Of course, for such a small number of movements using turtle_do() does not matter much, but we will practice using it for a bit.

How might we make a square? The following code offers one way to do it. See Figure 5.9 for the results.

turtle_init()
turtle_do({
  turtle_move(20)
  turtle_right(90)
  turtle_move(20)
  turtle_right(90)
  turtle_move(20)
  turtle_right(90)
  turtle_move(20)
  turtle_right(90)
})
Making a square.

Figure 5.9: Making a square.

This is a bit repetitious. Surely we can take advantage of the fact that there is a clear pattern to the turtle’s movements. A for-loop seems called for, as in the following code to build the square:

turtle_init()
turtle_do({
  for(i in 1:4) {
    turtle_forward(dist = 20)
    turtle_right(angle = 90)
  }
})

As we learned in Chapter 4, the more you need to repeat a particular pattern, the more it makes sense to write your code with a loop. Suppose, for example, that you decide to make regular octagons. A regular octagon has eight sides, and you turn 45 degrees after drawing each side. You can do this easily by modifying the square-code as follows (see Figure 5.10 for the results):

turtle_init()
turtle_do({
  for(i in 1:8) {
    turtle_forward(dist = 20)
    turtle_right(angle = 45)
  }
})
Making an octagon.

Figure 5.10: Making an octagon.

You can even make many small turns, so that the resulting figure starts to look like a circle (see Figure 5.11 for the results):

turtle_init()
turtle_setpos(x = 30, y = 50)
turtle_do({
  for(i in 1:180) {
    turtle_forward(dist = 1)
    turtle_right(angle = 2)
  }
})
Making a circle.

Figure 5.11: Making a circle.

Notice that in the above code the turtle was initially set a bit to the left of center, so that the resulting circle would be situated close to middle of the region.

If you allow the index variable to be involved in the computations in the body of the loop then you can start making more complex figures. For example, here is the code for a spiral (see Figure 5.12 for the results):

turtle_init(width = 150, height = 150, mode = "clip")
turtle_do({
  turtle_right(90)
  for (i in 1:720) {
    turtle_left(1)
    turtle_forward(i/720)
  }
})
Using a loop to make a spiral.

Figure 5.12: Using a loop to make a spiral.

The turtle turns one degree every time R goes through the loop, but the amount it travels forward (\(i/720\)) increases as the index variable i increases.

Another thing to notice is that we set the width and height of the region ourselves, so that the spiral would fit into it. We also set mode to clip rather then leaving it at its default value of error. With mode = "clip", R won’t throw an error message at you when the turtle moves outside of its region. Clip-mode is very handy when you are developing a graph and don’t know in advance precisely where the turtle will go.

5.2.1 Practice Exercises

  1. Write a program to make a four-sided star with rays of length 20 each, like this:

  2. Write a program to make an eight-sided star with rays of length 30 each, like this:

5.2.2 Solutions to the Practice Exercises

  1. In order to make a single ray you walk 20 units forward from a central point, then walk 20 units back to the center. In order to prepare to make the next ray, you turn after you get back to the center. Since you plan on four rays, you must turn \(360/4 = 90\) degrees each time. It makes sense to trace each ray once inside a for-loop. Using turtle_do() will make the loop run much faster. Here’s the code:

    turtle_init(mode = "clip")
    turtle_do({
      for ( i in 1:4 ) {
        turtle_forward(20)
        turtle_backward(20)
        turtle_left(90)
      }
    })
  2. This time in order to make a single ray you walk 30 units forward from a central point, then walk 30 units back to the center. Since you now plan on eight rays, you must turn \(360/8 = 45\) degrees each time. Again it makes sense to trace each ray once inside a for-loop. Here’s the code:

    turtle_init(mode = "clip")
    turtle_do({
      for ( i in 1:8 ) {
        turtle_forward(30)
        turtle_backward(30)
        turtle_left(45)
      }
    })