The openGL library takes care of drawing polygons, but it does not provide for windows and user interaction. The GLUT library takes care of those details.
If you look the source code for question 6, you'll see that the main program registers five callback functions:
glutReshapeFunc (handleReshape); glutKeyboardFunc(handleKey); glutMouseFunc (handleMouseClick); glutMotionFunc (handleMouseMotion); glutDisplayFunc (display);These tell the GLUT code to call our
handleReshape
function when the drawing window is resized or exposed, or needs
to re-drawn for some reason, to call handleKey
when
the user presses a key, to call handleMouseClick
when they press or release a mouse button, and to call
handleMouseMotino
when the user moves the mouse
with abutton held down ("drags" the mouse). The
display
function does the actual drawing on the
screen, and has all the necessary openGL code in it. You don't
call it directly. You have to ask GLUT to call it. You ask
GLUT by calling glutPostRedisplay()
.
If you're working on CDF, GLUT is already installed. But if you're working on a Windows machine, Microsoft's Visual C includes only the openGL library. You have to get GLUT off the net. The whole compiled library (150Kb) for Windows 95/98/NT is available at SGI's site.
You will have to install the files yourself. The files should
be placed follows, for Windows 98:
You have to tell Visual C which libraries you're using. This
should be set automatically for you if you use the
rectangle.dsp
file provided. If you don't use it,
you'll have to tell VC about the libraries as follows:
opengl32.lib glu32.lib glut32.lib
You'll need to keep track of what the user did most
recently. A finite state machine should help a lot to organize
your code. Figure out what the new shape of the rectangle
should be, and call glutPostRedisplay
to redraw it.
You could use the code from Q5, but actually the point-in-polygon problem for a rectangle is a lot simpler: just check if the X and Y of the mouse position is between the left-right bounds of the rectangle, and between the top-bottom bounds.
Furthermore, you are not just looking for whether the user clicked INSIDE the rectangle, but whether they clicked near a vertex (and which vertex), near an edge (which edge), or somewhere inside.
See the lecture notes on raster graphics off the course web page, to learn how a tv monitor image is created.
Too much storage is O(n x n) or O(n) storage. Try to use constant storage.
Pictures with the worst-case example should be enough for an answer. Assume convex polygons in all cases (no extra points for concave polygons, but you're welcome to answer that problem too).
First, the issue of "nearness": there should be a reasonable neighbourhood of a vertex for the user to click and drag, otherwise it will be very hard to click exactly on the pixel that the vertex covers.
Secondly, when a vertex is moved, the opposite vertex stays fixed. The moved vertex and the opposite vertex will define a new rectangle. In other words, you have to preserve the rectangular shape. Similarly, when you move an edge, the opposite edge should stay fixed, thus stretching the other two edges with your movement.
Think of what's happening from the user's point of view, in detail, when they "drag" a corner:
handleMouseClick (int button, int state, int col,
int row)
,button==GLUT_LEFT_BUTTON
,state==GLUT_DOWN
. col
and row
tell you where
the mouse was when the click happened.
handleMouseMotion (int col, int row)
,(row,col)
.
handleMouseClick
, with
and state==GLUT_UP
.
Not really. If you click somewhere and let go, the square JUMPS to your mouse position. It's not supposed to do that. You're supposed to be able to move it gradually.
Another way to look at it is this: if the rectangle was a window on your desktop, you would click the title bar of the window and drag it around. If you clicked in the middle of the title bar, then moved the mouse, the rectangle would still have the mouse pointer in the middle of the title bar.
The convention used is that a list of (x,y) pairs will be considered the vertices of a polygon, as we travel consecutively along the polygon's edges. Implicitly, the last vertex in the list is joined to the first one.
Thus the list:
Yes they do. They aren't "simple" (their edges cross). The polygon I gave you looks like a bow-tie. Don't worry. It's deliberately like that. It's equivalent to two triangles touching:
|\ /| | \ / | | \ / | | * X | | / \ | | / \ | |/ \|The asterisk marks the test point, for in2.dat, which is INSIDE the polygon.
Oops! That should read "Click and drag" outside the rectangle to rotate it. Think of a coordinate axis centred on the rectangle, which turns when you drag the mouse. The important thing is:
Assume the user does not drag vertices or edges outside the window, and does not move vertices or edges past opposite edges, thus flipping the rectangle over.
Look here.