CSC418/2504F, Fall 1999: Assignment 3 FAQ

Q: I have trouble understanding the example code. Where are the selected key frames specified? For the given example, how many key frames are selected?

A: In the example code, there are 5 key frames. They are set at t=0, 1, 1.5, 2, and 3. For each key frame, all variables or degrees of freedom are specified. Hence you need 4 cubic segments per variable, to interpolate between the key frames.

Q: In the

 typedef struct{
  double a[MAXDOF][4];
  double length;
} spline;
I don't understand the "length" field. What is this field for?

A: The array a contains the 4 coefficients of the cubic curve that is interpolating one of the degrees of freedom, from one keyframe to the next.

The length field specifies the time between the two keyframes. Keyframes are not necessarily equally far apart, in time.

Q: What does "MAXSPLINES" mean? Does this mean 4 piecewise curves?

A: Yes, that's exactly what it means. In the sample code, there are 5 keyframes, and 4 cubic curves between the keyframes. You will probably have more than 5 keyframes, though.

Q: When will init_splines() be called except in main?

A: Call it just once, in main.

Q: In question 1, how can I plot the basis functions?

A: On unix, you can use gnuplot. Run gnuplot on a cdf machine, and then tell it what to do. Here's a gnuplot script which will plot sin(x) and cos(x) on your screen:

set xrange[0:6]
set xlabel x
set ylabel "sine and cosine"
set title "Plot of Sine and Cosine"
plot sin(x) title "sine" with lines,\
     cos(x) title "cosine" with lines
and if the file sc.plot has the following contents:
set term pbm
set xrange[0:6]
set xlabel x
set ylabel "sine and cosine"
set title "Plot of Sine and Cosine"
plot sin(x) title "sine" with lines,\
     cos(x) title "cosine" with lines
then the following line will store the plot in a PBM file, which can be converted to GIF with xv:
gnuplot < sc.plot > sc.pbm

Q: I do not know how to record frames in PPM files.

A: To record a sequence of frames, press r to turn on recording, then animate the frames, either:

  1. automatically by pressing space, < or >,
  2. or one frame at a time, by pressing + or -.

Q: Where can I find sample animations?

A: Here are animations from Spring 1997.

Q: For refraction, we calculate the angle of refraction via the indices of refraction in the incident and refracting materials (from text). How do we account for this in our ray tracer -- do we store a value with each object stating its index? or is there a better way?

A: Yes, each transparent object must have an index of refraction associated with it. Air has n=1, and glass has n=1.5, roughly.

When computing a refracted ray, you need to know if the ray is coming INTO the glass object or OUT of it. On simple way to test if a ray is coming OUT to check if the ray and the normal point in the "same" direction (their dot product is positive).

Also, you need to be careful that numerical precision doesn't cause the reflected and refracted rays to intersect the object they were spawned from. When you compute t in (x,y,z) = P + tV, reject intersections with t < epsilon.

Q: Also, how should diffuse surfaces be handled; i.e. how many rays should be reflected from the surface?

In practice, we can't treat diffuse surfaces correctly by sampling all the scattering directions. It's horribly expensive. Better to just use the local illumination model there.

Q: also, what is a good cut off to stop "bouncing" around a pixel ray (i.e. at what depth of the tree is a good spot to cut off? )

Q: A depth of 3 or so looks ok. It allows for one refracted ray into, and out of, a transparent object.

Q: anim.cpp CRASHES!

A: The function nextFrame has a bug, which causes the keyframe counter to overflow the array.

Where it used to read:

  tStart = 0.0;
  for (i=0; i<MAXSPLINES; i++) {
    if (tStart <= t && t < tStart +dofHistory[i].len) {
it should read
  /*
   * ADD These two lines
   */
  if (t > tMax) t = tMax;
  if (t < 0.0)  t = 0.0;

  /*
   * ADD This line
   */
  iSpline = 0;
  tStart = 0.0;
  for (i=0; i<MAXSPLINES; i++) {
    /*
     * CHANGE this line.
     */
    if (tStart < t && t <= tStart +dofHistory[i].len) {