PLplot  5.13.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
plshade.c
Go to the documentation of this file.
1 // Functions to shade regions on the basis of value.
2 // Can be used to shade contour plots or alone.
3 // Copyright 1993 Wesley Ebisuzaki
4 //
5 // Copyright (C) 2004-2014 Alan W. Irwin
6 //
7 // This file is part of PLplot.
8 //
9 // PLplot is free software; you can redistribute it and/or modify
10 // it under the terms of the GNU Library General Public License as published
11 // by the Free Software Foundation; either version 2 of the License, or
12 // (at your option) any later version.
13 //
14 // PLplot is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 // GNU Library General Public License for more details.
18 //
19 // You should have received a copy of the GNU Library General Public License
20 // along with PLplot; if not, write to the Free Software
21 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 //
23 //
24 
25 //--------------------------------------------------------------------------
26 // Call syntax for plshade():
27 //
28 // void plshade(PLFLT *a, PLINT nx, PLINT ny, char *defined,
29 // PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax,
30 // PLFLT shade_min, PLFLT shade_max,
31 // PLINT sh_color, PLFLT sh_width, PLINT min_color, PLFLT min_width,
32 // PLINT max_color, PLFLT max_width, void (*fill)(), PLINT
33 // rectangular, ...)
34 //
35 // arguments:
36 //
37 // PLFLT &(a[0][0])
38 //
39 // Contains array to be plotted. The array must have been declared as
40 // PLFLT a[nx][ny]. See following note on fortran-style arrays.
41 //
42 // PLINT nx, ny
43 //
44 // Dimension of array "a".
45 //
46 // char &(defined[0][0])
47 //
48 // Contains array of flags, 1 = data is valid, 0 = data is not valid.
49 // This array determines which sections of the data is to be plotted.
50 // This argument can be NULL if all the values are valid. Must have been
51 // declared as char defined[nx][ny].
52 //
53 // PLFLT xmin, xmax, ymin, ymax
54 //
55 // Defines the "grid" coordinates. The data a[0][0] has a position of
56 // (xmin,ymin).
57 //
58 // void (*mapform)()
59 //
60 // Transformation from `grid' coordinates to world coordinates. This
61 // pointer to a function can be NULL in which case the grid coordinates
62 // are the same as the world coordinates.
63 //
64 // PLFLT shade_min, shade_max
65 //
66 // Defines the interval to be shaded. If shade_max <= shade_min, plshade
67 // does nothing.
68 //
69 // PLINT sh_cmap, PLFLT sh_color, PLFLT sh_width
70 //
71 // Defines color map, color map index, and width used by the fill pattern.
72 //
73 // PLINT min_color, PLFLT min_width, PLINT max_color, PLFLT max_width
74 //
75 // Defines pen color, width used by the boundary of shaded region. The min
76 // values are used for the shade_min boundary, and the max values are used
77 // on the shade_max boundary. Set color and width to zero for no plotted
78 // boundaries.
79 //
80 // void (*fill)()
81 //
82 // Routine used to fill the region. Use plfill. Future version of plplot
83 // may have other fill routines.
84 //
85 // PLINT rectangular
86 //
87 // Flag. Set to 1 if rectangles map to rectangles after (*mapform)() else
88 // set to zero. If rectangular is set to 1, plshade tries to save time by
89 // filling large rectangles. This optimization fails if (*mapform)()
90 // distorts the shape of rectangles. For example a plot in polor
91 // coordinates has to have rectangular set to zero.
92 //
93 // Example mapform's:
94 //
95 // Grid to world coordinate transformation.
96 // This example goes from a r-theta to x-y for a polar plot.
97 //
98 // void mapform(PLINT n, PLFLT *x, PLFLT *y) {
99 // int i;
100 // double r, theta;
101 // for (i = 0; i < n; i++) {
102 // r = x[i];
103 // theta = y[i];
104 // x[i] = r*cos(theta);
105 // y[i] = r*sin(theta);
106 // }
107 // }
108 //
109 // Grid was in cm, convert to world coordinates in inches.
110 // Expands in x direction.
111 //
112 // void mapform(PLINT n, PLFLT *x, PLFLT *y) {
113 // int i;
114 // for (i = 0; i < n; i++) {
115 // x[i] = (1.0 / 2.5) * x[i];
116 // y[i] = (1.0 / 2.5) * y[i];
117 // }
118 // }
119 //
120 //--------------------------------------------------------------------------
121 
122 #include "plplotP.h"
123 #include <float.h>
124 
125 #define NEG 1
126 #define POS 8
127 #define OK 0
128 #define UNDEF 64
129 #define NUMBER_BISECTIONS 10
130 
131 #define linear( val1, val2, level ) ( ( level - val1 ) / ( val2 - val1 ) )
132 
133 // Global variables
134 
137 static int min_pts[4], max_pts[4];
140 static PLFLT int_val;
141 
142 // Function prototypes
143 
144 static void
145 set_cond( register int *cond, register PLFLT *a, register PLINT n );
146 
147 static int
148 find_interval( PLFLT a0, PLFLT a1, PLINT c0, PLINT c1, PLFLT *x );
149 
150 static void
152  PLFLT_VECTOR x, PLFLT_VECTOR y, PLINT v1, PLINT v2, PLINT v3, PLINT v4 );
153 
154 static void
156  int n, PLFLT_VECTOR x, PLFLT_VECTOR y );
157 
158 static void
159 big_recl( int *cond_code, register int ny, int dx, int dy,
160  int *ix, int *iy );
161 
162 static void
163 draw_boundary( PLINT slope, PLFLT *x, PLFLT *y );
164 
165 static PLINT
166 plctest( PLFLT *x, PLFLT level );
167 
168 static PLINT
169 plctestez( PLFLT *a, PLINT nx, PLINT ny, PLINT ix,
170  PLINT iy, PLFLT level );
171 
172 static void
173 plshade_int( PLF2EVAL_callback f2eval, PLPointer f2eval_data,
174  PLF2EVAL_callback c2eval, PLPointer c2eval_data,
175  PLDEFINED_callback defined,
176  PLINT nx, PLINT ny,
177  PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax,
178  PLFLT shade_min, PLFLT shade_max,
179  PLINT sh_cmap, PLFLT sh_color, PLFLT sh_width,
180  PLINT min_color, PLFLT min_width,
181  PLINT max_color, PLFLT max_width,
182  PLFILL_callback fill, PLINT rectangular,
183  PLTRANSFORM_callback pltr, PLPointer pltr_data );
184 
185 // N.B. This routine only needed by the Fortran interface to distinguish
186 // the case where pltr and pltr_data are NULL. So don't put declaration in
187 // header which might encourage others to use this in some other context.
188 PLDLLIMPEXP void
190  PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax,
191  PLFLT_VECTOR clevel, PLINT nlevel, PLFLT fill_width,
192  PLINT cont_color, PLFLT cont_width,
193  PLFILL_callback fill, PLINT rectangular )
194 {
195  plfshades( plf2ops_c(), (PLPointer) a, nx, ny, defined,
196  xmin, xmax, ymin, ymax,
197  clevel, nlevel, fill_width,
198  cont_color, cont_width,
199  fill, rectangular,
200  NULL, NULL );
201 }
202 
203 //--------------------------------------------------------------------------
204 // plshades()
205 //
206 // Shade regions via a series of calls to plshade.
207 // All arguments are the same as plshade except the following:
208 // clevel is a pointer to an array of values representing
209 // the shade edge values, nlevel-1 is
210 // the number of different shades, (nlevel is the number of shade edges),
211 // fill_width is the pattern fill width, and cont_color and cont_width
212 // are the color and width of the contour drawn at each shade edge.
213 // (if cont_color <= 0 or cont_width <=0, no such contours are drawn).
214 //--------------------------------------------------------------------------
215 
217  PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax,
218  PLFLT_VECTOR clevel, PLINT nlevel, PLFLT fill_width,
219  PLINT cont_color, PLFLT cont_width,
220  PLFILL_callback fill, PLINT rectangular,
221  PLTRANSFORM_callback pltr, PLPointer pltr_data )
222 {
223  plfshades( plf2ops_c(), (PLPointer) a, nx, ny, defined,
224  xmin, xmax, ymin, ymax,
225  clevel, nlevel, fill_width,
226  cont_color, cont_width,
227  fill, rectangular,
228  pltr, pltr_data );
229 }
230 
231 //--------------------------------------------------------------------------
232 // plfshades()
233 //
234 // Shade regions via a series of calls to plfshade1.
235 // All arguments are the same as plfshade1 except the following:
236 // clevel is a pointer to an array of values representing
237 // the shade edge values, nlevel-1 is
238 // the number of different shades, (nlevel is the number of shade edges),
239 // fill_width is the pattern fill width, and cont_color and cont_width
240 // are the color and width of the contour drawn at each shade edge.
241 // (if cont_color <= 0 or cont_width <=0, no such contours are drawn).
242 //--------------------------------------------------------------------------
243 
244 void
246  PLDEFINED_callback defined,
247  PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax,
248  PLFLT_VECTOR clevel, PLINT nlevel, PLFLT fill_width,
249  PLINT cont_color, PLFLT cont_width,
250  PLFILL_callback fill, PLINT rectangular,
251  PLTRANSFORM_callback pltr, PLPointer pltr_data )
252 {
253  PLFLT shade_min, shade_max, shade_color;
254  PLINT i, init_color;
255  PLFLT init_width, color_min, color_max, color_range;
256 
257  // Color range to use
258  color_min = plsc->cmap1_min;
259  color_max = plsc->cmap1_max;
260  color_range = color_max - color_min;
261 
262  for ( i = 0; i < nlevel - 1; i++ )
263  {
264  shade_min = clevel[i];
265  shade_max = clevel[i + 1];
266  shade_color = color_min + i / (PLFLT) ( nlevel - 2 ) * color_range;
267  // The constants in order mean
268  // (1) color map1,
269  // (0, 0, 0, 0) all edge effects will be done with plcont rather
270  // than the normal plshade drawing which gets partially blocked
271  // when sequential shading is done as in the present case
272 
273  plfshade1( zops, zp, nx, ny, defined, xmin, xmax, ymin, ymax,
274  shade_min, shade_max,
275  1, shade_color, fill_width,
276  0, 0, 0, 0,
277  fill, rectangular, pltr, pltr_data );
278  }
279  if ( cont_color > 0 && cont_width > 0 )
280  {
281  init_color = plsc->icol0;
282  init_width = plsc->width;
283  plcol0( cont_color );
284  plwidth( cont_width );
285  if ( pltr )
286  {
287  plfcont( zops->f2eval, zp, nx, ny, 1, nx, 1, ny, clevel, nlevel, pltr, pltr_data );
288  }
289  else
290  {
291  // For this case use the same interpretation that occurs internally
292  // for plshade. That is set up x and y grids that map from the
293  // index ranges to xmin, xmax, ymin, ymax, and use those grids
294  // for the plcont call.
295  //
296  PLcGrid cgrid1;
297  PLFLT *x, *y;
298  cgrid1.nx = nx;
299  cgrid1.ny = ny;
300  x = (PLFLT *) malloc( (size_t) nx * sizeof ( PLFLT ) );
301  if ( x == NULL )
302  plexit( "plfshades: Out of memory for x" );
303  cgrid1.xg = x;
304  for ( i = 0; i < nx; i++ )
305  cgrid1.xg[i] = xmin + ( xmax - xmin ) * (float) i / (float) ( nx - 1 );
306  y = (PLFLT *) malloc( (size_t) ny * sizeof ( PLFLT ) );
307  if ( y == NULL )
308  plexit( "plfshades: Out of memory for y" );
309  cgrid1.yg = y;
310  for ( i = 0; i < ny; i++ )
311  cgrid1.yg[i] = ymin + ( ymax - ymin ) * (float) i / (float) ( ny - 1 );
312  plfcont( zops->f2eval, zp, nx, ny, 1, nx, 1, ny, clevel, nlevel,
313  pltr1, (void *) &cgrid1 );
314  free( x );
315  free( y );
316  }
317  plcol0( init_color );
318  plwidth( init_width );
319  }
320 }
321 
322 // N.B. This routine only needed by the Fortran interface to distinguish
323 // the case where pltr and pltr_data are NULL. So don't put declaration in
324 // header which might encourage others to use this in some other context.
325 PLDLLIMPEXP void
327  PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax,
328  PLFLT shade_min, PLFLT shade_max,
329  PLINT sh_cmap, PLFLT sh_color, PLFLT sh_width,
330  PLINT min_color, PLFLT min_width,
331  PLINT max_color, PLFLT max_width,
332  PLFILL_callback fill, PLINT rectangular )
333 {
335  NULL, NULL,
336 // plc2eval, (PLPointer) &cgrid,
337  defined, nx, ny, xmin,
338  xmax, ymin, ymax, shade_min, shade_max,
339  sh_cmap, sh_color, sh_width,
340  min_color, min_width, max_color, max_width,
341  fill, rectangular, NULL, NULL );
342 }
343 
344 //--------------------------------------------------------------------------
345 // plshade()
346 //
347 // Shade region.
348 // This interface to plfshade() assumes the 2d function array is passed
349 // via a (PLFLT **), and is column-dominant (normal C ordering).
350 //--------------------------------------------------------------------------
351 
353  PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax,
354  PLFLT shade_min, PLFLT shade_max,
355  PLINT sh_cmap, PLFLT sh_color, PLFLT sh_width,
356  PLINT min_color, PLFLT min_width,
357  PLINT max_color, PLFLT max_width,
358  PLFILL_callback fill, PLINT rectangular,
359  PLTRANSFORM_callback pltr, PLPointer pltr_data )
360 {
362  NULL, NULL,
363 // plc2eval, (PLPointer) &cgrid,
364  defined, nx, ny, xmin,
365  xmax, ymin, ymax, shade_min, shade_max,
366  sh_cmap, sh_color, sh_width,
367  min_color, min_width, max_color, max_width,
368  fill, rectangular, pltr, pltr_data );
369 }
370 
371 //--------------------------------------------------------------------------
372 // plshade1()
373 //
374 // Shade region.
375 // This interface to plfshade() assumes the 2d function array is passed
376 // via a (PLFLT *), and is column-dominant (normal C ordering).
377 //--------------------------------------------------------------------------
378 
380  PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax,
381  PLFLT shade_min, PLFLT shade_max,
382  PLINT sh_cmap, PLFLT sh_color, PLFLT sh_width,
383  PLINT min_color, PLFLT min_width,
384  PLINT max_color, PLFLT max_width,
385  PLFILL_callback fill, PLINT rectangular,
386  PLTRANSFORM_callback pltr, PLPointer pltr_data )
387 {
388  PLfGrid grid;
389 
390  grid.f = a;
391  grid.nx = nx;
392  grid.ny = ny;
393 
394  plshade_int( plf2eval, ( PLPointer ) & grid,
395  NULL, NULL,
396 // plc2eval, (PLPointer) &cgrid,
397  defined, nx, ny, xmin,
398  xmax, ymin, ymax, shade_min, shade_max,
399  sh_cmap, sh_color, sh_width,
400  min_color, min_width, max_color, max_width,
401  fill, rectangular, pltr, pltr_data );
402 }
403 
404 //--------------------------------------------------------------------------
405 // plfshade()
406 //
407 // Shade region.
408 // Array values are determined by the input function and the passed data.
409 //--------------------------------------------------------------------------
410 
411 void
412 plfshade( PLF2EVAL_callback f2eval, PLPointer f2eval_data,
413  PLF2EVAL_callback c2eval, PLPointer c2eval_data,
414  PLINT nx, PLINT ny,
415  PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax,
416  PLFLT shade_min, PLFLT shade_max,
417  PLINT sh_cmap, PLFLT sh_color, PLFLT sh_width,
418  PLINT min_color, PLFLT min_width,
419  PLINT max_color, PLFLT max_width,
420  PLFILL_callback fill, PLINT rectangular,
421  PLTRANSFORM_callback pltr, PLPointer pltr_data )
422 {
423  plshade_int( f2eval, f2eval_data, c2eval, c2eval_data,
424  NULL,
425  nx, ny, xmin, xmax, ymin, ymax,
426  shade_min, shade_max, sh_cmap, sh_color, sh_width,
427  min_color, min_width, max_color, max_width,
428  fill, rectangular, pltr, pltr_data );
429 }
430 
431 //--------------------------------------------------------------------------
432 // plfshade1()
433 //
434 // Shade region.
435 //
436 // This function is a plf2ops variant of c_plfshade and c_plfshade1. It
437 // differs from plfshade in that it supports a "defined" callback (like
438 // c_plshade and c_plfshade1) rather than a "defined mask" (like plfshade
439 // even though it is not yet implemented).
440 //--------------------------------------------------------------------------
441 
442 void
444  PLDEFINED_callback defined,
445  PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax,
446  PLFLT shade_min, PLFLT shade_max,
447  PLINT sh_cmap, PLFLT sh_color, PLFLT sh_width,
448  PLINT min_color, PLFLT min_width,
449  PLINT max_color, PLFLT max_width,
450  PLFILL_callback fill, PLINT rectangular,
451  PLTRANSFORM_callback pltr, PLPointer pltr_data )
452 {
453  plshade_int( zops->f2eval, zp,
454  NULL, NULL,
455 // plc2eval, (PLPointer) &cgrid,
456  defined, nx, ny, xmin,
457  xmax, ymin, ymax, shade_min, shade_max,
458  sh_cmap, sh_color, sh_width,
459  min_color, min_width, max_color, max_width,
460  fill, rectangular, pltr, pltr_data );
461 }
462 
463 //--------------------------------------------------------------------------
464 // plshade_int()
465 //
466 // Shade region -- this routine does all the work
467 //
468 // This routine is internal so the arguments can and will change.
469 // To retain some compatibility between versions, you must go through
470 // some stub routine!
471 //
472 // 4/95
473 //
474 // parameters:
475 //
476 // f2eval, f2eval_data: data to plot
477 // defined: defined mask (old API - implimented)
478 // nx, ny: array dimensions
479 // xmin, xmax, ymin, ymax: grid coordinates
480 // shade_min, shade_max: shade region with values between ...
481 // sh_cmap, sh_color, sh_width: shading parameters, width is only for hatching
482 // min_color, min_width: line parameters for boundary (minimum)
483 // max_color, max_width: line parameters for boundary (maximum)
484 // set min_width == 0 and max_width == 0 for no contours
485 // fill: fill function, set to NULL for no shading (contour plot)
486 // rectangular: flag set to 1 if pltr() maps rectangles to rectangles
487 // this helps optimize the plotting
488 // pltr: function to map from grid to plot coordinates
489 //
490 //
491 //--------------------------------------------------------------------------
492 
493 static void
495  PLF2EVAL_callback c2eval, PLPointer PL_UNUSED( c2eval_data ), //c2eval is unused.
496  PLDEFINED_callback defined,
497  PLINT nx, PLINT ny,
498  PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax,
499  PLFLT shade_min, PLFLT shade_max,
500  PLINT sh_cmap, PLFLT sh_color, PLFLT sh_width,
501  PLINT min_color, PLFLT min_width,
502  PLINT max_color, PLFLT max_width,
503  PLFILL_callback fill, PLINT rectangular,
504  PLTRANSFORM_callback pltr, PLPointer pltr_data )
505 {
506  PLINT n, slope = 0, ix, iy;
507  int count, i, j, nxny;
508  PLFLT *a, *a0, *a1, dx, dy;
509  PLFLT x[8], y[8], xp[2], tx, ty, init_width;
510  int *c, *c0, *c1;
511 
512  (void) c2eval; // Cast to void to silence compiler warning about unused parameter
513 
514  if ( plsc->level < 3 )
515  {
516  plabort( "plfshade: window must be set up first" );
517  return;
518  }
519 
520  if ( nx <= 0 || ny <= 0 )
521  {
522  plabort( "plfshade: nx and ny must be positive" );
523  return;
524  }
525 
526  if ( shade_min >= shade_max )
527  {
528  plabort( "plfshade: shade_max must exceed shade_min" );
529  return;
530  }
531 
532  if ( pltr == NULL && plsc->coordinate_transform == NULL )
533  rectangular = 1;
534 
535  int_val = shade_max - shade_min;
536  init_width = plsc->width;
537 
538  pen_col_min = min_color;
539  pen_col_max = max_color;
540 
541  pen_wd_min = min_width;
542  pen_wd_max = max_width;
543 
544  plstyl( (PLINT) 0, NULL, NULL );
545  plwidth( sh_width );
546  if ( fill != NULL )
547  {
548  switch ( sh_cmap )
549  {
550  case 0:
551  plcol0( (PLINT) sh_color );
552  break;
553  case 1:
554  plcol1( sh_color );
555  break;
556  default:
557  plabort( "plfshade: invalid color map selection" );
558  return;
559  }
560  }
561  // alloc space for value array, and initialize
562  // This is only a temporary kludge
563  nxny = nx * ny;
564  if ( ( a = (PLFLT *) malloc( (size_t) nxny * sizeof ( PLFLT ) ) ) == NULL )
565  {
566  plabort( "plfshade: unable to allocate memory for value array" );
567  return;
568  }
569 
570  for ( ix = 0; ix < nx; ix++ )
571  for ( iy = 0; iy < ny; iy++ )
572  a[iy + ix * ny] = f2eval( ix, iy, f2eval_data );
573 
574  // alloc space for condition codes
575 
576  if ( ( c = (int *) malloc( (size_t) nxny * sizeof ( int ) ) ) == NULL )
577  {
578  plabort( "plfshade: unable to allocate memory for condition codes" );
579  free( a );
580  return;
581  }
582 
583  sh_min = shade_min;
584  sh_max = shade_max;
585 
586  set_cond( c, a, nxny );
587  dx = ( xmax - xmin ) / ( nx - 1 );
588  dy = ( ymax - ymin ) / ( ny - 1 );
589  a0 = a;
590  a1 = a + ny;
591  c0 = c;
592  c1 = c + ny;
593 
594  for ( ix = 0; ix < nx - 1; ix++ )
595  {
596  for ( iy = 0; iy < ny - 1; iy++ )
597  {
598  count = c0[iy] + c0[iy + 1] + c1[iy] + c1[iy + 1];
599 
600  // No filling needs to be done for these cases
601 
602  if ( count >= UNDEF )
603  continue;
604  if ( count == 4 * POS )
605  continue;
606  if ( count == 4 * NEG )
607  continue;
608 
609  // Entire rectangle can be filled
610 
611  if ( count == 4 * OK )
612  {
613  // find biggest rectangle that fits
614  if ( rectangular )
615  {
616  big_recl( c0 + iy, ny, nx - ix, ny - iy, &i, &j );
617  }
618  else
619  {
620  i = j = 1;
621  }
622  x[0] = x[1] = ix;
623  x[2] = x[3] = ix + i;
624  y[0] = y[3] = iy;
625  y[1] = y[2] = iy + j;
626 
627  if ( pltr )
628  {
629  for ( i = 0; i < 4; i++ )
630  {
631  ( *pltr )( x[i], y[i], &tx, &ty, pltr_data );
632  x[i] = tx;
633  y[i] = ty;
634  }
635  }
636  else
637  {
638  for ( i = 0; i < 4; i++ )
639  {
640  x[i] = xmin + x[i] * dx;
641  y[i] = ymin + y[i] * dy;
642  }
643  }
644  if ( fill != NULL )
645  exfill( fill, defined, (PLINT) 4, x, y );
646  iy += j - 1;
647  continue;
648  }
649 
650  // Only part of rectangle can be filled
651 
652  n_point = min_points = max_points = 0;
653  n = find_interval( a0[iy], a0[iy + 1], c0[iy], c0[iy + 1], xp );
654  for ( j = 0; j < n; j++ )
655  {
656  x[j] = ix;
657  y[j] = iy + xp[j];
658  }
659 
660  i = find_interval( a0[iy + 1], a1[iy + 1],
661  c0[iy + 1], c1[iy + 1], xp );
662 
663  for ( j = 0; j < i; j++ )
664  {
665  x[j + n] = ix + xp[j];
666  y[j + n] = iy + 1;
667  }
668  n += i;
669 
670  i = find_interval( a1[iy + 1], a1[iy], c1[iy + 1], c1[iy], xp );
671  for ( j = 0; j < i; j++ )
672  {
673  x[n + j] = ix + 1;
674  y[n + j] = iy + 1 - xp[j];
675  }
676  n += i;
677 
678  i = find_interval( a1[iy], a0[iy], c1[iy], c0[iy], xp );
679  for ( j = 0; j < i; j++ )
680  {
681  x[n + j] = ix + 1 - xp[j];
682  y[n + j] = iy;
683  }
684  n += i;
685 
686  if ( pltr )
687  {
688  for ( i = 0; i < n; i++ )
689  {
690  ( *pltr )( x[i], y[i], &tx, &ty, pltr_data );
691  x[i] = tx;
692  y[i] = ty;
693  }
694  }
695  else
696  {
697  for ( i = 0; i < n; i++ )
698  {
699  x[i] = xmin + x[i] * dx;
700  y[i] = ymin + y[i] * dy;
701  }
702  }
703 
704  if ( min_points == 4 )
705  slope = plctestez( a, nx, ny, ix, iy, shade_min );
706  if ( max_points == 4 )
707  slope = plctestez( a, nx, ny, ix, iy, shade_max );
708 
709  // n = number of end of line segments
710  // min_points = number times shade_min meets edge
711  // max_points = number times shade_max meets edge
712 
713  // special cases: check number of times a contour is in a box
714 
715  switch ( ( min_points << 3 ) + max_points )
716  {
717  case 000:
718  case 020:
719  case 002:
720  case 022:
721  if ( fill != NULL && n > 0 )
722  exfill( fill, defined, n, x, y );
723  break;
724  case 040: // 2 contour lines in box
725  case 004:
726  if ( n != 6 )
727  fprintf( stderr, "plfshade err n=%d !6", (int) n );
728  if ( slope == 1 && c0[iy] == OK )
729  {
730  if ( fill != NULL )
731  exfill( fill, defined, n, x, y );
732  }
733  else if ( slope == 1 )
734  {
735  selected_polygon( fill, defined, x, y, 0, 1, 2, -1 );
736  selected_polygon( fill, defined, x, y, 3, 4, 5, -1 );
737  }
738  else if ( c0[iy + 1] == OK )
739  {
740  if ( fill != NULL )
741  exfill( fill, defined, n, x, y );
742  }
743  else
744  {
745  selected_polygon( fill, defined, x, y, 0, 1, 5, -1 );
746  selected_polygon( fill, defined, x, y, 2, 3, 4, -1 );
747  }
748  break;
749  case 044:
750  if ( n != 8 )
751  fprintf( stderr, "plfshade err n=%d !8", (int) n );
752  if ( slope == 1 )
753  {
754  selected_polygon( fill, defined, x, y, 0, 1, 2, 3 );
755  selected_polygon( fill, defined, x, y, 4, 5, 6, 7 );
756  }
757  else
758  {
759  selected_polygon( fill, defined, x, y, 0, 1, 6, 7 );
760  selected_polygon( fill, defined, x, y, 2, 3, 4, 5 );
761  }
762  break;
763  case 024:
764  case 042:
765  // 3 contours
766  if ( n != 7 )
767  fprintf( stderr, "plfshade err n=%d !7", (int) n );
768 
769  if ( ( c0[iy] == OK || c1[iy + 1] == OK ) && slope == 1 )
770  {
771  if ( fill != NULL )
772  exfill( fill, defined, n, x, y );
773  }
774  else if ( ( c0[iy + 1] == OK || c1[iy] == OK ) && slope == 0 )
775  {
776  if ( fill != NULL )
777  exfill( fill, defined, n, x, y );
778  }
779 
780  else if ( c0[iy] == OK )
781  {
782  selected_polygon( fill, defined, x, y, 0, 1, 6, -1 );
783  selected_polygon( fill, defined, x, y, 2, 3, 4, 5 );
784  }
785  else if ( c0[iy + 1] == OK )
786  {
787  selected_polygon( fill, defined, x, y, 0, 1, 2, -1 );
788  selected_polygon( fill, defined, x, y, 3, 4, 5, 6 );
789  }
790  else if ( c1[iy + 1] == OK )
791  {
792  selected_polygon( fill, defined, x, y, 0, 1, 5, 6 );
793  selected_polygon( fill, defined, x, y, 2, 3, 4, -1 );
794  }
795  else if ( c1[iy] == OK )
796  {
797  selected_polygon( fill, defined, x, y, 0, 1, 2, 3 );
798  selected_polygon( fill, defined, x, y, 4, 5, 6, -1 );
799  }
800  else
801  {
802  fprintf( stderr, "plfshade err logic case 024:042\n" );
803  }
804  break;
805  default:
806  fprintf( stderr, "prog err switch\n" );
807  break;
808  }
809  draw_boundary( slope, x, y );
810 
811  if ( fill != NULL )
812  {
813  plwidth( sh_width );
814  if ( sh_cmap == 0 )
815  plcol0( (PLINT) sh_color );
816  else if ( sh_cmap == 1 )
817  plcol1( sh_color );
818  }
819  }
820 
821  a0 = a1;
822  c0 = c1;
823  a1 += ny;
824  c1 += ny;
825  }
826 
827  free( c );
828  free( a );
829  plwidth( init_width );
830 }
831 
832 //--------------------------------------------------------------------------
833 // set_cond()
834 //
835 // Fills out condition code array.
836 //--------------------------------------------------------------------------
837 
838 static void
839 set_cond( register int *cond, register PLFLT *a, register PLINT n )
840 {
841  while ( n-- )
842  {
843  if ( *a < sh_min )
844  *cond++ = NEG;
845  else if ( *a > sh_max )
846  *cond++ = POS;
847  else if ( isnan( *a ) ) //check for nans and set cond to undefined
848  *cond++ = UNDEF;
849  else
850  *cond++ = OK;
851  a++;
852  }
853 }
854 
855 //--------------------------------------------------------------------------
856 // find_interval()
857 //
858 // Two points x(0) = a0, (condition code c0) x(1) = a1, (condition code c1)
859 // return interval on the line that are shaded
860 //
861 // returns 0 : no points to be shaded 1 : x[0] <= x < 1 is the interval 2 :
862 // x[0] <= x <= x[1] < 1 interval to be shaded n_point, max_points,
863 // min_points are incremented location of min/max_points are stored
864 //--------------------------------------------------------------------------
865 
866 static int
867 find_interval( PLFLT a0, PLFLT a1, PLINT c0, PLINT c1, PLFLT *x )
868 {
869  register int n;
870 
871  n = 0;
872  if ( c0 == OK )
873  {
874  x[n++] = 0.0;
875  n_point++;
876  }
877  if ( c0 == c1 )
878  return n;
879 
880  if ( c0 == NEG || c1 == POS )
881  {
882  if ( c0 == NEG )
883  {
884  x[n++] = linear( a0, a1, sh_min );
885  min_pts[min_points++] = n_point++;
886  }
887  if ( c1 == POS )
888  {
889  x[n++] = linear( a0, a1, sh_max );
890  max_pts[max_points++] = n_point++;
891  }
892  }
893  if ( c0 == POS || c1 == NEG )
894  {
895  if ( c0 == POS )
896  {
897  x[n++] = linear( a0, a1, sh_max );
898  max_pts[max_points++] = n_point++;
899  }
900  if ( c1 == NEG )
901  {
902  x[n++] = linear( a0, a1, sh_min );
903  min_pts[min_points++] = n_point++;
904  }
905  }
906  return n;
907 }
908 
909 //--------------------------------------------------------------------------
910 // selected_polygon()
911 //
912 // Draws a polygon from points in x[] and y[].
913 // Point selected by v1..v4
914 //--------------------------------------------------------------------------
915 
916 static void
918  PLFLT_VECTOR x, PLFLT_VECTOR y, PLINT v1, PLINT v2, PLINT v3, PLINT v4 )
919 {
920  register PLINT n = 0;
921  PLFLT xx[4], yy[4];
922 
923  if ( fill == NULL )
924  return;
925  if ( v1 >= 0 )
926  {
927  xx[n] = x[v1];
928  yy[n++] = y[v1];
929  }
930  if ( v2 >= 0 )
931  {
932  xx[n] = x[v2];
933  yy[n++] = y[v2];
934  }
935  if ( v3 >= 0 )
936  {
937  xx[n] = x[v3];
938  yy[n++] = y[v3];
939  }
940  if ( v4 >= 0 )
941  {
942  xx[n] = x[v4];
943  yy[n++] = y[v4];
944  }
945  exfill( fill, defined, n, (PLFLT *) xx, (PLFLT *) yy );
946 }
947 
948 //--------------------------------------------------------------------------
949 // bisect()
950 //
951 // Find boundary recursively by bisection.
952 // (x1, y1) is in the defined region, while (x2, y2) in the undefined one.
953 // The result is returned in
954 //--------------------------------------------------------------------------
955 
956 static void
958  PLFLT x1, PLFLT y1, PLFLT x2, PLFLT y2, PLFLT* xb, PLFLT* yb )
959 {
960  PLFLT xm;
961  PLFLT ym;
962 
963  if ( niter == 0 )
964  {
965  *xb = x1;
966  *yb = y1;
967  return;
968  }
969 
970  xm = ( x1 + x2 ) / 2.;
971  ym = ( y1 + y2 ) / 2.;
972 
973  if ( defined( xm, ym ) )
974  bisect( defined, niter - 1, xm, ym, x2, y2, xb, yb );
975  else
976  bisect( defined, niter - 1, x1, y1, xm, ym, xb, yb );
977 }
978 
979 //--------------------------------------------------------------------------
980 // exfill()
981 //
982 // Fills a polygon from points in x[] and y[] with all points in
983 // undefined regions dropped and replaced by points at the bisected
984 // edge of the defined region.
985 // Note, undefined regions that are confined to the areas between polygon
986 // points are completely ignored. Also, a range of undefined polygon points
987 // are simply replaced with a straight line with accurately bisected end
988 // points. So this routine can produce problematic plotted results
989 // if the polygon is not a lot smaller than the typical resolution of
990 // the defined region.
991 //--------------------------------------------------------------------------
992 
993 static void
995  int n, PLFLT_VECTOR x, PLFLT_VECTOR y )
996 {
997  if ( n < 3 )
998  {
999  plabort( "exfill: Not enough points in object" );
1000  return;
1001  }
1002 
1003  if ( defined == NULL )
1004 
1005  ( *fill )( n, x, y );
1006 
1007  else
1008  {
1009  PLFLT *xx;
1010  PLFLT *yy;
1011  PLFLT xb, yb;
1012  PLINT count = 0;
1013  PLINT im1 = n - 1;
1014  PLINT is_defined = defined( x[im1], y[im1] );
1015  PLINT i;
1016 
1017  // Slightly less than 2 n points are required for xx, yy, but
1018  // allocate room for 2 n to be safe.
1019  if ( ( xx = (PLFLT *) malloc( 2 * (size_t) n * sizeof ( PLFLT ) ) ) == NULL )
1020  plexit( "exfill: out of memory for xx" );
1021  if ( ( yy = (PLFLT *) malloc( 2 * (size_t) n * sizeof ( PLFLT ) ) ) == NULL )
1022  plexit( "exfill: out of memory for yy." );
1023 
1024  for ( i = 0; i < n; i++ )
1025  {
1026  // is_defined tells whether im1 point was in defined region.
1027  if ( defined( x[i], y[i] ) )
1028  {
1029  if ( !is_defined )
1030  {
1031  // Cross from undefined (at im1) to defined region.
1032  // Bisect for the first point inside the defined region
1033  // and add it to xx, yy.
1034  bisect( defined, NUMBER_BISECTIONS,
1035  x[i], y[i], x[im1], y[im1], &xb, &yb );
1036  xx[count] = xb;
1037  yy[count++] = yb;
1038  }
1039  // x[i], y[i] known to be in defined region so add this
1040  // point to xx, yy.
1041  xx[count] = x[i];
1042  yy[count++] = y[i];
1043  is_defined = 1;
1044  }
1045  else
1046  {
1047  if ( is_defined )
1048  {
1049  // Cross from defined (at im1) to undefined region.
1050  // Bisect for the last point in the defined region and
1051  // add it to xx, yy.
1052  bisect( defined, NUMBER_BISECTIONS,
1053  x[im1], y[im1], x[i], y[i], &xb, &yb );
1054  xx[count] = xb;
1055  yy[count++] = yb;
1056  is_defined = 0;
1057  }
1058  }
1059  im1 = i;
1060  }
1061 
1062  if ( count >= 3 )
1063  ( *fill )( count, (PLFLT_VECTOR) xx, (PLFLT_VECTOR) yy );
1064 
1065  free( xx );
1066  free( yy );
1067  }
1068 }
1069 
1070 //--------------------------------------------------------------------------
1071 // big_recl()
1072 //
1073 // find a big rectangle for shading
1074 //
1075 // 2 goals: minimize calls to (*fill)()
1076 // keep ratio 1:3 for biggest rectangle
1077 //
1078 // only called by plshade()
1079 //
1080 // assumed that a 1 x 1 square already fits
1081 //
1082 // c[] = condition codes
1083 // ny = c[1][0] == c[ny] (you know what I mean)
1084 //
1085 // returns ix, iy = length of rectangle in grid units
1086 //
1087 // ix < dx - 1
1088 // iy < dy - 1
1089 //
1090 // If iy == 1 -> ix = 1 (so that cond code can be set to skip)
1091 //--------------------------------------------------------------------------
1092 
1093 #define RATIO 3
1094 #define COND( x, y ) cond_code[x * ny + y]
1095 
1096 static void
1097 big_recl( int *cond_code, register int ny, int dx, int dy,
1098  int *ix, int *iy )
1099 {
1100  int ok_x, ok_y, j;
1101  register int i, x, y;
1102  register int *cond;
1103 
1104  // ok_x = ok to expand in x direction
1105  // x = current number of points in x direction
1106 
1107  ok_x = ok_y = 1;
1108  x = y = 2;
1109 
1110  while ( ok_x || ok_y )
1111  {
1112 #ifdef RATIO
1113  if ( RATIO * x <= y || RATIO * y <= x )
1114  break;
1115 #endif
1116  if ( ok_y )
1117  {
1118  // expand in vertical
1119  ok_y = 0;
1120  if ( y == dy )
1121  continue;
1122  cond = &COND( 0, y );
1123  for ( i = 0; i < x; i++ )
1124  {
1125  if ( *cond != OK )
1126  break;
1127  cond += ny;
1128  }
1129  if ( i == x )
1130  {
1131  // row is ok
1132  y++;
1133  ok_y = 1;
1134  }
1135  }
1136  if ( ok_x )
1137  {
1138  if ( y == 2 )
1139  break;
1140  // expand in x direction
1141  ok_x = 0;
1142  if ( x == dx )
1143  continue;
1144  cond = &COND( x, 0 );
1145  for ( i = 0; i < y; i++ )
1146  {
1147  if ( *cond++ != OK )
1148  break;
1149  }
1150  if ( i == y )
1151  {
1152  // column is OK
1153  x++;
1154  ok_x = 1;
1155  }
1156  }
1157  }
1158 
1159  // found the largest rectangle of 'ix' by 'iy'
1160  *ix = --x;
1161  *iy = --y;
1162 
1163  // set condition code to UNDEF in interior of rectangle
1164 
1165  for ( i = 1; i < x; i++ )
1166  {
1167  cond = &COND( i, 1 );
1168  for ( j = 1; j < y; j++ )
1169  {
1170  *cond++ = UNDEF;
1171  }
1172  }
1173 }
1174 
1175 //--------------------------------------------------------------------------
1176 // draw_boundary()
1177 //
1178 // Draw boundaries of contour regions based on min_pts[], and max_pts[].
1179 //--------------------------------------------------------------------------
1180 
1181 static void
1182 draw_boundary( PLINT slope, PLFLT *x, PLFLT *y )
1183 {
1184  int i;
1185 
1186  if ( pen_col_min != 0 && pen_wd_min != 0 && min_points != 0 )
1187  {
1188  plcol0( pen_col_min );
1189  plwidth( pen_wd_min );
1190  if ( min_points == 4 && slope == 0 )
1191  {
1192  // swap points 1 and 3
1193  i = min_pts[1];
1194  min_pts[1] = min_pts[3];
1195  min_pts[3] = i;
1196  }
1197  pljoin( x[min_pts[0]], y[min_pts[0]], x[min_pts[1]], y[min_pts[1]] );
1198  if ( min_points == 4 )
1199  {
1200  pljoin( x[min_pts[2]], y[min_pts[2]], x[min_pts[3]],
1201  y[min_pts[3]] );
1202  }
1203  }
1204  if ( pen_col_max != 0 && pen_wd_max != 0 && max_points != 0 )
1205  {
1206  plcol0( pen_col_max );
1207  plwidth( pen_wd_max );
1208  if ( max_points == 4 && slope == 0 )
1209  {
1210  // swap points 1 and 3
1211  i = max_pts[1];
1212  max_pts[1] = max_pts[3];
1213  max_pts[3] = i;
1214  }
1215  pljoin( x[max_pts[0]], y[max_pts[0]], x[max_pts[1]], y[max_pts[1]] );
1216  if ( max_points == 4 )
1217  {
1218  pljoin( x[max_pts[2]], y[max_pts[2]], x[max_pts[3]],
1219  y[max_pts[3]] );
1220  }
1221  }
1222 }
1223 
1224 //--------------------------------------------------------------------------
1225 //
1226 // plctest( &(x[0][0]), PLFLT level)
1227 // where x was defined as PLFLT x[4][4];
1228 //
1229 // determines if the contours associated with level have
1230 // positive slope or negative slope in the box:
1231 //
1232 // (2,3) (3,3)
1233 //
1234 // (2,2) (3,2)
1235 //
1236 // this is heuristic and can be changed by the user
1237 //
1238 // return 1 if positive slope
1239 // 0 if negative slope
1240 //
1241 // algorithmn:
1242 // 1st test:
1243 // find length of contours assuming positive and negative slopes
1244 // if the length of the negative slope contours is much bigger
1245 // than the positive slope, then the slope is positive.
1246 // (and vice versa)
1247 // (this test tries to minimize the length of contours)
1248 //
1249 // 2nd test:
1250 // if abs((top-right corner) - (bottom left corner)) >
1251 // abs((top-left corner) - (bottom right corner)) ) then
1252 // return negatiave slope.
1253 // (this test tries to keep the slope for different contour levels
1254 // the same)
1255 //--------------------------------------------------------------------------
1256 
1257 #define X( a, b ) ( x[a * 4 + b] )
1258 #define POSITIVE_SLOPE (PLINT) 1
1259 #define NEGATIVE_SLOPE (PLINT) 0
1260 #define RATIO_SQ 6.0
1261 
1262 static PLINT
1263 plctest( PLFLT *x, PLFLT PL_UNUSED( level ) )
1264 {
1265  int i, j;
1266  double t[4], sorted[4], temp;
1267 
1268  sorted[0] = t[0] = X( 1, 1 );
1269  sorted[1] = t[1] = X( 2, 2 );
1270  sorted[2] = t[2] = X( 1, 2 );
1271  sorted[3] = t[3] = X( 2, 1 );
1272 
1273  for ( j = 1; j < 4; j++ )
1274  {
1275  temp = sorted[j];
1276  i = j - 1;
1277  while ( i >= 0 && sorted[i] > temp )
1278  {
1279  sorted[i + 1] = sorted[i];
1280  i--;
1281  }
1282  sorted[i + 1] = temp;
1283  }
1284  // sorted[0] == min
1285 
1286  // find min contour
1287  temp = int_val * ceil( sorted[0] / int_val );
1288  if ( temp < sorted[1] )
1289  {
1290  // one contour line
1291  for ( i = 0; i < 4; i++ )
1292  {
1293  if ( t[i] < temp )
1294  return i / 2;
1295  }
1296  }
1297 
1298  // find max contour
1299  temp = int_val * floor( sorted[3] / int_val );
1300  if ( temp > sorted[2] )
1301  {
1302  // one contour line
1303  for ( i = 0; i < 4; i++ )
1304  {
1305  if ( t[i] > temp )
1306  return i / 2;
1307  }
1308  }
1309  // nothing better to do - be consistant
1310  return POSITIVE_SLOPE;
1311 }
1312 
1313 //--------------------------------------------------------------------------
1314 // plctestez
1315 //
1316 // second routine - easier to use
1317 // fills in x[4][4] and calls plctest
1318 //
1319 // test location a[ix][iy] (lower left corner)
1320 //--------------------------------------------------------------------------
1321 
1322 static PLINT
1323 plctestez( PLFLT *a, PLINT nx, PLINT ny, PLINT ix,
1324  PLINT iy, PLFLT level )
1325 {
1326  PLFLT x[4][4];
1327  int i, j, ii, jj;
1328 
1329  for ( i = 0; i < 4; i++ )
1330  {
1331  ii = ix + i - 1;
1332  ii = MAX( 0, ii );
1333  ii = MIN( ii, nx - 1 );
1334  for ( j = 0; j < 4; j++ )
1335  {
1336  jj = iy + j - 1;
1337  jj = MAX( 0, jj );
1338  jj = MIN( jj, ny - 1 );
1339  x[i][j] = a[ii * ny + jj];
1340  }
1341  }
1342  return plctest( &( x[0][0] ), level );
1343 }
#define X(a, b)
Definition: plshade.c:1257
static int min_pts[4]
Definition: plshade.c:137
void plexit(PLCHAR_VECTOR errormsg)
Definition: plctrl.c:1948
PLFLT plf2eval(PLINT ix, PLINT iy, PLPointer plf2eval_data)
Definition: plcont.c:447
PLINT nx
Definition: plplot.h:493
static int max_points
Definition: plshade.c:136
#define linear(val1, val2, level)
Definition: plshade.c:131
const PLFLT *const * PLFLT_MATRIX
Definition: plplot.h:255
#define NEG
Definition: plshade.c:125
static void set_cond(register int *cond, register PLFLT *a, register PLINT n)
Definition: plshade.c:839
#define plstyl
Definition: plplot.h:848
#define isnan(x)
Definition: plplotP.h:262
static PLINT pen_col_max
Definition: plshade.c:138
#define MAX(a, b)
Definition: dsplint.c:28
#define POS
Definition: plshade.c:126
static int max_pts[4]
Definition: plshade.c:137
void plabort(PLCHAR_VECTOR errormsg)
Definition: plctrl.c:1884
void * PLPointer
Definition: plplot.h:202
static PLFLT pen_wd_max
Definition: plshade.c:139
PLINT(* PLDEFINED_callback)(PLFLT x, PLFLT y)
Definition: plplot.h:263
static PLFLT sh_min
Definition: plshade.c:135
static PLFLT sh_max
Definition: plshade.c:135
PLFLT(* PLF2EVAL_callback)(PLINT ix, PLINT iy, PLPointer data)
Definition: plplot.h:261
static PLINT plctest(PLFLT *x, PLFLT level)
void(* PLFILL_callback)(PLINT n, PLFLT_VECTOR x, PLFLT_VECTOR y)
Definition: plplot.h:262
int PLINT
Definition: plplot.h:174
#define MIN(a, b)
Definition: dsplint.c:29
static PLFLT pen_wd_min
Definition: plshade.c:139
#define pljoin
Definition: plplot.h:755
void plfshade1(PLF2OPS zops, PLPointer zp, PLINT nx, PLINT ny, PLDEFINED_callback defined, PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax, PLFLT shade_min, PLFLT shade_max, PLINT sh_cmap, PLFLT sh_color, PLFLT sh_width, PLINT min_color, PLFLT min_width, PLINT max_color, PLFLT max_width, PLFILL_callback fill, PLINT rectangular, PLTRANSFORM_callback pltr, PLPointer pltr_data)
Definition: plshade.c:443
PLFLT(* f2eval)(PLINT ix, PLINT iy, PLPointer p)
Definition: plplot.h:612
PLINT ny
Definition: plplot.h:521
#define NUMBER_BISECTIONS
Definition: plshade.c:129
static void plshade_int(PLF2EVAL_callback f2eval, PLPointer f2eval_data, PLF2EVAL_callback c2eval, PLPointer c2eval_data, PLDEFINED_callback defined, PLINT nx, PLINT ny, PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax, PLFLT shade_min, PLFLT shade_max, PLINT sh_cmap, PLFLT sh_color, PLFLT sh_width, PLINT min_color, PLFLT min_width, PLINT max_color, PLFLT max_width, PLFILL_callback fill, PLINT rectangular, PLTRANSFORM_callback pltr, PLPointer pltr_data)
static PLINT plctestez(PLFLT *a, PLINT nx, PLINT ny, PLINT ix, PLINT iy, PLFLT level)
Definition: plshade.c:1323
#define POSITIVE_SLOPE
Definition: plshade.c:1258
PLFLT_NC_FE_POINTER yg
Definition: plplot.h:520
void c_plshade1(PLFLT_VECTOR a, PLINT nx, PLINT ny, PLDEFINED_callback defined, PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax, PLFLT shade_min, PLFLT shade_max, PLINT sh_cmap, PLFLT sh_color, PLFLT sh_width, PLINT min_color, PLFLT min_width, PLINT max_color, PLFLT max_width, PLFILL_callback fill, PLINT rectangular, PLTRANSFORM_callback pltr, PLPointer pltr_data)
Definition: plshade.c:379
PLFLT plf2eval1(PLINT ix, PLINT iy, PLPointer plf2eval_data)
Definition: plcont.c:410
#define COND(x, y)
Definition: plshade.c:1094
void plfshades(PLF2OPS zops, PLPointer zp, PLINT nx, PLINT ny, PLDEFINED_callback defined, PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax, PLFLT_VECTOR clevel, PLINT nlevel, PLFLT fill_width, PLINT cont_color, PLFLT cont_width, PLFILL_callback fill, PLINT rectangular, PLTRANSFORM_callback pltr, PLPointer pltr_data)
Definition: plshade.c:245
#define plcol1
Definition: plplot.h:700
static void bisect(PLDEFINED_callback defined, PLINT niter, PLFLT x1, PLFLT y1, PLFLT x2, PLFLT y2, PLFLT *xb, PLFLT *yb)
Definition: plshade.c:957
#define plwidth
Definition: plplot.h:868
static void draw_boundary(PLINT slope, PLFLT *x, PLFLT *y)
Definition: plshade.c:1182
void(* PLTRANSFORM_callback)(PLFLT x, PLFLT y, PLFLT_NC_SCALAR xp, PLFLT_NC_SCALAR yp, PLPointer data)
Definition: plplot.h:259
void c_plshades(PLFLT_MATRIX a, PLINT nx, PLINT ny, PLDEFINED_callback defined, PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax, PLFLT_VECTOR clevel, PLINT nlevel, PLFLT fill_width, PLINT cont_color, PLFLT cont_width, PLFILL_callback fill, PLINT rectangular, PLTRANSFORM_callback pltr, PLPointer pltr_data)
Definition: plshade.c:216
static void selected_polygon(PLFILL_callback fill, PLDEFINED_callback defined, PLFLT_VECTOR x, PLFLT_VECTOR y, PLINT v1, PLINT v2, PLINT v3, PLINT v4)
Definition: plshade.c:917
PLINT ny
Definition: plplot.h:493
static PLFLT int_val
Definition: plshade.c:140
#define PL_UNUSED(x)
Definition: plplot.h:128
float PLFLT
Definition: plplot.h:157
#define OK
Definition: plshade.c:127
#define UNDEF
Definition: plshade.c:128
void plfshade(PLF2EVAL_callback f2eval, PLPointer f2eval_data, PLF2EVAL_callback c2eval, PLPointer c2eval_data, PLINT nx, PLINT ny, PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax, PLFLT shade_min, PLFLT shade_max, PLINT sh_cmap, PLFLT sh_color, PLFLT sh_width, PLINT min_color, PLFLT min_width, PLINT max_color, PLFLT max_width, PLFILL_callback fill, PLINT rectangular, PLTRANSFORM_callback pltr, PLPointer pltr_data)
Definition: plshade.c:412
static void exfill(PLFILL_callback fill, PLDEFINED_callback defined, int n, PLFLT_VECTOR x, PLFLT_VECTOR y)
Definition: plshade.c:994
#define RATIO
Definition: plshade.c:1093
#define plcol0
Definition: plplot.h:699
static void big_recl(int *cond_code, register int ny, int dx, int dy, int *ix, int *iy)
Definition: plshade.c:1097
PLFLT_NC_FE_POINTER xg
Definition: plplot.h:520
PLF2OPS plf2ops_c()
Definition: plf2ops.c:126
static int n_point
Definition: plshade.c:136
static int find_interval(PLFLT a0, PLFLT a1, PLINT c0, PLINT c1, PLFLT *x)
Definition: plshade.c:867
static PLINT pen_col_min
Definition: plshade.c:138
void c_plshade(PLFLT_MATRIX a, PLINT nx, PLINT ny, PLDEFINED_callback defined, PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax, PLFLT shade_min, PLFLT shade_max, PLINT sh_cmap, PLFLT sh_color, PLFLT sh_width, PLINT min_color, PLFLT min_width, PLINT max_color, PLFLT max_width, PLFILL_callback fill, PLINT rectangular, PLTRANSFORM_callback pltr, PLPointer pltr_data)
Definition: plshade.c:352
#define PLDLLIMPEXP
Definition: pldll.h:49
const PLFLT * PLFLT_VECTOR
Definition: plplot.h:246
static int min_points
Definition: plshade.c:136
void plfcont(PLF2EVAL_callback f2eval, PLPointer f2eval_data, PLINT nx, PLINT ny, PLINT kx, PLINT lx, PLINT ky, PLINT ly, PLFLT_VECTOR clevel, PLINT nlevel, PLTRANSFORM_callback pltr, PLPointer pltr_data)
Definition: plcont.c:535
PLDLLIMPEXP void plshades_null(PLFLT_MATRIX a, PLINT nx, PLINT ny, PLDEFINED_callback defined, PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax, PLFLT_VECTOR clevel, PLINT nlevel, PLFLT fill_width, PLINT cont_color, PLFLT cont_width, PLFILL_callback fill, PLINT rectangular)
Definition: plshade.c:189
PLFLT_FE_POINTER f
Definition: plplot.h:492
PLDLLIMPEXP_CXX void fill(PLINT n, const PLFLT *x, const PLFLT *y)
Definition: plstream.cc:240
PLDLLIMPEXP void plshade_null(PLFLT_MATRIX a, PLINT nx, PLINT ny, PLDEFINED_callback defined, PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax, PLFLT shade_min, PLFLT shade_max, PLINT sh_cmap, PLFLT sh_color, PLFLT sh_width, PLINT min_color, PLFLT min_width, PLINT max_color, PLFLT max_width, PLFILL_callback fill, PLINT rectangular)
Definition: plshade.c:326
PLINT nx
Definition: plplot.h:521