int main(int argc, char *argv[]) { int i, j, k; PLFLT *x, *y, **z; PLFLT xx, yy; int nlevel = LEVELS; PLFLT clevel[LEVELS]; PLFLT zmin, zmax, step; /* Parse and process command line arguments */ (void) plparseopts(&argc, argv, PL_PARSE_FULL); /* Initialize plplot */ plinit(); x = (PLFLT *) calloc(XPTS, sizeof(PLFLT)); y = (PLFLT *) calloc(YPTS, sizeof(PLFLT)); plAlloc2dGrid(&z, XPTS, YPTS); for (i = 0; i < XPTS; i++) { x[i] = 3. * (double) (i - (XPTS / 2)) / (double) (XPTS / 2); } for (i = 0; i < YPTS; i++) y[i] = 3.* (double) (i - (YPTS / 2)) / (double) (YPTS / 2); for (i = 0; i < XPTS; i++) { xx = x[i]; for (j = 0; j < YPTS; j++) { yy = y[j]; z[i][j] = 3. * (1.-xx)*(1.-xx) * exp(-(xx*xx) - (yy+1.)*(yy+1.)) - 10. * (xx/5. - pow(xx,3.) - pow(yy,5.)) * exp(-xx*xx-yy*yy) - 1./3. * exp(-(xx+1)*(xx+1) - (yy*yy)); if(0) { /* Jungfraujoch/Interlaken */ if (z[i][j] < -1.) z[i][j] = -1.; } } } plMinMax2dGrid(z, XPTS, YPTS, &zmax, &zmin); step = (zmax - zmin)/(nlevel+1); for (i=0; i<nlevel; i++) clevel[i] = zmin + step + step*i; cmap1_init(); for (k = 0; k < 2; k++) { for (i=0; i<4; i++) { pladv(0); plcol0(1); plvpor(0.0, 1.0, 0.0, 0.9); plwind(-1.0, 1.0, -1.0, 1.5); plw3d(1.0, 1.0, 1.2, -3.0, 3.0, -3.0, 3.0, zmin, zmax, alt[k], az[k]); plbox3("bnstu", "x axis", 0.0, 0, "bnstu", "y axis", 0.0, 0, "bcdmnstuv", "z axis", 0.0, 4); plcol0(2); /* wireframe plot */ if (i==0) plmesh(x, y, z, XPTS, YPTS, opt[k]); /* magnitude colored wireframe plot */ else if (i==1) plmesh(x, y, z, XPTS, YPTS, opt[k] | MAG_COLOR); /* magnitude colored wireframe plot with sides */ else if (i==2) plot3d(x, y, z, XPTS, YPTS, opt[k] | MAG_COLOR, 1); /* magnitude colored wireframe plot with base contour */ else if (i==3) plmeshc(x, y, z, XPTS, YPTS, opt[k] | MAG_COLOR | BASE_CONT, clevel, nlevel); plcol0(3); plmtex("t", 1.0, 0.5, 0.5, title[k]); } } /* Clean up */ free((void *) x); free((void *) y); plFree2dGrid(z, XPTS, YPTS); plend(); exit(0); }
int main( int argc, const char *argv[] ) { int i, j, k; PLFLT *x, *y, **z, *z_row_major, *z_col_major; PLFLT dx = 2. / (PLFLT) ( XPTS - 1 ); PLFLT dy = 2. / (PLFLT) ( YPTS - 1 ); PLfGrid2 grid_c, grid_row_major, grid_col_major; PLFLT xx, yy, r; PLINT ifshade; PLFLT zmin, zmax, step; PLFLT clevel[LEVELS]; PLINT nlevel = LEVELS; PLINT indexxmin = 0; PLINT indexxmax = XPTS; PLINT *indexymin; PLINT *indexymax; PLFLT **zlimited; // parameters of ellipse (in x, y index coordinates) that limits the data. // x0, y0 correspond to the exact floating point centre of the index // range. PLFLT x0 = 0.5 * (PLFLT) ( XPTS - 1 ); PLFLT a = 0.9 * x0; PLFLT y0 = 0.5 * (PLFLT) ( YPTS - 1 ); PLFLT b = 0.7 * y0; PLFLT square_root; // Parse and process command line arguments plMergeOpts( options, "x08c options", NULL ); (void) plparseopts( &argc, argv, PL_PARSE_FULL ); // Initialize plplot plinit(); // Allocate data structures x = (PLFLT *) calloc( XPTS, sizeof ( PLFLT ) ); y = (PLFLT *) calloc( YPTS, sizeof ( PLFLT ) ); plAlloc2dGrid( &z, XPTS, YPTS ); z_row_major = (PLFLT *) malloc( XPTS * YPTS * sizeof ( PLFLT ) ); z_col_major = (PLFLT *) malloc( XPTS * YPTS * sizeof ( PLFLT ) ); if ( !z_row_major || !z_col_major ) plexit( "Memory allocation error" ); grid_c.f = z; grid_row_major.f = (PLFLT **) z_row_major; grid_col_major.f = (PLFLT **) z_col_major; grid_c.nx = grid_row_major.nx = grid_col_major.nx = XPTS; grid_c.ny = grid_row_major.ny = grid_col_major.ny = YPTS; for ( i = 0; i < XPTS; i++ ) { x[i] = -1. + (PLFLT) i * dx; if ( rosen ) x[i] *= 1.5; } for ( j = 0; j < YPTS; j++ ) { y[j] = -1. + (PLFLT) j * dy; if ( rosen ) y[j] += 0.5; } for ( i = 0; i < XPTS; i++ ) { xx = x[i]; for ( j = 0; j < YPTS; j++ ) { yy = y[j]; if ( rosen ) { z[i][j] = pow( 1. - xx, 2. ) + 100. * pow( yy - pow( xx, 2. ), 2. ); // The log argument might be zero for just the right grid. if ( z[i][j] > 0. ) z[i][j] = log( z[i][j] ); else z[i][j] = -5.; // -MAXFLOAT would mess-up up the scale } else { r = sqrt( xx * xx + yy * yy ); z[i][j] = exp( -r * r ) * cos( 2.0 * M_PI * r ); } z_row_major[i * YPTS + j] = z[i][j]; z_col_major[i + XPTS * j] = z[i][j]; } } // Allocate and calculate y index ranges and corresponding zlimited. plAlloc2dGrid( &zlimited, XPTS, YPTS ); indexymin = (PLINT *) malloc( XPTS * sizeof ( PLINT ) ); indexymax = (PLINT *) malloc( XPTS * sizeof ( PLINT ) ); if ( !indexymin || !indexymax ) plexit( "Memory allocation error" ); //printf("XPTS = %d\n", XPTS); //printf("x0 = %f\n", x0); //printf("a = %f\n", a); //printf("YPTS = %d\n", YPTS); //printf("y0 = %f\n", y0); //printf("b = %f\n", b); // These values should all be ignored because of the i index range. #if 0 for ( i = 0; i < indexxmin; i++ ) { indexymin[i] = 0; indexymax[i] = YPTS; for ( j = indexymin[i]; j < indexymax[i]; j++ ) // Mark with large value to check this is ignored. zlimited[i][j] = 1.e300; } #endif for ( i = indexxmin; i < indexxmax; i++ ) { square_root = sqrt( 1. - MIN( 1., pow( ( (PLFLT) i - x0 ) / a, 2. ) ) ); // Add 0.5 to find nearest integer and therefore preserve symmetry // with regard to lower and upper bound of y range. indexymin[i] = MAX( 0, (PLINT) ( 0.5 + y0 - b * square_root ) ); // indexymax calculated with the convention that it is 1 // greater than highest valid index. indexymax[i] = MIN( YPTS, 1 + (PLINT) ( 0.5 + y0 + b * square_root ) ); //printf("i, b*square_root, indexymin[i], YPTS - indexymax[i] = %d, %e, %d, %d\n", i, b*square_root, indexymin[i], YPTS - indexymax[i]); #if 0 // These values should all be ignored because of the j index range. for ( j = 0; j < indexymin[i]; j++ ) // Mark with large value to check this is ignored. zlimited[i][j] = 1.e300; #endif for ( j = indexymin[i]; j < indexymax[i]; j++ ) zlimited[i][j] = z[i][j]; #if 0 // These values should all be ignored because of the j index range. for ( j = indexymax[i]; j < YPTS; j++ ) // Mark with large value to check this is ignored. zlimited[i][j] = 1.e300; #endif } #if 0 // These values should all be ignored because of the i index range. for ( i = indexxmax; i < XPTS; i++ ) { indexymin[i] = 0; indexymax[i] = YPTS; for ( j = indexymin[i]; j < indexymax[i]; j++ ) // Mark with large value to check this is ignored. zlimited[i][j] = 1.e300; } #endif plMinMax2dGrid( (const PLFLT * const *) z, XPTS, YPTS, &zmax, &zmin ); step = ( zmax - zmin ) / ( nlevel + 1 ); for ( i = 0; i < nlevel; i++ ) clevel[i] = zmin + step + step * i; pllightsource( 1., 1., 1. ); for ( k = 0; k < 2; k++ ) { for ( ifshade = 0; ifshade < 5; ifshade++ ) { pladv( 0 ); plvpor( 0.0, 1.0, 0.0, 0.9 ); plwind( -1.0, 1.0, -0.9, 1.1 ); plcol0( 3 ); plmtex( "t", 1.0, 0.5, 0.5, title[k] ); plcol0( 1 ); if ( rosen ) plw3d( 1.0, 1.0, 1.0, -1.5, 1.5, -0.5, 1.5, zmin, zmax, alt[k], az[k] ); else plw3d( 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, zmin, zmax, alt[k], az[k] ); plbox3( "bnstu", "x axis", 0.0, 0, "bnstu", "y axis", 0.0, 0, "bcdmnstuv", "z axis", 0.0, 0 ); plcol0( 2 ); if ( ifshade == 0 ) // diffuse light surface plot { cmap1_init( 1 ); plfsurf3d( x, y, plf2ops_c(), (PLPointer) z, XPTS, YPTS, 0, NULL, 0 ); } else if ( ifshade == 1 ) // magnitude colored plot { cmap1_init( 0 ); plfsurf3d( x, y, plf2ops_grid_c(), ( PLPointer ) & grid_c, XPTS, YPTS, MAG_COLOR, NULL, 0 ); } else if ( ifshade == 2 ) // magnitude colored plot with faceted squares { cmap1_init( 0 ); plfsurf3d( x, y, plf2ops_grid_row_major(), ( PLPointer ) & grid_row_major, XPTS, YPTS, MAG_COLOR | FACETED, NULL, 0 ); } else if ( ifshade == 3 ) // magnitude colored plot with contours { cmap1_init( 0 ); plfsurf3d( x, y, plf2ops_grid_col_major(), ( PLPointer ) & grid_col_major, XPTS, YPTS, MAG_COLOR | SURF_CONT | BASE_CONT, clevel, nlevel ); } else // magnitude colored plot with contours and index limits. { cmap1_init( 0 ); plsurf3dl( x, y, (const PLFLT * const *) zlimited, XPTS, YPTS, MAG_COLOR | SURF_CONT | BASE_CONT, clevel, nlevel, indexxmin, indexxmax, indexymin, indexymax ); } } } // Clean up free( (void *) x ); free( (void *) y ); plFree2dGrid( z, XPTS, YPTS ); free( (void *) z_row_major ); free( (void *) z_col_major ); plFree2dGrid( zlimited, XPTS, YPTS ); free( (void *) indexymin ); free( (void *) indexymax ); plend(); exit( 0 ); }
int main(int argc, char *argv[]) { PLFLT *x, *y, *z, *clev; PLFLT *xg, *yg, **zg, **szg; PLFLT zmin, zmax, lzm, lzM; long ct; int i, j, k; PLINT alg; char ylab[40], xlab[40]; char *title[] = {"Cubic Spline Approximation", "Delaunay Linear Interpolation", "Natural Neighbors Interpolation", "KNN Inv. Distance Weighted", "3NN Linear Interpolation", "4NN Around Inv. Dist. Weighted"}; PLFLT opt[] = {0., 0., 0., 0., 0., 0.}; xm = ym = -0.2; xM = yM = 0.8; plMergeOpts(options, "x21c options", NULL); plparseopts(&argc, argv, PL_PARSE_FULL); opt[2] = wmin; opt[3] = (PLFLT) knn_order; opt[4] = threshold; /* Initialize plplot */ plinit(); create_data(&x, &y, &z, pts); /* the sampled data */ zmin = z[0]; zmax = z[0]; for (i=1; i<pts; i++) { if (z[i] > zmax) zmax = z[i]; if (z[i] < zmin) zmin = z[i]; } create_grid(&xg, xp, &yg, yp); /* grid the data at */ plAlloc2dGrid(&zg, xp, yp); /* the output grided data */ clev = (PLFLT *) malloc(nl * sizeof(PLFLT)); sprintf(xlab, "Npts=%d gridx=%d gridy=%d", pts, xp, yp); plcol0(1); plenv(xm, xM, ym, yM, 2, 0); plcol0(15); pllab(xlab, "", "The original data"); plcol0(2); plpoin(pts, x, y, 5); pladv(0); plssub(3,2); for (k=0; k<2; k++) { pladv(0); for (alg=1; alg<7; alg++) { ct = clock(); plgriddata(x, y, z, pts, xg, xp, yg, yp, zg, alg, opt[alg-1]); sprintf(xlab, "time=%d ms", (clock() - ct)/1000); sprintf(ylab, "opt=%.3f", opt[alg-1]); /* - CSA can generate NaNs (only interpolates?!). * - DTLI and NNI can generate NaNs for points outside the convex hull * of the data points. * - NNLI can generate NaNs if a sufficiently thick triangle is not found * * PLplot should be NaN/Inf aware, but changing it now is quite a job... * so, instead of not plotting the NaN regions, a weighted average over * the neighbors is done. */ if (alg == GRID_CSA || alg == GRID_DTLI || alg == GRID_NNLI || alg == GRID_NNI) { int ii, jj; PLFLT dist, d; for (i=0; i<xp; i++) { for (j=0; j<yp; j++) { if (isnan(zg[i][j])) { /* average (IDW) over the 8 neighbors */ zg[i][j] = 0.; dist = 0.; for (ii=i-1; ii<=i+1 && ii<xp; ii++) { for (jj=j-1; jj<=j+1 && jj<yp; jj++) { if (ii >= 0 && jj >= 0 && !isnan(zg[ii][jj])) { d = (abs(ii-i) + abs(jj-j)) == 1 ? 1. : 1.4142; zg[i][j] += zg[ii][jj]/(d*d); dist += d; } } } if (dist != 0.) zg[i][j] /= dist; else zg[i][j] = zmin; } } } } plMinMax2dGrid(zg, xp, yp, &lzM, &lzm); plcol0(1); pladv(alg); if (k == 0) { lzm = MIN(lzm, zmin); lzM = MAX(lzM, zmax); for (i=0; i<nl; i++) clev[i] = lzm + (lzM-lzm)/(nl-1)*i; plenv0(xm, xM, ym, yM, 2, 0); plcol0(15); pllab(xlab, ylab, title[alg-1]); plshades(zg, xp, yp, NULL, xm, xM, ym, yM, clev, nl, 1, 0, 1, plfill, 1, NULL, NULL); plcol0(2); } else { for (i=0; i<nl; i++) clev[i] = lzm + (lzM-lzm)/(nl-1)*i; cmap1_init(); plvpor(0.0, 1.0, 0.0, 0.9); plwind(-1.0, 1.0, -1.0, 1.5); /* * For the comparition to be fair, all plots should have the * same z values, but to get the max/min of the data generated * by all algorithms would imply two passes. Keep it simple. * * plw3d(1., 1., 1., xm, xM, ym, yM, zmin, zmax, 30, -60); */ plw3d(1., 1., 1., xm, xM, ym, yM, lzm, lzM, 30, -60); plbox3("bnstu", ylab, 0.0, 0, "bnstu", xlab, 0.0, 0, "bcdmnstuv", "", 0.0, 4); plcol0(15); pllab("", "", title[alg-1]); plot3dc(xg, yg, zg, xp, yp, DRAW_LINEXY | MAG_COLOR | BASE_CONT, clev, nl); } } } plend(); free_data(x, y, z); free_grid(xg, yg); free((void *)clev); plFree2dGrid(zg, xp, yp); }