This project demonstrated the use of matrix operations to manipulate graphics. It expanded on some of the operations available in Project 1 and introduced new opeartions such as rotate and scale. This project also helped refine RapidApp programming skills.
Even though this project required developing matrix operations and functions ourselves, it still showed just how powerful the matrix operations are. Translating or rotating points is as easy as multiplying them by a matrix.
The basic premise of this project was to draw an arbitrary number of
arbitrary sized polygons on the screen. The user can then manipulate them
with the Motif widgetry. The manipulations required were translation and
rotation, plus changing the colors, clearing the screen, undoing changes,
and exiting. I also added the ability to shear polygons and scale them. Also,
my project has some 'extra' features. The basic mouse routines seem to query
the mouse too often, making it possible to draw many, many sided polygons. I
added the ability to add a large delay between pollings to toggle this
'feature'. I also added a function to select all of the currently drawn
polygons so that they may all be manipulated at the same time. Also, there is
a toggle to select both the X and Y operations, ie, you can translate both
along the X and Y axis at the same time.
Section 1: Sample Screenshots of what the program does
Figure 1: The Initial Program Appearance With Some Polygons Drawn (click to enlarge)
(Actually, the polygons start being drawn in white, but I made these green right away. The undo operation later on will show that they started life colored white)
Now, the bottom pentagon is selected and rotated a bit. The rotate operation first translates the polygon's center to the origin (and moves the verteces accordingly), then rotates using the rotation matrix, then un-translates the polygon's center (and verteces).
Figure 2: Program Appearance After Rotation (click to enlarge)
Now, the top pentagon is scaled in both the X and Y dimensions at the same time. The quadrilateral on the left is scaled in the Y direction. The triangle on the left is scaled in the X direction (all scaling is by a factor of 2 in this example shot). Again, to do the scaling, the polygon is moved to the origin, then scaled, then moved back.
Figure 3: Program Appearance After Scaling (click to enlarge)
Now, the top pentagon is sheared on both the X and Y dimension. The triangle is sheared on the X axis and the rectangle on the Y (again, this example is a factor of 2). As in the scaling operation, the polygon is moved to the origin, sheared, and then moved back.
Figure 4: Program Appearance After Shaering (click to enlarge)
Now, we change the colors of the different objects, one at a time.
Figure 5: Program Appearance After Changing Colors (click to enlarge)
Now, we translate the polygons. The quadrilateral is translated by 100 units up. The upper pentagon is translated 100 units in both the X and Y direction. The triangle is translated -100 units in the X direction.
Figure 6: Program Appearance After Translating Polygons (click to enlarge)
Now, the undo option. Notice the polygons really started out white and I changed them for the example.
Figure 7: Program Appearance After Undo Transformations (click to enlarge)
The next screen shot shows many of the opeartions combined on a single image (also, it nicely shows the effects of Affect All being selected)
Figure 8: Multiple Transformations
Without Precise Points selected, points are drawn nearly continuously as the mouse is moved. This allows weird polygons to be drawn such as shown in Figure 9.
Figure 9: Pacman
Section 2: Program Opeartion
When the program is first started, it is in 'select' mode. However, there are no polygons created at that point. Clicking 'Start New' switches to 'drawing' mode. The right mouse button is equivalent to clicking 'Start New'. As polygons are created, they can be closed either explicitly by clicking the 'Close' button or by hitting 'Start New' (or the right mouse button). However, the only way to re-enter 'select' mode is by hitting the 'Close' button.
When in select mode, clicking on a polygon will cause it to be selected. Selected polygons are indicated by drawing the center point in a very large point size. Selecting 'Affect All' will cause all polygons to be selected.
When a polygon is selected, the controls become active. The scroll bars are a little 'touchy' for some reason. If you actually try to scroll, the polygons usually end up in strange places very rapidally. It is somewhat more desirable to simply click on the scale button. The color scroll bars do work fine though, as does the rotate dial.
Selecting 'Both X/Y' causes scales/translations/shears to be done on both the X and Y axis with a single operation.
Selecting 'Undo' from the File Menu restores the polygons to their original locations/colors/orientations (from the last 'Close' clicking).
Selecting 'Clear' from the File Menu clears the drawing area.
Selecting 'Exit' from the Ext Menu exits the program.
Section 3: Code
There are several pieces of code for this project. The first four are the header files for the type definitions and the matrix, list, and overall project.
The next file is the matrix functions.
The next file is the list functions.
The last file is the BulletinBoardClass.C file.
The code is generally straightforward and easily followed. Most of the functions end up doing the same things, just with a different matrix function.
Section 4: Known Bugs
Once in a while (especially if you move the project window to the right side of the screen), the program will generate a Bus Error when you start drawing the third polygon. I have no idea why or how this occurs. I poked around a great deal using gdb and I was still unable to determine the exact cause of this bug. Also, the bug manifests itself as a seg fault inside of gdb, rather than a bus error. I am not sure why I would get a bus error. They generally are caused by poor memory alignment, but that should not be possible in my code.
Sometimes, after hitting Undo, individual polygons will not be selectable. They can still be selected with the 'Affect All' button, and generally the last polygon drawn will still be selectable. I think this is a problem with my copy_list() function. However, it doesn't seem to be an obvious problem - I can output the polygon list and everything is exactly as it should be.
free()ing the polygon list pointers causes weird problems, none of which
should happen. The memory referenced by those pointers doesn't actually end up
getting changed, so they should be free()able. Actually, I can free() them,
I just can't re-alloc them. I tried using realloc() but still had an occasional