HW 6 : Shape Hierarchy

DUE: FRIDAY, May 25th 2007, 11:59PM

This homework will give you the opportunity to design your own class heirarchy and object model from scratch.

You will be writing the engine for a simple vector based drawing program.

Submission:

Since this program will consist of multiple files, you will put all of your source files (including the UML diagram) into one folder (named hw6), zipping them up and e-mailing them to me at chipp@sci.brooklyn.cuny.edu

Points: The point value for this assignment is 6.


Overview

Write a program that manages a simple hierarchy of shapes (lines, rectangles, circles) and exports a SVG file representing those shapes. Your program will be driven by commands inputted either through an interactive command prompt or through a script file (specified at the command line).

Criteria

1. Your hierarchy of shapes will be represented in an Object Oriented fashion, utilizing 2 levels of inheritance.
2. Submit a UML Class diagram electronically along with your program.
3. The program will be multi-file.
4. Use a Vector container to store the shapes during run-time.
5. Shapes are created through simple commands through an interactive prompt or through a script file.
6. The Shapes are printed out to a SVG file (upon the "print" command).

Criteria Details

1. Creating your Class Heirarchy

Read over the Shapes (listed below) and their SVG output format (read up on SVG from HW 3).

Try to find common general attributes in all of the shapes and create a base class (with a meaningful name) that can hold these attributes. For example, all Animals have an age attribute that can be put into the Animal base class.

Split your shapes into general groups that share common attributes and create a class that inherits from the base class. So in our example, Dogs share common attributes in that they all bark().

More specialized classses can be described by inheriting from these general groups. Again, in our example, Boxers are dogs with special characteristics that are different than Greyhounds, but both would be classes that are derived from the Dog class (an thus inherite the bark() function). And since Dog in turn is derived from Animal, all of these classes inherit the age attribute.

2. Draw your UML Class Diagram

Start with a rough sketch on paper. Do not worry about listing every function immediately. Take your sketch and draw it electronically. You can use a drawing program (like Adobe Illustrator) or a more specific UML designing program (like MS Visio).

Here is a listing of other UML programs.

Linux (KDE) - Umbrello
Windows - UMLPad (very simple program )
Mac - OmniGraffle ( trial )

Update your UML diagram as your program so that you have the latest version of your Class Hierarchy available.

To submit your UML diagram - either export a PNG, JPEG, or GIF. Or you can take a screen-shot of the UML program.
DO NOT SEND ME THE UML FILE, I will not download all of these programs to view these formats.

3. The program will be multi-file.

Split your program up into multiple files. Every class will have a .cpp file (a code file) and a .h files (a header file) (unless of course there are no external member functions, where there is only a .h file).

Name the files as the same name as the Class that is contained within them. So, a Dog class will have its class definition in the file file Dog.h and all of its member functions in Dog.cpp. You will have one other file named main.cpp (which will contain the main() function and any small utility functions your main() may need).

As an example, here is the HW 5, split up into multiple files. (Link active once HW 5 deadline passed)

4. Use a Vector container to store the shapes during your program's run-time.

Specify a Vector in main() that contains all of the dynamically allocated shapes that are created in your program. To keep things simple, have the Vector be templated to the the class type that is at the TOP of your class hierarchy. This way, every class derived from this base class can be stored in the Vector.

5. Shape Creation

Every shape in the heirarchy has a command that creates it. The command can be entered from a prompt (denoted by the '>' in all of these examples) in your program, example:

$ hw6
> rect 10 20 30 40
Created Rectangle at (10, 20) width 30 and height 40.

> print output.svg
File output.svg written.

> quit

$

Or you can put the commands into a file (one command at a time) and have them executed in a batch by specifying the file name on the command line.

$ hw6 commands.txt
Created Rectangle at (10, 20) width 30 and height 40.
File output.svg written.

$

Example command.txt file.

(Note the "quit" command is not necessary in the command file. Every line is executed as if it is a command).

6. The Shapes stored in the Vector are printed to an SVG file.

Since the Vector container only contains the Base Class of our Shape Hierarchy, then how will the program know which kind of Shape is being stored in the Vector in order to print the specifics of the shape?

Declare a print() function in this Base Class as a pure virtual function (use the keyword virtual before the return type of the funtion, and "= 0" before the semi-colon in the function declaration. That means that this print() function is not implemented in the Base Class, but it expected to be implemented in a class derived from this Base Class.

Example with the bark() function declared as a pure virtual function:

  class Dog {
    public:
    	virtual void bark() = 0;
  };
			
  class Boxer : public Dog {
    public:
 		void bark() { cout << "woof!"; }
  };
			
  class Greyhound : public Dog {
    public:
		void bark() { cout << "arf!"; }
  };
			
  int main() {
  	vector<Dog *> pack;
			
	pack.push_back(new Boxer());
	pack.push_back(new Greyhound());
			
	pack[0]->bark();
	cout <<  endl;
			
	pack[1]->bark(); 
	cout << endl;
			
	delete pack[0];
	delete pack[1];
  }
			
Shapes (with their Properties that you will represent)

(Note: the coordinate system that these Shapes are situated in is the same as in HW 3)

Line

A line has start point (x1, y1) and an end point (x2, y2)

Rectangle

A rectangle has a point at the corner (x,y) a width (w) and a height (h).

Ellipse

An ellipse has a center point (cx, cy), and a radius in the x direction (rx) and a radius in the y direction (ry).

Circle

A circle has a center point (cx, cy) and a single radius (i.e. it is an ellipse with rx = ry).

Square

A square is a rectangle with its width equal to it's height, shown a side length (s)


Commands Format

(Parameter names correspond to the attributes described above in Shapes)

Line

line x1 y1 x2 y2

Example:

> line 10 20 50 60

Draws a line from (10,20) to (50,60)

Rectangle

rect x y w h

Example

> rect 10 20 40 60

Draws a Rectangle with a corner point (10,20) a width of 40 and a height 60

Ellipse

ellipse cx cy rx ry

Example

> ellipse 50 60 20 30

Draws an ellipse centered at the point (50,60) with a radius in the x direction of 20, and a radius in the y direction of 30.

Circle

circle cx cy r

Example

> circle 50 60 20

Draws a circle centered at the point (50,60) with a radius of 20

Square

square x y s

Example

> square 10 20 30

Draws a square with a corner point at (10,20) and with its sides having a length of 30.

Reverse

reverse

This single word command reverses the order of all of the shapes in the Vector that stores the shapes in the program. (This is very easy if you look up the Vector container for a function with a similar name).

Print

print file.svg

Example

> print output.svg

Prints the shapes currently in the Vector container out to a properly formated SVG file (see below for links to the SVG specifications).

Quit

quit

Quits the program in the interactive mode (i.e. not necessary in the batch script mode).

SVG Specifications for the Shapes

Here is an excellent reference for all of the SVG Shapes that you program will support.

Your SVG file (remember from HW 3) will have a header (i.e. text that appears before the SVG tags of the shapes), and a foot
(i.e. text that follows the SVG tags).

Here is the standard header we will use in our SVG file, this is what your file will start with:

<?xml version="1.0" standalone="no"?>

<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

<svg width="100%" height="100%" version="1.1"
xmlns="http://www.w3.org/2000/svg">


Here is the standard footer, this is what your file will end with:

</svg>

Every shape in the Vector will be outputed to the SVG file according to the SVG specifications for that shape.


Line http://www.w3schools.com/svg/svg_line.asp

<line x1="0" y1="0" x2="300" y2="300"/>

Draws a line from (0,0) to (300, 300).

Rectangle http://www.w3schools.com/svg/svg_rect.asp

<rect x="20" y="20" width="250" height="250"/>

Draws a rectangle from (20,20) with a width 250 and a height 250.

Ellipse http://www.w3schools.com/svg/svg_ellipse.asp

<ellipse cx="240" cy="100" rx="220" ry="30"/>

Draws an ellipse centered at (240,100), with a radius of 220 in the x direction and a radius of 30 in the y direction.

Circle http://www.w3schools.com/svg/svg_circle.asp

<circle cx="100" cy="50" r="40"/>

Draws a circle centered at (100,50) with a radius of 40.

Square (There is no Square Tag)

Which of the previous tags can you use (with constraints) to draw a square?

Note
Remember to have the double quotes character (i.e. ") printed in a string literal, you must precede the double quotes with a back-slash (i.e. \").

Example
cout << "\"double quotes\"" << endl;

Deliverables

Put all of your .cpp and .h files, along with your UML image into a folder name hw6.

Zip the folder up (DO NOT SEND THE FILES INDIVIDUALLY)!

E-mail the folder to me: chipp@sci.brooklyn.cuny.edu


Extras

There are alot of extras that are rather doable, I suggest you try to complete as many Extras as possible to help your Homework grade out.


Selection (1 point)
Implement a click command:

> click 20 40

Which simulates a mouse click at the point (20,40).

Any shapes that this click falls on will be selected. Any selected shape will be outputed in the SVG file as having a thicker light blue stroke. A click at another point will deselect the shapes already selected, and select new shapes. A click that falls on no shapes, just unselects ll currently selected shapes.

To make this easier, imagine a bounding box around all of the shapes (i.e. a box that encloses a line, or an ellipse, or a circle). A click that falls within a shapes bounding box is a click on the shape.

Multiple Selection (1 point)
Implement a shift click command:

> shiftclick 30 50

Simulates a shift-mouse click at the point (30, 50)

This is the same as the mouse click, except that shapes previous selected are NOT deselected. This just adds to the batch of selected shapes.

Delete (1 point)
Implement a delete command:

> delete

Any shapes that are selected will be removed from the Vector containing all of the shapes.

Fill (1 point)
Implement a fill command:

> fill 128 128 128

Fills the selected shapes with the RGB (red, green, blue) colors (128, 128, 128). Look at the SVG documentation to see how shapes are filled with RGB colors.

Stroke (1 point)
Implement a stroke command:

> stroke 255 255 255

Sets the stroke color of the selected shapes with the RGB (red, green, blue) colors (255,255,255)

Polygon (1 point)
Implement a polygon command:

> poly 10 20 30 40 50 60

This will draw a polygon with the points (10,20), (30,40), and (50,60) as it's vertices, and will be closed (this is a triangle).
Use an Vector container in the class that you create for the Polygon to hold the point data.

Here is the SVG output format: http://www.w3schools.com/svg/svg_polygon.asp


Updated 5/8/2007