00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124 #include "plplotP.h"
00125 #include <float.h>
00126
00127 #define MISSING_MIN_DEF (PLFLT) 1.0
00128 #define MISSING_MAX_DEF (PLFLT) -1.0
00129
00130
00131 #define NEG 1
00132 #define POS 8
00133 #define OK 0
00134 #define UNDEF 64
00135
00136 #define linear(val1, val2, level) ((level - val1) / (val2 - val1))
00137
00138
00139
00140 static PLFLT sh_max, sh_min;
00141 static int min_points, max_points, n_point;
00142 static int min_pts[4], max_pts[4];
00143 static PLINT pen_col_min, pen_col_max;
00144 static PLINT pen_wd_min, pen_wd_max;
00145 static PLFLT int_val;
00146
00147
00148
00149 static void
00150 set_cond(register int *cond, register PLFLT *a, register PLINT n);
00151
00152 static int
00153 find_interval(PLFLT a0, PLFLT a1, PLINT c0, PLINT c1, PLFLT *x);
00154
00155 static void
00156 selected_polygon(void (*fill) (PLINT, PLFLT *, PLFLT *),
00157 PLINT (*defined) (PLFLT, PLFLT),
00158 PLFLT *x, PLFLT *y, PLINT v1, PLINT v2, PLINT v3, PLINT v4);
00159
00160 static void
00161 exfill(void (*fill) (PLINT, PLFLT *, PLFLT *),
00162 PLINT (*defined) (PLFLT, PLFLT),
00163 int n, PLFLT *x, PLFLT *y);
00164
00165 static void
00166 big_recl(int *cond_code, register int ny, int dx, int dy,
00167 int *ix, int *iy);
00168
00169 static void
00170 draw_boundary(PLINT slope, PLFLT *x, PLFLT *y);
00171
00172 static PLINT
00173 plctest(PLFLT *x, PLFLT level);
00174
00175 static PLINT
00176 plctestez(PLFLT *a, PLINT nx, PLINT ny, PLINT ix,
00177 PLINT iy, PLFLT level);
00178
00179 static void
00180 plshade_int(PLFLT (*f2eval) (PLINT, PLINT, PLPointer),
00181 PLPointer f2eval_data,
00182 PLFLT (*c2eval) (PLINT, PLINT, PLPointer),
00183 PLPointer c2eval_data,
00184 PLINT (*defined) (PLFLT, PLFLT),
00185 PLFLT missing_min, PLFLT missing_max,
00186 PLINT nx, PLINT ny,
00187 PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax,
00188 PLFLT shade_min, PLFLT shade_max,
00189 PLINT sh_cmap, PLFLT sh_color, PLINT sh_width,
00190 PLINT min_color, PLINT min_width,
00191 PLINT max_color, PLINT max_width,
00192 void (*fill) (PLINT, PLFLT *, PLFLT *), PLINT rectangular,
00193 void (*pltr) (PLFLT, PLFLT, PLFLT *, PLFLT *, PLPointer),
00194 PLPointer pltr_data);
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209 void c_plshades( PLFLT **a, PLINT nx, PLINT ny, PLINT (*defined) (PLFLT, PLFLT),
00210 PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax,
00211 PLFLT *clevel, PLINT nlevel, PLINT fill_width,
00212 PLINT cont_color, PLINT cont_width,
00213 void (*fill) (PLINT, PLFLT *, PLFLT *), PLINT rectangular,
00214 void (*pltr) (PLFLT, PLFLT, PLFLT *, PLFLT *, PLPointer),
00215 PLPointer pltr_data )
00216 {
00217 PLFLT shade_min, shade_max, shade_color;
00218 PLINT i, init_color, init_width;
00219
00220 for (i = 0; i < nlevel-1; i++) {
00221 shade_min = clevel[i];
00222 shade_max = clevel[i+1];
00223 shade_color = i / (PLFLT) (nlevel-2);
00224
00225
00226
00227
00228
00229
00230 plshade(a, nx, ny, defined, xmin, xmax, ymin, ymax,
00231 shade_min, shade_max,
00232 1, shade_color, fill_width,
00233 0, 0, 0, 0,
00234 fill, rectangular, pltr, pltr_data);
00235 }
00236 if(cont_color > 0 && cont_width > 0) {
00237 init_color = plsc->icol0;
00238 init_width = plsc->width;
00239 plcol0(cont_color);
00240 plwid(cont_width);
00241 if(pltr && pltr_data) {
00242 plcont(a, nx, ny, 1, nx, 1, ny, clevel, nlevel, pltr, pltr_data);
00243 }
00244 else {
00245
00246
00247
00248
00249
00250 PLcGrid cgrid1;
00251 PLFLT *x, *y;
00252 cgrid1.nx = nx;
00253 cgrid1.ny = ny;
00254 x = (PLFLT *) malloc(nx * sizeof(PLFLT));
00255 if (x == NULL)
00256 plexit("plshades: Out of memory for x");
00257 cgrid1.xg = x;
00258 for (i = 0; i < nx; i++)
00259 cgrid1.xg[i] = xmin + (xmax - xmin)*(float)i/(float)(nx-1);
00260 y = (PLFLT *) malloc(ny * sizeof(PLFLT));
00261 if (y == NULL)
00262 plexit("plshades: Out of memory for y");
00263 cgrid1.yg = y;
00264 for (i = 0; i < ny; i++)
00265 cgrid1.yg[i] = ymin + (ymax - ymin)*(float)i/(float)(ny-1);
00266 plcont(a, nx, ny, 1, nx, 1, ny, clevel, nlevel,
00267 pltr1, (void *) &cgrid1);
00268 free(x);
00269 free(y);
00270 }
00271 plcol0(init_color);
00272 plwid(init_width);
00273 }
00274 }
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284 void c_plshade( PLFLT **a, PLINT nx, PLINT ny, PLINT (*defined) (PLFLT, PLFLT),
00285 PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax,
00286 PLFLT shade_min, PLFLT shade_max,
00287 PLINT sh_cmap, PLFLT sh_color, PLINT sh_width,
00288 PLINT min_color, PLINT min_width,
00289 PLINT max_color, PLINT max_width,
00290 void (*fill) (PLINT, PLFLT *, PLFLT *), PLINT rectangular,
00291 void (*pltr) (PLFLT, PLFLT, PLFLT *, PLFLT *, PLPointer),
00292 PLPointer pltr_data )
00293 {
00294 PLfGrid2 grid;
00295
00296 grid.f = a;
00297 grid.nx = nx;
00298 grid.ny = ny;
00299
00300 plshade_int( plf2eval2, (PLPointer) &grid,
00301 NULL, NULL,
00302
00303 defined, MISSING_MIN_DEF, MISSING_MAX_DEF, nx, ny, xmin,
00304 xmax, ymin, ymax, shade_min, shade_max,
00305 sh_cmap, sh_color, sh_width,
00306 min_color, min_width, max_color, max_width,
00307 fill, rectangular, pltr, pltr_data );
00308 }
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318 void c_plshade1( PLFLT *a, PLINT nx, PLINT ny, PLINT (*defined) (PLFLT, PLFLT),
00319 PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax,
00320 PLFLT shade_min, PLFLT shade_max,
00321 PLINT sh_cmap, PLFLT sh_color, PLINT sh_width,
00322 PLINT min_color, PLINT min_width,
00323 PLINT max_color, PLINT max_width,
00324 void (*fill) (PLINT, PLFLT *, PLFLT *), PLINT rectangular,
00325 void (*pltr) (PLFLT, PLFLT, PLFLT *, PLFLT *, PLPointer),
00326 PLPointer pltr_data )
00327 {
00328 PLfGrid grid;
00329
00330 grid.f = a;
00331 grid.nx = nx;
00332 grid.ny = ny;
00333
00334 plshade_int( plf2eval, (PLPointer) &grid,
00335 NULL, NULL,
00336
00337 defined, MISSING_MIN_DEF, MISSING_MAX_DEF, nx, ny, xmin,
00338 xmax, ymin, ymax, shade_min, shade_max,
00339 sh_cmap, sh_color, sh_width,
00340 min_color, min_width, max_color, max_width,
00341 fill, rectangular, pltr, pltr_data );
00342 }
00343
00344
00345
00346
00347
00348
00349
00350
00351 void
00352 plfshade(PLFLT (*f2eval) (PLINT, PLINT, PLPointer),
00353 PLPointer f2eval_data,
00354 PLFLT (*c2eval) (PLINT, PLINT, PLPointer),
00355 PLPointer c2eval_data,
00356 PLINT nx, PLINT ny,
00357 PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax,
00358 PLFLT shade_min, PLFLT shade_max,
00359 PLINT sh_cmap, PLFLT sh_color, PLINT sh_width,
00360 PLINT min_color, PLINT min_width,
00361 PLINT max_color, PLINT max_width,
00362 void (*fill) (PLINT, PLFLT *, PLFLT *), PLINT rectangular,
00363 void (*pltr) (PLFLT, PLFLT, PLFLT *, PLFLT *, PLPointer),
00364 PLPointer pltr_data)
00365 {
00366 plshade_int(f2eval, f2eval_data, c2eval, c2eval_data,
00367 NULL, MISSING_MIN_DEF, MISSING_MAX_DEF,
00368 nx, ny, xmin, xmax, ymin, ymax,
00369 shade_min, shade_max, sh_cmap, sh_color, sh_width,
00370 min_color, min_width, max_color, max_width,
00371 fill, rectangular, pltr, pltr_data);
00372 }
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414 static void
00415 plshade_int(PLFLT (*f2eval) (PLINT, PLINT, PLPointer),
00416 PLPointer f2eval_data,
00417 PLFLT (*c2eval) (PLINT, PLINT, PLPointer),
00418 PLPointer c2eval_data,
00419 PLINT (*defined) (PLFLT, PLFLT),
00420 PLFLT missing_min, PLFLT missing_max,
00421 PLINT nx, PLINT ny,
00422 PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax,
00423 PLFLT shade_min, PLFLT shade_max,
00424 PLINT sh_cmap, PLFLT sh_color, PLINT sh_width,
00425 PLINT min_color, PLINT min_width,
00426 PLINT max_color, PLINT max_width,
00427 void (*fill) (PLINT, PLFLT *, PLFLT *), PLINT rectangular,
00428 void (*pltr) (PLFLT, PLFLT, PLFLT *, PLFLT *, PLPointer),
00429 PLPointer pltr_data)
00430 {
00431
00432 PLINT init_width, n, slope = 0, ix, iy;
00433 int count, i, j, nxny;
00434 PLFLT *a, *a0, *a1, dx, dy;
00435 PLFLT x[8], y[8], xp[2], tx, ty;
00436 int *c, *c0, *c1;
00437
00438 if (plsc->level < 3) {
00439 plabort("plfshade: window must be set up first");
00440 return;
00441 }
00442
00443 if (nx <= 0 || ny <= 0) {
00444 plabort("plfshade: nx and ny must be positive");
00445 return;
00446 }
00447
00448 if (shade_min >= shade_max) {
00449 plabort("plfshade: shade_max must exceed shade_min");
00450 return;
00451 }
00452
00453 if (pltr == NULL || pltr_data == NULL)
00454 rectangular = 1;
00455
00456 int_val = shade_max - shade_min;
00457 init_width = plsc->width;
00458
00459 pen_col_min = min_color;
00460 pen_col_max = max_color;
00461
00462 pen_wd_min = min_width;
00463 pen_wd_max = max_width;
00464
00465 plstyl((PLINT) 0, NULL, NULL);
00466 plwid(sh_width);
00467 if (fill != NULL) {
00468 switch (sh_cmap) {
00469 case 0:
00470 plcol0((PLINT) sh_color);
00471 break;
00472 case 1:
00473 plcol1(sh_color);
00474 break;
00475 default:
00476 plabort("plfshade: invalid color map selection");
00477 return;
00478 }
00479 }
00480
00481
00482 nxny = nx * ny;
00483 if ((a = (PLFLT *) malloc(nxny * sizeof(PLFLT))) == NULL) {
00484 plabort("plfshade: unable to allocate memory for value array");
00485 return;
00486 }
00487
00488 for (ix = 0; ix < nx; ix++)
00489 for (iy = 0; iy < ny; iy++)
00490 a[iy + ix*ny] = f2eval(ix, iy, f2eval_data);
00491
00492
00493
00494 if ((c = (int *) malloc(nxny * sizeof(int))) == NULL) {
00495 plabort("plfshade: unable to allocate memory for condition codes");
00496 free(a);
00497 return;
00498 }
00499
00500 sh_min = shade_min;
00501 sh_max = shade_max;
00502
00503 set_cond(c, a, nxny);
00504 dx = (xmax - xmin) / (nx - 1);
00505 dy = (ymax - ymin) / (ny - 1);
00506 a0 = a;
00507 a1 = a + ny;
00508 c0 = c;
00509 c1 = c + ny;
00510
00511 for (ix = 0; ix < nx - 1; ix++) {
00512
00513 for (iy = 0; iy < ny - 1; iy++) {
00514
00515 count = c0[iy] + c0[iy + 1] + c1[iy] + c1[iy + 1];
00516
00517
00518
00519 if (count >= UNDEF)
00520 continue;
00521 if (count == 4 * POS)
00522 continue;
00523 if (count == 4 * NEG)
00524 continue;
00525
00526
00527
00528 if (count == 4 * OK) {
00529
00530 if (rectangular) {
00531 big_recl(c0 + iy, ny, nx - ix, ny - iy, &i, &j);
00532 }
00533 else {
00534 i = j = 1;
00535 }
00536 x[0] = x[1] = ix;
00537 x[2] = x[3] = ix+i;
00538 y[0] = y[3] = iy;
00539 y[1] = y[2] = iy+j;
00540
00541 if (pltr && pltr_data) {
00542 for (i = 0; i < 4; i++) {
00543 (*pltr) (x[i], y[i], &tx, &ty, pltr_data);
00544 x[i] = tx;
00545 y[i] = ty;
00546 }
00547 }
00548 else {
00549 for (i = 0; i < 4; i++) {
00550 x[i] = xmin + x[i]*dx;
00551 y[i] = ymin + y[i]*dy;
00552 }
00553 }
00554 if (fill != NULL)
00555 exfill (fill, defined, (PLINT) 4, x, y);
00556 iy += j - 1;
00557 continue;
00558 }
00559
00560
00561
00562 n_point = min_points = max_points = 0;
00563 n = find_interval(a0[iy], a0[iy + 1], c0[iy], c0[iy + 1], xp);
00564 for (j = 0; j < n; j++) {
00565 x[j] = ix;
00566 y[j] = iy + xp[j];
00567 }
00568
00569 i = find_interval(a0[iy + 1], a1[iy + 1],
00570 c0[iy + 1], c1[iy + 1], xp);
00571
00572 for (j = 0; j < i; j++) {
00573 x[j + n] = ix + xp[j];
00574 y[j + n] = iy + 1;
00575 }
00576 n += i;
00577
00578 i = find_interval(a1[iy + 1], a1[iy], c1[iy + 1], c1[iy], xp);
00579 for (j = 0; j < i; j++) {
00580 x[n + j] = ix + 1;
00581 y[n + j] = iy + 1 - xp[j];
00582 }
00583 n += i;
00584
00585 i = find_interval(a1[iy], a0[iy], c1[iy], c0[iy], xp);
00586 for (j = 0; j < i; j++) {
00587 x[n + j] = ix + 1 - xp[j];
00588 y[n + j] = iy;
00589 }
00590 n += i;
00591
00592 if (pltr && pltr_data) {
00593 for (i = 0; i < n; i++) {
00594 (*pltr) (x[i], y[i], &tx, &ty, pltr_data);
00595 x[i] = tx;
00596 y[i] = ty;
00597 }
00598 }
00599 else {
00600 for (i = 0; i < n; i++) {
00601 x[i] = xmin + x[i]*dx;
00602 y[i] = ymin + y[i]*dy;
00603 }
00604 }
00605
00606 if (min_points == 4)
00607 slope = plctestez(a, nx, ny, ix, iy, shade_min);
00608 if (max_points == 4)
00609 slope = plctestez(a, nx, ny, ix, iy, shade_max);
00610
00611
00612
00613
00614
00615
00616
00617 switch ((min_points << 3) + max_points) {
00618 case 000:
00619 case 020:
00620 case 002:
00621 case 022:
00622 if (fill != NULL && n > 0)
00623 exfill (fill, defined, n, x, y);
00624 break;
00625 case 040:
00626 case 004:
00627 if (n != 6)
00628 fprintf(stderr, "plfshade err n=%d !6", (int) n);
00629 if (slope == 1 && c0[iy] == OK) {
00630 if (fill != NULL)
00631 exfill (fill, defined, n, x, y);
00632 }
00633 else if (slope == 1) {
00634 selected_polygon(fill, defined, x, y, 0, 1, 2, -1);
00635 selected_polygon(fill, defined, x, y, 3, 4, 5, -1);
00636 }
00637 else if (c0[iy + 1] == OK) {
00638 if (fill != NULL)
00639 exfill (fill, defined, n, x, y);
00640 }
00641 else {
00642 selected_polygon(fill, defined, x, y, 0, 1, 5, -1);
00643 selected_polygon(fill, defined, x, y, 2, 3, 4, -1);
00644 }
00645 break;
00646 case 044:
00647 if (n != 8)
00648 fprintf(stderr, "plfshade err n=%d !8", (int) n);
00649 if (slope == 1) {
00650 selected_polygon(fill, defined, x, y, 0, 1, 2, 3);
00651 selected_polygon(fill, defined, x, y, 4, 5, 6, 7);
00652 }
00653 else {
00654 selected_polygon(fill, defined, x, y, 0, 1, 6, 7);
00655 selected_polygon(fill, defined, x, y, 2, 3, 4, 5);
00656 }
00657 break;
00658 case 024:
00659 case 042:
00660
00661 if (n != 7)
00662 fprintf(stderr, "plfshade err n=%d !7", (int) n);
00663
00664 if ((c0[iy] == OK || c1[iy+1] == OK) && slope == 1) {
00665 if (fill != NULL)
00666 exfill (fill, defined, n, x, y);
00667 }
00668 else if ((c0[iy+1] == OK || c1[iy] == OK) && slope == 0) {
00669 if (fill !=NULL)
00670 exfill (fill, defined, n, x, y);
00671 }
00672
00673 else if (c0[iy] == OK) {
00674 selected_polygon(fill, defined, x, y, 0, 1, 6, -1);
00675 selected_polygon(fill, defined, x, y, 2, 3, 4, 5);
00676 }
00677 else if (c0[iy+1] == OK) {
00678 selected_polygon(fill, defined, x, y, 0, 1, 2, -1);
00679 selected_polygon(fill, defined, x, y, 3, 4, 5, 6);
00680 }
00681 else if (c1[iy+1] == OK) {
00682 selected_polygon(fill, defined, x, y, 0, 1, 5, 6);
00683 selected_polygon(fill, defined, x, y, 2, 3, 4, -1);
00684 }
00685 else if (c1[iy] == OK) {
00686 selected_polygon(fill, defined, x, y, 0, 1, 2, 3);
00687 selected_polygon(fill, defined, x, y, 4, 5, 6, -1);
00688 }
00689 else {
00690 fprintf(stderr, "plfshade err logic case 024:042\n");
00691 }
00692 break;
00693 default:
00694 fprintf(stderr, "prog err switch\n");
00695 break;
00696 }
00697 draw_boundary(slope, x, y);
00698
00699 if (fill != NULL) {
00700 plwid(sh_width);
00701 if (sh_cmap == 0) plcol0((PLINT) sh_color);
00702 else if (sh_cmap == 1) plcol1(sh_color);
00703 }
00704 }
00705
00706 a0 = a1;
00707 c0 = c1;
00708 a1 += ny;
00709 c1 += ny;
00710 }
00711
00712 free(c);
00713 free(a);
00714 plwid(init_width);
00715 }
00716
00717
00718
00719
00720
00721
00722
00723 static void
00724 set_cond(register int *cond, register PLFLT *a, register PLINT n)
00725 {
00726 while (n--) {
00727 if (*a < sh_min)
00728 *cond++ = NEG;
00729 else if (*a > sh_max)
00730 *cond++ = POS;
00731 else
00732 *cond++ = OK;
00733 a++;
00734 }
00735 }
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748 static int
00749 find_interval(PLFLT a0, PLFLT a1, PLINT c0, PLINT c1, PLFLT *x)
00750 {
00751 register int n;
00752
00753 n = 0;
00754 if (c0 == OK) {
00755 x[n++] = 0.0;
00756 n_point++;
00757 }
00758 if (c0 == c1)
00759 return n;
00760
00761 if (c0 == NEG || c1 == POS) {
00762 if (c0 == NEG) {
00763 x[n++] = linear(a0, a1, sh_min);
00764 min_pts[min_points++] = n_point++;
00765 }
00766 if (c1 == POS) {
00767 x[n++] = linear(a0, a1, sh_max);
00768 max_pts[max_points++] = n_point++;
00769 }
00770 }
00771 if (c0 == POS || c1 == NEG) {
00772 if (c0 == POS) {
00773 x[n++] = linear(a0, a1, sh_max);
00774 max_pts[max_points++] = n_point++;
00775 }
00776 if (c1 == NEG) {
00777 x[n++] = linear(a0, a1, sh_min);
00778 min_pts[min_points++] = n_point++;
00779 }
00780 }
00781 return n;
00782 }
00783
00784
00785
00786
00787
00788
00789
00790
00791 static void
00792 selected_polygon(void (*fill) (PLINT, PLFLT *, PLFLT *),
00793 PLINT (*defined) (PLFLT, PLFLT),
00794 PLFLT *x, PLFLT *y, PLINT v1, PLINT v2, PLINT v3, PLINT v4)
00795 {
00796 register PLINT n = 0;
00797 PLFLT xx[4], yy[4];
00798
00799 if (fill == NULL)
00800 return;
00801 if (v1 >= 0) {
00802 xx[n] = x[v1];
00803 yy[n++] = y[v1];
00804 }
00805 if (v2 >= 0) {
00806 xx[n] = x[v2];
00807 yy[n++] = y[v2];
00808 }
00809 if (v3 >= 0) {
00810 xx[n] = x[v3];
00811 yy[n++] = y[v3];
00812 }
00813 if (v4 >= 0) {
00814 xx[n] = x[v4];
00815 yy[n++] = y[v4];
00816 }
00817 exfill (fill, defined, n, xx, yy);
00818 }
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828 static void
00829 bisect(PLINT (*defined) (PLFLT, PLFLT), PLINT niter,
00830 PLFLT x1, PLFLT y1, PLFLT x2, PLFLT y2, PLFLT* xb, PLFLT* yb)
00831 {
00832 PLFLT xm;
00833 PLFLT ym;
00834
00835 if (niter == 0) {
00836 *xb = x1;
00837 *yb = y1;
00838 return;
00839 }
00840
00841 xm = (x1 + x2) / 2;
00842 ym = (y1 + y2) / 2;
00843
00844 if (defined (xm, ym))
00845 bisect (defined, niter - 1, xm, ym, x2, y2, xb, yb);
00846 else
00847 bisect (defined, niter - 1, x1, y1, xm, ym, xb, yb);
00848 }
00849
00850
00851
00852
00853
00854
00855
00856
00857 static void
00858 exfill(void (*fill) (PLINT, PLFLT *, PLFLT *),
00859 PLINT (*defined) (PLFLT, PLFLT),
00860 int n, PLFLT *x, PLFLT *y)
00861 {
00862 if (defined == NULL)
00863
00864 (*fill) (n, x, y);
00865
00866 else {
00867 PLFLT xx[16];
00868 PLFLT yy[16];
00869 PLFLT xb, yb;
00870 PLINT count = 0;
00871 PLINT is_inside = defined (x[n-1], y[n-1]);
00872 PLINT i;
00873
00874 for (i = 0; i < n; i++) {
00875
00876 if (defined(x[i], y[i])) {
00877 if (!is_inside) {
00878 if (i > 0)
00879 bisect (defined, 10,
00880 x[i], y[i], x[i-1], y[i-1], &xb, &yb);
00881 else
00882 bisect (defined, 10,
00883 x[i], y[i], x[n-1], y[n-1], &xb, &yb);
00884 xx[count] = xb;
00885 yy[count++] = yb;
00886 }
00887 xx[count] = x[i];
00888 yy[count++] = y[i];
00889 is_inside = 1;
00890 }
00891 else {
00892 if (is_inside) {
00893 if (i > 0)
00894 bisect (defined, 10,
00895 x[i-1], y[i-1], x[i], y[i], &xb, &yb);
00896 else
00897 bisect (defined, 10,
00898 x[n-1], y[n-1], x[i], y[i], &xb, &yb);
00899 xx[count] = xb;
00900 yy[count++] = yb;
00901 is_inside = 0;
00902 }
00903 }
00904 }
00905
00906 if (count)
00907 (*fill) (count, xx, yy);
00908 }
00909 }
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934 #define RATIO 3
00935 #define COND(x,y) cond_code[x*ny + y]
00936
00937 static void
00938 big_recl(int *cond_code, register int ny, int dx, int dy,
00939 int *ix, int *iy)
00940 {
00941
00942 int ok_x, ok_y, j;
00943 register int i, x, y;
00944 register int *cond;
00945
00946
00947
00948
00949 ok_x = ok_y = 1;
00950 x = y = 2;
00951
00952 while (ok_x || ok_y) {
00953 #ifdef RATIO
00954 if (RATIO * x <= y || RATIO * y <= x)
00955 break;
00956 #endif
00957 if (ok_y) {
00958
00959 ok_y = 0;
00960 if (y == dy)
00961 continue;
00962 cond = &COND(0, y);
00963 for (i = 0; i < x; i++) {
00964 if (*cond != OK)
00965 break;
00966 cond += ny;
00967 }
00968 if (i == x) {
00969
00970 y++;
00971 ok_y = 1;
00972 }
00973 }
00974 if (ok_x) {
00975 if (y == 2)
00976 break;
00977
00978 ok_x = 0;
00979 if (x == dx)
00980 continue;
00981 cond = &COND(x, 0);
00982 for (i = 0; i < y; i++) {
00983 if (*cond++ != OK)
00984 break;
00985 }
00986 if (i == y) {
00987
00988 x++;
00989 ok_x = 1;
00990 }
00991 }
00992 }
00993
00994
00995 *ix = --x;
00996 *iy = --y;
00997
00998
00999
01000 for (i = 1; i < x; i++) {
01001 cond = &COND(i, 1);
01002 for (j = 1; j < y; j++) {
01003 *cond++ = UNDEF;
01004 }
01005 }
01006 }
01007
01008
01009
01010
01011
01012
01013
01014 static void
01015 draw_boundary(PLINT slope, PLFLT *x, PLFLT *y)
01016 {
01017 int i;
01018
01019 if (pen_col_min != 0 && pen_wd_min != 0 && min_points != 0) {
01020 plcol0(pen_col_min);
01021 plwid(pen_wd_min);
01022 if (min_points == 4 && slope == 0) {
01023
01024 i = min_pts[1];
01025 min_pts[1] = min_pts[3];
01026 min_pts[3] = i;
01027 }
01028 pljoin(x[min_pts[0]], y[min_pts[0]], x[min_pts[1]], y[min_pts[1]]);
01029 if (min_points == 4) {
01030 pljoin(x[min_pts[2]], y[min_pts[2]], x[min_pts[3]],
01031 y[min_pts[3]]);
01032 }
01033 }
01034 if (pen_col_max != 0 && pen_wd_max != 0 && max_points != 0) {
01035 plcol0(pen_col_max);
01036 plwid(pen_wd_max);
01037 if (max_points == 4 && slope == 0) {
01038
01039 i = max_pts[1];
01040 max_pts[1] = max_pts[3];
01041 max_pts[3] = i;
01042 }
01043 pljoin(x[max_pts[0]], y[max_pts[0]], x[max_pts[1]], y[max_pts[1]]);
01044 if (max_points == 4) {
01045 pljoin(x[max_pts[2]], y[max_pts[2]], x[max_pts[3]],
01046 y[max_pts[3]]);
01047 }
01048 }
01049 }
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084 #define X(a,b) (x[a*4+b])
01085 #define POSITIVE_SLOPE (PLINT) 1
01086 #define NEGATIVE_SLOPE (PLINT) 0
01087 #define RATIO_SQ 6.0
01088
01089 static PLINT
01090 plctest(PLFLT *x, PLFLT level)
01091 {
01092 int i, j;
01093 double t[4], sorted[4], temp;
01094
01095 sorted[0] = t[0] = X(1,1);
01096 sorted[1] = t[1] = X(2,2);
01097 sorted[2] = t[2] = X(1,2);
01098 sorted[3] = t[3] = X(2,1);
01099
01100 for (j = 1; j < 4; j++) {
01101 temp = sorted[j];
01102 i = j - 1;
01103 while (i >= 0 && sorted[i] > temp) {
01104 sorted[i+1] = sorted[i];
01105 i--;
01106 }
01107 sorted[i+1] = temp;
01108 }
01109
01110
01111
01112 temp = int_val * ceil(sorted[0]/int_val);
01113 if (temp < sorted[1]) {
01114
01115 for (i = 0; i < 4; i++) {
01116 if (t[i] < temp) return i/2;
01117 }
01118 }
01119
01120
01121 temp = int_val * floor(sorted[3]/int_val);
01122 if (temp > sorted[2]) {
01123
01124 for (i = 0; i < 4; i++) {
01125 if (t[i] > temp) return i/2;
01126 }
01127 }
01128
01129 return POSITIVE_SLOPE;
01130 }
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141 static PLINT
01142 plctestez(PLFLT *a, PLINT nx, PLINT ny, PLINT ix,
01143 PLINT iy, PLFLT level)
01144 {
01145
01146 PLFLT x[4][4];
01147 int i, j, ii, jj;
01148
01149 for (i = 0; i < 4; i++) {
01150 ii = ix + i - 1;
01151 ii = MAX(0, ii);
01152 ii = MIN(ii, nx - 1);
01153 for (j = 0; j < 4; j++) {
01154 jj = iy + j - 1;
01155 jj = MAX(0, jj);
01156 jj = MIN(jj, ny - 1);
01157 x[i][j] = a[ii * ny + jj];
01158 }
01159 }
01160 return plctest(&(x[0][0]), level);
01161 }