- Assigned:
- September 10, 1999
- Due Date:
- September 24, 1999, 10:00am
For this MP, you will be implementing the Midpoint Line
algorithm (not the Bresenham Line algorithm) as
presented in class. Your program will take input from the mouse for
the endpoints of a line, and then draw the line connecting the endpoints
using your Midpoint Line drawing routine.
Since you will be implementing your own line drawing routine, you
may not use the built-in OpenGL line drawing routines. That would
certainly defeat the purpose of this MP. Instead, you may only draw points.
Upon completion of this MP, you should be able to do the following
things:
- Understand the Midpoint Line algorithm;
- Understand the differences/similarities between the Midpoint and
Bresenham algorithms;
- Get input from the mouse and keyboard; and
- Implement/derive the Midpoint Line algorithm.
Read Chapters 3 and 4 in the required text for this class - ``Computer
Graphics, C Version, 2nd Edition'' by Hearn & Baker. Chapter 3 contains
algorithms for drawing various graphics primitives. Chapter 4 talks about
attributes for those primitives.
Before you even start programming, sit down and derive the
midpoint line algorithm for a general line. Recall that we discussed
only the case where the slope is between 0 and 1. This can be generalized
for any line. However, you will need to do some thinking about it
before you begin programming.
You can write most of your program without actually implementing the
midpoint algorithm. The majority of your program will deal with the
technicalities of OpenGL. Write your mouse handling routine and see
if it works by drawing a line using GL_LINES. This is a good way
to make sure your mouse coordinates are being read in and used properly.
When you are done coding your line drawing routine, you can simply
replace the GL_LINES code with your own. The program that you submit
should use only GL_POINTS.
You must implement the Midpoint Line Algorithm presented in class.
Your program must be able to handle ALL possible slopes, not just
the case where 0 < slope < 1. You may not use the GL_LINES
primitive to draw the line. You must use the GL_POINTS primitive
and plot each pixel of the line.
The Left Mouse Button allows you to enter the two endpoints for your line.
Observe the following instructions when drawing the endpoints and the
connecting line segment.
When you enter the first endpoint of a line with the mouse, draw that
endpoint in GREEN with a point size of 3. The code needed
for this is as follows.
glColor3f(0.0,1.0,0.0); /* Set the drawing color to green */
glPointSize(3.0); /* Make a big endpoint */
glBegin(GL_POINTS);
glVertex2i(X1,Y1); /* Plot the first endpoint */
glEnd();
glPointSize(1.0); /* Restore the previous point size */
When you enter the second endpoint with the mouse, draw that endpoint
in RED, also with a point size of 3. To set the color to red,
do the following.
glColor3f(1.0,0.0,0.0); /* Set the drawing color to red */
Finally, draw the line in WHITE (glColor3f(1.0,1.0,1.0))
with a point size of 1. Your picture should now have two large endpoints
in green and red, and a thin line in white.
When you click the mouse a third time, that point becomes the new ``first''
endpoint, and you start all over. At this point, you would see just the
first endpoint in green, not the old line or the previous second enpoint.
When you finally click the mouse a fourth time, you would draw the red
endpoint and the connecting line segment.
You can continue to click the Left Mouse Button to enter the ``first'' and
``second'' endpoint in this fashion. You will always have a maximum of two
endpoints and 1 line on the screen at any given time.
When you type the letter ``q'' or ``Q'', the program should exit.
At the end of your code, show your derivation of the Midpoint Line
Algorithm for the general case of any line. Put this derivation
in a comment section at the bottom of your file. In particular,
you need to show how you came up with the decision parameter, how
you update the values of x and y based on the decision parameter,
and how you generalized your program to handle lines of any slope.
This section lists restrictions that are placed on your program. Please
read this section carefully, or you may lose points by implementing
something incorrectly.
- You may use only the GL_POINTS primitive.
- You may not swap the order of the two endpoints. You must draw from
the first point input to the second point.
- You must generalize your line drawing routine for lines of any slope.
Do not write specialized code for horizontal or vertical lines.
- You may not use more than 2 separate while loops,
one for when
|slope| <= 1 and one for when
|slope| > 1.
In other words, you may not have code specialized for the 8 different
cases of slope and endpoint ordering. Actually, you can reduce this to
just one while loop. (Hint: for cases with
|slope| > 1, swap the use of x and y, always increment
y by 1 (instead of x), and then plot (y,x). It's tricky since you
have to keep track of the slope and direction,
but it can be done.)
- You may not use any floating-point calculations when drawing
the line. (Hint: you may need to multiply various equations by
2 to remove the 0.5 term.)
- You may do only addition/subtraction and comparision inside your
while loop. Do all multiplications before the
while loop.
- You must document your code fully, especially your implementation
of the midpoint line algorithm. In particular, you must show
derivations of the decision parameter for the midpoint algorithm.
- Use a couple of global variables for the width and height of your
window (eg. WinWidth and WinHeight). That way, when you resize your
window, you can properly update the camera view as follows:
void SetCameraPosition(void)
{
/* Set the viewing transformation */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0,(GLdouble)WinWidth+1.0,(GLdouble)WinHeight+1.0,0.0);
glMatrixMode(GL_MODELVIEW);
}
- Call this SetCameraPosition function in your
``resize window'' procedure and in your ``update display'' procedure.
- Put your line drawing routine in one procedure. This may result in
a very long function, but it probably makes the most sense to keep
all the code in one place.
- Use a global variable of some sort to store the two
endpoints. You can set these values when you click with the
Left Mouse Button. For example:
void MouseButtonPressed(int Button, int State, int X, int Y)
{
if (State == GLUT_DOWN)
{
if (Button == GLUT_LEFT_BUTTON)
{
/* A new endpoint needs to be plotted. */
/* Make sure you keep track of both endpoints. */
}
glutPostRedisplay();
}
}
/* Later in your main() procedure */
glutMouseFunc(MouseButtonPressed);
- Test to see if your program correctly redraws the screen. Try
partially obscuring the OpenGL window with another window and then
bringing the OpenGL window to the front. Also try iconifying the
OpenGL window and then restoring it. The lines and endpoints
should be correctly redrawn.
Those graduate students enrolled for 1 unit of credit, and undergrad
students in the Campus Honors Program, must also implement the following
additional functionality.
Your program must be able to draw dashed as well as solid lines. When your
program is running, the user can type a number from 0 to 9 specifying the
length of the dashes and the space between the dashes.
When you type a number from ``0'' to ``9'', the program redraws the line as
a dashed line with the dashes and the spaces between the dashes having the
length input. For example, by typing a 6, your line should draw 6 white
pixels, skip 6 pixels, alternating from the start point to the end point.
A value of 0 (zero) indicates a solid line. This should be the default
behavior when your program is first invoked.
Your line will continue to have this dash length until it is changed by the
user. Also, be sure to redraw the line immediately when the user types in
a new dash length. (Note that it is not necessary to redraw the line if
the user types in a dash length that is the same as is currently set.)
Remember that you may not swap the order of the two endpoints, so endpoint
order will definitely affect the appearance of the dashes. You do not have
to be concerned with the fact that a line drawn at 45 degrees will have
slightly longer dash segments than a line drawn at 90 degrees.
You may not use the ``stippled lines'' feature built into OpenGL.
For this and future MPs, we will be using the electronic
handin program. Once you have completed your program,
logon or telnet to one of the Sun Sparc machines (``handin'' does
not work on the WindowsNT machines) and hand in your source code
by typing ``handin cs318 mp1 mp1.c''.
(For more information on handing in your code, consult the class web page
at
http://www-courses.cs.uiuc.edu/~cs318/handin.html.)
This will send your program to the class directory for grading.
Do not submit your executable program. Also, put all your
source code in one file. You must hand in your source code file before
10:00am of the due date, as handin will not accept late
assignments. Make sure your name, login, MP#, and date appear at the top
of your code listing. See the class web page for a sample file header.
If your program does not run as required, you will be given at most
50% of the total points for the MP. You are responsible
for making sure your program compiles on the WindowsNT machines using
the makewin batch file.
Late assignments will not be accepted. If you are having problems
beyond your control, you must let a TA know at least 24 hours
before the due date to arrange for a possible extension. There will
be no exceptions!