CS 101 Laboratory #7

Recursive Doodling


Objective: To gain experience using recursion.

Due date: Monday, April 17, at the beginning of your lecture section.

Bring to lab: Two copies of a design document for the three Triangle classes and the three Stairs classes.

Exercises: 13.2.2, 13.6.5, 14.5.2, 14.9.2 (turn in with your HW7 on Monday).


When we doodle, those of us who are less than gifted artistically often resort to making simple geometric patterns on the backs of our notebooks, envelopes, napkins or whatever. One all-time favorite activity is to draw smaller and smaller copies of a single shape inside of another. For example, one can take a shape like a triangle or rectangle and then divide it up into smaller shapes (perhaps by drawing lines between midpoints of adjacent sides) and then divide each of the new regions and so on until all that's left is a big blob of ink on the paper.

Fortunately, Java's drawing resolution is good enough that if we get it to do this kind of doodling, we can produce things quite a bit more interesting than a big blob. For example, repeatedly dividing triangles into smaller triangles can lead to a picture like that shown below.

This week's assignment has two parts, each of which involves writing a program that draws a recursive image.

Part 1. Sierpinski's Gasket

Your first task is to draw the following picture:

This image was formed by first drawing a triangle and connecting the midpoints of its sides. This breaks the triangle into four smaller triangles (at the top, center, lower-left, and lower-right):

The center triangle is then left untouched, but the top, lower-left, and lower-right triangles are further triangulated in exactly the same way until the length of all of the edges is smaller than 12 pixels long. (In case you are interested, this shape is called Sierpinski's Gasket.)

How to Proceed

To start, click on this link to download the Recursion starter. Drag the "hw07_recursion" folder into your "cs101" folder. Inside this starter folder, you will find two projects: "Triangulate" is the starter for Part 1, and "Stairs" is the starter for Part 2.

Because this triangle doodle is going to be a recursive structure, you will need to design an interface for the doodle (called TriangleDoodle), a base class (called EmptyTriangleDoodle), and a recursive class (called ComplexTriangleDoodle). The only method that will be needed for triangle doodles is a move method, so design the interface appropriately.

The EmptyTriangleDoodle class represents an empty doodle. Like the empty base rectangle in the nested rectangles example in the text, nothing is drawn on the screen, so the constructor and move method are both pretty trivial.

The ComplexTriangleDoodle is more complicated. It will need instance variables for the lines composing the outer triangle as well as instance variables for the three triangle doodles inside.

Its constructor will take parameters for the vertices of the triangle (in the order: left, right, and top), and the drawing canvas. It should then draw lines between the vertices to form a triangle. It will also construct three more triangle doodles inside this triangle. If any of the edges of the new triangle are long enough (with length greater than or equal to 12 pixels), then the constructor should find the midpoints of each of the sides and then create complex triangle doodles in the top, lower-left, and lower-right portions of the triangle (leaving the middle blank). If none of the edges are long enough, then it should just create three empty triangle doodles for the instance variables. The move method should move the lines forming the triangle as well as the contained triangle doodles.

We have provided you with a main program that extends FrameWindowController. The begin method constructs a new object from class ComplexTriangleDoodle. The onMousePress and onMouseDrag methods use the move method to drag the triangle doodle around (even when the mouse is not in the triangle doodle).

To start out, it's often a good idea to write a simpler version of the problem. For example, first have the constructor of ComplexTriangleDoodle just draw a simple triangle out of lines. Then try drawing only the triangle doodles in the top part of the triangle. Then add the lower right. Finally, add those in the lower left portion.

You will also find the distanceTo method defined in the Location class useful to solve this problem:

   public double distanceTo(Location point)

While the only requirement is that your program be able to draw the gasket and move it, you can experiment with a color scheme to achieve a picture like that shown above. This extension will require the addition of a color parameter to the complex triangle doodle constructor (and the addition of such a parameter to the begin method of the Triangulate class).

If you are not careful in writing this program (and the next one), you may get a StackOverflowError. This will occur if your program continues to construct new triangle doodles without ever terminating. You can avoid this if you make sure you have written the base class correctly and that the complex doodle invokes its constructor only to create simpler doodles, eventually creating only empty doodles.


Part 2. Variegated Stairs

Your second task is to draw the following picture:

Let's call this variegated stairs. A variegated stairs drawing is constructed by first drawing a large square and then drawing variegated stairs half as large on top of the square, as well as variegated stairs, also half as large, immediately to the right of the square.

The size of the initial square is normally a power of 2 (128 is a good choice) so that you don't end up with gaps between the rectangles when you divide the size in half. Stop creating non-empty stairs when the squares are less than 3 pixels on a side.

As before, you will need to create an interface, StairsInterface, and two classes, EmptyStairs and VariegatedStairs. We have provided the class StairController, which extends FrameWindowController. Write the class so that the stairs will only drag around if the user is pressing the mouse down on the stairs. Thus, you will need to create methods contains and move. The constructor call in the begin method is:

    stairs = new VariegatedStairs(lowerLeft, initialSize, initialColor, canvas);

We made it look nicer by drawing the first square in a color created by new Color(225,225,255). At each level of recursion, the values of the first two components, the red and green components, are decreased by 30, resulting in nice shading.

You can obtain the red, green, and blue components from a color with the methods:

    int getRed();
    int getGreen();
    int getBlue();

Submitting Your Work

We will grade your assignment both by running your program over the web and by reading a printout of your Java source code. Homework is due by the beginning of your lecture section.

Before submitting your work, make sure that each of the .java files includes a comment containing your name and lab section. Also, before turning in your work, be sure to double check both its logical organization and your style of presentation. Make your code as clear as possible and include appropriate comments describing major sections of code and declarations. Make sure your indentation is all consistent. Refer to the lab style sheet for more information about style.

Print out a copy of your java source files and the Homework 7 Cover Page. This page provides the guidelines for how your homework will be graded. Don't forget to include the assigned exercises. Turn in one stapled hardcopy of all your work, with this cover page on top.

We have provided HTML files so that each of your programs may be run from a browser. As with the past labs, modify them to include your name. In your "Triangulate" folder there is a file named "Triangulate.html". Drag this file to the TextWrangler icon in the dock. Replace the text that reads My_Name with your first and last names, and then save the file. Do the same for the "Stairs.html" file in your "Stairs" folder.

You can see what the graders will see by visiting http://bj.middlebury.edu/~USERNAME/cs101/hw07_recursion/Triangulate/Triangulate.html and http://bj.middlebury.edu/~USERNAME/cs101/hw07_recursion/Stairs/Stairs.html from your web browser, where USERNAME is replaced by your username. You will notice that a blank "panel" window gets created. Don't worry about this; just close the window to see your program running in the browser.

Good luck and have fun!


Back to Computer Science 101 Home
Department of Computer Science