CISC 3620 - Computer Graphics
Assignment #1 - Frame Buffers / Line and Circle Rasterization Algorithm

This first assignment consists of several parts and has several objective s:

Part 1. A Class Modelling a Text-Based Frame Buffer

Implement the following class which models the frame bufer we discussed in class:
class FrameBuffer {
public:
    FrameBuffer(int width, int height);
    void setPixel(int x, int y, bool on = true);
    void display(ostream &os = cout);
    int getWidth() const;
    int getHeight() const;
private:
    int height, width;
    bool **pixels;
};
		
Notes:

Here is a sample program that produces this output

Part 2. A Simple Line Algorithm ( DDA)

We've just touched upon this in class; here is the VERY simple-minded line drawing algorithm (in pseudocode):
drawLine(x1, y1, x2, y2)
	slope = (y2 - y1) / (x2 - x1)  // slope is not an integer
	
	y = y1
	for x = x1 to x2
		drawPoint(x, y)
		y = y + slope		// need to either truncate, ceiling, or round
Notes: Implement the following class:
class Graphic {
public:
    Graphic(int width, int height);
    void ddaLine(int x1, int y1, int x2, int y2);
private:
    FrameBuffer fb;
};
		
Notes:

Make sure your algorith works for the following types of lines:

Also make sure your algorithm works regardles of whether x1 is larger or smaller than x2.

Here is a sample program that produces this output

Part 3. Adding Color

The frame buffer up to this point is monochrome (i.e., black & white); now add color.

Modify the frame buffer to accept color pixels. If you wish, come up with your own scheme; alternatively, feel free to copy what I did which is to allow 10 colors -- 0 being black (absence of color) and 1-9 representing 9 other colors. The Graphic class must also change to reflect this modification. Here are the new class declarations (you, obviously are to finsih off the implementations):

class FrameBuffer {
public:
    FrameBuffer(int width, int height);
    void setPixel(int x, int y, int color);
    void display(ostream &os = cout);
    int getWidth() const {return width;}
    int getHeight() const {return height;}
private:
    int height, width;
    int **pixels;
};

class Graphic {
public:
    Graphic(int width, int height);
    void drawLine(int x1, int y1, int x2, int y2, int color);
private:
    FrameBuffer fb;
};
		
Again, feel free to come up with your own color scheme. Remember that each pixel probably takes up only one character when displayed and thus whatever color representation you decide on should have the color represented by a single character (which is why I limited myself to the integers 0-9-- representable by single-characters).

Here is a sample program that produces this output

Part 4. Frame-Buffer Color Blending

Now that the frame buffer is capable of maintaining and displaying multiple colors, the issue arises of what do we display at the pixel(s) at which two or more lines intersect?

One possibility is to blend the colors, and in particular, to have the frame buffer blend the colors.

Modify the FrameBuffer class so that when setPixel is called on a pixel that is already on (i.e., not black or color 0), the new color value is blended with the current pixel color.

I blended my colors by taking the average of the new and current color and translating it to the corresponding letter 'A' for 1, 'B' for 2, etc. How YOU blend the color is up to you-- come up with your own scheme, or use mine or some variant.

Notice that the user does not change their application here. We COULD provide a function either in the Graphic and/or FrameBuffer class that allows the user to turn on and off color blending.

Here is a sample program (same as Part 3) that produces this output

Part 5. A First Circle Algorithm (DDA)

The equation for a circle of radius r is:
r2 = y2 + y2 
					
There are three basic variations: A third variation uses the parameterized equation of the circle:
x = r cos(t)	 		
y = r sin(t)

where t varies from 0 to 2 * PI
					
Code each of the above algorithms and see how good a circle you get. Try an algorithm that calls the x-varies followed by the y-varies and seem what that does.

Add a function to your Graphic class that allows the user to select which circle algorithm they wish to use.

You don't really have to do the calculation on the ENTIRE circle-- calculate the first quadrant-- the others are mirror images around one or both axes (i.e., reverse the sign of the x and/or y coordinate of the resulting point. In actuality, all you really need is one either of the circle in order to use an approach like this). See if you can figure out how to do this.

Part 6. Bresenham's (Midpoint) Algorithm

Bresenham's algorithm is discussed in the text (sections 7.9)-- the algorithm uses integer arithmetic only. You can also get informtation on it from Wikipedia-- look it up (I believe the Wiki discussion is simpler).

The original algorithm was for line segments, but was extended to a circle version (look under either Bresenham or midpoint).

Implement Bresenham's algorithm for lines and circles. As in the previous part, provide functionality to allow the user to select which algorithm to use.

Play with the same various slope types as described in Part 2. Try drawing the same line with DDA and Bresenham (with color blending) and see how they compare.

What and How to Submit

Have Fun!