Wellesley College, Summer 2003

Problem Set 9

Due: Fri., July 11 by 9am


Reading

About this Problem Set

  • Task 1 is an independent problem in which you will use iteration and Java graphics to draw a design. Because it is an independent problem, you may not consult with anyone else about this particular problem.
  • In Task 2, you will study data abstraction in the context of simple rectangle objects presented in Lecture 15.
  • In Task 3, you will create a sprite class for some simple animations. You will get some experience with arrays in implementing this class.
  • There is also an optional open-ended extra credit opportunity to create your own animation.

    All code for this assignment is available in the ps9_programs folder in the cs111 download directory on the CS fileserver.

    How to turn in this Problem Set

    You are required to turn in both a hardcopy and a softcopy. For general guidelines on problem set submission, including how to submit a softcopy and how to check if you softcopy submission was successful, click here. Please make sure to keep a copy of your work, either on a zip disk, or in your private directory (or, to play it safe, both).

    Hardcopy Submission

    Your hardcopy packet should consist of:
    1. The cover page;
    2. The final version of RectStairs.java from Task 1;
    3. Your object diagram from Task 2a;
    4. The final versions of Rect3.java, Rect4.java, and Rect5.java from Task 2b;
    5. Your object diagram from Task 2c;
    6. The final version of MorphingPolygon.java from Task 3.
    7. The final version of MyAnimation.java from (optional) Extra Credit Opportunity.
    Staple these together, and put them in the box in the back of 257.

    Softcopy Submission

    You should submit your final version of your ps9_programs folder. In particular,

    Task 1: Rectangular Stairs (Independent 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 context g, draw an n by n staircase pattern in rectangle r using colors c1 and c2. The staircase should consist of n columns. Assume the columns are indexed by i, which ranges from 1 to n. Then the ith column consists of (n + 1 - i) bricks that rest on the "ground", where each brick has a width that is 1/n the width of r and a height that is 1/n the height of r. Each brick in column i has painted on it a design that consists of i concentric rectangles whose colors alternate between c1 and c2. The outermost color in the design on the topmost brick in each column is c1, 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:


    Task 2: Data Abstraction with Rects

    Rects

    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), width width, and height height.

    public Rect (Point ll, Point ur);
    Construct a rect with lower left point ll and upper right point ur.

    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.

    Task 2a

    Below are the implementations of classes 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:


    Implementation of the Rect1 class:
    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 the Rect2 class:
    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;
      }
    }
    

    Task 2b

    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 the Rect3 class:
    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 the Rect4 class:
    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;
      }
    
    }
    


    Partial Implementation of the Rect5 class:
    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);
      }
    
    }
    

    For each of the above three class declarations, your goal is to flesh out the rest of the class declaration to correctly implement the 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:

    Task 2c

    Draw an object diagram showing the result of executing the following statements:
    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());
    

    Task 3: Morphing Polygons

    A Note on Viewing Applets

    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.

    Task 3: Morphing Polygons

    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:

    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:


    Extra Credit Opportunity: Open-Ended Animation [up to 10 points]

    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: