COMP3421/9415 Computer Graphics Assignment 1
Computer Graphics 08s2 Last updated Tue 05 Aug 2008 04:01
In this assignment you must implement an editor, DS (for Driving Simulator) that will allow users to interactively create a map for a driving simulator containing areas of ground, trees, road signs, buildings and roads defined by a Bezier curves.

I have packaged all the files in this directory in a zip file so that you can take it home to work with.

Getting Started

To make life easier for you I have provided a partial implementation of the editor. The editor is an application.

In a shell window do this:

% 3421
% cd /web/cs3421/08s2/assignments/dsed/
% java DSEdit

Now you can try all features I have implemented:

What you must do

Modify this program so you can:
  1. Create a new Sign with a Sign tool
  2. Create a new Tree with a Tree tool
  3. Create a new Building with a Building tool
  4. Create a new Road with a Road tool
  5. Create a new Light with a Light tool
  6. Create a new Viewpoint with the ViewPoint tool
  7. Reshape shapes with the Reshape tool
  8. Move the selected shape in front or behind the other shapes
  9. Add a rotate tool that allows you to interactively rotate a shape about its centre.
  10. Add a scale tool that allows you to interactively scale a shape about its centre.
You can try out my solution by typing:
% cd /web/cs3421/08s2/assignments/dsed/
% ./dsedsol

Here is a screenshot of my solution in action:

If you save this picture in a file you get this:

DSPolygon 255 255 255 grass.png 2.0 0.0  4 9.0 14.0 467.0 13.0 461.0 263.0 8.0 270.0
Road 255 255 255 street2.png 0.8 25.0  13 82.0 83.0 236.0 44.0 422.0 73.0 374.0 158.0 303.0 244.0 275.0 99.0 234.0 111.0 197.0 114.0 232.0 243.0 83.0 229.0 37.0 222.0 38.0 91.0 82.0 83.0
Tree 255 0 0 grass.png 2.0 4.0  2 276.0 194.0 285.0 207.0
Sign 255 255 0 grass.png 2.0 3.0  2 198.0 23.0 197.0 46.0
Sign 255 200 0 grass.png 2.0 3.0  2 406.0 125.0 427.0 124.0
Building 102 0 0 null 1.0 2.4  2 72.0 104.0 120.0 144.0
Light 255 255 255 null 1.0 10.0  1 336.0 40.0
ViewPoint 255 255 255 null 1.0 2.4  2 24.0 24.0 80.0 56.0
Each line contains the following information: The user interface to your solution does not have to look exactly like mine, indeed, you may be able to improve on it. If you do make radical changes to the user interface, make sure you provide a summary under the help menu so that your tutor can figure out how to use your program when he/she marks it.

Classes you need to study

There is an index of all the methods and fields defined in this directory. You also see a tree showing the inheritance hierarchy.

DSEdit (source)

This class controls the edit window that the user interacts with. The most important methods are the constructor, which creates all the GUI components of the application and add listeners so that the GUI components do something.

You will need to modify this class to create more GUI components and to respond to menu choices (such as Save As)

DSCanvas (source)

This class controls the OpenGL drawing area in which the picture is drawn and keeps track of selected objects.

DSShapeList (source)

This contains a Vector that stores a list of DSShape objects. It is also the class that knows how to read shapes from a file and write shapes to a file.

DSShape (source)

This abstract class represents an arbitrary shape on the screen such as a Sign or Polygon. Its most interesting method is paint, which uses OpenGL to draw the shape on the screen. There are also several useful methods that allow Tools to modify DSShapes.

DSPolygon (source) is a subclass of DSShape that implements a polygon shape.

Because OpenGL polygons must be convex, so must this.

ToolChoice (source)

This controls the JComboBox component that lets the user select which tool to use.

Adding new tools requires you to modify this class.

Tool (source)

This is the superclass for all tools that modify the DS.

PolygonTool (source) that implement the tool for interactive creation of a polygon shapes.

TranslateTool (source) is a subclass of Tool that implement the tool for translating shapes.

SelectTool (source) is a subclass of Tool that implement the tool for selecting shapes.

You will need to implement a subclass of Tool for each tool you implement (such as ReshapeTool). When you do this you will need to override some of the MousePressed, MouseReleased and MouseDragged methods to control how the tool reacts to user input.

TextureChoice (source)

This is a combo box that lets you select a texture.

MyTexture (source)

This class hides all the gory details involved in converting an image file (png) into an OpenGL texture.

Matrix classes

Matrix2D and Point2D are used by TranslateTool to create a translation matrix.

Hints

Use inheritance. If you find yourself copying whole methods from some other class. It probably means you should be extending that class instead.

Although OpenGL provides methods for drawing Bezier curves (glMap1 and glEvalCoord1) you will probably find it easier to use the Bezier code from the Bezier applet shown in lectures.

The provided code provides examples of most the OpenGL methods you need to use. About the only other ones you'll need are

gl.glBegin( GL.GL_TRIANGLE_STRIP );
to draw a sequence of triangles, and
gl.glLineWidth(4.0f);
to set the line width.

Provide feedback for any actions in your user interface. An example of this is the Translate tool which shows the new position of the shape as it is moved.

Make the state of the editor visible at all times. For example the selected tool is displayed in the Choice component and different cursors are used for different tools.

Use the status text field to display helpful messages. For example, my PolygonTool adds a new corner to the polygon on MouseReleased events and finishes the polygon on SHIFT-MouseReleased so it displays a message to the user explaining this when polygon drawing begins.

You will find Java's Math.atan2 method useful for working out the angles for the Rotate tool. To work out the angle shown in the diagram below you need to write something like:

angle = Math.atan2(p.y-c.y,p.x-c.x);
[angle between vector and x axis]

Selecting a Sign is a little tricky. You need to determine if the point where the user clicked is close enough to the Sign. This is easy once you find the right transformation. Transform the point (x,y) to (x',y') with the transform that maps the ends of the line to (0,0) and (1,0). You can work out this transform as a product of a translation, a rotation and a scaling. Then, if 0 < x' < 1, abs(y') is the distance of the point from the line.

The hardest part of the assignment is drawing the Road correctly. I suggest you start by modifying the Bezier applet so that it uses an OpenGL GL_LINE_STRIP to draw the road, and using glLineWidth to set the road width.

Unfortunately, this doesn't let you have very wide roads because there a maximum line width. In my solution I draw the road using a GL_TRIANGLE_STRIP. This picture shows the order of the vertices in the triangle strip. The actual Bezier curve is in black and runs down the centre of the road.

[triangle strip]
Vertices 1 and 2 are each half the width of the road from B(0), the first point on the Bezier curve. The line joining point 1 and point 22 is at right angles to the Bezier curve, so to compute the position of point 1 you need to calculate B'(0) (the derivative of the Bezier curve), divide by the length of B'(0) and multiply by half the road width to get a vector X. Finally, rotate X by 90 degrees and add it to B(0) to get point 1. You get point 2 the same way, except you rotate by -90 degrees.

Repeat for B(1/7), B(2/7) etc and you have all the points for the triangle strip.

Finally you have to apply the road texture so that it follows the road as in the example at the top of this page. To do that you just have to work out the right texture co-ordinates for the points. Point 1 and point 2 have texture co-ordinates (0,0) and (0,1). Point 3 and point 4 have texture co-ordinates (d,0) and (d,1) where d = (distance between B(0) and B(1/7))*scale/100 and scale is the texture scale factor.

Buildings are defined by two control points giving two opposite corners. That means they are always parallel to the x and y axes and rotating them gives funny results. Don't worry about this.

Don't forget to check the forum for answers to frequently asked questions about this assignment. You should always check the forum before emailing me a question.

Marking

There are 20 marks. 14 are for implementing the features described above. Most are worth one or two marks but roads are worth three. There are also three marks available for programming style and and three marks for documentation.

Plagiarism

Don't. It's fine to ask a friend or the forum for help but you have to write the code yourself. The best way to avoid trouble is to avoid looking at anyone else's code.

C++ version

You can use C++ if you prefer. There is zip file of C++ code you can start with.

Handing your assignment in.

Hand in the Java classes you have written using give:
% give cs3421 dsed *.java
If you have any non Java files (like more textures), you can put them in a file extras.jar and submit that with the others.

The assignment is due at 11:59:59 pm on Fri 5 September. Late assignments lost 10% off the maximum mark per day late for five days, after which all marks are lost.

cs3421 @ CSE @ UNSW