Drawing Program

Due: Extended to 5 pm, Wednesday, February 17, 1999

Introduction

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).

Program design

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.

Point class

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

PointArray class

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

PolyLine class

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

Implementation discussion

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.

Trying to get something running

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.

Implementing things one step at a time

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:

Notes on Debugging

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.