void WavefrontDisplayDevice::tristrip(int numverts, const float * cnv, int numstrips, const int *vertsperstrip, const int *facets) { int i, strip, t, v = 0; int stripaddr[2][3] = { {0, 1, 2}, {1, 0, 2} }; float vec1[3]; float norm1[3]; const float onethird = (1.0f / 3.0f); // write out list of vertices and normals for (i=0; i<numverts; i++) { int idx = i*10; (transMat.top()).multpoint3d(cnv + idx + 7, vec1); fprintf(outfile, "v %f %f %f\n", vec1[0], vec1[1], vec1[2]); (transMat.top()).multnorm3d(cnv + idx + 4, norm1); fprintf(outfile, "vn %f %f %f\n", norm1[0], norm1[1], norm1[2]); } // render triangle strips one triangle at a time // triangle winding order is: // v0, v1, v2, then v2, v1, v3, then v2, v3, v4, etc. // loop over all of the triangle strips for (strip=0; strip < numstrips; strip++) { // loop over all triangles in this triangle strip for (t = 0; t < (vertsperstrip[strip] - 2); t++) { // render one triangle, using lookup table to fix winding order int v0 = facets[v + (stripaddr[t & 0x01][0])]; int v1 = facets[v + (stripaddr[t & 0x01][1])]; int v2 = facets[v + (stripaddr[t & 0x01][2])]; #ifdef VMDGENMTLFILE // The Wavefront format does not allow per-vertex colors/materials, // so we use per-facet coloring, averaging the three vertex colors and // selecting the closest color from the VMD color table. const float *c1 = cnv + v0 * 10; const float *c2 = cnv + v1 * 10; const float *c3 = cnv + v2 * 10; float r, g, b; r = (c1[0] + c2[0] + c3[0]) * onethird; // average three vertex colors g = (c1[1] + c2[1] + c3[1]) * onethird; b = (c1[2] + c2[2] + c3[2]) * onethird; int cindex = nearest_index(r, g, b); write_cindexmaterial(cindex, materialIndex); #endif // use negative relative indices required for wavefront obj format v0 -= numverts; v1 -= numverts; v2 -= numverts; fprintf(outfile, "f %d//%d %d//%d %d//%d\n", v0, v0, v1, v1, v2, v2); v++; // move on to next vertex } v+=2; // last two vertices are already used by last triangle } }
// use an efficient mesh primitve rather than individual triangles // when possible. void WavefrontDisplayDevice::trimesh_c4n3v3(int numverts, float * cnv, int numfacets, int * facets) { int i; float vec1[3]; float norm1[3]; const float onethird = (1.0f / 3.0f); // write out list of vertices and normals for (i=0; i<numverts; i++) { int idx = i*10; (transMat.top()).multpoint3d(cnv + idx + 7, vec1); fprintf(outfile, "v %f %f %f\n", vec1[0], vec1[1], vec1[2]); (transMat.top()).multnorm3d(cnv + idx + 4, norm1); fprintf(outfile, "vn %f %f %f\n", norm1[0], norm1[1], norm1[2]); } // loop over all of the facets in the mesh for (i=0; i<numfacets*3; i+=3) { int v0 = facets[i ]; int v1 = facets[i + 1]; int v2 = facets[i + 2]; #ifdef VMDGENMTLFILE // The Wavefront format does not allow per-vertex colors/materials, // so we use per-facet coloring, averaging the three vertex colors and // selecting the closest color from the VMD color table. const float *c1 = cnv + v0 * 10; const float *c2 = cnv + v1 * 10; const float *c3 = cnv + v2 * 10; float r, g, b; r = (c1[0] + c2[0] + c3[0]) * onethird; // average three vertex colors g = (c1[1] + c2[1] + c3[1]) * onethird; b = (c1[2] + c2[2] + c3[2]) * onethird; int cindex = nearest_index(r, g, b); write_cindexmaterial(cindex, materialIndex); #endif // use negative relative indices required for wavefront obj format v0 -= numverts; v1 -= numverts; v2 -= numverts; fprintf(outfile, "f %d//%d %d//%d %d//%d\n", v0, v0, v1, v1, v2, v2); } }
// draw a sphere array void TachyonDisplayDevice::sphere_array(int spnum, int spres, float *centers, float *radii, float *colors) { float vec[3]; float radius; int i, ind; ind = 0; for (i=0; i<spnum; i++) { // transform the world coordinates (transMat.top()).multpoint3d(¢ers[ind], vec); radius = scale_radius(radii[i]); // draw the sphere fprintf(outfile, "Sphere \n"); // sphere fprintf(outfile, " Center %g %g %g \n ", vec[0], vec[1], -vec[2]); fprintf(outfile, " Rad %g \n", radius ); write_colormaterial(&colors[ind], materialIndex); ind += 3; // next sphere } // set final color state after array has been drawn ind=(spnum-1)*3; super_set_color(nearest_index(colors[ind], colors[ind+1], colors[ind+2])); }
void PSDisplayDevice::render(const VMDDisplayList *display_list) { DepthSortObject depth_obj; char *cmd_ptr; int draw; int tok; int nc; float a[3], b[3], c[3], d[3]; float cent[3]; float r; Matrix4 ident; float textsize=1.0f; // default text size // first we want to clear the transformation matrix stack while (transMat.num()) transMat.pop(); // push on the identity matrix transMat.push(ident); // load the display list's transformation matrix super_multmatrix(display_list->mat.mat); // Now we need to calculate the normalized position of the light // so we can compute angles of surfaces to that light for shading norm_light[0] = lightState[0].pos[0]; norm_light[1] = lightState[0].pos[1]; norm_light[2] = lightState[0].pos[2]; if (norm_light[0] || norm_light[1] || norm_light[2]) vec_normalize(norm_light); // Computer periodic images ResizeArray<Matrix4> pbcImages; find_pbc_images(display_list, pbcImages); int nimages = pbcImages.num(); for (int pbcimage = 0; pbcimage < nimages; pbcimage++) { transMat.dup(); super_multmatrix(pbcImages[pbcimage].mat); // Loop through the display list and add each object to our // depth-sort list for final rendering. VMDDisplayList::VMDLinkIter cmditer; display_list->first(&cmditer); while ((tok = display_list->next(&cmditer, cmd_ptr)) != DLASTCOMMAND) { draw = 0; nc = -1; switch (tok) { case DPOINT: // allocate memory depth_obj.points = (float *) malloc(sizeof(float) * 2); if (!depth_obj.points) { // memory error if (!memerror) { memerror = 1; msgErr << "PSDisplayDevice: Out of memory. Some " << "objects were not drawn." << sendmsg; } break; } // copy data depth_obj.npoints = 1; depth_obj.color = colorIndex; (transMat.top()).multpoint3d(((DispCmdPoint *) cmd_ptr)->pos, a); memcpy(depth_obj.points, a, sizeof(float) * 2); // compute the distance to the eye depth_obj.dist = compute_dist(a); // valid object to depth sort draw = 1; break; case DSPHERE: { (transMat.top()).multpoint3d(((DispCmdSphere *) cmd_ptr)->pos_r, c); r = scale_radius(((DispCmdSphere *) cmd_ptr)->pos_r[3]); sphere_approx(c, r); break; } case DSPHEREARRAY: { DispCmdSphereArray *sa = (DispCmdSphereArray *) cmd_ptr; int cIndex, rIndex; // cIndex: index of colors & centers // rIndex: index of radii. float * centers; float * radii; float * colors; sa->getpointers(centers, radii, colors); set_sphere_res(sa->sphereres); for (cIndex = 0, rIndex=0; rIndex < sa->numspheres; cIndex+=3, rIndex++) { colorIndex = nearest_index(colors[cIndex], colors[cIndex+1], colors[cIndex+2]); (transMat.top()).multpoint3d(¢ers[cIndex] , c); r = scale_radius(radii[rIndex]); sphere_approx(c, r); } break; } case DLINE: // check for zero-length line (degenerate) if (!memcmp(((DispCmdLine *) cmd_ptr)->pos1, ((DispCmdLine *) cmd_ptr)->pos2, sizeof(float) * 3)) { // degenerate line break; } // allocate memory depth_obj.points = (float *) malloc(sizeof(float) * 4); if (!depth_obj.points) { // memory error if (!memerror) { memerror = 1; msgErr << "PSDisplayDevice: Out of memory. Some " << "objects were not drawn." << sendmsg; } break; } // copy data depth_obj.npoints = 2; depth_obj.color = colorIndex; (transMat.top()).multpoint3d(((DispCmdLine *) cmd_ptr)->pos1, a); (transMat.top()).multpoint3d(((DispCmdLine *) cmd_ptr)->pos2, b); memcpy(depth_obj.points, a, sizeof(float) * 2); memcpy(&depth_obj.points[2], b, sizeof(float) * 2); // compute the centerpoint of the object cent[0] = (a[0] + b[0]) / 2; cent[1] = (a[1] + b[1]) / 2; cent[2] = (a[2] + b[2]) / 2; // compute the distance to the eye depth_obj.dist = compute_dist(cent); // valid object to depth sort draw = 1; break; case DLINEARRAY: { // XXX much replicated code from DLINE float *v = (float *)cmd_ptr; int nlines = (int)v[0]; v++; for (int i=0; i<nlines; i++) { // check for degenerate line if (!memcmp(v,v+3,3*sizeof(float))) break; // allocate memory depth_obj.points = (float *) malloc(sizeof(float) * 4); if (!depth_obj.points) { // memory error if (!memerror) { memerror = 1; msgErr << "PSDisplayDevice: Out of memory. Some " << "objects were not drawn." << sendmsg; } break; } // copy data depth_obj.npoints = 2; depth_obj.color = colorIndex; (transMat.top()).multpoint3d(v, a); (transMat.top()).multpoint3d(v+3, b); memcpy(depth_obj.points, a, sizeof(float) * 2); memcpy(&depth_obj.points[2], b, sizeof(float) * 2); // compute the centerpoint of the object cent[0] = (a[0] + b[0]) / 2; cent[1] = (a[1] + b[1]) / 2; cent[2] = (a[2] + b[2]) / 2; // compute the distance to the eye depth_obj.dist = compute_dist(cent); // we'll add the object here, since we have multiple objects draw = 0; memusage += sizeof(float) * 2 * depth_obj.npoints; points += depth_obj.npoints; objects++; depth_list.append(depth_obj); v += 6; } } break; case DPOLYLINEARRAY: { // XXX much replicated code from DLINE / DLINEARRAY float *v = (float *)cmd_ptr; int nverts = (int)v[0]; v++; for (int i=0; i<nverts-1; i++) { // check for degenerate line if (!memcmp(v,v+3,3*sizeof(float))) break; // allocate memory depth_obj.points = (float *) malloc(sizeof(float) * 4); if (!depth_obj.points) { // memory error if (!memerror) { memerror = 1; msgErr << "PSDisplayDevice: Out of memory. Some " << "objects were not drawn." << sendmsg; } break; } // copy data depth_obj.npoints = 2; depth_obj.color = colorIndex; (transMat.top()).multpoint3d(v, a); (transMat.top()).multpoint3d(v+3, b); memcpy(depth_obj.points, a, sizeof(float) * 2); memcpy(&depth_obj.points[2], b, sizeof(float) * 2); // compute the centerpoint of the object cent[0] = (a[0] + b[0]) / 2; cent[1] = (a[1] + b[1]) / 2; cent[2] = (a[2] + b[2]) / 2; // compute the distance to the eye depth_obj.dist = compute_dist(cent); // we'll add the object here, since we have multiple objects draw = 0; memusage += sizeof(float) * 2 * depth_obj.npoints; points += depth_obj.npoints; objects++; depth_list.append(depth_obj); v += 3; } } break; case DCYLINDER: { int res; (transMat.top()).multpoint3d((float *) cmd_ptr, a); (transMat.top()).multpoint3d(&((float *) cmd_ptr)[3], b); r = scale_radius(((float *) cmd_ptr)[6]); res = (int) ((float *) cmd_ptr)[7]; cylinder_approx(a, b, r, res, (int) ((float *) cmd_ptr)[8]); break; } case DCONE: { (transMat.top()).multpoint3d(((DispCmdCone *) cmd_ptr)->pos1, a); (transMat.top()).multpoint3d(((DispCmdCone *) cmd_ptr)->pos2, b); float r1 = scale_radius(((DispCmdCone *) cmd_ptr)->radius); float r2 = scale_radius(((DispCmdCone *) cmd_ptr)->radius2); // XXX current implementation can't draw truncated cones. if (r2 > 0.0f) { msgWarn << "PSDisplayDevice) can't draw truncated cones" << sendmsg; } cone_approx(a, b, r1); break; } case DTEXTSIZE: textsize = ((DispCmdTextSize *)cmd_ptr)->size; break; case DTEXT: { float* pos = (float *)cmd_ptr; #if 0 // thickness not implemented yet float thickness = pos[3]; // thickness is stored in 4th slot #endif char* txt = (char *)(pos+4); int txtlen = strlen(txt); // allocate memory depth_obj.points = (float *) malloc(sizeof(float) * 2); depth_obj.text = (char *) malloc(sizeof(char) * (txtlen+1)); if ( !(depth_obj.points || depth_obj.text) ) { // memory error if (!memerror) { memerror = 1; msgErr << "PSDisplayDevice: Out of memory. Some " << "objects were not drawn." << sendmsg; } break; } // copy data depth_obj.npoints = 1; depth_obj.color = colorIndex; (transMat.top()).multpoint3d(((DispCmdPoint *) cmd_ptr)->pos, a); memcpy(depth_obj.points, a, sizeof(float) * 2); strcpy(depth_obj.text , txt); // note scale factor, stored into "light_scale", so we didn't // have to add a new structure member just for this. depth_obj.light_scale = textsize * 15; // compute the distance to the eye depth_obj.dist = compute_dist(a); // valid object to depth sort draw = 1; break; } case DTRIANGLE: // check for degenerate triangle if (!memcmp(((DispCmdTriangle *) cmd_ptr)->pos1, ((DispCmdTriangle *) cmd_ptr)->pos2, sizeof(float) * 3) || !memcmp(((DispCmdTriangle *) cmd_ptr)->pos2, ((DispCmdTriangle *) cmd_ptr)->pos3, sizeof(float) * 3) || !memcmp(((DispCmdTriangle *) cmd_ptr)->pos2, ((DispCmdTriangle *) cmd_ptr)->pos3, sizeof(float) * 3)) { // degenerate triangle break; } // allocate memory depth_obj.points = (float *) malloc(sizeof(float) * 6); if (!depth_obj.points) { // memory error if (!memerror) { memerror = 1; msgErr << "PSDisplayDevice: Out of memory. Some " << "objects were not drawn." << sendmsg; } break; } // copy data depth_obj.npoints = 3; depth_obj.color = (nc >= 0) ? nc : colorIndex; (transMat.top()).multpoint3d(((DispCmdTriangle *) cmd_ptr)->pos1, a); (transMat.top()).multpoint3d(((DispCmdTriangle *) cmd_ptr)->pos2, b); (transMat.top()).multpoint3d(((DispCmdTriangle *) cmd_ptr)->pos3, c); memcpy(depth_obj.points, a, sizeof(float) * 2); memcpy(&depth_obj.points[2], b, sizeof(float) * 2); memcpy(&depth_obj.points[4], c, sizeof(float) * 2); // compute the centerpoint of the object cent[0] = (a[0] + b[0] + c[0]) / 3; cent[1] = (a[1] + b[1] + c[1]) / 3; cent[2] = (a[2] + b[2] + c[2]) / 3; // compute the distance to the eye for depth sorting depth_obj.dist = compute_dist(cent); // compute a light shading factor depth_obj.light_scale = compute_light(a, b, c); // valid object to depth sort draw = 1; break; case DTRIMESH_C4F_N3F_V3F: // call a separate routine to break up the mesh into // its component triangles decompose_mesh((DispCmdTriMesh *) cmd_ptr); break; case DTRISTRIP: // call a separate routine to break up the strip into // its component triangles decompose_tristrip((DispCmdTriStrips *) cmd_ptr); break; case DSQUARE: // check for degenerate quadrilateral if (!memcmp(((DispCmdSquare *) cmd_ptr)->pos1, ((DispCmdSquare *) cmd_ptr)->pos2, sizeof(float) * 3) || !memcmp(((DispCmdSquare *) cmd_ptr)->pos1, ((DispCmdSquare *) cmd_ptr)->pos3, sizeof(float) * 3) || !memcmp(((DispCmdSquare *) cmd_ptr)->pos1, ((DispCmdSquare *) cmd_ptr)->pos4, sizeof(float) * 3) || !memcmp(((DispCmdSquare *) cmd_ptr)->pos2, ((DispCmdSquare *) cmd_ptr)->pos3, sizeof(float) * 3) || !memcmp(((DispCmdSquare *) cmd_ptr)->pos2, ((DispCmdSquare *) cmd_ptr)->pos4, sizeof(float) * 3) || !memcmp(((DispCmdSquare *) cmd_ptr)->pos3, ((DispCmdSquare *) cmd_ptr)->pos4, sizeof(float) * 3)) { // degenerate quadrilateral break; } // allocate memory depth_obj.points = (float *) malloc(sizeof(float) * 8); if (!depth_obj.points) { // memory error if (!memerror) { memerror = 1; msgErr << "PSDisplayDevice: Out of memory. Some " << "objects were not drawn." << sendmsg; } break; } // copy data depth_obj.npoints = 4; depth_obj.color = colorIndex; (transMat.top()).multpoint3d(((DispCmdSquare *) cmd_ptr)->pos1, a); (transMat.top()).multpoint3d(((DispCmdSquare *) cmd_ptr)->pos2, b); (transMat.top()).multpoint3d(((DispCmdSquare *) cmd_ptr)->pos3, c); (transMat.top()).multpoint3d(((DispCmdSquare *) cmd_ptr)->pos4, d); memcpy(depth_obj.points, a, sizeof(float) * 2); memcpy(&depth_obj.points[2], b, sizeof(float) * 2); memcpy(&depth_obj.points[4], c, sizeof(float) * 2); memcpy(&depth_obj.points[6], d, sizeof(float) * 2); // compute the centerpoint of the object cent[0] = (a[0] + b[0] + c[0] + d[0]) / 4; cent[1] = (a[1] + b[1] + c[1] + d[1]) / 4; cent[2] = (a[2] + b[2] + c[2] + d[2]) / 4; // compute the distance to the eye for depth sorting depth_obj.dist = compute_dist(cent); // compute a light shading factor depth_obj.light_scale = compute_light(a, b, c); // valid object to depth sort draw = 1; break; case DCOLORINDEX: colorIndex = ((DispCmdColorIndex *) cmd_ptr)->color; break; case DSPHERERES: set_sphere_res(((int *) cmd_ptr)[0]); break; default: // unknown object, so just skip it break; } // if we have a valid object to add to the depth sort list if (draw && depth_obj.npoints) { memusage += sizeof(float) * 2 * depth_obj.npoints; if ( depth_obj.text ) memusage += sizeof(char) * (1+strlen(depth_obj.text)); points += depth_obj.npoints; objects++; depth_list.append(depth_obj); } depth_obj.npoints = 0; depth_obj.points = NULL; } // while (tok != DLASTCOMMAND) transMat.pop(); } // end for() [periodic images] }
void PSDisplayDevice::decompose_tristrip(DispCmdTriStrips *strip) { int s, t, v = 0; int v0, v1, v2; float r, g, b; float x[3], y[3], z[3], cent[3]; DepthSortObject depth_obj; depth_obj.npoints = 3; // lookup table for winding order const int stripaddr[2][3] = { {0, 1, 2}, {1, 0, 2} }; float *cnv; int *f; int *vertsperstrip; strip->getpointers(cnv, f, vertsperstrip); // loop over all of the triangle strips for (s = 0; s < strip->numstrips; s++) { // loop over all triangles in this triangle strip for (t = 0; t < vertsperstrip[s] - 2; t++) { v0 = f[v + (stripaddr[t & 0x01][0])] * 10; v1 = f[v + (stripaddr[t & 0x01][1])] * 10; v2 = f[v + (stripaddr[t & 0x01][2])] * 10; // allocate memory for the points depth_obj.points = (float *) malloc(6 * sizeof(float)); if (!depth_obj.points) { if (!memerror) { memerror = 1; msgErr << "PSDisplayDevice: Out of memory. Some " << "objects were not drawn." << sendmsg; } continue; } // average the three colors and use that average as the color for // this triangle r = (cnv[v0+0] + cnv[v1+0] + cnv[v2+0]) / 3; g = (cnv[v0+1] + cnv[v1+1] + cnv[v2+1]) / 3; b = (cnv[v0+2] + cnv[v1+2] + cnv[v2+2]) / 3; depth_obj.color = nearest_index(r, g, b); // transform from world coordinates to screen coordinates and copy // each point to the depth sort structure in one fell swoop (transMat.top()).multpoint3d(&cnv[v0 + 7], x); (transMat.top()).multpoint3d(&cnv[v1 + 7], y); (transMat.top()).multpoint3d(&cnv[v2 + 7], z); memcpy(depth_obj.points, x, sizeof(float) * 2); memcpy(&depth_obj.points[2], y, sizeof(float) * 2); memcpy(&depth_obj.points[4], z, sizeof(float) * 2); // compute the centerpoint of the object cent[0] = (x[0] + y[0] + z[0]) / 3; cent[1] = (x[1] + y[1] + z[1]) / 3; cent[2] = (x[2] + y[2] + z[2]) / 3; // now compute distance to eye depth_obj.dist = compute_dist(cent); // light shading factor depth_obj.light_scale = compute_light(x, y, z); // done ... add the object to the list memusage += sizeof(float) * 2 * depth_obj.npoints; points += depth_obj.npoints; objects++; depth_list.append(depth_obj); v++; // move on to next vertex } // triangles v+=2; // last two vertices are already used by last triangle } // strips }
void PSDisplayDevice::decompose_mesh(DispCmdTriMesh *mesh) { int i; int fi; int f1, f2, f3; float r, g, b; float x[3], y[3], z[3], cent[3]; float *cnv; int *f; mesh->getpointers(cnv, f); DepthSortObject depth_obj; depth_obj.npoints = 3; fi = -3; for (i = 0; i < mesh->numfacets; i++) { fi += 3; f1 = f[fi ] * 10; f2 = f[fi + 1] * 10; f3 = f[fi + 2] * 10; // allocate memory for the points depth_obj.points = (float *) malloc(6 * sizeof(float)); if (!depth_obj.points) { if (!memerror) { memerror = 1; msgErr << "PSDisplayDevice: Out of memory. Some " << "objects were not drawn." << sendmsg; } continue; } // average the three colors and use that average as the color for // this triangle r = (cnv[f1] + cnv[f2] + cnv[f3]) / 3; g = (cnv[f1 + 1] + cnv[f2 + 1] + cnv[f3 + 1]) / 3; b = (cnv[f1 + 2] + cnv[f2 + 2] + cnv[f3 + 2]) / 3; depth_obj.color = nearest_index(r, g, b); // transform from world coordinates to screen coordinates and copy // each point to the depth sort structure in one fell swoop (transMat.top()).multpoint3d(&cnv[f1 + 7], x); (transMat.top()).multpoint3d(&cnv[f2 + 7], y); (transMat.top()).multpoint3d(&cnv[f3 + 7], z); memcpy(depth_obj.points, x, sizeof(float) * 2); memcpy(&depth_obj.points[2], y, sizeof(float) * 2); memcpy(&depth_obj.points[4], z, sizeof(float) * 2); // compute the centerpoint of the object cent[0] = (x[0] + y[0] + z[0]) / 3; cent[1] = (x[1] + y[1] + z[1]) / 3; cent[2] = (x[2] + y[2] + z[2]) / 3; // now compute distance to eye depth_obj.dist = compute_dist(cent); // light shading factor depth_obj.light_scale = compute_light(x, y, z); // done ... add the object to the list memusage += sizeof(float) * 2 * depth_obj.npoints; points += depth_obj.npoints; objects++; depth_list.append(depth_obj); } }
void cubic_spline(int size1, int size2, const double *grid1, const double *grid2, const double *data1, double *data2, double yp1, double ypn ) { double *y2=NULL, *u=NULL; double p, sig, qn, un, h, a, b; int i, k, n, klo, khi; for(i=1; i<size1; i++) { if( grid1[i] <= grid1[i-1] ) error_handler("cubic_spline: grid1 is not monotonic increasing"); } for(i=0; i<size2; i++) { if( grid2[i] < grid1[0] || grid2[i] > grid1[size1-1]) error_handler("cubic_spline: grid2 lies outside grid1"); } if(size1 < 2) error_handler("cubic_spline: the size of input grid should be at least 2"); if(size1 == 2) { /* when size1 is 2, it just reduced to a linear interpolation */ p = (data1[1]-data1[0])/(grid1[1]-grid1[0]); for(i=0; i< size2; i++) data2[i] = p*(grid2[i] - grid1[0]) + data1[0]; return; } y2 = (double *)malloc(size1*sizeof(double)); u = (double *)malloc(size1*sizeof(double)); if (yp1 >.99e30) { y2[0]=0.; u[0]=0.; } else { y2[0]=-0.5; u[0]=(3./(grid1[1]-grid1[0]))*((data1[1]-data1[0])/(grid1[1]-grid1[0])-yp1); } for(i=1; i<size1-1; i++) { sig=(grid1[i]-grid1[i-1])/(grid1[i+1]-grid1[i-1]); p=sig*y2[i-1]+2.; y2[i]=(sig-1.)/p; u[i]=(6.*((data1[i+1]-data1[i])/(grid1[i+1]-grid1[i])-(data1[i]-data1[i-1]) /(grid1[i]-grid1[i-1]))/(grid1[i+1]-grid1[i-1])-sig*u[i-1])/p; } if (ypn > .99e30) { qn=0.; un=0.; } else { qn=0.5; un=(3./(grid1[size1-1]-grid1[size1-2]))*(ypn-(data1[size1-1]-data1[size1-2])/(grid1[size1-1]-grid1[size1-2])); } y2[size1-1]=(un-qn*u[size1-2])/(qn*y2[size1-2]+1.); for(k=size1-2; k>=0; k--) y2[k] = y2[k]*y2[k+1]+u[k]; /* interpolate data onto grid2 */ for(k=0; k<size2; k++) { n = nearest_index(grid2[k],grid1, size1); if (grid1[n] < grid2[k]) { klo = n; } else { if(n==0) { klo = n; } else { klo = n -1; } } khi = klo+1; h = grid1[khi]-grid1[klo]; a = (grid1[khi] - grid2[k])/h; b = (grid2[k] - grid1[klo])/h; data2[k] = a*data1[klo] + b*data1[khi]+ ((pow(a,3.0)-a)*y2[klo] + (pow(b,3.0)-b)*y2[khi])*(pow(h,2.0))/6; } free(y2); free(u); };/* cubic spline */
void WavefrontDisplayDevice::write_colormaterial(float *rgb, int material) { #ifdef VMDGENMTLFILE int cindex = nearest_index(rgb[0], rgb[1], rgb[2]); write_cindexmaterial(cindex, material); #endif }