This is contour_plot.c in view mode; [Download] [Up]
/* contour_plot.f -- translated by f2c (version of 22 January 1991 19:25:10). You must link the resulting object file with the libraries: -lF77 -lI77 -lm -lc (in that order) */ #import <appkit/color.h> #import "f2c.h" #import <dpsclient/wraps.h> /* Common Block Declarations */ struct { real xt[1000], yt[1000], zt[1000]; integer ia[3000]; } temp1_; #define temp1_1 temp1_ /* Table of constant values */ static integer c__1 = 1; /* Subroutine */ int contour_(jdim, kdim, nj, nk, x, y, f, ncont, acont, ppxunit, ppyunit, colorMap) integer *jdim, *kdim, *nj, *nk, *colorMap; real *x, *y, *f; integer *ncont; real *acont; float *ppxunit, *ppyunit; { /* System generated locals */ integer x_dim1, x_offset, y_dim1, y_offset, f_dim1, f_offset; /* Local variables */ extern /* Subroutine */ int con2l_(); /* Parameter adjustments */ --acont; f_dim1 = *jdim; f_offset = f_dim1 + 1; f -= f_offset; y_dim1 = *jdim; y_offset = y_dim1 + 1; y -= y_offset; x_dim1 = *jdim; x_offset = x_dim1 + 1; x -= x_offset; /* Function Body */ con2l_(jdim, kdim, &c__1, nj, &c__1, nk, &x[x_offset], &y[y_offset], &f[ f_offset], ncont, &acont[1], ppxunit, ppyunit, colorMap); return 0; } /* contour_ */ /* Subroutine */ int cline2_(cont, np, x, y, ppxunit, ppyunit, colorMap, icont, ncont) real *cont; integer *np, *colorMap; int icont, *ncont; real *x, *y; float *ppxunit, *ppyunit; { int i; float pattern0[] = {}; /* solid */ float pattern1[] = {4.0, 4.0}; /* dash */ NXColor color; float r,g,b; float h,s,br; int one_third; /* Parameter adjustments */ --y; --x; /* PSsetlinewidth(0.0); set outside ! */ /* PSsetgray(0); set outside ! */ switch(*colorMap) { case 0: PSsetdash(pattern0, 0, 0.0); break; case 1: if(*cont >= 0.0)PSsetdash(pattern0, 0, 0.0); if(*cont < 0.0) PSsetdash(pattern1, 2, 0.0); break; case 2: PSsetdash(pattern0, 0, 0.0); one_third = *ncont/3; r = 0; g = 0; b = 0; h = 0; s = 0; br = 0; /* if(icont <= one_third) { b = 1.-(float)icont/one_third; g = (float)icont/one_third; r = b*g; } if(icont > one_third && icont <= 2*one_third) { b = ((float)icont - (float)one_third)/one_third; g = 1. - ((float)icont - (float)one_third)/one_third; r = g*b; } if(icont > 2*one_third && icont <= *ncont) { r = 1.-((float)icont-2.*(float)one_third)/((float)*ncont-2.*one_third); b = ((float)icont-2.*(float)one_third)/((float)*ncont-2.*one_third); g = r*b; } color = NXConvertRGBToColor(r,g,b); */ h = 0.6666*icont/(float)*ncont; s = 1.0; br = 1.0; color = NXConvertHSBToColor(h,s,br); NXSetColor(color); break; case 3: if(*cont >= 0.0)PSsetdash(pattern0, 0, 0.0); if(*cont < 0.0) PSsetdash(pattern1, 2, 0.0); one_third = *ncont/3; r = 0; g = 0; b = 0; h = 0; s = 0; br = 0; /* if(icont <= one_third) { b = 1.-(float)icont/one_third; g = (float)icont/one_third; r = b*g; } if(icont > one_third && icont <= 2*one_third) { b = ((float)icont - (float)one_third)/one_third; g = 1. - ((float)icont - (float)one_third)/one_third; r = g*b; } if(icont > 2*one_third && icont <= *ncont) { r = 1.-((float)icont-2.*(float)one_third)/((float)*ncont-2.*one_third); b = ((float)icont-2.*(float)one_third)/((float)*ncont-2.*one_third); g = r*b; } color = NXConvertRGBToColor(r,g,b); */ h = 0.6666*icont/(float)*ncont; s = 1.0; br = 1.0; color = NXConvertHSBToColor(h,s,br); NXSetColor(color); break; } PSnewpath(); PSmoveto(x[1]*(*ppxunit), y[1]*(*ppyunit)); for (i=2; i <= *np; i++){ PSlineto(x[i]*(*ppxunit), y[i]*(*ppyunit)); } PSstroke(); /* Function Body */ return 0; } /* cline2_ */ /* ----------------------------------------------------------------------- */ /* Subroutine */ int con2l_(idim, jdim, is, ie, js, je, x, y, f, ncont, acont, ppxunit, ppyunit, colorMap) integer *idim, *jdim, *is, *ie, *js, *je, *colorMap; real *x, *y, *f; integer *ncont; real *acont; float *ppxunit, *ppyunit; { /* System generated locals */ integer x_dim1, x_offset, y_dim1, y_offset, f_dim1, f_offset, i__1, i__2, i__3, i__4; /* Local variables */ static integer ibeg, jbeg, idir; static real cont; static integer i, j, iaend, icont; extern /* Subroutine */ int cline2_(); static integer ij, np; static real wx, wy; static integer ignext, lnstrt, iae, iia, iee, jee, imb, ima; static real fij; static integer iss, jss; static real xyf, wxx, wyy; /* Calculate contour lines for the function F in the region IS to IE, JS to*/ /* JE. X,Y coordinates corresponding to the grid points are in arrays X and*/ /* Y. */ /* Common block TEMP1 contains scratch arrays XT, YT, ZT, and IA, and may be*/ /* used elsewhere. This subroutine is supposed to be able to recover fro m*/ /* filling either array. */ /* One little check. If IS=IE or JS=JE, return with no contour lines. */ /* Parameter adjustments */ --acont; f_dim1 = *idim; f_offset = f_dim1 + 1; f -= f_offset; y_dim1 = *idim; y_offset = y_dim1 + 1; y -= y_offset; x_dim1 = *idim; x_offset = x_dim1 + 1; x -= x_offset; /* Function Body */ if (*is == *ie || *js == *je) { return 0; } /* Zero the marker array. */ for (iia = 1; iia <= 3000; ++iia) { temp1_1.ia[iia - 1] = 0; /* L100: */ } /* LNSTRT=1 means we're starting a new line. */ lnstrt = 1; ignext = 0; /* Loop through each contour level. */ i__1 = *ncont; for (icont = 1; icont <= i__1; ++icont) { cont = acont[icont]; /* The IS-IE,JS-JE region may have to be subdivided because of IA spa ce. This*/ /* may have a detrimental effect on labelling of the contour lines. Move*/ /* IS,IE,JS,JE to new variables. */ iss = *is; iee = *ie; jss = *js; jee = *je; /* Flag points in IA where the the function increases through the con tour*/ /* level, not including the boundaries. This is so we have a list of at least*/ /* one point on each contour line that doesn't intersect a boundary. */ L110: iae = 0; i__2 = jee - 1; for (j = jss + 1; j <= i__2; ++j) { imb = 0; iaend = iae; i__3 = iee; for (i = iss; i <= i__3; ++i) { if (f[i + j * f_dim1] <= cont) { imb = 1; } else if (imb == 1) { ++iae; temp1_1.ia[iae - 1] = i * 1000 + j; imb = 0; /* Check if the IA array is full. If so, the subdividing algorithm goes like*/ /* this: if we've marked at least one J row, drop back t o the last completed*/ /* J and call that the region. If we haven't even finish ed one J row, our*/ /* region just extends to this I location. */ if (iae == 3000) { if (j > jss + 1) { iae = iaend; jee = j; } else { /* Computing MIN */ i__4 = j + 1; jee = min(i__4,jee); iee = i; } goto L210; } } /* L200: */ } } /* Search along the boundaries for contour line starts. IMA tells w hich */ /* boundary of the region we're on. */ L210: ima = 1; imb = 0; ibeg = iss - 1; jbeg = jss; L1: ++ibeg; if (ibeg == iee) { ima = 2; } goto L5; L2: ++jbeg; if (jbeg == jee) { ima = 3; } goto L5; L3: --ibeg; if (ibeg == iss) { ima = 4; } goto L5; L4: --jbeg; if (jbeg == jss) { ima = 5; } L5: if (f[ibeg + jbeg * f_dim1] > cont) { goto L7; } imb = 1; L6: switch ((int)ima) { case 1: goto L1; case 2: goto L2; case 3: goto L3; case 4: goto L4; case 5: goto L91; } L7: if (imb != 1) { goto L6; } /* Got a start point. */ imb = 0; i = ibeg; j = jbeg; fij = f[ibeg + jbeg * f_dim1]; /* Round the corner if necessary. */ switch ((int)ima) { case 1: goto L21; case 2: goto L11; case 3: goto L12; case 4: goto L13; case 5: goto L51; } L11: if (j != jss) { goto L31; } goto L21; L12: if (i != iee) { goto L41; } goto L31; L13: if (j != jee) { goto L51; } goto L41; /* This is how we start in the middle of the region, using IA. */ L10: i = temp1_1.ia[iia - 1] / 1000; j = temp1_1.ia[iia - 1] - i * 1000; fij = f[i + j * f_dim1]; temp1_1.ia[iia - 1] = 0; goto L21; /* 4 */ /* Look different directions to see which way the contour line went: 1-|-3*/ /* 2 */ L20: ++j; L21: --i; if (i < iss) { goto L90; } idir = 1; if (f[i + j * f_dim1] <= cont) { goto L52; } fij = f[i + j * f_dim1]; goto L31; L30: --i; L31: --j; if (j < jss) { goto L90; } idir = 2; if (f[i + j * f_dim1] <= cont) { goto L60; } fij = f[i + j * f_dim1]; goto L41; L40: --j; L41: ++i; if (i > iee) { goto L90; } idir = 3; if (f[i + j * f_dim1] <= cont) { goto L60; } fij = f[i + j * f_dim1]; goto L51; L50: ++i; L51: ++j; idir = 4; if (j > jee) { goto L90; } if (f[i + j * f_dim1] <= cont) { goto L60; } fij = f[i + j * f_dim1]; goto L21; /* Wipe this point out of IA if it's in the list. */ L52: if (iae == 0) { goto L60; } ij = i * 1000 + j + 1000; i__3 = iae; for (iia = 1; iia <= i__3; ++iia) { if (temp1_1.ia[iia - 1] == ij) { temp1_1.ia[iia - 1] = 0; goto L60; } /* L300: */ } /* Do interpolation for X,Y coordinates. */ L60: xyf = (cont - f[i + j * f_dim1]) / (fij - f[i + j * f_dim1]); /* This tests for a contour point coinciding with a grid point. In t his case*/ /* the contour routine comes up with the same physical coordinate twi ce. If*/ /* If we don't trap it, it can (in some cases significantly) increase the*/ /* number of points in a contour line. Also, if this happens on the first*/ /* point in a line, the second point could be misinterpreted as the e nd of a*/ /* (circling) contour line. */ if (xyf == (float)0.) { ++ignext; } switch ((int)idir) { case 1: goto L61; case 2: goto L62; case 3: goto L63; case 4: goto L64; } L61: wxx = x[i + j * x_dim1] + xyf * (x[i + 1 + j * x_dim1] - x[i + j * x_dim1]); wyy = y[i + j * y_dim1] + xyf * (y[i + 1 + j * y_dim1] - y[i + j * y_dim1]); goto L65; L62: wxx = x[i + j * x_dim1] + xyf * (x[i + (j + 1) * x_dim1] - x[i + j * x_dim1]); wyy = y[i + j * y_dim1] + xyf * (y[i + (j + 1) * y_dim1] - y[i + j * y_dim1]); goto L65; L63: wxx = x[i + j * x_dim1] + xyf * (x[i - 1 + j * x_dim1] - x[i + j * x_dim1]); wyy = y[i + j * y_dim1] + xyf * (y[i - 1 + j * y_dim1] - y[i + j * y_dim1]); goto L65; L64: wxx = x[i + j * x_dim1] + xyf * (x[i + (j - 1) * x_dim1] - x[i + j * x_dim1]); wyy = y[i + j * y_dim1] + xyf * (y[i + (j - 1) * y_dim1] - y[i + j * y_dim1]); /* Figure out what to do with this point. */ L65: if (lnstrt != 1) { goto L66; } /* This is the first point in a contour line. */ np = 1; temp1_1.xt[np - 1] = wxx; temp1_1.yt[np - 1] = wyy; wx = wxx; wy = wyy; lnstrt = 0; goto L67; /* Add a point to this line. Check for duplicate point first. */ L66: if (ignext == 2) { if (wxx == temp1_1.xt[np - 1] && wyy == temp1_1.yt[np - 1]) { ignext = 0; goto L67; } else { ignext = 1; } } ++np; temp1_1.xt[np - 1] = wxx; temp1_1.yt[np - 1] = wyy; /* See if the temporary array xT is full. */ if (np == 1000) { cline2_(&cont, &np, temp1_1.xt, temp1_1.yt, ppxunit, ppyunit, colorMap, icont, ncont); temp1_1.xt[0] = temp1_1.xt[np - 1]; temp1_1.yt[0] = temp1_1.yt[np - 1]; np = 1; } /* Check to see if we're back to the initial point. */ if (wxx != wx) { goto L67; } if (wyy == wy) { goto L90; } /* Nope. Search for the next point on this line. */ L67: switch ((int)idir) { case 1: goto L50; case 2: goto L20; case 3: goto L30; case 4: goto L40; } /* This is the end of a contour line. After this we'll start a new l ine.*/ L90: lnstrt = 1; ignext = 0; cline2_(&cont, &np, temp1_1.xt, temp1_1.yt, ppxunit, ppyunit, colorMap, icont, ncont); /* If we're not done looking along the boundaries, go look there some more.*/ if (ima != 5) { goto L6; } /* Otherwise, get the next start out of IA. */ L91: if (iae != 0) { i__3 = iae; for (iia = 1; iia <= i__3; ++iia) { if (temp1_1.ia[iia - 1] != 0) { goto L10; } /* L400: */ } } /* And if there are no more of these, we're done with this region. I f we've*/ /* subdivided, update the region pointers and go back for more. */ if (iee == *ie) { if (jee != *je) { jss = jee; jee = *je; goto L110; } } else { iss = iee; iee = *ie; goto L110; } /* Loop back for the next contour level. */ /* L1000: */ } return 0; } /* con2l_ */
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.