CS 424: Computer Graphics, Fall 2013
Lab 2: Hierarchical Modeling in Java Graphics2D
For this lab, you will be working with hierarchical modeling in Java. You will do this in two ways: by writing a hierarchy of subroutines that draw object and sub-objects, and by using a simple scene graph API to build a data structure to represent the objects in the picture. Both techniques are discussed in Section 3 of the course notes, and you should be familiar with that material before coming to lab.
You will need copies of the following two files, which you can find in /classes/cs424/lab2-files: Hierarchical2D.java and SceneGraph2D.java. You should copy them into your lab2 project.
This lab is due at the beginning of lab next week. You should copy your work into your homework folder in /classes/cs424/homework. Your work should be in a folder named lab2 or something very similar.
Exercise 1: Hierarchical Modeling with Subroutines
For the first exercise, you will create a simple hierarchical model by writing subroutines to draw parts of the model. The model that you draw must be as follows: a triangular base; a long rectangular bar whose center is "attached" to the tip of the triangular base; two wheels attached to the two ends of the rectangular bar. The wheel must rotate about their centers, rather quickly. The bar must rotate about its center, rather slowly.
The starting point for this exercise is Hierarchical2D.java, which defines a framework for writing and animating a hierarchical model. This class includes a number of subroutines for drawing basic objects, such as lines, filled squares, outlines of circles, and triangles. Your model should be constructed from these basic objects. You should write a subroutine to draw the model, and call that subroutine in the paintComponent() method (possibly with some transformation applied). That subroutine can, in turn, call other subroutines. A subroutine that makes any modification to the transform should save the transform at the beginning and restore it at the end. In between, it should draw the sub-objects of the object, with any necessary transformations. That is, the general format for each of the subroutines is
void drawObject(Graphics2D g) { AffineTransform st = g.getTransform(); // ... Draw the sub-objects g.setTransform(g); }
If the subroutine modifies the drawing color in g, it should also save and restore the color using g.getColor() and g.setColor().
To make this easier on yourself, you should build the model from the bottom up. That is, you should first write a subroutine that draws a wheel -- maybe a rotating wheel. You can make it from a circle and some lines. Call that subroutine in the paintComponent method to test it. You should get a picture like the one shown on the top left below, although the wheel might not be the same size. Next, make an object that consists of a bar with a rotating wheel on each end, and test it; the picture should look like the one on the top right below. Finally, make the complete object, consisting of the bar and a base. The pictures on the bottom left and bottom right below show two frames of the animated object from my program. You should make yours as similar as possible.
Exercise 2: Building a Scene Graph
For the second exercise, you should make exactly the same animation as for Exercise 1, but this time you should do it by building a scene graph data structure to represent the model.
The starting point for this exercise is SceneGraph2D.java. This class defines essentially the same scene graph API that was used in the sample program SceneGraphAPI2D.java, which was used as an example in Section 3 of the course notes, except that it doesn't define exactly the same set of basic objects.
To write the program, you want to create CompoundObjects to represent the model and its sub-objects. To apply transformations to objects, create TransformedObjects. Since the top-level object is called world, then paintComponent() just calls world.draw(g); you do not have to change this. You only have to work at the three points that are marked as TODO. Most of your work will be in the createWorld() method, which has to build the scene graph data structure. To animate the model, you need to keep references to some of the TransformedObjects in the model, so that you can change the transformation for each frame. The changes are made in the updateFrame() method. This is the same pattern that is used in the sample program, SceneGraphAPI2D.java, and you should understand that example before you begin. In particular, refer to the createWorld() method in that class.
As with Exercise 1, it's best to work in stages. First, make a rotating wheel object, and use that as the only object in the world. When that works, make the object that consists of the bar and two wheels, and use that as the world. Finally, build the full model.
Exercise 3: Create a Complex Scene
The third exercise is simply to create a complex animated scene that uses hierarchical modeling. You can do it using either a subroutine or a scene graph, whichever you prefer. Start with a copy of either your Hierarchy2D.java or your SceneGraph2D.java. It should be similar in complexity to the sample program from the notes. You can include the model that you built for Exercise 1 or 2 in the scene, if you want, but you should also build a couple of other hierarchical models, and at least one of them should be animated. If you can't think of anything else, build a model of a house, and use it several times in the scene, with different sizes. Build a simple model of a tree and make it grow over time. Model a clock that shows the actual current time. Or think of something entirely different on your own.