Overview

The goal of this lab is to explore and experience good object oriented design with regards to encapsulation and information hiding. The program you are going to write is simple: it takes commands from the user and produces output. Its functionality is to keep track of the bounding box for points as they are "added". The bounding box for a set of points is the smallest rectangle (aligned with the x/y axis) that contains all the points. The commands are:
  1. add x y adds another point that the bounding box needs to include. No output.
  2. box outputs the current bounding box in the format xmin < x < xmax , ymin < y < ymax.
  3. map x y prints the point (x,y) (which should be inside the bounding box) mapped into the unit square according to the following formula: newx = (x - minX)/width and newy = (y - minY)/height, where minX is the minimum x-value in the bounding box, minY is the minimum y-value in the bounding box, and width and height are the bounding box's width and height. map should return "error" if (x,y) is not in the current bounding box.
  4. done exits the program
Here's a sample run:
~/$ java Lab03
add 4 5
add 9 3
add 6 7
box
4.0 < x < 9.0, 3.0 < y < 7.0
map 5 6
0.2 0.75
add 2 6
map 5 6
0.42857142857142855 0.75
box
2.0 < x < 9.0, 3.0 < y < 7.0
done

The Rules

I'm going to try and force you to use good Object Oriented Design practices. So, there are a few rules. First and foremost, in all that you do, fields are private. Otherwise, here are my rules:
You must define a class Point with at least the constructor
public Point(double x, double y)
and method
public static Point read(Scanner sc)
that reads an x and a y value from the scanner and returns the associated point, and method
public String toString()
that returns a String consisting of the x-coordinate, a space, and the y-coordinate. Anything else you want in point is OK except that you must declare all data-members (fields) private!

Your program must be able to be run as:

java Lab03
... and it must accept exactly the input syntax described above, and produce exactly the output described above. Also, Step 3 has one more rule!

You must define a class Box with the interface shown below, and no other public methods or fields!
public class Box
{
  // constructor for Box that consists of a single point
  public Box(Point p) { ... }

  // constructor for the Box containing two initial points
  public Box(Point a, Point b) { ... }

  // growBy(p) expands the bounding box (if needed) to include point p
  public void growBy(Point p) { ... }

  // given point p in the bounding box, returns associated point in the unit square (see notes)
  // return null if p is not inside the bounding box.
  public Point mapIntoUnitSquare(Point p) { ... }

  // returns string representation like: 2.0 < x < 9.0, 3.0 < y < 7.0
  public String toString() { ... }
}

Step 1: Get to the Point

You know you're going to want a class Point. Go ahead and write it. Think first of what operations you're likely to need, and then start writing them one-by-one. Make sure to have a
public static void main(String[] args)
you can use to test as you go. Keep adding new code that tests each new function as you add it, but don't get rid of the old tests. When you're done with the program, main() should be a complete test suite you can run to verify that Point works the way it should!

Step 2: Think inside the Box

Now start implementing the Box class. Start with the one-argument constructor and the toString() function. Be sure to include a main() that tests them. Then start adding the other methods, testing as often as you can, and never deleting tests from main(). You may find that you have to go back and add some new methods to Point as you go along. That's OK. Be sure to re-test whenever you do, though!

Step 3: Get with the Program

Finally, write the class Lab03. It should be a breeze now that you've got Box and Point written. One more rule: only use the read and toString methods from the class Point. Here's some runs for testing separating interface and implmentationpurposes: exout1.txt.

Step 4: How well did you follow the rules?

Let's see if you followed the rule. Find a classmate who has finished the other steps as well. Copy his/her Point.java and Box.java into a new directory, and copy your Lab03.java in there as well. Compile it all and run and test. Did it work? If you followed the rules, it has to work! That's the beauty of separating interface and implmentation! As long as the interface elments you rely on stay the same, you can change the the implementation behind it as much as you like.