Page 3: The Train: Assignment

CS559 Spring 2021 Sample Solution - Workbook 6

Written by CS559 course staff

You can try out the example solutions here. The interesting code is on page 3.

The last page introduced the train assignment. This page will give you the details, and then you can edit 06-03-01.js and 06-03-01.html to make your own train.

We have provided a UI that gives you a Canvas window, the ability to manipulate a set of points in that window and a slider/run button that allows you to move and animate the train by controlling a parameter. You may add additional buttons to the page in order to switch features on and off, or add sliders.

Your job is to (1) create a track that goes through these points (an interpolating curve) and (2) make a train that goes around that track. There are bonus points available for drawing the track nicely, and having a train that moves in more complex ways. You are encouraged to try to make things look nice, but the focus of this assignment is on curves. The grading and requirements focus on elements that demonstrate your knowledge of using curves.

Note: you must edit the text box (at the end of the page) documenting what features you have implemented.

We recommend that you implement the requirements in the order below. The scoring is designed so that the main features get the majority of the points. Fancier features (that are more challenging) are worth fewer points (bonus points, to get you to an A or A+).

  1. Create a Cardinal Cubic Spline that passes through the control points. You should do this by converting the cardinal spline to a Bézier curve so that you can draw the curve as a Canvas path with Bézier pieces (rather than, say, approximating it as a sequence of lines).

    • Note: even if you add a fancier track in a later step, your interface should have a “simple” checkbox that draws the track as a single, solid Canvas “stroke.”
    • Note: you must draw the curve using Canvas cubic Bézier segments (the bezierCurveTo function), with one segment for each of the segments of the cardinal spline. Also, in the event that you add curve types beyond Cardinal Cubic Splines (bonus points below), you should still support Cardinal splines.
  2. Create a train that goes around the track. Note that the slider goes from 0 to n (where n is the number of control points). The position of the train should be the value of this parameter on the track (so at zero, it is at the beginning of the first Bézier segment, at 1.5 it is on the second segment between the beginning and end, etc.). If you move the slider (or click the run button), the train should go around the track. You may choose how to draw the train, but the shape must have an obvious front and be rigid (not stretch as the train goes around the track). A rectangle and triangle would do. Of course, feel free to make something fancier. The train’s position should always be on the track.

  3. Have the train point in the right direction as it goes around the track. Its orientation should be aligned with the tangent vector of the curve at the current position.

  4. Set things so that the default track (i.e., what you seen when the page first loads) is in a configuration where it will be obvious that we do not have an arc-length parameterization. Since the slider moves at a constant rate (approximately, since it depends on computer speed), the train will speed up and slow down as it goes around the track. (The slider moves at a constant rate in parameter value, so without an arc-length parameterization, it won’t be a constant rate in position.)

The train is on the page 06-03-01.html. The html is simple. The guts are in 06-03-01.js. You can do the basic assignment by simply improving the draw function.

Note: we put the box on this page, but you probably want to look at it on its own as 06-03-01.html with the code in 06-03-01.js.

The code for the first three example solutions are in 06-03-01-01.js, 06-03-01.js, and 06-03-01-02.js

You must list the features you have implemented in the text file 06-03-01.txt:

Advanced Features (for bonus points)

Add fancier features to earn more points. You can score a maximum of 100 points in total on this assignment.

  1. Create an arc-length parameterization of the curve. This will be essential for many of the next steps. Use the checkbox in the UI to switch between the normal parameterization and the arc-length one. When switched on, the train should still go around the track as the slider goes from 0 to N, it should just do so at constant apparent speed (assuming the frame rate is constant).

  2. Make “rail ties” (the beams that go across railroad tracks). These should be regularly spaced and be perpendicular to the track. If you don’t have arc-length parameterization, then making regularly spaced rail ties will be difficult. On the other hand, if you have correctly working arc-length parameterization and you switch it off, the rails will look wrong - which is a great way to test. You should make rail ties by drawing small lines or boxes perpendicular to the track. You do not get credit for this feature by drawing a single curve with a fancy style (say, using thick dashed lines).

  3. Make “parallel” rails (two rails for the track). The rails should always be the same distance apart (the should be “offset curves” from the main curve). Note that you cannot just move the control points of the Bézier segments. To draw these, you probably need to break the curve into small pieces. Note: you need to have a switch in the UI that allows you to show the “simple” curve as well (see #1 above). You will not get points for this feature if you achieve the parallel rails by drawing a single curve with a fancy style (such as drawing a thick curve with a thin curve over it).

  4. Let the train have multiple cars. The cars need to stay a fixed distance apart (this requires arc-length parameterization). Note: the common way to implement the train is to put the center of the train (or each car) on the track; this means that the ends of the cars are off of the track and may not attach perfectly. Your cars must each have different appearances.

  5. Give the train / cars “trucked” wheels. The common way to implement the train is to attach the center of the train to the track and turn the body accordingly. Real trains have their wheels on the track, and the wheels turn relative to the car/train body (see the Wikipedia article, specifically this diagram). You could compute locations and orientations for each set of wheels, and then attach the train cars to the wheels. You need arc-length parameterization so that the train doesn’t stretch. This is only recommended for train geeks.

  6. Add a slider that controls the tension of the cardinal spline.

  7. Add support for uniform cubic B-Splines . Note: if you implement this, you still need to have interpolating cardinal splines, so you must add a checkbox that switches between the cardinal splines and the B-Splines. While we didn’t really discuss B-Splines in the workbook, you should be able to figure them out from the book. Hint: it’s just a different basis matrix.

  8. Make the train emit smoke. This could have the form of simple gray circles that move away from the train and then dissipate (like the fireworks in an old workbook).

  9. Make things look nicer. Have a nicer looking train, a nicer looking track, and/or “scenery” (so the area around the train tracks is not a boring white space). We leave it to you to be creative. These bonus points are at the grader’s discretion.

  10. If you make scenery, you can get additional points by making it “adapt” to the track. For example, if you put a building or tree near the tracks, it should be moved if you move the track (the train track shouldn’t go through the scenery - the scenery should move out of the way).

How many points can you earn?

There are 29 bonus points possible, but we will only allow you to earn 20. This still means you can score 105 on this workbook (there are points on page 1). 95 is an A+.

Box 06-03-01 Rubric (94 points total)
Points (65):
Box 06-03-01
15 pt
Drawing the track as a simple curve (cardinal spline) that interpolates the control points
Box 06-03-01
15 pt
Train goes around the track
Box 06-03-01
10 pt
The interface still works (the track can be moved and the run slider works, even while the train is in motion)
Box 06-03-01
5 pt
Train has a front
Box 06-03-01
10 pt
Train points in the right direction as it goes around the track
Box 06-03-01
5 pt
Track configuration shows off arc length (train should speed up and slow down if arc length parameterization is turned off)
Box 06-03-01
5 pt
Text file explains features
Bonus points (29):
Box 06-03-01
5 pt
Arc Length parameterization (train goes at a relatively constant speed as it goes around the track, no matter what the control point spacing is). You must add a checkbox to turn this on and off. This one is hard, but it enables several of the other things, so it is actually worth a lot
Box 06-03-01
2 pt
Rail Ties drawn perpendicular to track
Box 06-03-01
2 pt
Rail Ties drawn with correct spacing (this is simple once you have arc-length
Box 06-03-01
3 pt
Parallel rails
Box 06-03-01
5 pt
Multiple cars (requires keeping the cars a fixed distance apart)
Box 06-03-01
3 pt
Trucked wheels (requires keeping the pairs of wheels the correct distance apart and on the track, and having the train car positioned appropriately - this is only for people who are into trains and appreciate this detail)
Box 06-03-01
1 pt
Slider to control tension
Box 06-03-01
2 pt
Switchable B-Splines
Box 06-03-01
2 pt
Smoke
Box 06-03-01
1 pt
Scenery
Box 06-03-01
1 pt
Scenery adapts to the track
Box 06-03-01
1 pt
Artistic merit: nice looking train
Box 06-03-01
1 pt
Artistic merit: nice looking track

Some Hints

  1. Remember the connection between Bézier cubics and Hermite cubics, and between cardinal splines and Hermite cubics. You may not need the parametric functions for Cardinals in order to convert them to Béziers. Once they are converted to Béziers, Canvas can draw them well.
  2. You do need to evaluate either the cardinal spline, or the Béziers that you converted them to, to figure out where the train is.
  3. You need to compute the derivatives of the spline to know what the tangent direction is. That will help you orient the train, as well as orient the rail ties (should you try to do them).
  4. Implement arc-length parameterization by using the table-based approach given in the previous workbook. We used 10 steps per cubic segment.
  5. Implement parallel rails by connecting points along the rail ties (but you may want to sample more finely). You will want to draw them as many small line segments. It turns out that displacing a Bezier curve in the normal direction does not lead to another Bezier curve - it’s a more complex shape.
  6. Play with my demo ( discussed on the previous page). You can look at last year’s gallery for inspiration (there are some very cool trains, you need to pick Workbook 6). You can see 3D trains in some of the Workbook 12 examples.
  7. The UI uses shift-click to add a point and ctrl-click to remove a point.

The Train!

That ends this week’s workbook. The train is probably enough work for one week.