Fall 2003
October 28 - The "draft" version didn't seem to need much change. The only addition is a few comments on grading.

Project 2:
Trains and Roller Coasters


In this assignment, you must create a program that allows the user to create a train track and to animate a train that moves along the track. You should allow the user to place other objects into the world (so that there's scenery for the train). Finally, you should allow the user to create tracks that aren't just on the ground (to make a rollercoaster, not just a train).

The purposes of this assignment are to give you an experience writing an interactive 3D program, and exposure to working with curves. Therefore, for this assignment, getting basic 3D functionality (such as viewing and view control) and getting the curves right are essential to the grade. Getting the program to look nice is less important (it's a good added feature, but there will be another assignment that focuses on this later in the semester).

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.

my example train program

Pep Talk, Ground Rules, and Grading

This project may seem intimidating at first: you need to create a world, allow the user to view the world, put a train track into the world, let the user manipulate the train track, make a train that moves along the track, ...

This is quite daunting, especially if this will be your first time writing a 3D graphics program or working with curves.

Project 1 may have seemed big, but it was easily broken down into a series of smaller (and independent) pieces. This assignment does not break into pieces as easily. Instead, you might be better off trying to tackle this problem in phases.

Because of the way that grading works, it is more important to get the basic parts of the assignment correct than to make fancier features. If you make a very simple train that moves correctly along the track, and give the user a very basic way to specify the track, you will be much better off than if you made very fancy scenery, but don't have a working train. Towards the end of this assignment, we'll talk more about how grading is to be done.

Be sure to think and plan BEFORE you write any code. Having a general strategy about how to tackle this project is the key to doing it. It's too big to swallow whole.

Many of the things in this project will be discussed in class. As you read the project, you will see terms like "Frenet Frames" and "B-Splines" and "Arc-Length Parameterization" that you may not understand yet. We will get to these in class. My suggestion is to start working on aspects of the project that you do understand and add these other features as we get to them in class. In terms of curves, you might start by just considering how to place the control points in 3D. Later on, you'll learn how to create the curve.

There are some basic "skills" you need to accomplish in order to build this project. I suggest that you start with those. First write a program that draws something with OpenGL. Then write a program that animates something with OpenGL (see my "RunButton" code). Then try to do something in 3D....

You are permitted to use the example code (remember to attribute code that you get from elsewhere), user interface toolkits, "general purpose" data structure libraries (like the STL), and OpenGL. If there is some other code that you would like to use, please ask first.

A basic version of this project is probably in the 1000 line range.

You can play with my example to get ideas as to what it should do.

Getting Started in 3D

For many of you, this will be the first time you've written a 3D program with OpenGL (or even period). With other projects, we first gave you homework that forced you to learn the basics of how to use the programming tools. Because of time constraints, we did not do that with this project.

Hopefully, all of the mathematics of 3D programming were explained in the discussions in class. The OpenGL book does a good job at explaining how these ideas are mapped to the specific code that you need to write.

I recommend that you try something simple to make sure that you have all of the pieces. For example, try writing a simple program that displays a simple 3D object (like a cube) hovering over a "floor." Use this program to try out the basic features that you need: setting up material properties and lighting, providing the user with control of the viewpoint, and moving objects around. To get started, look at the example programs provided for the programming assignments.

Making the Track

You must allow the user to specify a train track that is a curve along the floor. You must draw the track along the ground, as well as drawing the ground as a flat plane. (and advanced feature would be to have non-flat ground).

The simplest thing would be to allow the user to place a series of points along the floor and to create an interpolating cubic spline (e.g. a cardinal spline) between the points. You should use a curve that is at least C(1) continuous. (If you're stuck, you can make the track out of straight segments, however, your train will look silly when it makes abrupt turns! )

You might want to give a more controllable curve (like a Bezier and allow the user to control the tangents). Or, you might want to make tracks that are C(2) continuous since they will lead to better train motions. The sample solution uses Cardinal splines as well as periodic, uniform, cubic B-Splines.

Specifying the track is actually a 2D problem. It is probably easier to create a 2D user interface than it is to create a 3D user interface. This is totally acceptable. The easiest user interface would force the user to type coordinate points in.

A non-graphical interface (e.g. requiring the user to type in the coordinates of the points) is clearly less desirable than one that allows the user to drag points around. However, it is more important to make sure you can make a train move around the track than to have a nice interface.

The track should be a loop, always.

User Interfaces in 3D

Controlling things interactively in 3D is a very hard problem. Especially given that your only input device is a 2D pointer (the mouse). (well, there's the keyboard too).

As a starting point, you probably want to focus on giving the user control of a bunch of points in space that will serve as the control points for the curve. This will let you work on the 3D interface aspects and the curve aspects independently.

The most basic user interface would force the user to type in all coordinates. While this is undesireable, it is probably better for you to implement this first, get the other parts of the assignment working (drawing the track and train), and then improve your interface as time permits.

Another strategy for the interface is to treat it as a 2D problem. Give the user a "top" view of the "world," and allow them to do things in 2D. This will be completely suffificient until you get to roller coasters.

Advanced interfaces might allow the user to sketch the curve of the track. There were some cool ideas on curve sketching in 3D - let me know if you want more info on this.

The Train

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.

A more advanced train would be made out of several cars that remain attached as the train moves around the track. In this case, each car must point in the correct direction. This is actually kindof tricky to implement, but is a good challenge for the mathematically inclined. (you need to figure out an arc-length parameterization for the curve).

The most basic train would be drawn as a rectangular box. Hopefully, you will choose to make something nicer looking.

Drawing your tracks as tracks (e.g. with parallel rails and planks going across) would be very cool, but is a challenging advanced feature (since you need to figure out how to make parallel curves and to make the cross pieces be evenly spaced).


You must allow the user to animate the train driving along the track.

Note: probably, your track will have different parameterizations as the train moves along it. A basic implementation would have the train moving with a constant velocity in parameter space. A more advanced implementation would give the user the option of having the train move with a constant velocity in its position. If you implement constant velocity motion, you should allow the user to switch this on and off to emphasize the difference.

You must give the user the option of either viewing the "whole world" or viewing out the front of the train. If the user is looking out the front of the train, and the train is being animated, the user should see what it would look like to ride the train.

The World

You should allow the user to place objects other than the train tracks into your world. Placing colored cubes in the world is OK. Placing more complicated objects would make your project more interesting. The goal is to allow for some scenery to view as the train drives along.


You should use lighting to make your world look nicer.

One desireable advanced feature would be to allow the user to position a light, and to use this light not only for object lighting but also to position hack shadows (as will be described in class).


You must allow the user to switch between a view out the front of the train and a "birds-eye" view of the whole world (required for editing). For the latter, you should give the user some kind of control over their viewpoint, such as a virtual trackball.

You may also want to provide 2D (orthographic or plan) views of the world, such as a top view. These views are convenient for user interfaces.

Roller Coasters

A Roller Coaster is simply a train in which the track isn't flat. This is probably simple for you to do if you implemented your train correctly.

To make a good roller coaster (e.g. for a more advanced project):

You need to have a good way to determine which way is up for the rider of the roller coaster (e.g. you know 1 direction in the Frenet frame, so you need to pick a twist around the forward axis). You might give the user the ability to specify the twist along the track (as a parameter that gets interpolated), or simply compute it in some reasonable way.

Roller coasters do not go at constant velocities - they speed up and slow down. Simulating this (in a simple way) isn't that difficult, and would make for a good advanced feature. 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.

What it looks like

A basic assignment might just draw simple lines and boxes. I am hoping that you'll put some effort into making it look nicer, but creating more interesting objects in your world, or other things to make your world more attractive, ...

The Sample Answer

Two programs you can play with are in p:/course/cs559-gleicher/public/bin. My train program (from 1999) and Rob Iverson's train program (also from 1999).

My assignment fails some of the basic criteria (you can't make scenery), and does only very simple drawing. However, it should give you some ideas.

However, it does let you see different curve types for the track, do the different kinds of viewing, and animate the "train" (including riding it). I implemented "constant velocity" using the tangent magnitude approximation described in class. You can move the light around, and see the hacked shadows move around.

When you drag a point, it moves parallel to the ground plane. If you hold down the control key, you drag the point perpendicular to the ground plane (up and down).

Rob's train program is much better - its really above and beyond the call of duty. It has just about every advanced feature, and then some. For a completely absurd assignment, check out RocketCoaster, but remember, it was done by two students with an excess of time on their hands.

Rob Iverson's Train Program (from 1999)

So what do I need to do?
(and what grade will I get?)


Signs of Life
  • You have a world
  • You can manipulate points in the world
  • You can control viewing
  • You have a track that is a loop
  • You can make the train go around the track
  • You have a train view
  • The train is oriented correctly in 2D
  • You have scenery
  • You support C1 and C2 curves
  • You have a 3D user interface
  • Your train is oriented correctly in 3D
  • You have constant velocity
  • You have conservation of momentumn (easy once you have constant velocity, actually)
  • You have a nice looking train
  • You have rail ties and/or parallel rails (the latter is difficult)
Awesome Features
  • Your train is really correctly oriented in 3D (e.g. you can do a loop)
  • You have a sketch-based interface
  • You can save and load tracks
  • You have people on your roller coaster
  • You have done something so cool that I can't even imagine it before I see it.


But What Grade will I get?

It's hard to say beforehand, because we do adjust the grading depending on how people do. To get a B, you probably have to have most of the "Better" features. To get an "A" you should have most of the Advanced features.

What you will turn in...

Into your handin directory, you will need to provide the complete source code, project files, and workspace files. You will need to provide a README.txt file explaining what each file you hand in is. You will need to provide a text file called "DOCUMENTATION.TXT" that can serve as a user manual for your program, describing which features you implemented, and how they are accessed.

We may ask you to answer questions about your project. If we do this, we'll provide them later.