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 #define NUMBER_BISECTIONS 10
00136
00137 #define linear( val1, val2, level ) ( ( level - val1 ) / ( val2 - val1 ) )
00138
00139
00140
00141 static PLFLT sh_max, sh_min;
00142 static int min_points, max_points, n_point;
00143 static int min_pts[4], max_pts[4];
00144 static PLINT pen_col_min, pen_col_max;
00145 static PLINT pen_wd_min, pen_wd_max;
00146 static PLFLT int_val;
00147
00148
00149
00150 static void
00151 set_cond( register int *cond, register PLFLT *a, register PLINT n );
00152
00153 static int
00154 find_interval( PLFLT a0, PLFLT a1, PLINT c0, PLINT c1, PLFLT *x );
00155
00156 static void
00157 selected_polygon( void ( *fill )( PLINT, const PLFLT *, const PLFLT * ),
00158 PLINT ( *defined )( PLFLT, PLFLT ),
00159 const PLFLT *x, const PLFLT *y, PLINT v1, PLINT v2, PLINT v3, PLINT v4 );
00160
00161 static void
00162 exfill( void ( *fill )( PLINT, const PLFLT *, const PLFLT * ),
00163 PLINT ( *defined )( PLFLT, PLFLT ),
00164 int n, const PLFLT *x, const PLFLT *y );
00165
00166 static void
00167 big_recl( int *cond_code, register int ny, int dx, int dy,
00168 int *ix, int *iy );
00169
00170 static void
00171 draw_boundary( PLINT slope, PLFLT *x, PLFLT *y );
00172
00173 static PLINT
00174 plctest( PLFLT *x, PLFLT level );
00175
00176 static PLINT
00177 plctestez( PLFLT *a, PLINT nx, PLINT ny, PLINT ix,
00178 PLINT iy, PLFLT level );
00179
00180 static void
00181 plshade_int( PLFLT ( *f2eval )( PLINT, PLINT, PLPointer ),
00182 PLPointer f2eval_data,
00183 PLFLT ( *c2eval )( PLINT, PLINT, PLPointer ),
00184 PLPointer c2eval_data,
00185 PLINT ( *defined )( PLFLT, PLFLT ),
00186 PLFLT missing_min, PLFLT missing_max,
00187 PLINT nx, PLINT ny,
00188 PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax,
00189 PLFLT shade_min, PLFLT shade_max,
00190 PLINT sh_cmap, PLFLT sh_color, PLINT sh_width,
00191 PLINT min_color, PLINT min_width,
00192 PLINT max_color, PLINT max_width,
00193 void ( *fill )( PLINT, const PLFLT *, const PLFLT * ), PLINT rectangular,
00194 void ( *pltr )( PLFLT, PLFLT, PLFLT *, PLFLT *, PLPointer ),
00195 PLPointer pltr_data );
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210 void c_plshades( const PLFLT **a, PLINT nx, PLINT ny, PLINT ( *defined )( PLFLT, PLFLT ),
00211 PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax,
00212 const PLFLT *clevel, PLINT nlevel, PLINT fill_width,
00213 PLINT cont_color, PLINT cont_width,
00214 void ( *fill )( PLINT, const PLFLT *, const PLFLT * ), PLINT rectangular,
00215 void ( *pltr )( PLFLT, PLFLT, PLFLT *, PLFLT *, PLPointer ),
00216 PLPointer pltr_data )
00217 {
00218 plfshades( plf2ops_c(), a, nx, ny, defined,
00219 xmin, xmax, ymin, ymax,
00220 clevel, nlevel, fill_width,
00221 cont_color, cont_width,
00222 fill, rectangular,
00223 pltr, pltr_data );
00224 }
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239 void
00240 plfshades( PLF2OPS zops, PLPointer zp, PLINT nx, PLINT ny,
00241 PLINT ( *defined )( PLFLT, PLFLT ),
00242 PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax,
00243 const PLFLT *clevel, PLINT nlevel, PLINT fill_width,
00244 PLINT cont_color, PLINT cont_width,
00245 void ( *fill )( PLINT, const PLFLT *, const PLFLT * ), PLINT rectangular,
00246 void ( *pltr )( PLFLT, PLFLT, PLFLT *, PLFLT *, PLPointer ),
00247 PLPointer pltr_data )
00248 {
00249 PLFLT shade_min, shade_max, shade_color;
00250 PLINT i, init_color, init_width;
00251 PLFLT color_min, color_max, color_range;
00252
00253
00254 color_min = plsc->cmap1_min;
00255 color_max = plsc->cmap1_max;
00256 color_range = color_max - color_min;
00257
00258 for ( i = 0; i < nlevel - 1; i++ )
00259 {
00260 shade_min = clevel[i];
00261 shade_max = clevel[i + 1];
00262 shade_color = color_min + i / (PLFLT) ( nlevel - 2 ) * color_range;
00263
00264
00265
00266
00267
00268
00269 plfshade1( zops, zp, nx, ny, defined, xmin, xmax, ymin, ymax,
00270 shade_min, shade_max,
00271 1, shade_color, fill_width,
00272 0, 0, 0, 0,
00273 fill, rectangular, pltr, pltr_data );
00274 }
00275 if ( cont_color > 0 && cont_width > 0 )
00276 {
00277 init_color = plsc->icol0;
00278 init_width = plsc->width;
00279 plcol0( cont_color );
00280 plwid( cont_width );
00281 if ( pltr )
00282 {
00283 plfcont( zops->f2eval, zp, nx, ny, 1, nx, 1, ny, clevel, nlevel, pltr, pltr_data );
00284 }
00285 else
00286 {
00287
00288
00289
00290
00291
00292 PLcGrid cgrid1;
00293 PLFLT *x, *y;
00294 cgrid1.nx = nx;
00295 cgrid1.ny = ny;
00296 x = (PLFLT *) malloc( nx * sizeof ( PLFLT ) );
00297 if ( x == NULL )
00298 plexit( "plfshades: Out of memory for x" );
00299 cgrid1.xg = x;
00300 for ( i = 0; i < nx; i++ )
00301 cgrid1.xg[i] = xmin + ( xmax - xmin ) * (float) i / (float) ( nx - 1 );
00302 y = (PLFLT *) malloc( ny * sizeof ( PLFLT ) );
00303 if ( y == NULL )
00304 plexit( "plfshades: Out of memory for y" );
00305 cgrid1.yg = y;
00306 for ( i = 0; i < ny; i++ )
00307 cgrid1.yg[i] = ymin + ( ymax - ymin ) * (float) i / (float) ( ny - 1 );
00308 plfcont( zops->f2eval, zp, nx, ny, 1, nx, 1, ny, clevel, nlevel,
00309 pltr1, (void *) &cgrid1 );
00310 free( x );
00311 free( y );
00312 }
00313 plcol0( init_color );
00314 plwid( init_width );
00315 }
00316 }
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326 void c_plshade( const PLFLT **a, PLINT nx, PLINT ny, PLINT ( *defined )( PLFLT, PLFLT ),
00327 PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax,
00328 PLFLT shade_min, PLFLT shade_max,
00329 PLINT sh_cmap, PLFLT sh_color, PLINT sh_width,
00330 PLINT min_color, PLINT min_width,
00331 PLINT max_color, PLINT max_width,
00332 void ( *fill )( PLINT, const PLFLT *, const PLFLT * ), PLINT rectangular,
00333 void ( *pltr )( PLFLT, PLFLT, PLFLT *, PLFLT *, PLPointer ),
00334 PLPointer pltr_data )
00335 {
00336 plshade_int( plf2eval1, (PLPointer) a,
00337 NULL, NULL,
00338
00339 defined, MISSING_MIN_DEF, MISSING_MAX_DEF, nx, ny, xmin,
00340 xmax, ymin, ymax, shade_min, shade_max,
00341 sh_cmap, sh_color, sh_width,
00342 min_color, min_width, max_color, max_width,
00343 fill, rectangular, pltr, pltr_data );
00344 }
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354 void c_plshade1( const PLFLT *a, PLINT nx, PLINT ny, PLINT ( *defined )( PLFLT, PLFLT ),
00355 PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax,
00356 PLFLT shade_min, PLFLT shade_max,
00357 PLINT sh_cmap, PLFLT sh_color, PLINT sh_width,
00358 PLINT min_color, PLINT min_width,
00359 PLINT max_color, PLINT max_width,
00360 void ( *fill )( PLINT, const PLFLT *, const PLFLT * ), PLINT rectangular,
00361 void ( *pltr )( PLFLT, PLFLT, PLFLT *, PLFLT *, PLPointer ),
00362 PLPointer pltr_data )
00363 {
00364 PLfGrid grid;
00365
00366 grid.f = (PLFLT *) a;
00367 grid.nx = nx;
00368 grid.ny = ny;
00369
00370 plshade_int( plf2eval, ( PLPointer ) & grid,
00371 NULL, NULL,
00372
00373 defined, MISSING_MIN_DEF, MISSING_MAX_DEF, nx, ny, xmin,
00374 xmax, ymin, ymax, shade_min, shade_max,
00375 sh_cmap, sh_color, sh_width,
00376 min_color, min_width, max_color, max_width,
00377 fill, rectangular, pltr, pltr_data );
00378 }
00379
00380
00381
00382
00383
00384
00385
00386
00387 void
00388 plfshade( PLFLT ( *f2eval )( PLINT, PLINT, PLPointer ),
00389 PLPointer f2eval_data,
00390 PLFLT ( *c2eval )( PLINT, PLINT, PLPointer ),
00391 PLPointer c2eval_data,
00392 PLINT nx, PLINT ny,
00393 PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax,
00394 PLFLT shade_min, PLFLT shade_max,
00395 PLINT sh_cmap, PLFLT sh_color, PLINT sh_width,
00396 PLINT min_color, PLINT min_width,
00397 PLINT max_color, PLINT max_width,
00398 void ( *fill )( PLINT, const PLFLT *, const PLFLT * ), PLINT rectangular,
00399 void ( *pltr )( PLFLT, PLFLT, PLFLT *, PLFLT *, PLPointer ),
00400 PLPointer pltr_data )
00401 {
00402 plshade_int( f2eval, f2eval_data, c2eval, c2eval_data,
00403 NULL, MISSING_MIN_DEF, MISSING_MAX_DEF,
00404 nx, ny, xmin, xmax, ymin, ymax,
00405 shade_min, shade_max, sh_cmap, sh_color, sh_width,
00406 min_color, min_width, max_color, max_width,
00407 fill, rectangular, pltr, pltr_data );
00408 }
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421 void
00422 plfshade1( PLF2OPS zops, PLPointer zp, PLINT nx, PLINT ny,
00423 PLINT ( *defined )( PLFLT, PLFLT ),
00424 PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax,
00425 PLFLT shade_min, PLFLT shade_max,
00426 PLINT sh_cmap, PLFLT sh_color, PLINT sh_width,
00427 PLINT min_color, PLINT min_width,
00428 PLINT max_color, PLINT max_width,
00429 void ( *fill )( PLINT, const PLFLT *, const PLFLT * ), PLINT rectangular,
00430 void ( *pltr )( PLFLT, PLFLT, PLFLT *, PLFLT *, PLPointer ),
00431 PLPointer pltr_data )
00432 {
00433 plshade_int( zops->f2eval, zp,
00434 NULL, NULL,
00435
00436 defined, MISSING_MIN_DEF, MISSING_MAX_DEF, nx, ny, xmin,
00437 xmax, ymin, ymax, shade_min, shade_max,
00438 sh_cmap, sh_color, sh_width,
00439 min_color, min_width, max_color, max_width,
00440 fill, rectangular, pltr, pltr_data );
00441 }
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482 static void
00483 plshade_int( PLFLT ( *f2eval )( PLINT, PLINT, PLPointer ),
00484 PLPointer f2eval_data,
00485 PLFLT ( *c2eval )( PLINT, PLINT, PLPointer ),
00486 PLPointer c2eval_data,
00487 PLINT ( *defined )( PLFLT, PLFLT ),
00488 PLFLT missing_min, PLFLT missing_max,
00489 PLINT nx, PLINT ny,
00490 PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax,
00491 PLFLT shade_min, PLFLT shade_max,
00492 PLINT sh_cmap, PLFLT sh_color, PLINT sh_width,
00493 PLINT min_color, PLINT min_width,
00494 PLINT max_color, PLINT max_width,
00495 void ( *fill )( PLINT, const PLFLT *, const PLFLT * ), PLINT rectangular,
00496 void ( *pltr )( PLFLT, PLFLT, PLFLT *, PLFLT *, PLPointer ),
00497 PLPointer pltr_data )
00498 {
00499 PLINT init_width, n, slope = 0, ix, iy;
00500 int count, i, j, nxny;
00501 PLFLT *a, *a0, *a1, dx, dy;
00502 PLFLT x[8], y[8], xp[2], tx, ty;
00503 int *c, *c0, *c1;
00504
00505 if ( plsc->level < 3 )
00506 {
00507 plabort( "plfshade: window must be set up first" );
00508 return;
00509 }
00510
00511 if ( nx <= 0 || ny <= 0 )
00512 {
00513 plabort( "plfshade: nx and ny must be positive" );
00514 return;
00515 }
00516
00517 if ( shade_min >= shade_max )
00518 {
00519 plabort( "plfshade: shade_max must exceed shade_min" );
00520 return;
00521 }
00522
00523 if ( pltr == NULL && plsc->coordinate_transform == NULL )
00524 rectangular = 1;
00525
00526 int_val = shade_max - shade_min;
00527 init_width = plsc->width;
00528
00529 pen_col_min = min_color;
00530 pen_col_max = max_color;
00531
00532 pen_wd_min = min_width;
00533 pen_wd_max = max_width;
00534
00535 plstyl( (PLINT) 0, NULL, NULL );
00536 plwid( sh_width );
00537 if ( fill != NULL )
00538 {
00539 switch ( sh_cmap )
00540 {
00541 case 0:
00542 plcol0( (PLINT) sh_color );
00543 break;
00544 case 1:
00545 plcol1( sh_color );
00546 break;
00547 default:
00548 plabort( "plfshade: invalid color map selection" );
00549 return;
00550 }
00551 }
00552
00553
00554 nxny = nx * ny;
00555 if ( ( a = (PLFLT *) malloc( nxny * sizeof ( PLFLT ) ) ) == NULL )
00556 {
00557 plabort( "plfshade: unable to allocate memory for value array" );
00558 return;
00559 }
00560
00561 for ( ix = 0; ix < nx; ix++ )
00562 for ( iy = 0; iy < ny; iy++ )
00563 a[iy + ix * ny] = f2eval( ix, iy, f2eval_data );
00564
00565
00566
00567 if ( ( c = (int *) malloc( nxny * sizeof ( int ) ) ) == NULL )
00568 {
00569 plabort( "plfshade: unable to allocate memory for condition codes" );
00570 free( a );
00571 return;
00572 }
00573
00574 sh_min = shade_min;
00575 sh_max = shade_max;
00576
00577 set_cond( c, a, nxny );
00578 dx = ( xmax - xmin ) / ( nx - 1 );
00579 dy = ( ymax - ymin ) / ( ny - 1 );
00580 a0 = a;
00581 a1 = a + ny;
00582 c0 = c;
00583 c1 = c + ny;
00584
00585 for ( ix = 0; ix < nx - 1; ix++ )
00586 {
00587 for ( iy = 0; iy < ny - 1; iy++ )
00588 {
00589 count = c0[iy] + c0[iy + 1] + c1[iy] + c1[iy + 1];
00590
00591
00592
00593 if ( count >= UNDEF )
00594 continue;
00595 if ( count == 4 * POS )
00596 continue;
00597 if ( count == 4 * NEG )
00598 continue;
00599
00600
00601
00602 if ( count == 4 * OK )
00603 {
00604
00605 if ( rectangular )
00606 {
00607 big_recl( c0 + iy, ny, nx - ix, ny - iy, &i, &j );
00608 }
00609 else
00610 {
00611 i = j = 1;
00612 }
00613 x[0] = x[1] = ix;
00614 x[2] = x[3] = ix + i;
00615 y[0] = y[3] = iy;
00616 y[1] = y[2] = iy + j;
00617
00618 if ( pltr )
00619 {
00620 for ( i = 0; i < 4; i++ )
00621 {
00622 ( *pltr )( x[i], y[i], &tx, &ty, pltr_data );
00623 x[i] = tx;
00624 y[i] = ty;
00625 }
00626 }
00627 else
00628 {
00629 for ( i = 0; i < 4; i++ )
00630 {
00631 x[i] = xmin + x[i] * dx;
00632 y[i] = ymin + y[i] * dy;
00633 }
00634 }
00635 if ( fill != NULL )
00636 exfill( fill, defined, (PLINT) 4, x, y );
00637 iy += j - 1;
00638 continue;
00639 }
00640
00641
00642
00643 n_point = min_points = max_points = 0;
00644 n = find_interval( a0[iy], a0[iy + 1], c0[iy], c0[iy + 1], xp );
00645 for ( j = 0; j < n; j++ )
00646 {
00647 x[j] = ix;
00648 y[j] = iy + xp[j];
00649 }
00650
00651 i = find_interval( a0[iy + 1], a1[iy + 1],
00652 c0[iy + 1], c1[iy + 1], xp );
00653
00654 for ( j = 0; j < i; j++ )
00655 {
00656 x[j + n] = ix + xp[j];
00657 y[j + n] = iy + 1;
00658 }
00659 n += i;
00660
00661 i = find_interval( a1[iy + 1], a1[iy], c1[iy + 1], c1[iy], xp );
00662 for ( j = 0; j < i; j++ )
00663 {
00664 x[n + j] = ix + 1;
00665 y[n + j] = iy + 1 - xp[j];
00666 }
00667 n += i;
00668
00669 i = find_interval( a1[iy], a0[iy], c1[iy], c0[iy], xp );
00670 for ( j = 0; j < i; j++ )
00671 {
00672 x[n + j] = ix + 1 - xp[j];
00673 y[n + j] = iy;
00674 }
00675 n += i;
00676
00677 if ( pltr )
00678 {
00679 for ( i = 0; i < n; i++ )
00680 {
00681 ( *pltr )( x[i], y[i], &tx, &ty, pltr_data );
00682 x[i] = tx;
00683 y[i] = ty;
00684 }
00685 }
00686 else
00687 {
00688 for ( i = 0; i < n; i++ )
00689 {
00690 x[i] = xmin + x[i] * dx;
00691 y[i] = ymin + y[i] * dy;
00692 }
00693 }
00694
00695 if ( min_points == 4 )
00696 slope = plctestez( a, nx, ny, ix, iy, shade_min );
00697 if ( max_points == 4 )
00698 slope = plctestez( a, nx, ny, ix, iy, shade_max );
00699
00700
00701
00702
00703
00704
00705
00706 switch ( ( min_points << 3 ) + max_points )
00707 {
00708 case 000:
00709 case 020:
00710 case 002:
00711 case 022:
00712 if ( fill != NULL && n > 0 )
00713 exfill( fill, defined, n, x, y );
00714 break;
00715 case 040:
00716 case 004:
00717 if ( n != 6 )
00718 fprintf( stderr, "plfshade err n=%d !6", (int) n );
00719 if ( slope == 1 && c0[iy] == OK )
00720 {
00721 if ( fill != NULL )
00722 exfill( fill, defined, n, x, y );
00723 }
00724 else if ( slope == 1 )
00725 {
00726 selected_polygon( fill, defined, x, y, 0, 1, 2, -1 );
00727 selected_polygon( fill, defined, x, y, 3, 4, 5, -1 );
00728 }
00729 else if ( c0[iy + 1] == OK )
00730 {
00731 if ( fill != NULL )
00732 exfill( fill, defined, n, x, y );
00733 }
00734 else
00735 {
00736 selected_polygon( fill, defined, x, y, 0, 1, 5, -1 );
00737 selected_polygon( fill, defined, x, y, 2, 3, 4, -1 );
00738 }
00739 break;
00740 case 044:
00741 if ( n != 8 )
00742 fprintf( stderr, "plfshade err n=%d !8", (int) n );
00743 if ( slope == 1 )
00744 {
00745 selected_polygon( fill, defined, x, y, 0, 1, 2, 3 );
00746 selected_polygon( fill, defined, x, y, 4, 5, 6, 7 );
00747 }
00748 else
00749 {
00750 selected_polygon( fill, defined, x, y, 0, 1, 6, 7 );
00751 selected_polygon( fill, defined, x, y, 2, 3, 4, 5 );
00752 }
00753 break;
00754 case 024:
00755 case 042:
00756
00757 if ( n != 7 )
00758 fprintf( stderr, "plfshade err n=%d !7", (int) n );
00759
00760 if ( ( c0[iy] == OK || c1[iy + 1] == OK ) && slope == 1 )
00761 {
00762 if ( fill != NULL )
00763 exfill( fill, defined, n, x, y );
00764 }
00765 else if ( ( c0[iy + 1] == OK || c1[iy] == OK ) && slope == 0 )
00766 {
00767 if ( fill != NULL )
00768 exfill( fill, defined, n, x, y );
00769 }
00770
00771 else if ( c0[iy] == OK )
00772 {
00773 selected_polygon( fill, defined, x, y, 0, 1, 6, -1 );
00774 selected_polygon( fill, defined, x, y, 2, 3, 4, 5 );
00775 }
00776 else if ( c0[iy + 1] == OK )
00777 {
00778 selected_polygon( fill, defined, x, y, 0, 1, 2, -1 );
00779 selected_polygon( fill, defined, x, y, 3, 4, 5, 6 );
00780 }
00781 else if ( c1[iy + 1] == OK )
00782 {
00783 selected_polygon( fill, defined, x, y, 0, 1, 5, 6 );
00784 selected_polygon( fill, defined, x, y, 2, 3, 4, -1 );
00785 }
00786 else if ( c1[iy] == OK )
00787 {
00788 selected_polygon( fill, defined, x, y, 0, 1, 2, 3 );
00789 selected_polygon( fill, defined, x, y, 4, 5, 6, -1 );
00790 }
00791 else
00792 {
00793 fprintf( stderr, "plfshade err logic case 024:042\n" );
00794 }
00795 break;
00796 default:
00797 fprintf( stderr, "prog err switch\n" );
00798 break;
00799 }
00800 draw_boundary( slope, x, y );
00801
00802 if ( fill != NULL )
00803 {
00804 plwid( sh_width );
00805 if ( sh_cmap == 0 )
00806 plcol0( (PLINT) sh_color );
00807 else if ( sh_cmap == 1 )
00808 plcol1( sh_color );
00809 }
00810 }
00811
00812 a0 = a1;
00813 c0 = c1;
00814 a1 += ny;
00815 c1 += ny;
00816 }
00817
00818 free( c );
00819 free( a );
00820 plwid( init_width );
00821 }
00822
00823
00824
00825
00826
00827
00828
00829 static void
00830 set_cond( register int *cond, register PLFLT *a, register PLINT n )
00831 {
00832 while ( n-- )
00833 {
00834 if ( *a < sh_min )
00835 *cond++ = NEG;
00836 else if ( *a > sh_max )
00837 *cond++ = POS;
00838 else
00839 *cond++ = OK;
00840 a++;
00841 }
00842 }
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855 static int
00856 find_interval( PLFLT a0, PLFLT a1, PLINT c0, PLINT c1, PLFLT *x )
00857 {
00858 register int n;
00859
00860 n = 0;
00861 if ( c0 == OK )
00862 {
00863 x[n++] = 0.0;
00864 n_point++;
00865 }
00866 if ( c0 == c1 )
00867 return n;
00868
00869 if ( c0 == NEG || c1 == POS )
00870 {
00871 if ( c0 == NEG )
00872 {
00873 x[n++] = linear( a0, a1, sh_min );
00874 min_pts[min_points++] = n_point++;
00875 }
00876 if ( c1 == POS )
00877 {
00878 x[n++] = linear( a0, a1, sh_max );
00879 max_pts[max_points++] = n_point++;
00880 }
00881 }
00882 if ( c0 == POS || c1 == NEG )
00883 {
00884 if ( c0 == POS )
00885 {
00886 x[n++] = linear( a0, a1, sh_max );
00887 max_pts[max_points++] = n_point++;
00888 }
00889 if ( c1 == NEG )
00890 {
00891 x[n++] = linear( a0, a1, sh_min );
00892 min_pts[min_points++] = n_point++;
00893 }
00894 }
00895 return n;
00896 }
00897
00898
00899
00900
00901
00902
00903
00904
00905 static void
00906 selected_polygon( void ( *fill )( PLINT, const PLFLT *, const PLFLT * ),
00907 PLINT ( *defined )( PLFLT, PLFLT ),
00908 const PLFLT *x, const PLFLT *y, PLINT v1, PLINT v2, PLINT v3, PLINT v4 )
00909 {
00910 register PLINT n = 0;
00911 PLFLT xx[4], yy[4];
00912
00913 if ( fill == NULL )
00914 return;
00915 if ( v1 >= 0 )
00916 {
00917 xx[n] = x[v1];
00918 yy[n++] = y[v1];
00919 }
00920 if ( v2 >= 0 )
00921 {
00922 xx[n] = x[v2];
00923 yy[n++] = y[v2];
00924 }
00925 if ( v3 >= 0 )
00926 {
00927 xx[n] = x[v3];
00928 yy[n++] = y[v3];
00929 }
00930 if ( v4 >= 0 )
00931 {
00932 xx[n] = x[v4];
00933 yy[n++] = y[v4];
00934 }
00935 exfill( fill, defined, n, (PLFLT *) xx, (PLFLT *) yy );
00936 }
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946 static void
00947 bisect( PLINT ( *defined )( PLFLT, PLFLT ), PLINT niter,
00948 PLFLT x1, PLFLT y1, PLFLT x2, PLFLT y2, PLFLT* xb, PLFLT* yb )
00949 {
00950 PLFLT xm;
00951 PLFLT ym;
00952
00953 if ( niter == 0 )
00954 {
00955 *xb = x1;
00956 *yb = y1;
00957 return;
00958 }
00959
00960 xm = ( x1 + x2 ) / 2.;
00961 ym = ( y1 + y2 ) / 2.;
00962
00963 if ( defined( xm, ym ) )
00964 bisect( defined, niter - 1, xm, ym, x2, y2, xb, yb );
00965 else
00966 bisect( defined, niter - 1, x1, y1, xm, ym, xb, yb );
00967 }
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983 static void
00984 exfill( void ( *fill )( PLINT, const PLFLT *, const PLFLT * ),
00985 PLINT ( *defined )( PLFLT, PLFLT ),
00986 int n, const PLFLT *x, const PLFLT *y )
00987 {
00988 if ( n < 3 )
00989 {
00990 plabort( "exfill: Not enough points in object" );
00991 return;
00992 }
00993
00994 if ( defined == NULL )
00995
00996 ( *fill )( n, x, y );
00997
00998 else
00999 {
01000 PLFLT *xx;
01001 PLFLT *yy;
01002 PLFLT xb, yb;
01003 PLINT count = 0;
01004 PLINT im1 = n - 1;
01005 PLINT is_defined = defined( x[im1], y[im1] );
01006 PLINT i;
01007
01008
01009
01010 if ( ( xx = (PLFLT *) malloc( 2 * n * sizeof ( PLFLT ) ) ) == NULL )
01011 plexit( "exfill: out of memory for xx" );
01012 if ( ( yy = (PLFLT *) malloc( 2 * n * sizeof ( PLFLT ) ) ) == NULL )
01013 plexit( "exfill: out of memory for yy." );
01014
01015 for ( i = 0; i < n; i++ )
01016 {
01017
01018 if ( defined( x[i], y[i] ) )
01019 {
01020 if ( !is_defined )
01021 {
01022
01023
01024
01025 bisect( defined, NUMBER_BISECTIONS,
01026 x[i], y[i], x[im1], y[im1], &xb, &yb );
01027 xx[count] = xb;
01028 yy[count++] = yb;
01029 }
01030
01031
01032 xx[count] = x[i];
01033 yy[count++] = y[i];
01034 is_defined = 1;
01035 }
01036 else
01037 {
01038 if ( is_defined )
01039 {
01040
01041
01042
01043 bisect( defined, NUMBER_BISECTIONS,
01044 x[im1], y[im1], x[i], y[i], &xb, &yb );
01045 xx[count] = xb;
01046 yy[count++] = yb;
01047 is_defined = 0;
01048 }
01049 }
01050 im1 = i;
01051 }
01052
01053 if ( count >= 3 )
01054 ( *fill )( count, (const PLFLT *) xx, (const PLFLT *) yy );
01055
01056 free( xx );
01057 free( yy );
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 RATIO 3
01085 #define COND( x, y ) cond_code[x * ny + y]
01086
01087 static void
01088 big_recl( int *cond_code, register int ny, int dx, int dy,
01089 int *ix, int *iy )
01090 {
01091 int ok_x, ok_y, j;
01092 register int i, x, y;
01093 register int *cond;
01094
01095
01096
01097
01098 ok_x = ok_y = 1;
01099 x = y = 2;
01100
01101 while ( ok_x || ok_y )
01102 {
01103 #ifdef RATIO
01104 if ( RATIO * x <= y || RATIO * y <= x )
01105 break;
01106 #endif
01107 if ( ok_y )
01108 {
01109
01110 ok_y = 0;
01111 if ( y == dy )
01112 continue;
01113 cond = &COND( 0, y );
01114 for ( i = 0; i < x; i++ )
01115 {
01116 if ( *cond != OK )
01117 break;
01118 cond += ny;
01119 }
01120 if ( i == x )
01121 {
01122
01123 y++;
01124 ok_y = 1;
01125 }
01126 }
01127 if ( ok_x )
01128 {
01129 if ( y == 2 )
01130 break;
01131
01132 ok_x = 0;
01133 if ( x == dx )
01134 continue;
01135 cond = &COND( x, 0 );
01136 for ( i = 0; i < y; i++ )
01137 {
01138 if ( *cond++ != OK )
01139 break;
01140 }
01141 if ( i == y )
01142 {
01143
01144 x++;
01145 ok_x = 1;
01146 }
01147 }
01148 }
01149
01150
01151 *ix = --x;
01152 *iy = --y;
01153
01154
01155
01156 for ( i = 1; i < x; i++ )
01157 {
01158 cond = &COND( i, 1 );
01159 for ( j = 1; j < y; j++ )
01160 {
01161 *cond++ = UNDEF;
01162 }
01163 }
01164 }
01165
01166
01167
01168
01169
01170
01171
01172 static void
01173 draw_boundary( PLINT slope, PLFLT *x, PLFLT *y )
01174 {
01175 int i;
01176
01177 if ( pen_col_min != 0 && pen_wd_min != 0 && min_points != 0 )
01178 {
01179 plcol0( pen_col_min );
01180 plwid( pen_wd_min );
01181 if ( min_points == 4 && slope == 0 )
01182 {
01183
01184 i = min_pts[1];
01185 min_pts[1] = min_pts[3];
01186 min_pts[3] = i;
01187 }
01188 pljoin( x[min_pts[0]], y[min_pts[0]], x[min_pts[1]], y[min_pts[1]] );
01189 if ( min_points == 4 )
01190 {
01191 pljoin( x[min_pts[2]], y[min_pts[2]], x[min_pts[3]],
01192 y[min_pts[3]] );
01193 }
01194 }
01195 if ( pen_col_max != 0 && pen_wd_max != 0 && max_points != 0 )
01196 {
01197 plcol0( pen_col_max );
01198 plwid( pen_wd_max );
01199 if ( max_points == 4 && slope == 0 )
01200 {
01201
01202 i = max_pts[1];
01203 max_pts[1] = max_pts[3];
01204 max_pts[3] = i;
01205 }
01206 pljoin( x[max_pts[0]], y[max_pts[0]], x[max_pts[1]], y[max_pts[1]] );
01207 if ( max_points == 4 )
01208 {
01209 pljoin( x[max_pts[2]], y[max_pts[2]], x[max_pts[3]],
01210 y[max_pts[3]] );
01211 }
01212 }
01213 }
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247
01248 #define X( a, b ) ( x[a * 4 + b] )
01249 #define POSITIVE_SLOPE (PLINT) 1
01250 #define NEGATIVE_SLOPE (PLINT) 0
01251 #define RATIO_SQ 6.0
01252
01253 static PLINT
01254 plctest( PLFLT *x, PLFLT level )
01255 {
01256 int i, j;
01257 double t[4], sorted[4], temp;
01258
01259 sorted[0] = t[0] = X( 1, 1 );
01260 sorted[1] = t[1] = X( 2, 2 );
01261 sorted[2] = t[2] = X( 1, 2 );
01262 sorted[3] = t[3] = X( 2, 1 );
01263
01264 for ( j = 1; j < 4; j++ )
01265 {
01266 temp = sorted[j];
01267 i = j - 1;
01268 while ( i >= 0 && sorted[i] > temp )
01269 {
01270 sorted[i + 1] = sorted[i];
01271 i--;
01272 }
01273 sorted[i + 1] = temp;
01274 }
01275
01276
01277
01278 temp = int_val * ceil( sorted[0] / int_val );
01279 if ( temp < sorted[1] )
01280 {
01281
01282 for ( i = 0; i < 4; i++ )
01283 {
01284 if ( t[i] < temp )
01285 return i / 2;
01286 }
01287 }
01288
01289
01290 temp = int_val * floor( sorted[3] / int_val );
01291 if ( temp > sorted[2] )
01292 {
01293
01294 for ( i = 0; i < 4; i++ )
01295 {
01296 if ( t[i] > temp )
01297 return i / 2;
01298 }
01299 }
01300
01301 return POSITIVE_SLOPE;
01302 }
01303
01304
01305
01306
01307
01308
01309
01310
01311
01312
01313 static PLINT
01314 plctestez( PLFLT *a, PLINT nx, PLINT ny, PLINT ix,
01315 PLINT iy, PLFLT level )
01316 {
01317 PLFLT x[4][4];
01318 int i, j, ii, jj;
01319
01320 for ( i = 0; i < 4; i++ )
01321 {
01322 ii = ix + i - 1;
01323 ii = MAX( 0, ii );
01324 ii = MIN( ii, nx - 1 );
01325 for ( j = 0; j < 4; j++ )
01326 {
01327 jj = iy + j - 1;
01328 jj = MAX( 0, jj );
01329 jj = MIN( jj, ny - 1 );
01330 x[i][j] = a[ii * ny + jj];
01331 }
01332 }
01333 return plctest( &( x[0][0] ), level );
01334 }