Project 3
Dynamic Quadrilaterals
Assigned |
March 10, 2003 |
Design Due
| March 16, 2003, 11:59pm
|
Program Due |
March 23, 2003, 11:59pm |
Updates |
March 16, 7:00pm
Please note that two bugs were found in the
code posted by you instructors :-(
Fortunately, they are minor and should not affect
your development if you're using that code as a starting
point for project 3. The corrected versions are now
in Mr. Frey's public directory.
In Quadrilateral.C one edit was made to IsRectangle().
In Quad2.C the same edit was made to IsRectangle()
and other edits were made to IsWellFormed().
You can choose to make the edits in your copies of these files,
or simply replace the functions altogether.
Also note that destructors were not listed as required public
methods. Since we are dealing with dynamically allocate memory,
these are obviously needed.
March 12, 10:30am
Several people have discovered one issue
with our project that we purposely didn't tell you
about in the project description. Since enough
students have had time to think about it, here's
the scoop.
It's not possible for a function to return
the value in a dynamically allocated local variable
AND delete that variable... which would you do first??
if you return first, you never execute the delete
if you delete first, you have nothing to return
PLEASE DO NOT return a pointer to the dynamically allocated variable
and expect the user to delete it for you.... this is ALWAYS dangerous and almost never a good idea.
if you REALLY need to return a value from a function, and can't do it any other way besides creating a local variable in that function,
then it's not necessary to dynamically allocate
that local variable. You must still
dynamically allocate any other local variables
in the function.
March 10, 11:30pm
- for-loop indices are NOT required to be dynamically allocated
- function parameters DO NOT have to be pointers.
Passing by reference and by value is acceptable.
- The Distance( ) function is to be removed from
your project 2 solution and replaced with the
overloaded subtraction operator for Points
|
Objectives
This project is a modified version of project 2. The purpose of this project is
- To gain experience modifying existing code
- To gain experience writing and using overloaded operators
- To gain experience using pointers and dynamic memory
The main differences between project 2 and project 3 are
- There are no trapezoids in project 3
- Point coordinates will be read from a file instead of input by the user
- Some operators will be overloaded
- We will use dynamic memory for our variables and data members.
Project Description
In geometry, a 4-sided figure is called a "Quadrilateral". Depending on its exact shape, a quadrilateral can be classified as follows
- A parallelogram -- both pairs of sides parallel
- A rectangle - a parallelogram with right angles
- A square - a rectangle with equal sides
- Irregular -- none of the above.
In this project, you will read the x- and y-coordinates of the four corners of a
quadrilateral from a data file (described below).
The corners are called "UpperRight", "UpperLeft", "LowerLeft" and
"LowerRight" and hereafter referred to as UR, UL, LL and LR respectively.
Your program will then classify the quadrilateral as above and
output some information about the quadrilateral.
To make this project reasonable, your code may assume that the base of the quadrilateral is parallel to the x-axis (i.e. the y-coordinate of "LowerLeft" and "LowerRight" is the same).
What to Code
You may start with your solution to project 2 and modify it to complete this
assignment. Your instructors have also posted a
project 2 solution which you
may use as a starting point for this project. You may of course start from
scratch.
This project will require you to design and implement two C++
classes as described below.
Be sure to consider the OOP principles of encapsulation and data hiding when designing and implementing these classes. main() and other functions are also described.
A Point Class
The Point class will encapsulate the x- and y-coordinates of one point in the
coordinate plane. In keeping with the coding standards, the Point class will be
defined in Point.H and implemented in Point.C.
The Quadrilateral class uses the Point class to represent each of its
four corners (an example of aggregation/composition).
You may assume that the coordinates are integers
(although this has little effect on your code).
The only operations allowed by the Point class are listed.
If you find that you don't need all these operations,
then you are not required to implement them (except for those labelled
as which MUST be implemented, even if not used
in your project).
No other public methods are permitted. You may provide whatever
PRIVATE methods you feel are necessary.
- One or more constructors
- The copy constructor
- Assignment operator (operator=)
- Destructor
- Accessors for the coordinates
- Mutators for the coordinates
- Overloaded subtraction operator for Point objects as a member function.
The result of subtracting two Points is the distance between them on the
coordinate plane.
- Overloaded operator<< to output the Point's
x- and y- coordinates in the format described below in the
sample output below.
- Overloaded operator>> to input the Point's
x- and y- coordinates.
The coordinates should be input as two integers separated
by whitespace.
A Quadrilateral Class
This class represents a quadrilateral in the coordinate plane by using the
Point class to store the x- and y-coordinates of its corners.
This class will be defined in Quadrilateral.H and implemented in Quadrilateral.C.
The "const"ness of the member functions has purposely been omitted.
It's up to you to determine which should be const and which should not.
The operations permitted by the Quadrilateral class are listed.
No other public methods are permitted. If you find that you don't need all
these operations, then you are not required to implement them (except those
labelled as which MUST be implemented, even if not
used in your project).
No other public methods are permitted. You may provide whatever
PRIVATE methods you feel are necessary.
- One or more constructors
- The copy constructor
- Assignment operator (operator=)
- Destructor
- Accessors for the corners
You may name and implement these as you see fit,
but their return type must be const Point&
- Mutators for the corners
You may name and implement these as you see fit,
but their one and only parameter must be a const Point&
- bool IsParallelogram( void ) -- returns true if the
quadrilateral is a parallelogram; false otherwise.
- bool IsRectangle( void ) -- returns true if the
quadrilateral is a rectangle; false otherwise.
- bool IsSquare( void ) -- returns true if the
quadrilateral is a square; false otherwise.
- bool IsIrregular( void ) -- returns true if the
quadrilateral is irregular; false otherwise.
- double Area( void ) -- returns the area of the quadrilateral.
This method returns 0.0 if called for an irregular quadrilateral.
- double Perimeter( void ) -- returns the perimeter
of the quadrilateral
- Overloaded operator<< for the Quadrilateral class.
This operator displays all required output as shown in the
sample output below.
- Overloaded operator>> for the Quadrilateral class.
This operator inputs all necessary data for the Quadrilateral class.
Classifying A Quadrilateral
- Parallelogram
A quadrilateral is a parallelogram if both pairs of sides are parallel.
This is equivalent saying that the lengths of the opposite sides of each pair of
sides are equal.
I.e. if the distance from UL to UR equals the distance from LL to LR
and the distance from UL to LL equals the distance from UR to LR
- Rectangle
A quadrilateral is rectangle if it is a parallelogram with four right angles.
Note that it is sufficient to test the angle at just one corner, since if
a parallelogram has one right angle, it must have four right angles,
else it's not a parallelogram.
- Square
A quadrilateral is a square if it is a rectangle with four equal sides.
Note that since it is a rectangle (and hence a parallelogram) it is only necessary
to compare the length of one horizontal side with the length of one vertical side.
- Irregular
A quadrilateral is irregular if it is none of the above.
Distance Functions
To ease the coding of the Quadrilateral methods, the following functions are also
permitted (not required). These functions are NOT members of either the Point or
Quadrilateral classes; they are "non-member" functions.
Since they are related to Points, their prototypes may be defined in Point.H and
they may be implemented in Point.C.
These use of these functions rely the base of the quadrilateral
being parallel to the x-axis.
Because of this constraint in our project,
you can use these functions to find the distance
between two parallel lines.
- double VerticalDistance (const Point& point1, const Point& point2)
The vertical distance between two points is the absolute value of the
difference of the y-coordinates.
- double HorizontalDistance (const Point& point1, const Point& point2)
The horizontal distance between two points is the absolute value of the difference
of the x-coordinates.
About math functions
- The abs() function returns the
absolute value of an integer expression. To use the abs() function, #include <cstdlib>
- The sqrt() function returns the square root of a double expression.
If you want to find the sqrt() of an integer expression,
cast the integer expression to be a double using static_cast
double result = sqrt( static_cast (integerExpression));
To use the sqrt() function, #include <cmath>.
The math library is automatically included when you link your program
main() in Proj3.C
Proj3 is invoked with one command line argument - the name of the
data file that contains the x- and y-coordinates of
a quadrilateral. An appropriate error message must be displayed if command line
contains too many or too few arguments or if the data file cannot be opened.
Your program should then exit.
Your program will read the coordinates from the file and
produce the output shown below and formatted as described.
You should of course use good top-down design for main.
If you write any functions called by main, they must be implemented in
Proj3Aux.C and their prototypes must be in Proj3Aux.H.
Dynamic Memory
One major objective of this project is to gain experience
using pointers, allocating dynamic memory using new and
dellocating memory using delete. To accomplish this objective,
-
All local variables in all functions (including main())
must be dynamically allocated and then deleted when appropriate.
- All local variables in all public and private member functions
of any class must be dynamically allocated and then deleted when appropriate.
- All data members of all classes must be dynamically
allocated and deleted when appropriate.
Data File
The data file will contain 8 integers which represent the x- and y-coordinates
of a quadrilateral, separated by whitespace (i.e. spaces,
tabs and/or blank lines). The integers will be stored in the file in this order
- x-coordinate of the upper-left corner
- y-coordinate of the upper-left corner
- x-coordinate of the lower-left corner
- y-coordinate of the lower-left corner
- x-coordinate of the lower-right corner
- y-coordinate of the lower-right corner
- x-coordinate of the upper-right corner
- y-coordinate of the upper-right corner
You may assume that the corners represent a "well formed" quadrilateral, so
no error checking of the data is required.
Sample Output
Your output must be formatted exactly as shown below.
In particular,
the area and perimeter must be printed on separate lines, their labels must be right
justified and aligned and their values must be aligned and printed with
exactly 4 decimal places of precision. Print trailing zeros if necessary.
The corners must be printed as shown. In particular, the labels must be right
justified and aligned and the coordinates must be printed in a 3-character
field, separated by a comma and enclosed in parentheses.
linx3[2]% Proj3 square.dat
The Quadrilateral's Corners
Upper Left: ( 4, 5) Upper Right: ( 8, 5)
Lower Left: ( 4, 1) Lower Right: ( 8, 1)
This Quadrilateral is a Square
Area: 16.0000
Perimeter: 16.0000
linux3[3]% Proj3 rectangle.dat
The Quadrilateral's Corners
Upper Left: ( 1, 4) Upper Right: ( 10, 4)
Lower Left: ( 1, 2) Lower Right: ( 10, 2)
This Quadrilateral is a Rectangle
Area: 18.0000
Perimeter: 22.0000
linux3[4]% Proj3 parallelogram.dat
The Quadrilateral's Corners
Upper Left: ( 6, 4) Upper Right: ( 13, 4)
Lower Left: ( 9, 1) Lower Right: ( 16, 1)
This Quadrilateral is a Parallelogram
Area: 21.0000
Perimeter: 22.4853
linux3[5]% Proj3 irregular.dat
The Quadrilateral's Corners
Upper Left: ( 2, 3) Upper Right: ( 7, 5)
Lower Left: ( 0, 1) Lower Right: ( 11, 1)
This quadrilateral is Irregular
Area: 0.0000
Perimeter: 24.8704
Free Advice
- Don't start from scratch
Modify your program to add new required functionality, then
modify it to use dynamically allocated memory.
Don't forget to fix the problems identified by your grader in Project 2
- A simple approach to reading the data from the file is best.
Read the data as integers, not strings.
- Create test files and trade them with your friends
- Read the discussion board
Error Handling
Your program, and ALL programs in this class, must handle the following errors:
- Correct number of command line arguments
- Invalid command line argument
- Files which cannot be opened
These errors may be handled by displaying an error message to 'cerr'
and exiting the program.
- Function pre-conditions which are not satisfied
Handling unsatisfied preconditions was discussed in class.
Project Design Assignment
Your project design document
for project 3 must be named design3.txt.
Be sure to read the design specification
carefully.
Submit your design in the usual way.
submit cs202 Proj3 design3.txt
Project Make File
You are required to submit a make file with this project.
The grader should simply need to type "make Proj3" and your project should compile
and link to an executable called Proj3. The grader should also have the ability
to do a "make clean" and "make cleanest."
Hint: Start with the makefile from project 2 and modify it as necessary.
See the
make tutorial for more help on make and makefiles.
Project Grading
The grade for this project will be broken down as follows. A more detailed
breakdown will be provided in the grade form you recieve
with your project grade.
- 85% - Correctness
- All required error handling is performed as specified
- Your design is submitted on time and meets the design specification
- Your program produces the correct output for each set of points entered
- Your output is formatted according to the requirements
- Your code exhibits good top-down and good OO design
- Your member functions are appropriately defined as const
- Your function parameters correctly passed by value, by reference
or by const reference as appropriate.
- You have implemented all required methods and functions
- You have dynamically allocated all local variables and class data members
- You have deleted all allocated memory at the first opportunity and have
no memory leaks in your program.
- 15% - Coding Standards
Your code adheres to the
CMSC 202 coding standards as discussed
and reviewed in class.
Project Submission
You must use separate compilation for this project.
You should submit the following files.
- Point.H and Point.C
- Quadrilateral.H and Quadrilateral.C
- Proj3Aux.C and Proj3Aux.H if necessary
- Proj3.C
- Your makefile
Submit as follows:
submit cs202 Proj3
A complete guide to
submit tools is available on the course website.
More complete documentation for submit and related commands can be found
here.
Remember -- if you make any change to your program, no matter how
insignificant it may seem, you should recompile and retest your program before
submitting it. Even the smallest typo can cause compiler errors and a reduction
in your grade.