Notes for Tuesday March 31 class -- computing normals and intro to splines

 

Computing the surface normal

Here is the new version of createTriangleMesh that we implemented in class:
let createTriangleMesh = (uvToVertex, nCols, nRows, data) => {
   let mesh = [];
   let appendVertex = (f, u, v, data) => {
      v = Math.min(v, 1 - 2/1000);
      let p = f(u, v, data);
      if (p) {
         for (let n = 0 ; n < p.length ; n++)
            mesh.push(p[n]);

         // IF NO SURFACE NORMAL WAS PRODUCED BY uvToVertex

         if (p.length == 3) {

            // THEN COMPUTE TWO TANGENT VECTORS

            let pu = f(u + 1/1000, v, data);
            let pv = f(u, v + 1/1000, data);
            let du = [], dv = [];
            for (let i = 0 ; i < 3 ; i++) {
               du[i] = pu[i] - p[i];
               dv[i] = pv[i] - p[i];
            }

            // USE THOSE VECTORS TO COMPUTE AND ADD THE NORMAL

            let n = normalize(cross(du, dv));
            mesh.push(n[0], n[1], n[2], u, v);
         }
      }
   }
   for (let row = 0 ; row < nRows ; row++) {
      let v0 =  row    / nRows,
          v1 = (row+1) / nRows;
      for (let col = 0 ; col <= nCols ; col++) {
         let u = col / nCols;
         appendVertex(uvToVertex, u, v0, data);
         appendVertex(uvToVertex, u, v1, data);
      }
      appendVertex(uvToVertex, 1, v1, data);
      appendVertex(uvToVertex, 0, v1, data);
   }
   return mesh;
}
Here is how we incorporated our twisty torus into our code base:
// RETURN ONLY X,Y,Z. createTriangleMesh() WILL COMPUTE THE NORMAL.

let uvToTwistyTorus = (u,v) =>
   [ Math.cos(2 * Math.PI * u) * (1 + .4 * Math.cos(2 * Math.PI * v)),
     Math.sin(2 * Math.PI * u) * (1 + .4 * Math.cos(2 * Math.PI * v)),
     .2 * Math.sin(2 * Math.PI * (2 * u + v) + time) ];
In index.html we need to make time a global variable:
let time = 0;

function animate() {

   // VARY THE ROTATION RATE DEPENDING ON THE SLIDER VALUE.

   time = (Date.now() - startTime) / 1000;
   ...

Also, inside the animate() function, we redefine the shape of the twisty torus at every animation frame:
test.child(0).shape = createTriangleMesh(uvToTwistyTorus, 30, 30);

Introduction to splines
Given four key points A, B, C and D, a Bezier spline is defined by multiple levels of linear interpolation.

We can join multiple Bezier splines end-to-end, in order to create smooth curves of arbitrary complexity.

Recalling that we the mix() function is defined as:

mix(a,b,t) => (1-t) * a + t * b
the Bezier curve is defined by:
Bezier(A,B,C,D, t) => mix( mix( mix(A, B, t), mix(B, C, t), t), mix( mix(B, C, t), mix(C, D, t), t), t)

To the right you can see two Bezier spline segments joined end to end. The first has keys A1, B1, C1, D1, and the second has keys A2, B2, C2, D2.

The condition for the two spline segments are touch each other is that D1 == A2.

The condition that the two spline segments have the same slope where they join is that the line segment C1→D1→ is co-linear with the line segment A2→B2→. The