Subscribe Bookmark
Craige_Hales

Staff

Joined:

Mar 21, 2013

Tile JSL part 3

8428_x000008.gif

Using the kites and darts from part 2, make a 3D surface. Some of the Scene3D code was borrowed from some of the examples that ship with JMP. This JSL was written to make the video clip. Buried in it are some scaling and animation controlling values, tweaked to make the video just right. There is also a path to a directory on the desktop that will be filled with numbered bitmaps. Part 4 will explain how to use other tools outside of JMP to assemble the bitmaps into a video.

This code expects the variables from part 2 to still be in JMP's memory. 

scale = 50;//50;
sbscale = .5;//2;//.4;//1;
///////////////// 3D ///////////////////
fn = Function( {x, y},
  x /= scale;
  y /= scale;
  (((1 + Cos( -Pi() + fraction * 2 * Pi() )) / 2) ^ .95) * scale * Sin( 100 * fraction * Pi() + Sqrt( x * x + y * y ) );
); // the function to plot.  the sheet color assumes the result is between -1 and +1.
addvertex = Function( {a, b, c},
  If(
  af < 100, b[3] += Random Normal( 0, If( af <= 0, .1, 1 / Sqrt( 100 * af ) ) ),
  af > nframes, b[3] += Random Normal( 0, .01 * Sqrt( af - nframes ) ),
  0
  );
    // calculate the normal; this is the vector cross product of the two lines leaving b to a or c
  qx = a[1] - b[1];
  qy = a[2] - b[2];
  qz = a[3] - b[3];
  px = c[1] - b[1];
  py = c[2] - b[2];
  pz = c[3] - b[3];
  nx = py * qz - pz * qy;
  ny = pz * qx - px * qz;
  nz = px * qy - py * qx;
    // normalize the normal vector (sheet<<enable(NORMALIZE) could be used, but normalizes every frame)
  len = Sqrt( nx * nx + ny * ny + nz * nz );
  nx /= len;
  ny /= len;
  nz /= len;
  sheet << Normal( nx, ny, nz ); // the normal at each vertex could be averaged to make the surface more smooth
  sheet << Vertex( b[1], b[2], b[3] );
);
addpoly = Function( {verts}, //show(verts);stop();
  verts = verts |/ (// add a row of z-values to the row of x and row of y
  fn( verts[1, 1], verts[2, 1] ) || fn( verts[1, 2], verts[2, 2] ) || fn( verts[1, 3], verts[2, 3] ) || fn( verts[1, 4], verts[2, 4] ));
  addvertex( verts[0, 1] / scale, verts[0, 2] / scale, verts[0, 3] / scale );
  addvertex( verts[0, 2] / scale, verts[0, 3] / scale, verts[0, 4] / scale );
  addvertex( verts[0, 3] / scale, verts[0, 4] / scale, verts[0, 1] / scale );
  addvertex( verts[0, 4] / scale, verts[0, 1] / scale, verts[0, 2] / scale );
);
nFrames = 90 * 25;//2250 frames for 90 seconds
xangle = 0;
yangle = 0;
zangle = 0;
changeangle = Function( {frame},
  frame = 2 * Pi() * frame / nFrames;
  xangle = 400 * ((1 + Cos( Pi() + frame )) / 2);
  yangle = 20 * ((1 + Cos( Pi() + frame )) / 2);
  zangle = 900 * ((1 + Cos( frame )) / 2);
);
justbluepos = Function( {x, y, fraction}, 10000 ); // out of site
dropinpos = Function( {x, y, fraction}, (1 - fraction) * Random Normal( 10 ) );
scene = Scene Box( 1920 * sbscale, 1080 * sbscale );
scene << background color( RGB Color( 0, 0, .5 ) );
New Window( "Sheet", scene );
picno = 0;
picdir = "$desktop/picdir/x";
For( af = -130, af <= nFrames + 200, af = af + 1, // a loop to rotate the display list; a gets scaled below, so its not really in degrees
  fraction = (af - 1) / nFrames;
  sheet = Scene Display List(); // creates a display list, which will hold a list of commands
  sheet << Material( Front_and_Back, Specular, 1, 1, 1, 1 );
  sheet << Material( Front_and_Back, Shininess, 127 );
  sheet << Material( Front_and_Back, Ambient_and_Diffuse, 1, 1, 1, 1 );
  sheet << Enable( Color_Material ); // allows the color commands to update the material property
  sheet << Begin( QUADS ); // not a quad strip
  sheet << Color( HLS Color( .05, .6, .7 ) );
  For( i = 1, i <= nkite, i++,
  addpoly( kites[i] )
  );
  sheet << Color( HLS Color( .55, .4, .95 ) );
  For( i = 1, i <= ndart, i++,
  addpoly( darts[i] )
  );
  sheet << End();  // ends the quads
  sheet << Disable( Color_Material );
  scene << Clear;
  scene << Light( Light0, Position, -200, -200, 100, 1 );
  scene << Light( Light0, DIFFUSE, .8, .8, .8, 1 );
  scene << Light( Light0, SPECULAR, .5, .5, .5, 1 );
  scene << Enable( Lighting ); // any surfaces rendered after this will respond to the light
  scene << Enable( Light0 ); // turn on one of the eight available lights (0...7)
  scene << LightModel( LIGHT_MODEL_TWO_SIDE, 1 );
  scene << LightModel( LIGHT_MODEL_AMBIENT, .6, .6, .6, 1 );
  //scene << FrontFace( CW ); // whoops!  I must have defined the polygons backwards in the normal calculation.  this reverses the definition.
  scene << ShadeModel( SMOOTH );
  scene << Perspective( 45, 1, 100 );
  scene << Translate( 0.0, 0.0, If( af >= nframes, ((nframes - af) / 10) - 15, af <= 0, (af / 10) - 15, -15 ) );
  scene << enable( FOG );
  scene << fog( FOG_END, 25 ); // fog ends 3 units away, 1 beyond origin
  scene << fog( FOG_START, 20 ); // fog begins
  scene << fog( FOG_MODE, LINEAR );
  changeangle( af );//show(zangle);
  scene << Rotate( xangle, 1.0, 0.0, 0.0 ); // spin around the X axis
  scene << Rotate( yangle, 0.0, 1.0, 0.0 ); // and the Y axis
  scene << Rotate( zangle, 0.0, 0.0, 1.0 ); // and the Z axis
  scene << arcball( sheet, 8 );
  scene << Update;
  Wait( 0 );
 // scene << savepicture( picdir || Right( Char( picno++ ), 6, "0" ) || ".png" );
);

post pointing to video 

Article Tags