CS335
Fall, 2008
Programming Assignment 2 (40 points)
(Team project: two people a team)
Due: November 13 (Thursday)

1. Problem Description

In this assignment you are required to form a team with a commorade
and jointly develop java tools that allow a user to "create", "edit",
and "manipulate" simple geometric primitives.  A set of menu items
should be displayed in the menu panel (such as the following example)
so that the user can click in these items to create, edit or
manipulate geometric primitives.


You should keep a working area big enough for the user to do
the DESIGN.

Geometric primitives created by the user should be stored in an
"object list" so that they can be redrawn, edited or manipulated
later.

Editing and manipulation can only be performed on current set
which could be a line segment, a rectangle, a circle (special
case of an ellipse), or a set of primitives.


To facilitate the work of a user, a rectangular grid of points
(distance between each two horizontally or vertically adjacent
points = 8 or 16) should be displayed in the canvas when the
menu item "GRID" is clicked so the user can align input points
with some of the grid points.

                ...................
                ...................
                ...................
                ...................
                ...................
                ...................

If it is necessary, your Java program should also allow automatic
alignment to make the drawing of a horizontal or vertical line
easier.



2. Implementation Details

The mouse should be used for input.

To draw a polyline, use:	
Button1: to input the vertices (the points should be marked
         with small crosses) and then click in "POLYLINE".
         (Button1 is the left most button)
         (POLYGON and B-SPLINE CURVE can be implemented in
          a similar way)
				
To draw an (axis-oriented) ellipse*, use:
Button1: to input three points (one as the center and the
         the other two points to define the major and minor
         axes of the ellipse. These points should be marked
         with small crosses) and then click in "ELLIPSE".
				
To drawing an (orthogonal) rectangle, use:
Button1: to input two opposite vertices of the rectangle
         (these corner points should be marked with small
         crosses) and then click in "RECTANGLE".

If more/less points are input than needed, the user should be prompted.


CURRENT SET: BY inputting two points and then clicking in this
             item, every primitive contained in the rectangle
             defined by these two points are considered as part
             of the CURRENT SET.  Otherwise, the most recently
             input item will be considered as the current set.

TRANSLATE: By identifying a reference point in the current set
           and a destination point and then clicking in this
           item, the current set will be moved from the reference
		   point to the destination point.

SCALE:     By identifying a reference point in the current set
           and two other points to define a scaling factor and
           then clicking in this item, the current set will be
           scaled with respect to the reference point using
           the specified scaling factor.
           For instance, in the following, if R is a point in the
           current set, and A and B are two other points specified
           by the user

                    R ------ A ----- B

           then the scaling factor is defined as

                            |RB|
                     SF = ----------
                            |RA|

           where |RB| is the distance between R and B and |RA| is
           the distance between R and A.
            
           To scale the current set with respect to the reference 
           point R by the scaling factor SF, subtract each vertex
           by R first, then multiply that vertex by the 2x2 scaling
           matrix
                           _           _
                          |   SF    0   |
                          |             |
                          |_  0     SF _| ,

           and finally add R to the scaled vertex.


REFLECT:   By identifying a reference point in the current set
           and two other points to define a reflection line and
           then clicking in this item, the current set will be
           reflected about the reflection line.
           For instance, in the following, if R is a reference
           in the current set (a rectangle) and A and B are two
           points specified by the user,

                                    * A
              ____________          |
             |            |         |
             | *R         |         |
             |            |         |
             |____________|         |
                                    |
                                    * B

           then the current set is reflected about the line defined
           by A and B (a vertical line, in this case), with R as a
           pivot point:


                                    * A
                                    |          ____________
                                    |         |            |
                                    |         |         R* |
                                    |         |            |
                                    |         |____________|
                                    |
                                    * B


ROTATE:    By identifying a reference point in the current set
           and two other points to define an angle and
           then clicking in this item, the current set will be
           rotated with respect to the reference point for
           the degree of the angle defined by the three points.


DUPLICATE: similar to TRANSLATE except keeping a copy of the
           current set at the original location.

MOVE POINT: to adjust the location of a vertex of an object (or,
            control point of a cubic B-spline curve), one need
			to click in this item first.

ERASE:      clicked to temporary remove the current set from
            the screen.  The current set will be permanently
            removed from the object list only if another
			action has been performed. (WHY?)

REFRESH:    clicked to redraw all the objects.

UNDO:       clicked to undo the most recent action.

COLOR:      set the current color.

WIDTH:      Set the current line width.


Each object stored in the "Object List" should have the following
information:

	Object type (int)
	Number of points (int)
	Data points (arrays of x and y coordinates)
	color  (string)
	line width (int)

__________________________________________________________________
* How to approximate an ellipse by Bezier curve segments:

You can approximate the first quadrant of an ellipse using a cubic
Bezier curve segment whose control points are defined as follows:


where   P0 = (0, b),
        P1 = (o.55a, b),
        P2 = (a, 0.55b),
        P3 = (a, 0)

The corresponding cubic Bezier curve segment approximates the
first quadrant of the ellipse:


            x*x       y*y
           ------ +  ------  =  1
            a*a       b*b


You can then use reflection to construct control points for the 2nd, 3rd
and the 4th quadrants of the ellipse.

Now, rotating a ellipse is just a process of rotating the control
points and generating the corresponding Bezier curve segments.



3. What to Turn In

Mail your program (in one file) and external documentation (in
another file) of your team to the grader on or before the due date.
Name your driver "Draw.java" and put it in the first (comment) line
of the driver.
The names of the other classes of your program are not important.
Your java code must contain internal documentation.  The external
documentation named YourLastNames.txt should describe the
project specifications and the implementation details.