Using Abstraction to Nest Triangles

On this page, you will use abstraction to nest your triangle script inside itself as you learn about recursion.

Does all that copying and pasting of triangle scripts feel awkward to you? You know a better way: abstraction. In Unit 1, you used a pinwheel block to implement the similar programs asterisk and polygon rather than copying the code. Here, you can use a block to manage the abstraction too. But in this case, we want the similar code (a smaller triangle) nested inside, so we will actually use the same block inside itself, a process called recursion.

  1. If it isn't open already, open your U3L1-FractalArt project.
  2. Create a block called nested triangle that takes one input, size, and, for now, only draws one triangle, but only if size > 9. (Leave out the code about changing colors.)
    nested triangle, size: (size)

    Shouldn't it be blue?

    When you're building a new block, you can use any color you want. This block is purple so that it will stand out when you use it in a script later.

    Click for hints about building a nested triangle block.

    1. Use your first triangle script from the previous page as a model. But add one condition: draw the triangle only if it's big enough:
      if(size>9){repeat(3){move 100 steps; turn clockwise 120 degrees}}
    2. Click the "Apply" button in the Block Editor so that the block appears in the palette on the left.
  3. Try out your block giving at least the inputs 9, 18, 20 and 100 to make sure it works as you expect.

So far, this is just a triangle procedure, but next you'll make it recursive.

Calling a procedure from inside itself is called recursion.

On the previous page, you dragged a copy of the triangle script in between the move and turn blocks. You can do a similar thing with your nested triangle block.

  1. From the palette, drag nested triangle into the definition of nested triangle between the move and turn blocks. Make its size input half the current value of size.
    nested triangle, size: (size/2)
  2. Again try out your block with at least the inputs 9, 18, 20 and 100 to make sure it works as you expect.
    You are using nested triangle in its own definition; this makes it a recursive procedure. Recursion is one of the most powerful techniques in computer science and you will learn more about it in later projects.
  3. Save your work
  1. Use nested triangle as a model to define a recursive nested square block.
  2. In order to draw the parent triangle, the sprite must turn 120° between sides. For the fractal you just created, that turning happens after drawing the child, but you could turn before the recursive call, or split the turn, with part before and part after the recursive call. Try some modifications like these:
    repeat(3){move(size) steps; turn clockwise (120) degrees; triangle fractal level:(level-1) size:(size*0.5)}
    repeat(3){move(size) steps; turn clockwise (60) degrees; triangle fractal level:(level-1) size:(size*0.5); turn clockwise(60) degrees}
    repeat(3){move(size) steps; turn counter-clockwise (30) degrees; nested triangle, size:(size/2); turn clockwise(150) degrees}
  1. Experiment with the scale factor for the size of the recursive calls. A couple of interesting values are \frac{1}{3} and \frac{1}{\sqrt{3}}.
  2. Use for to make an animation that cycles through different turning angle arrangements (that is, 0° and 120°, then 1° and 119°, then 2° and 118°, etc.).
    Recursive Triangle Animation Recursive Square Animation