Due: Extended to 5 pm, Wednesday, February 17, 1999
Congratulations! You have just been hired as an intern for a small startup software company. The company is currently in the midst of developing a vector drawing program, and want you to help develop some of the core data structures that the program will use to keep track of the objects that users of the software will interact with.
The CEO is currently making the rounds trying to drum up more funding for the company, and as a result, the lead designers are really busy meeting potential investors and worrying more about the appearance of the program. The lead designers have already put in a large amount of work in developing the beginnings of a graphical user interface, as well as a set of interfaces that describe the data structures they'd like to use in the program.
It's your job to understand what needs to be done, and then actually finish up the work they started. If all goes well, then the CEO will actually be able to demonstrate a fully functioning (if barely) program to investors (making her happy), give the leads some breathing space (making them happy), and allow you to put something quite nice onto your resume (making you happy).
The drawing program is a Windows 9x program that utilizes the MFC application framework to create and manage the various components of the system. The designers realized, however, that they wanted to be able to easily port the software to other systems, so they made a conscious effort to separate out the functionality of the program from the visual interface of the program. The lead designers are currently more worried about the interface aspects of the program, as the CEO is currently making the rounds for more funding, and appearances count. That leaves you to worry about the functionality of the program, which is fortunately written in plain C++.
In particular, you have been asked to program and test three critical parts of the program: The abstraction for the points that the drawing program deals with, a dynamically flexible array that contains points, and an abstraction of polylines, which are groups of connected lines.
To help you on your way, the lead designers have thoughtfully included an archive of the files and project workspace you will be working with (compatible with VC++ 6.0 and above). You may not have WinZip or a similar archive handy, so we have also included a self-extracting archive which you can run. We have also included a sample executable, which is what they'd like your program to do.
A polyline consists of an interconnected set of points, so we first need an abstraction for what a point is. The implementation of this file is provided for you.
Method Name | Description | Use by interface |
Point() | Constructor | Define a Point |
Point(int newX, int newY) | Constructor | Define a Point |
setX(int newX) | Sets the X coordinate of the point | Sets a point while user is moving mouse |
setY(int newY) | Sets the Y coordinate of the point | Sets a point while user is moving mouse |
getX(int newX) | Returns the X coordinate of the point | Used to draw the polyline on the screen. |
getY(int newY) | Returns the Y coordinate of the point | Used to draw the polyline on the screen. |
distanceTo(Point other) | Determines the distance between this point and another | Used to determine if the user picked a point on the screen |
Friend Function | ||
operator<< (ostream&) | Output a point to a stream | Not explicitly used |
operator>> (istream&) | Input a point from a stream | Not explicitly used |
A polyline consists of an interconnected set of points, so we need a way of representing a set of points. A PointArray must be capable of dynamically resizing (you never know how many points the user may wish). Thus, this class has a copy constructor, operator=, and a destructor.
Method Name | Description |
PointArray() | Constructor |
PointArray(const PointArray& other) | Copy Constructor |
~PointArray() | Destructor |
operator= | Deep copying gets operator |
size() | Returns number of elements in the array |
clearAll() | Removes all elements from the array |
get(int pos) | Return the Point at position pos. |
set(int pos, Point pnt) | Sets the Point at position pos. Array expands as needed to accomodate new points. |
remove(int pos) | Removes the Point at position pos |
A polyline consists of an interconnected set of points, but with a specific meaning associated with the set of points. In particular, a point at location N in the array is connected to both points N-1 and N+1, if they exist. Why is there a separate PointArray and PolyLine class? That is because the idea of the PointArray is not only applicable to PolyLines, but also if the lead designers want to expand to using other types of drawing tools, such as polygons. This is an example of trying to build reuse into a system. The implementation of the friend functions has been provided for you.
Method Name | Description | Use by Interface |
reset() | Removes all points from the PolyLine's array of points | When user wishes to create a new picture |
getNumPoints() | Get the number of points in the PolyLine | Draw polylines on the screen |
addPoint(Point pt) | Add a point to the end of the PolyLine's array of points | When creating a polyline |
setPoint(int pos, Point pt) | Set Point pt at location pos in the PolyLine's array of points | When modifying points in a polyline, and sometimes in creating a polyline |
getPoint(int pos) | Gets the Point at location pos in the PolyLine's array of points | When modifying points in a polyline, or drawing polylines on screen |
removePoint(int pos) | Removes a point from the PolyLine's array of points | Removing points or polylines |
getPositionClosestTo(Point pt, int maxDistance) | Try to find within the PolyLine class the point closest to Point pt, with distance between the two at most maxDistance | Used to determine if user selected a point to move |
Friend function | ||
operator<< | Print out a formatted representation of the polyline to an output stream | Used to save a file |
operator>> | Read in a formatted representation of the polyline from an input stream | Used to load a file |
The lead designers will supply you with code that will implement the interface to the program users. The code makes assumptions based on the provided specifications, so it is imperative that you not change the public specification unless it's absolutely necessary. The designers also have provided a workspace file that you can use for this project. All of the files and workspace is conveniently available in archived format.. The table below gives a quick description of the files included in the archive. You are responsible for understanding the first six files:
Filename | Usage |
point.cpp | Implementation file for point.h |
point.h | Declares an abstraction for points (for a polyline) |
pointarray.cpp | Implementation file for pointarray.h |
pointarray.h | Declares a dynamically growing array of points |
polyline.cpp | Implementaion file for polyline.h |
polyline.h | Declares an abstraction for polylines (what user creates) |
drawer.cpp | Main file that sets up the Windowing system |
drawer.h | Header file for drawer.cpp |
drawerDoc.cpp | Defines the picture that you are creating as a document |
drawerDoc.h | Header file for drawerDoc.h |
drawerView.cpp | Handles the interface of the program |
drawerView.h | Header file for drawerView.h |
MainFrm.cpp | Handles the structure of the interface (toolbars, etc) |
MainFrm.h | Header file for MainFrm.cpp |
StdAfx.cpp | Defines constants used by the MFC framework |
StdAfx.h | Header file for StdAfx.cpp |
Resource.h | Defines resources (icons, etc) used by the program |
Note that you don't need to understand what's going on with all the files! You are certainly welcome to take a peek, however.
Your first task should be to try to get something up and running. This is extremely important, since more likely than not this will be your first attempt at writing an application that actually works with a graphical user interface (GUI). Towards this end, we suggest you create stub methods (methods that don't do anything or return some set value) for all the methods you will need to write, and then making sure the program can at least compile and start up. Such a program is often called a skeleton program. This is a great way to ensure that at all times you will have a compilable/runnable program, even if it doesn't function the way it should. This will also acclimate you to working with the environment, which may be daunting, being your first experience with a MFC application. You will note that by the time you complete this stage, you will be able to interact with the interface, but the commands don't seem to really be doing anything.
Now that you have a skeleton program up and running, you now need an action plan in which to try to tackle the data structures. The designers recommend one of two approaches:
Because this is a full fledged windows program, cin/cout/cerr will not work properly. You will have to rely on the debugger and assert statements to determine how your program behaves, if you need to do testing. You could also use fstreams to write debugging output to a temporary file, if you feel the need to do so. Alternatively, since the code you will be running will not involve writing windows code, you could test your code with testing programs in a console environment (like you've done in the past assignments) before trying to integrate the code back into the main system.
Also, remember that just because it happens to work within the framework provided by the interface doesn't mean that your code is correct. It is imperative on your part to test your code under a wide variety of conditions.