From CS559 Computer Graphics Fall 2007

Main: P2

Project 2 - Trains and Roller Coasters

On this page... (hide)

  1. 1. Overview
  2. 2. Project Phases
  3. 3. Some Basic Ground Rules
  4. 4. Phase 1 - The Transformations written assignment
  5. 5. Phase 2 - OpenGL Programming Signs of Life
  6. 6. Phase 3 - Theoretical Background
  7. 7. Phase 4 - Programming Checkpoint
  8. 8. Phase 5 - The Roller Coaster!
    1. 8.1 Advanced Features
  9. 9. Documentation
  10. 10. What to turn in
  11. 11. Some Hints

1.  Overview

In this project, you will create a train that will ride around on a track. When the track leaves the ground, the train becomes more like a roller coaster.

The two main purposes of this project are to give you experience in working with curves (e.g. the train and roller coaster tracks) and to give you experience with writing interactive 3D programs.

What you will turn in for the "final" part of the project is a program that creates a 3D world, allows you to position a track within the world and adjust it interactively, can make a roller coaster follow along that track, and will allow you to ride the roller coaster.

There are two example solutions to this project in P:/course/cs559-gleicher/public/bin, both from 1999. One is a version that I wrote (called mikes-Train) and another was written by a really good student (robs-train). I recommend that you try them out to get an idea as to what you'll be doing.

Mike's sample train, circa 1999

Rob Iverson's A+ assignment from 1999

While the assignment was a little bit different in 1999, the basic idea was the same. For a totally crazy solution to this assignment, check out RocketCoaster. It was what happened when I let two students work as a team. And they were really good students.

Note: at the beginning of the project, you might not understand all the things we're going to ask you to do. Don't worry - you'll be learning it all soon enough!

If you're curious, you can look at previous years' projects (2006, 2005, 2003, 2001, 2000, 1999) to see what to expect. This year's will be slightly different, but the basic ideas will be the same. Historically, students have really liked this project.

2.  Project Phases

Creating a world and a roller-coaster might seem a bit intimidating, especially if you haven't done much graphics programming before. Therefore, in this project, you will work up to the final roller coaster program through a series of phases:

Understanding transformations is the basis of any graphics programming, so before you start programming, there will be a written homework assignment to help make sure you understand them.
Before trying to write a complicated interactive 3D program like a roller coaster, we want you to write a simpler 2D interactive graphics program to make sure you have the basic mechanics down.
We will check to make sure everyone is making good progress - particularly on the parts of the project that are not central to it.
This is the actual project when you turn in your train/roller coaster program and feel the big sense of accomplishment that you've created something really cool. Along with the program itself, you'll turn in documentation as to how it works.

Remember: while the majority of you project grade will come from our evaluation of your final program, the earlier stages do count too! There will be a 1/2 letter grade penalty to your project grade for not completing the preliminary stages. In addition, the written assignments are important practice for the exams, so blowing them off will also hurt you there. Finally, the checkpoints are important to make sure you're making progress over the entire 5 weeks of the project: this project is a lot to do in 1 week, but not so bad if you think of it as a 5 week effort.

3.  Some Basic Ground Rules

You are to write this program doing the drawing with the OpenGL graphics library under Windows. You may use whatever user interface tools you wish (we recommend FlTk, but GLUT would be an acceptible alternative). See the GL Survival kit for thoughts on this. There is a lot of available sample code, but you do not have to use it.

You are to complete the assignment individually. We allow (encourage) you to discuss the project with your classmates, but the things you turn in must be substantively your own.

The basic part of this assignment is to provide a train going around the track. You must:

If you're curious, my sample solution (mikes-train.exe) does not do all of these. (the train doesn't have a front, and the only scenery is the point light source - also, there's a wierd bug where the train stretches out when it goes down a hill).

If your assignment does all of these basic parts, you will get at least a C. If your assignment doesn't do these basic parts, we will not look at its advanced features.

4.  Phase 1 - The Transformations written assignment

This written assignment is described on this page.

5.  Phase 2 - OpenGL Programming Signs of Life

The purpose of this phase is to:

  1. Make sure you have worked out the mechanics of getting and OpenGL program to compile.
  2. Can work out the basic mechanisms for making interactive programs.
  3. Can make programs that do animation in OpenGL.

These are all essential elements for your roller coaster. So we want you to try doing these things without all of the added complexity of curves and 3D.

You must turn in a program that:

You can make whatever user interface you like for this. You can make it direct manipulation (where the user clicks on the points and drags them around). You can make it keystroke driven (use the arrow keys to move things, and other buttons to cycle through the selection).

We encourage you to come up with creative programs that do cool things (yet meet the minimal restrictions). Making creative and cool programs is not only fun, but a great way to experiment with the graphics ideas we're learning in class.

Here are some examples of how you can fulfill the Stage 2 requirements (Simple 2D UI, FLTK Widgit Variant, Mouse Picking & Dragging Variant). (new!)

The tutorials will guide your through learning the basic skills you need to complete this assignment. Be sure to read the OpenGl Survival Guide for help getting started. The Main.Tutorials will help you with the mechanics of getting your program to compile and give your some ideas for user interfaces. The Main.SampleCode will provide you with useful elements for building things (particularly RunButton).

6.  Phase 3 - Theoretical Background

In order to make a roller coaster, you need to understand curves and perspective transformations. So we'll give you a written assignment described here designed to give you some practice.

The exam will cover the same material, so this assignment will be good practice for the exam. In fact, a portion of the problems from this written assignment will appear on the exam (with some of the details changed to discourage you from trying to just memorize the answers).

The assignment will be posted on or before October 23rd.

Note: Unlike every other thing in this class, this written assignment will be do at the begininning of the exam. (everything else is due at 11:59pm).

We will consider your homework assignment to be on-time if you turn it in before Tuesday, October 30th at noon. Note: there is good incentive to do the work earlier, since the questions may be on the exam.

7.  Phase 4 - Programming Checkpoint

We want to make sure that everyone is making good progress on the project. In particular, we want to make sure that by November 5th (one week before the project is due), you've at least gotten the basic 3D interactions working.

For this phase, you have to show that you have part of your project done. We're just checking for the first pieces to make sure you've started.

Be warned: if you only have these basic requirements done by the checkpoint, you still have a lot of work to do. To avoid having a hectic week before the project is due, we recommend that you have more than the checkpoint requirements done.

Your roller coaster program will need to have all of the following features, so you need to make a program that does all of these things. Basically, this program will provide the "world" that the roller coaster runs in:

We don't care what user interface you make to do these things. Ultimately, we care that you can position points in the world (since these will serve to specify where the track goes), that you can look around the world (so we can look at your creations), and that you can animate the roller coaster going around the track.

How you control the camera and points is up to you - we will give you example code (look here) that gives you some ideas, but:

We actually encourage you to use the example code to make your interface. The main part of this assignment should be the train, not the UI. (at the checkpoint, the train isn't necessarily due yet)

Bells and Whistles (like hack shadows) always make things nicer (and drop shadows actually make things easier to use since they are a depth cue).

What to turn in: You should turn in your .cpp and .H files, your .vcproj and .sln files, and a screen shot of your program. Please have a README.txt give a brief explanation of what your user interface is, and what (if any) of the example code you are using.

8.  Phase 5 - The Roller Coaster!

For this part of the project, you will turn in the actual roller coaster simulator, and the required documentation. As with all projects, we will evaluate your project both in a demo session (where you get to show it off) and by evaluation of your code and documentation.

The basic part of this assignment is to provide a train going around the track. You must:

If you're curious, my 1999 sample solution (mikes-train.exe) does not do all of these. (the train has no front, and the only scenery is the point light source - also, there's a wierd bug where the train stretches out when it goes down a hill).

8.1  Advanced Features

Meeting the basic requirements will get you a basic grade (definitely a C or better). But to get a better grade, and to really make the assignment fun, you should add some advanced features to your train.

Note: the exact point values for each of these is not given. The rough guide here will give you some relative importances (big features are worth more than small ones).

We will only check the features that you say that you have implemented correctly. Partial credit will be given for advanced features, but negative credit may be given for really incorrect features. (so, its better to not say you implemented a feature than to show us something that is totally wrong).

Also, remember that in your demo, you will have to show off the feature, so think about what demonstration will convince us that it works. For example, with arc-length parameterization, you're best off being able to switch it on and off (so we can compare with the normal parameterization), and think about a track that really shows off the differences.

Arc-Length Parameterization (BIG)

Having your train move at a constant velocity (rather than moving at a constant change of parameter value) makes things better. Implementing this is an important step towards many other advanced features.
You should allow arc-length parameterization to be switched on and off to emphasize the difference, you should also provide a speed control.

Give a tension control for the splines (small)

This is so simple, but it will give you some intuitions for what the tension parameter does. For cardinal splines, you could have a different tension value for each control point. You should allow for tension to be adjusted interactively (like with a slider).

C2 Curves (medium)

Having C2 Curves are better than C1 curves. (the 2nd order discontinuities would make the motion unrealistic). With C2 curves, your train may not go through the control points, but only approximate them.

Direct Manipulation or Intepolating C2 Curves (BIG)

The easier form of C2 curves are approximating. Making it so that the user has direct control of the C2 curves (either having it interpolate the control points, or having the user adjust the track and having the system adjust the control points to make the track fit.
One method for doing this is the paper:
Barry Fowler, Richard Bartels. "Constraint-Based Curve Manipulation," IEEE Computer Graphics and Applications, vol. 13, no. 5, pp. 43-49, September/October, 1993. If you're on the UW campus, you can get the article here.
Note: to get full credit for this feature, you need to provide for total control over the curve - just translating a control point when the user tries to move the curve doesn't apply.
An even more interesting variant of this is to allow the user to sketch a curve, and then fit a smooth curve to the sketched one.

Draw nicer looking tracks (medium)

Drawing rail ties (uniformly spaced lines perpindicular to the tracks) and parallel tracks is a little bit tricky. The rail ties require good arc-length parameterization (to get uniform spacing). For parallel rails, simply offsetting the control points doesn't work. See the comments on multi-part points below.

Correct Orientation in 3D (medium)

The simple schemes for orienting the train break down in 3D - in particular, when there are loops. Make it so that your train consistently moves along the track (so its under the track at the top of a loop).
One good way to provide for proper orientations is to allow the user to control which direction is "up" at points along the curve. This allows you to do things like corkscrew roller coasters.

Save and Load Tracks (small)

Being able to write out track designs and read them back in makes it easier to show off what your program can do. This feature will save you time as it will make your program easier to test.

Have Real Train Wheels (medium)

Real trains have wheels at the front and back that are both on the track and that swivel relative to the train itself. If you make real train wheels, you'll need arc-length parameterization to keep the front and rear wheels the right distances apart (make sure to draw them so we can see them swiveling when the train goes around a tight turn).

Have Multiple Cars on Your Train (medium)

Having multiple cars on your train (that stay connected) is tricky because you need to keep them the correct distance apart. You also need to make sure that the ends of the cars are on the tracks (even if the middles aren't) so the cars connect.
If you're really into trains, you could have different kinds of cars. In particular, you could have an engine and a caboose.

Have People On Your Roller Coaster (small)

Little people who put their hands up as they accelerate down the hill are a cool addition. (I don't know why putting your hands up makes roller coasters more fun, but it does). The hands going up when the train goes down hill is a requirement.

Implement simple physics (medium - its actually not hard once you have arc-length)

Roller coasters do not go at constant velocities - they speed up and slow down. Simulating this (in a simple way) is really easy once you have arc-length parameterization. Remember that Kinetic Energy - Potential Energy should remain constant (or decrease based on friction). This lets you compure what the velocity should be based on how high the roller coaster is.
Even Better is to have "Roller Coaster Physics" - the roller coaster is pulled up the first hill at a constant velocity, and "dropped " where it goes around the track in "free fall." You could even have it stop at the platform to pick up people .

Have a "sketch-based" interface (10-20 points, depending on features implemented)

Make an interface where the user draws a curve on the ground, and figure out how to fit a spline to it.
If you're really interested in this, there are methods for sketching 3D curves (such as sketching 2D at a time). Ask us.

Lighting (small)

Having proper lighting makes things look more 3D. Its really easy to do in OpenGL.

Hack Shadows (small)

Having hack shadows "dropped" onto the groundplane are more than just eye candy - they actually make things more usable by giving a depth cue. The sample programs do this - although to get full points, you'll need to use a stencil buffer to make overdraw work correctly.

Headlight for the Train (small)

Have the train have a headlight that actually lights up the objects in front of it. This is actually very tricky since it requires local lighting, which isn't directly supported.

Have the train make smoke (small/medium)

Steam trains are the coolest trains, even if they are being a roller coaster. Having some kind of smoke coming from the train's smoke stack would be really neat. Animate the smoke (for example, have "balls of smoke" that move upward and dissipate).

Something so cool we can't predict it

Yes, you might think of something to do that we didn't mention here. If its really cool, we might give you points for it. We'd like you to focus on trying to do more with the curves aspect of this assignment (rather than making arbitrary eye-candy), so we won't give you points for just making eye candy (e.g. putting textures on things) - there will be a whole project devoted to that. If you want to do something and you want to make sure it will be worth points, send the instructor email.

9.  Documentation

Your documentation must have 3 parts:

User Documentation

In a file called user.txt (or user.htm, if you want to make it a web page so you can include pictures - just make sure all the links are local and the pictures are included) you must explain how to use the program.

Technical Documentation

In a file called technical.txt (or technical.htm, if you want to make it a web page), you must list all of the advanced features that you have implemented, as well as a brief description of how you implemented in. Tell us the technique you used. Sometimes, this is simple ("C2 Curves: I implemted Uniform, Periodic, Cubic B-Splines"), or you might have some explaining to do (say, if you make a sketch-based interface).
Your list should only include the features that work (the ones you want us to grade). When we do the testing of your program, we will only try out the features listed.


You should have the normal readme file, explaining where everything is.

10.  What to turn in

By the deadline (November 12th, 11:59pm) you must turn in:

Late projects will be accepted according to the class late policy. We expect to do demos on 11/19, so this would be the very last opportunity to turn in very late projects.

11.  Some Hints

In case it isn't obvious, you will probably use Cardinal Cubic splines (like Catmull-Rom splines). Cubic Bezier's are an option (just be sure to give an interface that keeps things C1. For the C2 curves, Cubic B-Splines are probably your best bet.

You should make a train that can move along the track. The train needs to point in the correct direction. It is acceptable if the center of the train is on the track and pointing in the diretion of the tangent to the track. Technically, the front and back wheels of the train should be on the track (and they swivel with respect to the train). If you implement this level of detail, please say so in your documentation. It will look cool.

In order to correctly orient the train, you must define a coordinate system whose orientation moves along with the curve. The tangent to the curve only provides one direction. You must somehow come up with the other two directions to provide an entire coordinate frame. For a flat track, this isn't too difficult. (you know which way is up). However, when you have a roller coaster, things become more complicated. In fact, the sample solution is wrong in that it will break if the train does a loop.

The sample solution defines the coordinate frame as follows: (note: you might want to play with the sample solution to understand the effects of this)

  1. The tangent vector is used to define the forward (positive Z) direction.
  2. The "right" axis (positive X) is defined by the cross product of the world up vector (Y axis) and the forward vector.
  3. The local "up" axis is defined by the cross product of the first two.

Doing arc-length parameterizations analytically is difficult for cubics. A better approach is to do them numerically. A simple way to do it: create a table that maps parameter values to arc-lengths. Then, to compute a parameter value given an arc length, you can look up in the table and interpolate.

Retrieved from
Page last modified on October 22, 2007, at 04:54 PM