Graphic by Keith Ohlfs

CS111, Wellesley College, Fall, 1998

Problem Set 5

Due: Friday, October 23 by 4:00 p.m.

[CS111 Home Page] [Syllabus] [Students] [Lecture Notes] [Assignments] [Programs] [Documentation] [Software Installation] [FAQ] [CS Dept.] [CWIS]

This is the Final version of this problem set.

Note: The assigned readings which are relevant to this problem set are:

About this Problem Set

There are 2 pieces to this problem set: the laboratory assignment and the homework assignment. You are required to do both parts. We recommend that you do the laboratory assignment during your lab section and the homework assignment after completing the prelab and lab assignments.

How to turn in this Problem Set

Prelab Assignment: There is no prelab for this assignment.

Laboratory Assignment: Save the modified Fishtank.java file in the fishtank folder. Upload the entire folder to your ps5 drop folder. Turn in a hardcopy of the Fishtank.java file.

Homework Assignment problem 1: Save the modified QuiltWorld.java file in the graphicsQuilt folder. Upload the entire folder to your ps5 drop folder. Turn in a hard copy of the QuiltWorld.java.

Homework Assignment problem 2: Save the modified TurtleWorld.java file in the turtles folder. Upload the entire folder to your ps5 drop folder. Turn in a hard copy of the TurtleWorld.java.

Turn in only one package of hardcopy materials. Staple your files together with the cover page, and submit your hardcopy package by placing it in the box outside of Stanzi's office (E106, directly across from E101).

Reminders

Laboratory Assignment

Building a Class: The Fish class

In lecture we discussed how to create a simple class definition, using instance variables, a constructor method definition and instance method definitions. The instance variables keep track of the state of each instance of the class, the constructor method initializes the state of each instance as it is created, and instance method declarations define methods that instances of the class can carry out. We also discussed using the graphics methods from the Java abstract windows toolkit library. Today you will combine these to build your own Fish class. You will write a program that has two classes. The Fishtank class contains the code that will create fish objects and invoke fish methods to change their color, size and position. The Fish class definition will define fish objects according to their instance variables, constructor method and instance methods. In the end you will have an applet that looks like this:

Getting Started: Defining a generic fish object

Download the ps5_programs folder from the CS111 download folder. Open the "fishtank" folder. Open the Fishtank.proj file. Look at the Fishtank.java file. Notice the stubs for the two class definitions: Fishtank and Fish. The Fishtank class already has the stub of the paint() method that we will use for manipulating fish objects. Our first task is to write code for the Fish class that will produce a fish object in response to the following statement in the paint method:

	Fish freddy = new Fish(g);

The Fish object will be drawn as follows:

In order to accomplish this, we must complete 3 steps:

  1. Define the instance variables
  2. Define the constructor method
  3. Write an instance method to draw the fish.

Defining the instance variables

You should make your fish object so that a fish is defined by the following variables:
int lengthThe length of the entire fish
Point positionThe position of the upper left corner
Color fishClrThe Color of the fish body
Color tailClrThe Color of the fish tail
Graphics gfx The graphics object for drawing to the applet window

Define these variables at the top of the Fish class. Make them private variables. Do not assign any values to them. Thus, the variable declaration for the position variable will be as follows:

	private Point position;

Defining the Constructor method

The constructor method should initialize the instance variables to default values when a fish object is created. You should write code in the constructor method to set the following defaults for the Fish objects:
length100
position(1,1) (note that this is a point object)
fishClrColor.red
tailClrColor.green
gfxg (the parameter given in the method invocation)

To make these assignments, recall that we refer to the instance variables within the class using the keyword "this". Thus, we can set the value of the "postion" variable as follows:

	this.position = new Point(1,1);

To draw correctly to the applet window, the fish object needs to have access to the Graphics object from the paint method. The easiest way to do this is to use a parameter in the constructor method (this is the "Graphics g" parameter in the method definition). The fish object can keep track of this object by assigning its value to the "gfx" instance variable, as follows:

	this.gfx = g;

Fill in the other assignments for the length and colors of the fish.

When we create an instance of the fish class, we would like to have it drawn in the applet window. We can do this by invoking the "drawFish()" method from within the constructor method.

	this.drawFish();

Make sure you put this statement after the statements initializing the instance variables! (This doesn't do anything yet, we have to write the method first).

Writing the drawFish() method

Now you are ready to write the drawFish method. This method should draw a fish according to the following format:

In the above diagram, x and y refer to the x and y components of the "position" variable. They indicate the upper left hand corner of the bounding rectangle for the fish. They can be accessed in your class definition by the expressions "position.x" and "position.y". The red body should be colored in the color specified by the instance variable fishClr and the green tail should be colored according to the instance variable tailClr.

Use the java graphics methods: drawOval, fillOval, Polygon(), fillPolygon, and drawPolygon to draw the fish above. LeeAnn will help you compute the positions of critical points, such as the upper-left corner of the oval and the 3 points on the tail polygon. When you are finished, you should be able to include the statement:

	Fish freddy = new Fish(g);

in your paint method and have the fish appear in the applet window.

Instance Methods for the Fish Class

Now you are ready to write some methods that your fish can understand. You will write methods that set the body color, the tail color, the position of the fish, and the length of the fish. The methods names are as follows:

		public void setFishClr(Color c)
		Set the body color of the fish to c.  Redraw the fish with
		the new color.
		
		public void setTailColor(Color c)
		Set the tail color of the fish to c.  Redraw the fish with
		the new color.
		
		public void setPosition(Point p)
		Clear the current fish drawing and set the new fish position
		to be the point p.  Redraw the fish at point p.
			
		public void resize(int size)
		Clear the current fish drawing and set the length of the fish 
		to size (note that this is specified in number of pixels). 
		Redraw the fish in the new size.
			
		public void clearFish()
		Clear the fish from the screen.

In each method you must assign a new value to the appropriate instance variable and then redraw the Fish. In the setPosition and resize methods you must clear the old fish from the screen before you change the values of the instance variables. To clear the fish, you should write the instance method "clearFish()". clearFish() clears the fish by drawing over the current fish in the color white. For the purposes of this lab, you can make the clearFish() method nearly identical to the drawFish() method except for the changes in the drawing colors. As you write each instance method, test it out by invoking it from the paint method in the fishtank class. For example, you can test the setPostion method by invoking:

	freddy.setPosition(new Point(100,200));

Creating Multiple Fish

You can now create multiple fish and change their characteristics from the paint() method in your fishtank class. Inside the paint method create 5 fish: freddy, felicia, frances, frank and franny. Use the Fish instance methods to change the state of these fish as follows:

FishfishClrtailClrpositionlength
freddydefaultdefault(50,100)default
feliciagreenyellow(100,200)50
francescyanmagenta(175,150)25
frankbluered(225,125)default
frannymagentacyan(75,250)200

If you have completed the assignment correctly, your applet should look like the first figure in the lab assignment.

Extra Credit Problems

You can earn extra points on your homework set by completing the following extra steps on your lab assignment. You do not have to do these to receive full credit on your assignment. Please do not spend extra time on these until you have completed the rest of your homework assignment!

1. (Worth 1 extra point) Use java graphics to draw a background for your fish. Write a method in the Fishtank class, called drawFishTank(Graphics g), which draws the Fishtank with water and whatever else you would like to put in. Be creative--you can add bubbles, plants, a "toy castle", a boat or whatever you like. Make sure you invoke the drawFishtank() method before you create the fish and set their positions in the paint() method. Also, make sure the five fish still have the specified colors and positions and that they are visible on the fishtank background.

2. (Worth 1 extra point) The drawFish() and clearFish() methods are very similar and both execute a fair number of drawing commands. rewrite these methods in the Fish class so that there is only one method (drawColorFish()) that does the drawing, and takes 3 Color parameters that specify the border color, the body color and the tail color. Now write drawFish() so that it invokes the drawColorFish() with the appropriate instance Color variables (and Color.black for the border color) and clearFish so that it invokes drawColorFish() with Color.white as the value for all 3 color parameters. All of the Fish instance methods should work exactly as before. Note: Please keep the working versions of your drawFish() and clearFish() methods from the lab assignment in your fishTank.java file. Just use the "/*...*/" comments to comment them out so they will not be compiled with the new methods. This way, you can still get full credit on the original assignment if you don't write the extra-credit methods correctly.

Turning in the lab assignment

When you are finished modifying the Fishtank.java file. Save it in the fishtank folder. Upload the entire folder to your ps5 drop folder. Turn in a hardcopy of the Fishtank.java file.

Homework Assignment:

Problem 1: Using Java Graphics to Make a Quilt

Recall in Problem set 4, we used PictureWorld to create a Quilt in the laboratory assignment (Quilt1). In this assignment, we will use the Java awt to create a portion of the same quilt, the yellowCorner, shown here:

Use the same divide, conquer and glue strategy to draw this quilt that you used in PS4. Recall that the yellowCorner is composed of the redYellowTriangles and the redCorner.

yellowRedTriangles

redCorner

The redCorner can then be further divided into the 4x4 red patch and the greenCorner, and so on.

Open the graphicsQuilt folder and open the GraphicQuilt.proj. In the QuiltWorld.java file there is a paint() method, and stubs for the following methods:

public void drawSquare(Graphics g, int x, int y, int width, int height, Color c)
Draws a square color c and dimensions given by width and height and upper lefthand corner at position x,y (in pixels).

public void drawSquare2x2(Graphics g, int x, int y, int width, int height, Color c)
Draws a 2x2 square with upper left corner at position x,y, consisting of squares with the specified width, height, and color c.

public void drawSquare4x4(Graphics g, int x, int y, int width, int height, Color c)
Draws a 4x4 square with upper left corner at position x,y, consisting of squares with the specified width, height, and color c.

public void drawTriangles(Graphics g, int x, int y, int width, int height, Color c1, Color c2)
Draws a square divided in half along the diagonal, with the lower triangle of color c1, and the upper triangle of color c2. The square's upper lefthand corner is at position x,y (in pixels) and it has the specified width and height.

public void drawTriangles2x2 (Graphics g, int x, int y, int width, int height, Color c1, Color c2)
Draws triangles similar to drawTriangles(c1, c2) except that it consists of two triangles patches and two square patches to create a 2x2 square divided in half along the diagonal. width and height refer to the width and height of the smallest square patches.

public void drawTriangles4x4 (Graphics g, int x, int y, int width, int height, Color c1, Color c2)
Draws triangles similar to triangles(c1, c2) except that it consists of two triangles2x2 patches and two square2x2 patches to create a 4x4 square divided in half along the diagonal

public void drawTriangles8x8 (Graphics g, int x, int y, int width, int height, Color c1, Color c2)
Returns a picture similar to triangles(c1, c2) except that it consists of two triangles4x4 patches and two square4x4 patches to create a 8x8 square divided in half along the diagonal

Fill in the stubs for the methods so that they function as described. The only methods that use java graphics commands should be the drawSquare and the drawTriangles methods. You should make use of Polygon() to draw the triangle. The other methods should be organized like the plainQuilt example in the lec10_programs folder in the cs111 download folder.

Turning in Homework problem 1

Save your modified QuiltWorld.java file in the graphicsQuilt folder and upload it to your ps5 drop folder.

Problem 2: Creating the Turtle class

Turtles are handy graphics objects for drawing designs and learning programs. Some of you may have had some experience with Turtles, which are often used to teach students programming concepts. Turtles are similar to Buggles, in that they can move forward or backward and they leave a trail as they do so. They can also turn left and right. They differ from Buggles because their movement is not restricted to a grid. Instead they can move anywhere within the applet window, and their position is given in pixels. They can also turn any amount, specified by an angle given in degrees (unlike Buggles which can only turn by 90 degrees). Note that turtles are not drawn on the screen (You can think of them as invisible). The only evidence of their existence is the trail that they leave behind them as they move.

A Turtle's state can be specified by the state of 3 instance variables indicating its position, heading and color. We will also use an instance variable to keep track of the Graphics object the turtle will be using to draw to the applet window. Turtle methods allow it to move forward or backward, turn left or right, change color or change position. (Full fledged turtles also have a pen that can be up or down, but we don't have quite enough programming tools to implement that yet!)

Your assignment is to create the Turtle class.

Getting Started

To begin with, open the TurtleWorld.proj file in the Turtles folder. Open the TurtleWorld.java file. Note that the TurtleWorld class has one paint() method, with some code that is commented out. The Turtle class is empty. When you finish creating the Turtle class, you will uncomment the code in the paint() method to test your Turtles. As in the laboratory assignment, you should create the Turtle class in three steps:
  1. Declare the instance variables.
  2. Define the Constructor method.
  3. Define the instance methods.

The instance variables
Turtles should have four private instance variables:

Point positionThe position (in pixels) of the Turtle
Color ClrThe Color of the turtle
double headingThe Direction the turtle is facing
Graphics gfx The graphics object for drawing to the applet window

Fill in code at the top of the Turtle class to declare these variables. Note that the heading is of type "double". This means that it is a decimal number (like 4.5 or 73.0) instead of an integer. The heading is specified in degrees, with a heading of 0.0 indicating a direction facing toward the right of the screen. Increasing the angle indicates a change in the counterclockwise direction. Thus, an angle of 90.0 degrees would have the Turtle facing up. An angle of -90.0 degrees would have the Turtle facing down.

The Constructor Method
The constructor method should initialize the instance variables. Like the Constructor method for the Fish objects in lab, it should take one parameter--the Graphics object. Initialize the instance variables to the following values:

position(200,200) (note that this is a point object)
ClrColor.red
heading0.0
gfxg (the parameter given in the method invocation)

Write code for the constructor method. Remember that the constructor method must have the same name as the name of the class. Also, unlike the fish objects in the lab assignment, you don't have to draw the Turtle (turtles are invisible).

The instance methods
Turtles should be able to perform the following actions, defined by instance methods:

	public void setColor(Color c)
	Set the color of the Turtle to c.			

	public void setPosition(Point p)
	Set the turtle position to be the point p.
			
	public void fd(int dist)
	Move the turtle forward by the number of pixels given
	by dist, in the direction given by the Turtle's heading.
	The Turtle should leave a trail.  That is, it draws
	a line in its current color between it's old position 
	and it's new position.
			
	public void bd(int dist)
	Move the turtle backward by the number of pixels given
	by dist, in the direction given by the Turtle's heading.
	The Turtle should leave a trail.  That is, it draws
	a line in its current color between it's old position 
	and it's new position.
		
	public void lt(double angle)
	The Turtle increases its heading by the number of degrees
	given by angle.
		
	public void rt(double angle)
	The Turtle decreases its heading by the number of degrees
	given by angle.
		
	public void square(int length)
	Use the other instance methods to draw a square with sidelength
	specified by "length".  (This is not a standard turtle method,
	but we will use it in testing the turtles).

Note that when the Turtle moves forward or backward, the number of pixels it moves in the x and y directions depend on the parameter "dist" and on the current heading of the Turtle. You can calculate these with standard trigonometric functions:

	x = dist * cos(heading)
	y = -dist * sin(heading)
	

To compute sine and cosine in Java, you need to use methods from the Math class. There are two problems that arise with this. First, the sine and cosine methods require an angle parameter given in radians instead of degrees. Second, the methods return a value of type "double" and you will need to convert it to an integer to specify a new Point (since the x and y components of a Point object are integers). So, to compute the number of pixels the Turtle must move, you need to follow three steps:

  1. Convert the heading angle from degrees to radians.
  2. Compute the distance.
  3. Convert the result to an integer.
Let's take these one step at a time.

Converting degrees to radians
Recall that the number of radians is equal to the number of degrees times Pi divided by 180. Pi is given by the Math class constant: Math.PI. Thus, the statement:

	double rads = this.heading * Math.PI/180.0;

will create a variable, rads, that gives the heading angle in radians.

Computing the distance
The methods for computing Sine and Cosine are given as Math.sin(double angle) and Math.cos(double angle) respectively. Thus, to compute the number of pixels to move in the x direction, you would write the expression:

	dist * Math.cos(rads)	

Converting a double to an integer The expression above will compute the distance as a decimal number. You will need to convert it to an integer. You can do this by making use of a "cast". We convert a number to an integer by placing the key word "(int)" in front of the value. Thus, the expression:

	(int)(dist*Math.cos(rads)) 

will compute the number of pixels to be moved in the x direction. Similarly, the expression:

	-(int)(dist*Math.sin(rads)) 

will compute the number of pixels to be moved in the y direction. Note that the minus sign ensures that the turtle will move up, when it is facing a direction of 90.0 degrees (To move up, the y position decreases).

Finishing and testing the Turtle class

You should now have all the tools you need to finish writing the instance methods for the Turtle class. As you write each method, write a few lines of code in the paint() method to test the Turtle instance method. For example, if you write the fd(int dist) method first, you can test it by writing:
	Turtle tommy = new Turtle(g);
	tommy.fd(100);

You should end up with a red line on the screen extending from the middle of the applet window to the right (by 100 pixels). I would recommend writing the fd() and bd() methods first, because they are the only methods that cause something to be drawn on the screen. You can then add lt(), rt() and setPosition(), and test them by turning the Turtle (or changing its position) and then having it move forward.

After you have written the instance methods, test your code by uncommenting the code in the paint() method. (You will need to delete any lines of code you wrote to test individual methods). If everything works properly, you should get the following picture:

Handing in the Homework Problems

When you are finished writing the code for the graphics Quilt in QuiltWorld.java, save the modified file in the graphicsQuilt folder. Leave all the other .html, .java, .proj and .class files in this folder. Upload the entire folder to your ps5 drop folder on the CS111 server. Turn in a hardcopy of the QuiltWorld.java file.

Save the modified TurtleWorld.java file in the turtles folder. Upload the entire folder to your ps5 drop folder on the CS111 server. Turn in a hardcopy of the TurtleWorld.java file.