Homework 2

The second assignment involved the creation of a graphics environment and a set of graphics primitives.

Part 1: The Environment

We defined our environment such that C took on many aspects of an object oriented language (we hope to rewrite it in C++ later). We defined structures that looked a lot like classes, and initializers that looked a lot like constructors.
We decided to have all information relative to ploting stored in a structure called GC (for Graphics Context). This structure contains a pointer to an Image Structure, the pen color, and the fill color. The Image Structure contains a pointer to a Pixel array, the number of rows, the number of columns, and the number of colors.
The GraphicsEnv.h enviroment also contains some basic methods. GCConstructor allocates space for the graphics context and initializes variables. Dump frees the memory from a graphics context. FillImage fills the image with one color. SetPenColor sets the current pen color. SetFillColor sets the current fill color. SetPixel plots a pixel on the screen with the color of the current pen color. SetFillPixel plots a pixel on the screen with the current fill color. SetNumColors sets the number of colors. WriteImage outputs the current image to a ppm. We also have a GraphicsIncludes.h which includes GraphicsEnv.h and several other important libraries we've made, which follow.

Part 2: The Line

We wrote our drawLine algorithm by following Bresenham's algorithm in the Rogers textbook. Then, we adjusted it to the correct corner-based coordinate system rather than the error-prone center-based coordinate system. As an extension, we also improved the line drawing by taking advantage of the line symmetry and only calculating half the line while draying the whole thing. On a 440 MHz Sun in the Sun Lab, we got about 19000 lines per second for the unimproved line, and about 21000 lines per second for the improved line.
The line drawing function is in Line.c, and can be imported with Line.h.

Part 3: Circles and Ellipses

token random circle image We modeled an improved drawUnfilledCircle algorithm from Bresenham's algorithm in the book. Taking advantage of the fact that circles are symmetric such that each octent is identical, we drew only one octent, and reflected it around to the rest of the circle. In order to correct for the screen coordinates, we reflected our our points about the center-based coordinates to the third quadrant, then reflected it from there about the corner-based coordinates to the other quadrants. Basically, this ammounted to subtracting one from some values and not others.
For the ellipses, we did nearly the same thing, fixing the code from the book. Because an ellipse is only symmetric about a quadrant, we weren't able to make the code any faster.
The circle and ellipse drawing functions are in Circle.c and Ellipse.c respectively, and they can be included with Circle.h, and Ellipse.h. As an extension, we implemented filled circles and ellipses as well.

Part 4

We did indeed make a PlotPixel function, but we called it SetPixel. It's in the GraphicsEnv library.

Part 5: Line Examples

Here is a picture of the lines in the required list. After much alteration of the algorithm to fix the screen coordinate problem, our lines do indeed now work correctly. If you consider the corner marking a pixel to be the upper left hand corner (in screen coordinates so that the origin is also at the upper left), our lines all come out the proper lenght. They start at the desired corner, and go up to the ending corner. This means that a line starting at (30,40) may appear to start at (29,40) because of the compensation for the centered coordinates.


Part 6: The Box-on-Table Drawing



Part 7: Portfolio Pictures



Questions

1. Who did you work with on this assignment, and what tasks did each of you do?
I worked with Stephanie Wojtkowski. We worked on everything together.
2. Describe your graphics environment. Include the following information in your answer:
Our graphics environment resembles XWindows. To begin, a user creates a graphics context, which is a structure with state variables. In order to add primitives to the graphics context, the user calls a function which takes as arguments primitive-specific parameters (location, radius, etc) and a graphics context. It then uses the state variables from the graphics context (color, image array, etc) to draw the primitive. 3. Is your first required image consistent with how you match screen coordinates to the true mathematical lines? Why, why not?
Yes. In adjusting lines to match corner coordinates rather than center coordinates, we made our lines match true mathematical lines. We draw them all in the first and second quadrants, don't draw the last pixel, and move the starting point if the line is in the second quadrant to start on the correct side of the intersection.
4. If you extended this assignment in any way, describe what you did and how you did it. Include pictures to support your description.

Program Files

GraphicsEnv.h & .c : The graphics environment
Circle.h & Circle.c : circle drawing functions
Ellipse.h & Ellipse.c : ellipse drawing functions
GraphicsIncludes.h : a list of includes for the graphics libraries we've made
Line.h & .c : line drawing functions
casey.c : draws the table and box
circletest.c : tests the circle drawing functions
circletest2.c : also tests the circle drawing functions
dashed.c : tests the dashed line
ellipsetest.c : tests the ellipse
filldemo.c : draws a filled circle and ellipse
linetest.c : tests the line drawing function
linetest2.c : also tests the line drawing function
linetest3.c : also tests the line drawing function
randcircle.c : draws some random circles
testbench.c : runs a benchmark test on line drawing speed
makefile : the makefile