T-Th 9:05
or
T-Th 11:15
in Phillips 101

CS 1110: Introduction to Computing Using Java

Spring 2012

Turtles

Due to CMS by Thursday, April 5

This purpose of this assignment is to have some fun with computer graphics while gaining practice with recursion and simple loops. It will also give you a lot of experience with helper methods.

Read this entire document carefully. Budget your time wisely. Do not wait until the deadline to start this assignment. We advise starting now and working on one method a day. You may also want to experiment, drawing your own graphics designs.


Table of Contents


Before You Get Started

Academic Integrity

We have given this assignment before. It is a good one, and students really like it. Do not share your code with others. Do not obtain or look at a copy of the earlier solution or a version being done by another student. Such cheating helps no one, especially you, and it makes more unnecessary work for us.

As with the last assignment, it is highly unlikely that your code for this assignment will look exactly like someone else's. Once gain, we will actively be using Moss to check for instances of cheating and plagiarism. Anyone caught using files that are obviously from a previous semester will be prosecuted, with the end result perhaps being to fail the course.

Collaboration Policy

You may do this assignment with one other person. If you are going to work together, then form your group on CMS as soon as possible. If you do this assignment with another person, you must work together. It is against the rules for one person to do some programming on this assignment without the other person sitting nearby and helping.

With the exception of your CMS-registered partner, you may not look at anyone else's code or show your code to anyone else, in any form what-so-ever.

Assignment Scope

This is the first assignment that you do not need to create a JUnit testing class for. You will mostly be looking at visual output (graphics) to determine correctness.

To save you time, we have given complete specifications of most of the methods you are to write. Study them carefully. Note how precise and thorough they are. You should aim for this quality of specs when you start to write your own.

Assignment Source Code

The first thing to do in this assignment is to download the zip file A5.zip from this link. You should unzip it and put the contents in a new directory. This zip file contains the following:

A5.java
This is the primary file that you will modify, and the only file that you submit for a grade.
HSV.java
This is a simple implementation of the HSV color model from Assignment A4.
acm.jar
This is a jar file contains additional packages to add to Java. To add these to Java, select Preferences and look at the tab Resource Locations. You will see a line that says Extra Classpath with an Add button. Click the button, choose acm.jar, and click OK on the preferences pane.
docs
This is a directory which contains specifications of all the classes in package acm. Double-click docs/index.html (or open it in a browser) to see the specs; you should refer to them when writing method calls to draw things on the "graphics canvas". Spend some time looking at the methods that are available in classes GraphicsProgram, GTurtle, and GPen.

The package acm was developed under the auspices of the ACM (Association for Computing Machinery), the major CS professional society. The documentation provided has been abbreviated a bit to make it easier to follow. If you are curious, you can view the complete documentation at the official site.

Getting Help

If you do not know where to start, if you do not understand testing, or if you are completely lost, please see someone immediately. This can be the course instructor, a TA, or a consultant. Do not wait until the last minute, particularly since this assignment is much more complex than the previous ones. A little in-person help can do wonders. See the staff page for more information.


Drawing with the ACM Graphics Package

Look at A5.java. It contains two classes: A5 and A5Turtle. Earlier in the course, we told you to put each class in its own file. Now you see that you can put more classes in one file, but only one of them can be public, and the name of the file must be the name of the public class. We suggest you try this now: insert modifer public on the definition of A5Turtle and try to compile; then remove the modifier.

Class A5 is a subclass of abstract class GraphicsProgram, which is part of package acm. A GraphicsProgram is associated with a window on your monitor (much like a JFrame) that contains a "canvas" on which you can draw. When an instance of A5 is created, the associated window appears on your monitor. You can then create "turtles" and "pens" to draw (on the canvas) in that window.


Using GTurtle

An instance of class acm.graphics.GTurtle maintains a pen of a certain color at a pixel (x,y) that is pointing in some direction given by an angle (0 degrees is to the right, or east; 90 degrees, north; 180 degrees, west; and 270 degrees, south). When the turtle is moved to another spot using procedure forward, a line is drawn if its pen is currently "down" and nothing is drawn if its pen is "up". The pen is initially black, but its color, of class java.awt.Color, can be changed.

Before an instance of GTurtle can be used to draw something, it has to be added to an A5 object. You can add many turtles to the same A5 object and draw different things with each. Suppose a contains the name of an A5 object. Function a.newTurtle() — which is already written— creates a new turtle and adds it to object a. Study the function body; make sure you understand what it does and how. For this assignment, you shoul use only newTurtle to create new turtles.

GTurtle Position

The coordinates and angle of the turtle are maintained using type double. This is needed for maximum accuracy. If ints were used, errors might crop up after many calculations. However, whenever a point is to be placed in the window, its x- and y-coordinates are rounded to the nearest integer because the pixel coordinates are represented with ints.

The direction (angle) of the turtle may be negative or greater than 360. Adding a multiple of 360 does not change the direction the turtle faces (e.g. for angles -360, 0, 360, and 720 the turtle is facing east).

Important GTurtle Methods

Suppose t contains a GTurtle. The most important methods are as follows:

t.forward(d)
This method moves the turtle d pixels in its current direction.
t.setLocation(x,y)
This method moves t to pixel (x,y) without drawing anything.
t.left(a)
This method turns the turtle a degrees counterclockwise.
t.setDirection(a)
This methods sets the direction of the turtle to angle a.

The method t.setDirection(angle) does not redraw the turtle. To see this, in the Interactions pane, type the following:

> A5 a = new A5();
> acm.graphics.GTurtle t= a.newTurtle(); 
> t.setDirection(90)
To repaint the screen so that the turtle faces the right direction, execute a.repaint().

Drawing Speed

A turtle t moves with a speed, which must be in the range 0 <= speed <= 1. 0 is the slowest and 1 the fastest. This is not a lot of detail on the speed is the specification, so we cannot tell you more. Set t's speed to sp using t.setSpeed(sp).


Using GPen

Recall that a GTurtle maintains a position and a direction, and when you ask it to draw using forward(d), it draws a line of length d in that direction. A GPen (also in package acm.graphics) maintains is slightly different from a GTurtle in that it has a position, but no direction. Function a.newPen() — which is already written— creates a new pen and adds it to object a. Study the function body; make sure you understand what it does and how. For this assignment, you shoul use only newPen to create new pens.

With an instance of GPen, you can use procedure drawLine(dx,dy) to draw a line of length (dx,dy) from the pen's current position, ending up at the end of the drawn line:

> A5 a = new A5();
> acm.graphics.GPen p= a.newPen(); 
> p.drawLine(10,20)
The method move(dx,dy) can do the same thing but without drawing, and setLocation(x,y) can move to position (x, y) without drawing. A GPen has other useful methods. Spend 5 minutes looking through their specifications in the documentation.


Assignment Instructions

Throughout this assignment, you will be asked to draw shapes with the Turtle. There are generally two ways to do this. One is to use the Turtle directly with the Interactions pane, as described in the section above. You should start of drawing some shapes familiarize yourself with class Turtle.

The other way to draw is to add new methods to the class A5. If you look at the file, you will notice that the class A5 contains a procedure drawTwoLines; this procedure is added to show you how to write a graphics helper method. To try it out, compile class A5, and type the following in the Interactions pane.

> A5 a = new A5();
> a.drawTwoLines(0);
This causes a window to appear with two lines to be drawn inside of it, waiting a few seconds before drawing each one. Study the body of drawTwoLines, as it will help you with all of the tasks below.

For the remainder of this assignment, you will be writing method bodies that draw shapes, much like the drawTwoLines procedure. As you write a method body, refer constantly to the method specification; follow it carefully and rigorously. If you have to call another method, look at its specification and make sure you follow it. A huge number of programming errors arise from not following specifications carefully.


Override toString in A5Turtle

The function toString in GTurtle has a problem: it does not include the direction of the turtle in the string it returns. Therefore, we have defined a subclass A5Turtle (at the end of A5.java) of GTurtle so you can fix this issue. The ability to extend another class so easily for a small customization shows the power of object oriented programming. Throughout this assignment, then, we will use A5Turtle instead of GTurtle.

Write the body of function toString in A5Turtle, following the instructions given in the function itself. More specifically, you should modify the output of super.toString() to include

  , direction=<direction>
just before the closing bracket. Below are two examples of what our toString function produces; yours must be the same. The second one has RGB color (6, 7, 8).

"A5Turtle[location=(250.0, 250.0), color=GREEN, direction=270.0]"
"A5Turtle[location=(250.0, 250.0), color=0x60708, direction=180.0]"

Complete Procedure drawTriangle

This method should sraw an equilateral triangle of side length s and color c at the turtle's current position. The turtle should end its drawing at the same position, and facing the same direction, as when it started the triangle. You should not save the turtle position and direction in the beginning and then restore them at the end. If you draw the triangle correctly, following the instructions in the method specification, then this should happen automatically.

While working on this method, you should follow the instructions in the comment in the body to learn about rounding errors when using type double and why they do not really matter here. The comment asks you to put some information at the top of file A5.java (as a comment).


Complete Procedure drawHex

This method should draw six equilateral triangles using color Color.orange with side lengths s to form a hexagon, as shown to the right of this paragraph. You should follow the specification and hints carefully (e.g. use a helper method).


Radial Shapes

You should choose two (an only two!) from the choice of three actitivies: spiral, polygons, or radiating lines. Once you have done two of these, you are free (but not required) to do the remaining one. These are pretty fun assignments.

Each of these tasks involves creating a helper function with the same name. The first procedure does not have a turtle as parameter; it clears the canvas, creates a turtle, calls the second procedure to do the work, and hides the turtle. This allows you to draw a spiral, for example, without having to create a turtle first. When writing these procedures, write the first one, write the second one, and then test both by using calls of the first one in the interactions pane.

Draw a Spiral

The first picture to the right is done by drawing 10 lines. The first line has length 10; the second, 20; the third, 30; and so on. After each line, the turtle turns left 90 degrees. The second diagram to the right shows a similar spiral but with the turtle turning left 75 degrees after each line.

Complete the two procedures named drawSpiral. When you first test them, use 10 for d and 0 for sp. Try different angles, like 90 degrees, 92 degrees, 88 degrees, etc. Use sp = 0, or sp = .5 to see the lines drawn one at a time.

You will be amazed at what these methods do. Find out by trying these calls, assuming that a is an instance of A5:

> a.drawSpiral(.8,1,90,300);
> a.drawSpiral(.85,1,135,400);
> a.drawSpiral(.95,1,60,100);
> a.drawSpiral(.9,1,121,300);
> a.drawSpiral(1,1,89,400);
> a.drawSpiral(1,1,150,300);
> a.drawSpiral(.99,1,121,500);
> a.drawSpiral(1,1,119,500);

Draw Many Polygons

The first image to the right is a 9-sided polygon. The second image to the right is a series of 40 5-sided polygons of side length 35, the first started at angle 90, the second at an angle of 90 + 360.0/40, the third at an angle of 90 + 2*360.0/40, and so on. This demonstrates the kind of cool pictures you can draw just with polygons.

Complete the two multiPolygons procedures so that your program can draw such designs. Use procedure drawPolygon, which we give you. When finished, experiment to see what neat designs come out. Try, for example, try the following:

> a.multiPolygons(45,3,100,.8);
> a.multiPolygons(60,30,20,.88);

Draw Radiating Lines

The leftmost picture to the right is done by drawing 15 lines of the same length, radiating out from the current turtle position. The angle between the lines is the same. The second picture has 720 lines. If n lines are drawn, the angle between them is 360.0/n. Furthermore, the color of each line depends on the angle (i.e. the direction) of each line. A line drawn at angle ang is drawn with HSV color (ang,1,1).

Remember that this the HSV value has to be translated to the RGB system, because RGB is used by the turtle graphics system. So, we give you HSV.class, which allows you to create an object of the class and also contains a function that will translate an HSV value to the RGB system. See the note in procedure A5.radiate about this.

Complete the two radiate procedures. When finished, test them with small values of n, like 4 or 8. After the procedures are completely tested, try them with 360 lines of length 200, with turtle speed .85. Also, do it with 3,000 lines and turtle speed 1; notice how much more filled in the disk becomes.


Recursive Graphics

As part of the last task, we ask you to use recursion to draw some interesting shapes. You should choose two (an only two!) from the choice of three actitivies: the Sierpinski triangle, the Grisly snowflake, and the H-tree. Once you have done two of these, you are free (but not required) to do the remaining one.

Throughout all three of these tas, we ask that use use use a GPen instead of a GTurtle because (1) there is no need to maintain the direction and (2) GPen methods exist to draw regions that are filled in with a color. See the overview of GPen above for more information.

As with the radial shapes, for each of these recursive tasks, you should write two procedures. The first one set things up and calls the second; the first does not have a pen as a parameter, while the second does.

Sierpinski Triangles

Directly to the right is a filled-in equilateral triangle. We call it a Sierpinski triangle of size s (the length of a side) and depth 0. Next to it is a Sierpinski triangle of size s and depth 1. It is created by drawing 3 Sierpinski triangles of size s/2.0 and depth 0, in each of the corners of what would be a Sierpinski triangle of size s and depth 0. All the way on the right is a Sierpinski triangle of size s and depth 2; it is created by drawing 3 Sierpinski triangles of size s/2.0 and depth 1.

In the same way, we can draw a Sierpinski triangle of size s and depth d (> 0). We draw three Sierpinski triangles of size s/2.0 and depth d-1 in appropriate places. We have stubbed in two sierpinski procedures for you to complete. You can use procedure fillTriangle to draw a triangle —it is needed only at depth 0.

The most difficult part may be finding the height of the triangle with side length s. Knowing that it is an equilateral triangle, use the Pythagorean theorem to figure this out. Using h for the height, visualize a triangle that is 1/2 of the equilateral triangle, with side lengths s, s/2.0, and h. Then solve the formula s2 = (s/2)2 + h2 for h.

Grisly Snowflakes

To the right are three Grisly snowflakes of depth 0, 1, and 2. The depth 0 snowflake is simply a filled-in hexagon. The depth 1 snowflake of side length s is the depth 0 snowflake of side length s replaced by 7 hexagons of side length s/3. In general, for d > 0, the Grisly snowflake of side length s and depth d consists of 7 Grisly snowflakes of side length s/3 and depth d-1, drawn at the obvious places.

As with Sierpinski triangles, the difficulty will be figuring out where each of the 7 Grisly snowflakes of depth d-1 go. We leave you to try to figure it out but will put some explanation later on on the course website.

We have stubbed in two grisly procedures for you to complete. The first does not have a pen as a parameter; the second one does. We have also written procedure fillHex for you.

H-Trees

To the right are three H-trees of size s and depths 0, 1, and 2. Toudraw them, implement this set of instructions as given:

  1. Draw an H, with all three lines being of length s
  2. If d>0, draw four H-trees of size s/2 and depth d-1. The centers of the four H-trees are at the top and bottom of the two vertical lines drawn in the previous step.

H-trees are useful in designing microprocessor chips. The lines are wires that connect circuit components in a tree of interconnections, without wires crossing.

We have stubbed in two procedures Htree for you to complete. The first does not have a pen as a parameter, the second one does. We have also stubbed in procedure drawH, which may be useful to you. Complete it if you want to use it. Using pen p, draw lines using procedures p.setLocation (to move the pen) and p.drawLine (to actually draw the line).


Finishing the Assignment

At the very top A5.java you should put single line comments (//, not /** */) containing the following information:

  • Your name(s) and netid(s);
  • The information requested by drawTriangle
  • The names of the two radial shape procedures that you implemented
  • The names of the two recursive procedures that you implemented
  • What you liked best about this assignment;
  • What you most think could use improvement in this assignment
  • The time you spent on this assignment.

In addition, you should make sure that class A5 is indented properly. Do this by hitting tab on every line in DrJava, so that it will auto-indent for you.

Turning it In

Upload the file A5.java onto CMS by the due date: Thursday, April 5th at 11:59PM (week after coming back from Spring break). You do not need to submit any of the other source code files. Do not submit any files with the extension/suffix .java~ (with the tilde) or .class. It will help to set the preferences in your operating system so that extensions always appear.