struct fillc_struc { pointer zp, yp, xp, np, zc, yc, xc, nc; } func fillc(z, levs, x, y, contours=, miss_value=, miss_rect=, xperiodic=, nested=, maxseg=, maxpoly=, maxnode= ) /* DOCUMENT fillc( z, levs, x, y, contours=, miss_value=, miss_rect=, xperiodic=, nested=, maxseg=, maxpoly=, maxnode= ) FILLC locates contours of a function z(x,y), and returns a list of coordinates of polygons to be filled to accomplish contour-filled shading. (function plfp may be used to fill the polygons; e.g., f= fillc(z, levs); plfp, *f.zp, *f.yp, *f.xp, *f.np) Input: z -- 2-D array of values to be contoured levs -- contour levels array, with one or more values x, y -- 1-D or 2-D mesh array of X, Y coordinate values [If the X/Y coordinate values are omitted, a "logical" coordinate system (0,1,2,...) is used, consistent with the two dimensions of Z] (KEYWORD PARAMETERS: 0=> false (default), 1=> true) contours -- if true, return list contour nodes as well miss_value -- missing data value (0 => no missing values, the default) miss_rect -- if true, mark missing data values using rectangles, rather than using triangles xperiodic -- if true, data is assumed to be periodic in X direction nested -- if true, shade contours in a nested fashion (a bit slower, but reduces the number of shaded polygons) maxseg -- maximum number of contour segments (default 16384) maxpoly -- maximum number of contour polygons (default 16384) maxnode -- maximum number of contour nodes (default 262144) Output: A structure of the following form is returned by FILLC: struct fillc_struc { pointer zp, yp, xp, np, zc, yc, xc, nc; } ZP: pointer a 1-D integer array containing the "level" values associated with each filled polygon. The level values range from 0 to NUMBEROF(LEVS)+1: level value 0 denotes "below range" values, level values between 1 and NUMBEROF(LEVS)-1 denote within range values, level value NUMBEROF(LEVS) denotes "above range" values, and level value NUMBEROF(LEVS)+1 denotes missing value regions. YP,XP: pointer to 1-D arrays of the form ARRAY(FLOAT,NCORNER) containing the Y/X coordinates of NCORNER corners of polygons to be filled NP: number of corners for each successive polygon in the list [i.e., NCORNER == SUM(NP)] The following are values are returned only if parameters CONTOURS is true; otherwise, they are set nil values. ZC: pointer a 1-D integer array containing the "level" values associated with each contour. The level values range from' 0 to NUMBEROF(LEVS): level values between 0 and NUMBEROF(LEVS)-1 denote contour levels, and level value NUMBEROF(LEVS) denotes boundary of missing value regions. YC,XC: pointer to 1-D arrays of the form ARRAY(FLOAT,NNODE) containing the Y/X coordinates of NNODE contour nodes to be joined. NC: number of noded for each successive contour in the list; closed contours will have the first node repeated as the last node. [i.e., NNODE == SUM(NC)] NOTE: 1. If NESTED is true, polygons should be shaded in the order provided, with missing value regions being shaded last. 2. Shading should be completed prior to drawing the contour segments. * Last modified: 7 March 1997, R. Saravanan * * SEE ALSO: trishade, flexplot */ { // Set default values for input parameters if (is_void(contours)) contours= 0; if (is_void(miss_value)) miss_value= 0; if (is_void(maxseg)) maxseg= 16384; if (is_void(maxpoly)) maxpoly= 16384; if (is_void(maxnode)) maxnode= 262144; if (is_void(xperiodic)) xperiodic= 0; if (is_void(miss_rect)) miss_rect= 0; if (is_void(nested)) nested= 0; if (is_void(levs)) error, "No contour levels specified"; // Determine dimensions of data array zdims= dimsof(z); if (zdims(1) != 2) error, "Field not a 2-dimensional array" nx= zdims(2); ny= zdims(3); nlev= numberof(levs); // Generate "logical" coordinate for missing X/Y coordinates if (is_void(x)) x= span(0., zdims(2)-1., zdims(2)); if (is_void(y)) y= span(0., zdims(3)-1., zdims(3)); // Broadcast 1-D coordinate arrays to 2-D to generate a mesh if (dimsof(x)(1) == 1) x= x(,-:1:ny); if (dimsof(y)(1) == 1) y= y(-:1:nx,); // Check data consistency xdims= dimsof(x); ydims= dimsof(y); if ((xdims(1) != 2) || (xdims(2) != nx) || (xdims(3) != ny)) error, "X coordinate dimensions are not conformable with data dimensions"; if ((ydims(1) != 2) || (ydims(2) != nx) || (ydims(3) != ny)) error, "Y coordinate dimensions are not conformable with data dimensions"; if (xperiodic) if (max(abs(z(1,) - z(nx,))) != 0.) error, "Data not periodic in X direction" // Call RECCONTOUR to contour data polar= 0; reccontour, z, x, y, nx, nx, ny, xperiodic, polar, nested, miss_rect, levs, nlev, miss_value, maxseg, maxpoly, maxnode, nseg, iseg, jseg, lseg, npoly, ipoly, jpoly, lpoly, nnode, vnode; // Truncate polygon arrays xp= vnode(1,1:nnode); yp= vnode(2,1:nnode); zp= lpoly(1:npoly); np= jpoly(1:npoly); if (!contours || (nseg == 0)) { // Return output structure for polygon fills only return fillc_struc( zp=&zp, yp=&yp, xp=&xp, np=&np ); } else { // Contour details requested; allocate coordinate array for contour nodes vcont= array(float, 2, sum(jseg)); zc= array(long, nseg); nc= array(long, nseg); ncont= 0; ncnode= 0; ncnode_prev= 0; // Loop over the contour segments for (k=1; k<=nseg; k++) { // Check if current segment is linked to the next one if ( (k < nseg) && ((lseg(k) == lseg(k+1)) && ( vnode(1,iseg(k)+jseg(k)) == vnode(1,iseg(k+1)+1) ) && ( vnode(2,iseg(k)+jseg(k)) == vnode(2,iseg(k+1)+1) ) ) ) { // It is linked; copy current contour segment, omitting last node if (jseg(k) > 1) { vcont(,ncnode+1:ncnode+jseg(k)-1)= vnode(,iseg(k)+1:iseg(k)+jseg(k)-1); ncnode += jseg(k)-1; } // Go on to next contour segment, skipping rest of this iteration continue; } // Copy current segment vcont(,ncnode+1:ncnode+jseg(k))= vnode(,iseg(k)+1:iseg(k)+jseg(k)); ncnode += jseg(k); // Copy contour level value, node count ncont++; zc(ncont)= lseg(k); nc(ncont)= ncnode - ncnode_prev; ncnode_prev= ncnode; } // Truncate contour arrays xc= vcont(1,1:ncnode); yc= vcont(2,1:ncnode); zc= zc(1:ncont); nc= nc(1:ncont); // print, ncont, ncnode, nseg, sum(jseg(1:nseg)) // Return output structure for polygon fills and contours return fillc_struc( zp=&zp, yp=&yp, xp=&xp, np=&np, zc=&zc, yc=&yc, xc=&xc, nc=&nc ); } } /* *-------------------------------------------------------------------- * For GNU Emacs: * $Msg-digest-checksum: e2e2dc91670ad493e17dad6fbf246464 $ *-------------------------------------------------------------------- * Local Variables: * mode: C * msg-digest-active: t * End: *-------------------------------------------------------------------- */