Rectangle


General

  • All submissions must include a work history to be worth credit.
  • Submit all files to elearn. Make sure to name file(s) EXACTLY as specified - including capitalization.
  • Make sure your program accepts input in EXACTLY the order and format given. Do not ask for extra input or change the order of inputs.
    If you want to make an expanded version of a program that and get feedback on it, email it to me or show me in class.
  • Slight variations in output wording/formatting are usually fine (as long as formatting isn't part of the assignment).
    If you do not get the right final output, print out some evidence of the work your program did to demonstrate your progress.
  • Readability and maintainability of your code counts. Poor formatting, confusing variable names, unnecessarily complex code, etc… will all result in deductions to your score.

Requirements

Submit file: assign2.zip

Make sure to compress your entire folder, not just your code file.

Provide doxygen comments for all public members in your Rectangle.h file.

If I place all your code in one folder along with doctest.h and my Point.h and Point.cpp, I should be able to do this to build your code:

g++ -std=c++17 Point.cpp Rectangle.cpp tests.cpp -o tests.exe

Overview

You will create a class Rectangle that represents a simple rectangle on a Cartesian plane. You are not writing any particular program that uses rectangles, but the tool that could be used by someone who wanted to write a program and use your Rectangle class to do it. The way you will demonstrate your code works is by providing unit tests in tests.cpp.

Your Rectangle class will use a provided Point class.

Setup/Starting Tips

Make a Unit Test project. You should replace the starter code in tests.cpp with your own unit tests that demonstrate the functions of your class work correctly.

Download Point.h and Point.cpp into that folder.

Make new Rectangle.h and Rectangle.cpp files.

Add the two new .h and .cpp files to HEADERS and TEST_FILES sections of the Makefile.

# list .h files here
HEADERS = Rectangle.h Point.h

# list .cpp files here
TEST_FILES = tests.cpp Rectangle.cpp Point.cpp

If you are on Windows, you may have a conflict between your Rectangle class and one that is part of a standard library. If you see weird errors talking about Rectangle, add this line to the top of your tests.cpp file (it must come before #include "doctest.h"):

#define NOGDI

Rectangle Details

For the purposes of this problem, we will assume our rectangles are always aligned with the axes (their sides are always perfect up and down or side to side). A rectangle that is aligned to the axes can be described by the location of its upper left vertex, a width, and a height:

A rectangle defined by its upper left vertex, a height, and a width

There are of course other ways we could represent the shape. We could also describe it with the location of its upper left corner and lower right corner. Or we could use its center and the height and width. Etc...

Your task is to implement one of these representations using the UML shown below:

A UML diagram of the Rectangle and Point classes

Note the OR in the section that describes the member variables. You can chose either to store one Point, a width and a height, OR you can store two Points. Each representation will make some jobs easier and some jobs harder. (The upperLeftVertex, height, and width representation is probably the easiest overall.)

You should NOT combine the two by storing two Points and a width and a height (that is redundant).

Function Descriptions

Below are descriptions of expected behavior. Descriptions are written in UML format, not C++. You need to translate parameters/return types. UML also does not specify things like const qualifiers and passing by reference; it is up to you to use them where it is appropriate.

For each function, provide one or more TEST_CASES in the tests.cpp file that show the function works. See Testing Guidelines below.

Each function should have doxygen comments in your .h file.

When possible, use functions from Point to help you do work.

Rectangle(p1 : Point, heightValue : double, widthValue : double)

Construct rectangle using given point as upper left corner and the indicated width and height.

Rectangle(p1 : Point, p2 : Point)

Construct rectangle that has the two points as opposite vertices. The two points might not be in order as upperLeft and lowerRight. The constructor should figure out appropriate coordinates to use for its state based on coordinates of these two points.

Example: If the Points given are (10, 5) and (4, 2), the rectangle should have an upper left vertex of (4, 5), and either a height of 3 and width of 6 or a lower right vertex of (10, 2).

Note You need to provide both constructors listed above regardless of how your data is stored (Point/height/width vs two Points). One of the two constructors will require you to do a bit of work to figure out the data you need to store.

getUpperLeftVertex() : Point

Return Point representing location of the upper left vertex of the rectangle

getWidth() : double

Returns value

getHeight() : double

Returns value

getArea() : double

Calculate and return value

getPerimeter() : double

Calculate and return value

getCenter() : Point

Calculate location at center of rectangle, make a Point representing it to return.

translate(x : double, y : double)

Translate is the fancy word for "move". Move the rectangle by the given amount in x and y dimensions.

contains(p : Point) : boolean

Return true if indicated Point is within the rectangle (on edge counts as within)

Testing Guidelines

Your Unit tests in tests.cpp should test each public member. Each TEST_CASE should focus on testing one function. It is NOT okay to wrap a bunch of unrelated tests into one test function (e.g. one TEST_CASE that tests both getPerimeter and getArea). It is okay, in fact necessary, to use other functions as part of your tests—for example, it would be impossible to test the constructors without using getPoint function.

You may need multiple tests for any given function (a bool function should be tested to make sure it answers both true and false at appropriate times).

My Assignment2CircleSample project in the class git repository has sample unit tests. You won't be writing the same exact tests, but use them as a reference.

Here is a sample test, for your Rectangle constructor and getUpperLeftVertex, to get you going. The getUpperLeftVertex method will be tested in lots of other places; you do not need to write a separate test for it.

TEST_CASE( "Rectangle/Constructor1 - 3 Arguments" ) {
    //Build rectangle
    Point p1(1, 5);
    Rectangle r1(p1, 2, 4);
    
    //now see if it has the right info
    Point temp = r1.getUpperLeftVertex();
    REQUIRE( temp.isSameAs(p1) == true );


    //dimensions are doubles, compare using Approx from doctest to check equality
    REQUIRE( r1.getHeight() == Approx(2) );
    REQUIRE( r1.getWidth() == Approx(4) );
}

Note if you want, you could condense these two lines:

Point temp = r1.getUpperLeftVertex();
REQUIRE( temp.isSameAs(p1) == true );

Into this one line that asks r1 for its upper left vertex, then ask that if it is the same as p1:

REQUIRE( r1.getUpperLeftVertex().isSameAs(p1) == true );