CS-460/560 Assignment #5
Due Date: 3-25-2010

CS-560 students should do all parts of the assignment (A, B, and C); 
CS-460 students should do only parts A and C).

The program you write for this assignment should be a Visual C++ MFC 

Part A. (all students)

You are to write a "2-D Geometric Transformation Package" consisting of a
class that contains a set of C++ member functions that will perform the
following types of two-dimensional affine transformations on polygons or
polylines: trans_poly() that translates a polygon by a specified vector
(tx,ty); rotate_poly() which rotates the polygon by a given angle (theta)
about a specified point (x,y); scale_poly() which scales the polygon by
given scaling factors (sx,sy) with respect to a specified point (x,y). 
These functions, in turn, should make calls to the more primitive 
functions: settranslate(), setrotate(), setscale(), combine(), xformcoord(), 
and xformpoly() discussed in class. (See notes on the class web pages.)

The trans_poly(), rotate_poly(), and scale_poly() functions should take as
parameters a polygon or polyline (list of vertex points), the transformation
parameters (tx,ty for a translation, theta for a rotation, and sx, sy for a
scaling), in addition to the coordinates of the reference point for the
latter two functions. It should generate a new polygon or polyline (list of
vertex points). [Again see the web page notes for suggested prototypes for
these functions.]

To test the resulting "2-D Geometric Transformation Package" write a VC++ 
MFC program module that "creates" a set of polylines or polygons that make
a simple object (whatever you like as long as it is composed of at least 3 
polygons/polylines), and then makes appropriate calls to the  transformation 
package functions that will cause the object to move according to keyboard 
actions taken by the user. These actions could be any of the following:

Horizontal motion (left or right), vertical motion (up or down), rotations 
(clockwise or counterclockwise) about the object's center, increasing the 
size of the object, decreasing the size of the object. When the program 
starts, the object should be displayed more or less in the middle of the 
client area of the window. The key presses that determine what the next 
movement of the object will be are the following:
"u"   object moves up on screen
"d"   object moves down on screen
"l"   object moves left on screen
"r"   object moves right on screen
"c"   object rotates clockwise about its center
"v"   object rotates counter clockwise about its center
"+"   ojbect gets larger (center of object remains fixed)
"-"   ojbect gets smaller (center of object remains fixed)
In each case the current state of motion should continue until the user 
presses some other keyboard key. You may choose the increments/decrements 
to be used in the translations, rotations, and scalings as the object moves 
from one frame to the next. They should not be too large (object moves too 
fast) or too small (object moves too slowly).

To do one "frame" of the animation, the previous picture will need to be 
erased and the current one drawn in the pen/brush color(s) you choose. The 
erasing could be done by filling the picture's polygon/polylines with the 
background brush color or by filling the entire window client area with the 
background brush. Before the object's polygons are redrawn, they should be 
transformed to their next positions. A new frame should be generated in 
response to a timer tick event. Again, set up the timer's timeout interval 
in such a way that it is neither too short or too long. (See the "balltime"
example program.)

PART B. (only CS-560 students)

Add a function to your "2-D transformation package" that will reflect a 
polygon across a straight line whose endpoint coordinates are given. It 
should take as parameters an input polygon/polyline (a list of points)
and the endpoint coordinates of the line across which the polylgon is to 
be reflected. It should generate an output polygon/polyline. This 
function, in turn, could make a call to a function that sets up the 
composite transformation matrix required to reflect a point across an 
arbitrary straight line defined by the screen coordinates (x1, y1, x2, y2) 
of its endpoints. This function's prototype might be something like:

void setreflectline(float a[6], float x1, float y1, float x2, float y2);

where the a[i] are the six nontrivial matrix elements of the required
reflection matrix. Add some code to your main program file that will draw 
a straight line segment, draw your picture's polygons/polylines, and 
reflect them about the line. (This could be in response to the user 
selecting a menu item.) The endpoints of the reflection line should be 
determined by user mouse clicks. You should use different colors for the 
line, your  polygon, and your reflected polygon.

Part C. (all students)

Add to your program an animation of a sprite (small image or bitmap) over a 
background bitmap that occupies the entire client area of your program's 
window. (This could be in response to the user selecting a menu item.) You 
should create the sprite and the background bitmap (or image) using any 
paint program you have access to (e.g., the Windows "Paint" application). 
Or alternatively you could download them from the web. In either case the 
images should be saved as .BMP, .JPG, or .GIF files. They may be added to 
your program's resources and loaded in as bitmaps or, alternatively, set up 
as CImage objects that can be loaded in directly from the directory they 
were stored in. In either case your program should load in the bitmaps or 
images and make them move around on the screen using the BitBlt()/StretchBlt() 
functions discussed in class. Each new frame of the animation will be 
triggered by a timer timeout. Try to be original in the choreography of the 
motion. Again, after each frame is drawn - i.e., after each "blit" - the old 
background area should be restored and the sprite should appear in its new 
position. To do this you should make use of the "sprite animation" technique 
we'll discuss in class so that there is no "rectangular halo" as the sprite 
moves and no flicker. In other words, you will be using offscreen device 
contexts and offscreen bitmaps so that there will be only one access to the 
window's screen device context per frame. You may need to make use of the 
BITMAP structure and the GetObject() function to obtain the size of the 
sprite or, in the case of CImage objects, the GetWidth() and GetHeight() 
member functions of that class. (See the course notes and the VC++ online
help. You should also take a look at the listing for the "imageblt" program.

As usual you should email the zipped project directories to the TA.