![]() |
Wellesley College, Summer 2003
Problem Set 9Due: Fri., July 11 by 9am |
All code for this assignment is available in the ps9_programs folder in the cs111 download directory on the CS fileserver.
RectStairs.java
from Task 1;
Rect3.java,
Rect4.java, and
Rect5.java from Task 2b;
MorphingPolygon.java from Task 3.
MyAnimation.java from
(optional) Extra Credit Opportunity.
ps9_programs folder. In particular,
RectStairs subfolder should
contain your final version of RectStairs.java
from Task 1;
Rect subfolder should
include your final versions of
Rect3.java,
Rect4.java, and
Rect5.java from Task 2b;
MorphingPolygon subfolder should
contain your final version of MorphingPolygon.java.
MyAnimation subfolder should
contain your final version of any sprite and animation
classes you created (if you did the extra credit problem).
Task 1 is an independent problem (which is effectively a mini take-home exam). You may not consult with anyone else about this problem. (If you have any questions, you may of course ask Lyn or Elena; but we cannot help you to solve the problem.)
In this problem, you are asked to use Java graphics and iteration
to define a method that creates staircase patterns like those
illustrated below.
|
|
n = 4, c1 = Color.magenta, c2 = Color.cyan
|
|
|
n = 6, c1 = Color.red, c2 = Color.green
|
|
|
n = 10, c1 = Color.black, c2 = Color.yellow
|
All of the above examples are drawn by the following method, which you will define in this problem:
public static void rectStairs (Graphics g, Rectangle r, int n, Color c1, Color c2)
Using graphics contextg, draw annbynstaircase pattern in rectanglerusing colorsc1andc2. The staircase should consist ofncolumns. Assume the columns are indexed by i, which ranges from 1 ton. Then the ith column consists of (n+ 1 - i) bricks that rest on the "ground", where each brick has a width that is 1/nthe width ofrand a height that is 1/nthe height ofr. Each brick in column i has painted on it a design that consists of i concentric rectangles whose colors alternate betweenc1andc2. The outermost color in the design on the topmost brick in each column isc1, and the outermost brick color alternates going down the column.
Before beginning this problem, you should experiment with the test applet in
the Test subfolder of the RectStairs folder.
When you run the applet, a parameter window will be displayed that allows
you to specify n, c1, and c2.
Since there is no reset button on the applet, you will need to perform
some other action to get the applet window to repaint itself with the new
parameters when you change them. Such actions include resizing the
applet window, closing and opening the applet window, expanding and shrinking the applet window,
moving the applet window off the visible area of the screen and moving it back on,
or covering and uncovering the applet window with another window.
Note that the staircase always fills the rectangular area of the applet
window, even when it is resized.
To complete this problem, you should flesh out the skeleton of
the rectStairs method in RectStairs.java.
Note the following:
Graphics class)
to perform all drawing.
while or
for loops.
r into blocks or
drawing concentric rectangles on a given block, you will need
to perform arithmetic that involves truncation or rounding of
floating point numbers.
n
(which may be either a float or
a double) down to an integer,
use the cast (int) n.
n
(which must be a float and not
a double) to the nearest integer,
use the invocation Math.round(n).
n = 10 example staircase, the nested rectangular
patterns in the 7th, 8th, and 10th columns don't look so great.
RectStairs project.
This will invoke your rectStairs with the graphics context
and rectangle of the applet window using the n,
c1, and c2 specified in the parameter window.
A key idea in CS111 is data abstraction -- the notion that "users" can successfully use objects by understanding their contracts without knowing how the contracts have been implemented by the "implementers". Contracts not only serve to simplify the programming task for users, they also give implementers the flexibility to experiment with different ways to implement the same contract.
In Lecture 15, we studied the notion of multiple implementations
of a data abstraction in the context of a simple rectangle
abstraction known as a Rect. Conceptually,
an instance of Rect is a rectangle positioned in
the standard Cartesian coordinate system:
Here is a sample rectangle with lower left point (23,17), width 19, and height 11:
We emphasize that the rectangles we study in this problem are not the
same as the java.awt.Rectangle class used in
graphics applications, such as the Faces problem in Problem Set 9.
Below is a simple contract for the Rect class that
supports two constructor methods and four instance methods.
This class could easily be extended with more methods, such as
methods for finding the perimeter or area of a rectangle, or
returning its upper left and lower right points. But we've
kept the contract small for simplicity's sake.
Rect Contract
Constructor Methods
public Rect (int llx, int lly, int width, int height);
Construct a rect from with lower left point (llx,lly), widthwidth, and heightheight.
public Rect (Point ll, Point ur);
Construct a rect with lower left pointlland upper right pointur.Instance Methods
public int width ();
Returns the width of this rect.
public int height ();
Returns the height of this rect.
public Point lowerLeft ();
Returns the lower left point of this rect.
public Point upperRight ();
Returns the upper right point of this rect
As an example, the rectangle depicted above could be created by either of the following constructor method invocations:
new Rect(23, 17, 19, 11);new Rect(new Point(23, 17), new Point(42, 28));
In the remainder of this problem, you will consider five different
implementations of the Rect contract.
In order to be able to discuss the different implementations,
we will name them Recti, where
i ranges between 1 and 5.
Rect1 and Rect2
that implement the contract for Rect (modulo the change in constructor name).
In this subtask, you should draw an object diagram that shows the result of
the following sequence of statements:
Point p1 = new Point (1,2); Point p2 = new Point (9,6); Rect1 a1 = new Rect1 (p1,p2); Point ur1 = a1.upperRight(); Rect1 b1 = new Rect1 (ur1.y, ur1.x, a1.height(), a1.width()); Rect2 a2 = new Rect2 (p1,p2); Point ur2 = a2.upperRight(); Rect2 b2 = new Rect2 (ur2.y, ur2.x, a2.height(), a2.width());
The purpose of this problem is to give you some practice drawing object diagrams. Recall that an object diagram shows a collection of interconnected class instances and arrays:
Follow these conventions in drawing your object diagrams:
null pointer should have a slash
drawn through it.
Implementation of theRect1class:import java.awt.Point; public class Rect1 { // INSTANCE VARIABLES -------------------------------- private int llx; // x coordinate of the lower left corner private int lly; // y coordinate of the lower left corner private int width; // width of the rect private int height; // height of the rect // CONSTRUCTOR METHODS ------------------------------- // Construct a rect from the lower left (x,y), width, and height. public Rect1 (int llx, int lly, int width, int height) { this.llx = llx; this.lly = lly; this.width = width; this.height = height; } // Construct a rect from the lower left and upper right points. public Rect1 (Point ll, Point ur) { this.llx = ll.x; this.lly = ll.y; this.width = ur.x - ll.x; this.height = ur.y - ll.y; } // INSTANCE METHODS ---------------------------------- // Returns the width of this rect. public int width () { return width; } // Returns the height of this rect. public int height () { return height; } // Returns the lower left point of this rect. public Point lowerLeft () { return new Point (llx, lly); } // Returns the upper right point of this rect. public Point upperRight () { return new Point (llx + width, lly + height); } }
Implementation of theRect2class:import java.awt.Point; public class Rect2 { // INSTANCE VARIABLES -------------------------------- private Point ll; // lower left corner of rect. private Point ur; // upper right corner of rect. // CONSTRUCTOR METHODS ------------------------------- // Construct a rect from the lower left (x,y), width, and height. public Rect2 (int llx, int lly, int width, int height) { this.ll = new Point (llx, lly); this.ur = new Point (llx + width, lly + height); } // Construct a rect from the lower left and upper right points. public Rect2 (Point ll, Point ur) { this.ll = ll; this.ur = ur; } // INSTANCE METHODS ---------------------------------- // Returns the width of this rect. public int width () { return ur.x - ll.x; } // Returns the height of this rect. public int height () { return ur.y - ll.y; } // Returns the lower left point of this rect. public Point lowerLeft () { return ll; } // Returns the upper right point of this rect. public Point upperRight () { return ur; } }
Rect1 and Rect2 illustrate only two
of many ways to implement the given Rect contract.
In this subtask, you will consider three more implementations.
Below are skeletons of classes Rect3, Rect4,
and Rect5, each of which has one constructor method.
Partial Implementation of theRect3class:public class Rect3 { // This declaration allows us to indicate all IntList operations // using the prefix "IL." private static IntList IL; public Rect3 (int llx, int lly, int width, int height) { coords = IL.prepend(llx, IL.prepend(lly + height, IL.prepend(llx + width, IL.prepend(lly, IL.empty())))); } }
Partial Implementation of theRect4class:public class Rect4 { public Rect4 (int llx, int lly, int width, int height) { area = width * height; ul = new Point(llx, lly + height); ur = new int [2]; ur[0] = llx + width; ur[1] = lly + height; } }
For each of the above three class declarations, your goal is to flesh out the rest of the class declaration to correctly implement the
Partial Implementation of theRect5class:public class Rect5 { public Rect5 (Point ll, Point ur) { sumsAndDiffs = new Point [2]; sumsAndDiffs[0] = new Point(ur.x + ll.x, ur.y + ll.y); sumsAndDiffs[1] = new Point(ur.x - ll.x, ur.y - ll.y); } }
Rect contract. To do this, you will need to flesh out
the class skeleton with appropriately defined instance variables,
the other constructor method, and all instance methods.
All of these will need to be consistent with the given constructor
method (which you should not change).
Notes:
Rects of ps9_programs
contains the implementations of Rect1 and Rect2
as well as the skeletons of Rect3, Rect4,
and Rect5. You should flesh out the three skeletons.
.java file for the class to the Rects.mcp
project. You can do this via drag-and-drop (on the Macintosh),
or via the Project:Add Files menu item (on both Macs and PCs)
RectTest class contains code that performs
a simple test of the Rect1 and Rect2
implementations. It also contains commented out code that tests
the remaining implementations. When you flesh out an implementation,
you should uncomment the relevant testing code in
RectTest. Compiling and executing the project file
Rects.mcp will execute the main() method
in the RectTest class and display the results of
the tests in the Java Console window.
Rect3 has been configured with a declaration
that allows you to refer to any of the class methods of the
IntList by prefixing them with "IL.".
For instance: IL.prepend,
IL.head,
IL.tail,
IL.empty,
IL.isEmpty.
Rect5, consider the following. Suppose
there are two unknown numbers a and b, and you are given
two numbers c and d such that c = a + b and
d = a - b.
How can you determine the value of a given c and d?
How can you determine the value of b given c and d?
Point p1 = new Point (1,2); Point p2 = new Point (9,6); Rect3 a3 = new Rect3 (p1,p2); Point ur3 = a3.upperRight(); Rect3 b3 = new Rect3 (ur3.y, ur3.x, a3.height(), a3.width()); Rect4 a4 = new Rect4 (p1,p2); Point ur4 = a4.upperRight(); Rect4 b4 = new Rect4 (ur4.y, ur4.x, a4.height(), a4.width()); Rect5 a5 = new Rect5 (p1,p2); Point ur5 = a5.upperRight(); Rect5 b5 = new Rect5 (ur5.y, ur5.x, a5.height(), a5.width());
This problem description contains an embedded Animation World applet.
Experience shows that this applet may run fine in some browsers
but not in others. If you cannot get the applet
to work in one browser, try another one instead.
If you can't find any browser that works, you can run the applet
in CodeWarrior from the Test
subfolder of ps9_programs/MorphingPolygon.
The following animation shows a single sprite that is a five-sided polygon that "morphs" (changes) over time. It behaves as if each corner of the polygon is a ball that bounces off the edges of the applet window:
The polygon in the above applet is created via the invocation
new MorphingPolygon(5,Color.magenta),
which specifies a magenta polygon with 5 points. The initial
positions and velocities of the points are determined randomly
every time the animation is reset. Test this by clicking
the Reset button.
There are many other ways to invoke the MorphingPolygon
constructor, which are illustrated via other menu choices in
the above applet:
true
as a third parameter, the polygons will be drawn filled
rather than unfilled. For example, try new MorphingPolygon(5,Color.blue,true).
new MorphingPolygon(3).
new MorphingPolygon(Color.cyan).
new MorphingPolygon().
It is also possible to include several morphings polygons in the
same animation, as in the Many Polygons menu option.
Your goal in this problem is to flesh out the definition of
the MorphingPolygon class so that it describes
sprites with the behavior shown above.
Notes:
MorphingPolygon class,
you will have to do the following:
dx and dy.
Note that only the first constructor method definition should be nontrivial. The other four constructor methods should invoke the first constructor method using thepublic MorphingPolygon (int n, Color c, boolean isFilled) public MorphingPolygon (int n, Color c) public MorphingPolygon (int n) public MorphingPolygon (Color c) public MorphingPolygon ()
this constructor notation presented in lecture.
public void drawState (Graphics g) public void resetState () public void updateState ()
width and height
instance variables of a Sprite (these are
inherited by MorphingPolygon, which
is a subclass of Sprite).
MorphingPolygon instance
is created or the resetState() method
is invoked on a MorphingPolygon instance,
the positions and velocities of the polygon corners
should be randomly reset.
Randomizer.IntBetween(lo,hi)
to choose a random integer between lo
and hi, inclusive.
dx and dy components
that are between -20 and 20.
BouncingBall
sprite studied in lecture 13. You should carefully study
BouncingBall.java
as part of doing this problem.
MorphingPolygon implementation, select
the menu options in the the MorphingPolygonShowcase
applet. A correct definition of MorphingPolygon
will give rise to the same behavior shown in the test applet
in the Test subfolder of the
MorphingPolygon folder.
You can use AnimationWorld to create dazzling animations that show off your artistry and your programming talents. Here is a chance to be creative and earn some extra credit points at the same time.
For this challenge, build an animation of your own design. You may use existing sprites that we have studied, but you should create and use at least one new kind of sprite from scratch.
The MyAnimation subfolder of the
ps9_programs folder contains
a copy of the sprites and animations shown
in Lecture 13. This is a good starting point
for your own animations. You may edit the
existing files or create ones of your own.
Add any animations you create to
MyShowcase.java.
Notes: