PLplot: plcont.c Source File

PLplot 5.15.0

plcont.c
Go to the documentation of this file.
1 // Contour plotter.
2 //
3 // Copyright (C) 1995, 2000, 2001 Maurice LeBrun
4 // Copyright (C) 2000, 2002 Joao Cardoso
5 // Copyright (C) 2000-2014 Alan W. Irwin
6 // Copyright (C) 2004 Andrew Ross
7 //
8 // This file is part of PLplot.
9 //
10 // PLplot is free software; you can redistribute it and/or modify
11 // it under the terms of the GNU Library General Public License as published
12 // by the Free Software Foundation; either version 2 of the License, or
13 // (at your option) any later version.
14 //
15 // PLplot is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Library General Public License for more details.
19 //
20 // You should have received a copy of the GNU Library General Public License
21 // along with PLplot; if not, write to the Free Software
22 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 //
24
25 #include "plplotP.h"
26
27 #ifdef MSDOS
28 #pragma optimize("",off)
29 #endif
30
31 // Static function prototypes.
32
33 static void
34 plcntr( PLF2EVAL_callback plf2eval, PLPointer plf2eval_data,
35 PLINT nx, PLINT ny, PLINT kx, PLINT lx,
36 PLINT ky, PLINT ly, PLFLT flev, PLINT **ipts,
37 PLTRANSFORM_callback pltr, PLPointer pltr_data );
38
39 static void
40 pldrawcn( PLF2EVAL_callback plf2eval, PLPointer plf2eval_data,
41 PLINT nx, PLINT ny, PLINT kx, PLINT lx,
42 PLINT ky, PLINT ly, PLFLT flev, char *flabel, PLINT kcol, PLINT krow,
43 PLFLT lastx, PLFLT lasty, PLINT startedge,
44 PLINT **ipts, PLFLT *distance, PLINT *lastindex,
45 PLTRANSFORM_callback pltr, PLPointer pltr_data );
46
47 static void
48 plfloatlabel( PLFLT value, char *string, PLINT len );
49
50 static PLFLT
51 plP_pcwcx( PLINT x );
52
53 static PLFLT
54 plP_pcwcy( PLINT y );
55
56 static void
57 pl_drawcontlabel( PLFLT tpx, PLFLT tpy, char *flabel, PLFLT *distance, PLINT *lastindex );
58
59 // Error flag for aborts
60
61 static int error;
62
63 //**************************************
64 //
65 // Defaults for contour label printing.
66 //
67 //**************************************
68
69 // Font height for contour labels (normalized)
70 static PLFLT
71 contlabel_size = 0.3;
72
73 // Offset of label from contour line (if set to 0.0, labels are printed on the lines).
74 static PLFLT
75 contlabel_offset = 0.006;
76
77 // Spacing parameter for contour labels
78 static PLFLT
79 contlabel_space = 0.1;
80
81 // Activate labels, default off
82 static PLINT
83 contlabel_active = 0;
84
85 // If the contour label exceed 10^(limexp) or 10^(-limexp), the exponential format is used
86 static PLINT
87 limexp = 4;
88
89 // Number of significant digits
90 static PLINT
91 sigprec = 2;
92
93 //******* contour lines storage ***************************
94
95 static CONT_LEVEL *startlev = NULL;
96 static CONT_LEVEL *currlev;
97 static CONT_LINE *currline;
98
99 static int cont3d = 0;
100
101 static CONT_LINE *
102 alloc_line( void )
103 {
104 CONT_LINE *line;
105
106 if ( ( line = (CONT_LINE *) malloc( sizeof ( CONT_LINE ) ) ) == NULL )
107 {
108 plexit( "alloc_line: Insufficient memory" );
109 }
110
111 line->x = (PLFLT *) malloc( LINE_ITEMS * sizeof ( PLFLT ) );
112 line->y = (PLFLT *) malloc( LINE_ITEMS * sizeof ( PLFLT ) );
113
114 if ( ( line->x == NULL ) || ( line->y == NULL ) )
115 {
116 plexit( "alloc_line: Insufficient memory" );
117 }
118
119 line->npts = 0;
120 line->next = NULL;
121
122 return line;
123 }
124
125 static CONT_LEVEL *
126 alloc_level( PLFLT level )
127 {
128 CONT_LEVEL *node;
129
130 if ( ( node = (CONT_LEVEL *) malloc( sizeof ( CONT_LEVEL ) ) ) == NULL )
131 {
132 plexit( "alloc_level: Insufficient memory" );
133 }
134 node->level = level;
135 node->next = NULL;
136 node->line = alloc_line( );
137
138 return node;
139 }
140
141 static void
142 realloc_line( CONT_LINE *line )
143 {
144 if ( ( ( line->x = (PLFLT *) realloc( line->x,
145 (size_t) ( line->npts + LINE_ITEMS ) * sizeof ( PLFLT ) ) ) == NULL ) ||
146 ( ( line->y = (PLFLT *) realloc( line->y,
147 (size_t) ( line->npts + LINE_ITEMS ) * sizeof ( PLFLT ) ) ) == NULL ) )
148 plexit( "realloc_line: Insufficient memory" );
149 }
150
151
152 // new contour level
153 static void
154 cont_new_store( PLFLT level )
155 {
156 if ( cont3d )
157 {
158 if ( startlev == NULL )
159 {
160 startlev = alloc_level( level );
161 currlev = startlev;
162 }
163 else
164 {
165 currlev->next = alloc_level( level );
166 currlev = currlev->next;
167 }
168 currline = currlev->line;
169 }
170 }
171
172 void
173 cont_clean_store( CONT_LEVEL *ct )
174 {
175 CONT_LINE *tline, *cline;
176 CONT_LEVEL *tlev, *clevel;
177
178 if ( ct != NULL )
179 {
180 clevel = ct;
181
182 do
183 {
184 cline = clevel->line;
185 do
186 {
187 #ifdef CONT_PLOT_DEBUG
188 plP_movwor( cline->x[0], cline->y[0] );
189 for ( j = 1; j < cline->npts; j++ )
190 plP_drawor( cline->x[j], cline->y[j] );
191 #endif
192 tline = cline->next;
193 free( cline->x );
194 free( cline->y );
195 free( cline );
196 cline = tline;
197 }
198 while ( cline != NULL );
199 tlev = clevel->next;
200 free( clevel );
201 clevel = tlev;
202 }
203 while ( clevel != NULL );
204 startlev = NULL;
205 }
206 }
207
208 static void
209 cont_xy_store( PLFLT xx, PLFLT yy )
210 {
211 if ( cont3d )
212 {
213 PLINT pts = currline->npts;
214
215 if ( pts % LINE_ITEMS == 0 )
216 realloc_line( currline );
217
218 currline->x[pts] = xx;
219 currline->y[pts] = yy;
220 currline->npts++;
221 }
222 else
223 plP_drawor( xx, yy );
224 }
225
226 static void
227 cont_mv_store( PLFLT xx, PLFLT yy )
228 {
229 if ( cont3d )
230 {
231 if ( currline->npts != 0 ) // not an empty list, allocate new
232 {
233 currline->next = alloc_line( );
234 currline = currline->next;
235 }
236
237 // and fill first element
238 currline->x[0] = xx;
239 currline->y[0] = yy;
240 currline->npts = 1;
241 }
242 else
243 plP_movwor( xx, yy );
244 }
245
246 // small routine to set offset and spacing of contour labels, see desciption above
247 void c_pl_setcontlabelparam( PLFLT offset, PLFLT size, PLFLT spacing, PLINT active )
248 {
249 contlabel_offset = offset;
250 contlabel_size = size;
251 contlabel_space = spacing;
252 contlabel_active = active;
253 }
254
255 // small routine to set the format of the contour labels, description of limexp and prec see above
256 void c_pl_setcontlabelformat( PLINT lexp, PLINT sigdig )
257 {
258 limexp = lexp;
259 sigprec = sigdig;
260 }
261
262 static void pl_drawcontlabel( PLFLT tpx, PLFLT tpy, char *flabel, PLFLT *distance, PLINT *lastindex )
263 {
264 PLFLT delta_x, delta_y;
265 PLINT currx_old, curry_old;
266
267 delta_x = plP_pcdcx( plsc->currx ) - plP_pcdcx( plP_wcpcx( tpx ) );
268 delta_y = plP_pcdcy( plsc->curry ) - plP_pcdcy( plP_wcpcy( tpy ) );
269
270 currx_old = plsc->currx;
271 curry_old = plsc->curry;
272
273 *distance += sqrt( delta_x * delta_x + delta_y * delta_y );
274
275 plP_drawor( tpx, tpy );
276
277 if ( (int) ( fabs( *distance / contlabel_space ) ) > *lastindex )
278 {
279 PLFLT scale, vec_x, vec_y, mx, my, dev_x, dev_y, off_x, off_y;
280
281 vec_x = tpx - plP_pcwcx( currx_old );
282 vec_y = tpy - plP_pcwcy( curry_old );
283
284 // Ensure labels appear the right way up
285 if ( vec_x < 0 )
286 {
287 vec_x = -vec_x;
288 vec_y = -vec_y;
289 }
290
291 mx = (double) plsc->wpxscl / (double) plsc->phyxlen;
292 my = (double) plsc->wpyscl / (double) plsc->phyylen;
293
294 dev_x = -my * vec_y / mx;
295 dev_y = mx * vec_x / my;
296
297 scale = sqrt( ( mx * mx * dev_x * dev_x + my * my * dev_y * dev_y ) /
298 ( contlabel_offset * contlabel_offset ) );
299
300 off_x = dev_x / scale;
301 off_y = dev_y / scale;
302
303 plptex( tpx + off_x, tpy + off_y, vec_x, vec_y, 0.5, flabel );
304 plP_movwor( tpx, tpy );
305 ( *lastindex )++;
306 }
307 else
308 plP_movwor( tpx, tpy );
309 }
310
311
312 // Format contour labels. Arguments:
313 // value: floating point number to be formatted
314 // string: the formatted label, plptex must be called with it to actually
315 // print the label
316 //
317
318 static void plfloatlabel( PLFLT value, char *string, PLINT len )
319 {
320 PLINT setpre, precis;
321 // form[10] gives enough space for all non-malicious formats.
322 // tmpstring[15] gives enough room for 3 digits in a negative exponent
323 // or 4 digits in a positive exponent + null termination. That
324 // should be enough for all non-malicious use.
325 // Obviously there are security issues here that
326 // should be addressed as well.
327 //
328 #define FORM_LEN 10
329 #define TMPSTRING_LEN 15
330 char form[FORM_LEN], tmpstring[TMPSTRING_LEN];
331 PLINT exponent = 0;
332 PLFLT mant, tmp;
333
334 PLINT prec = sigprec;
335
336 plP_gprec( &setpre, &precis );
337
338 if ( setpre )
339 prec = precis;
340
341 if ( value > 0.0 )
342 tmp = log10( value );
343 else if ( value < 0.0 )
344 tmp = log10( -value );
345 else
346 tmp = 0;
347
348 if ( tmp >= 0.0 )
349 exponent = (int) tmp;
350 else if ( tmp < 0.0 )
351 {
352 tmp = -tmp;
353 if ( floor( tmp ) < tmp )
354 exponent = -(int) ( floor( tmp ) + 1.0 );
355 else
356 exponent = -(int) ( floor( tmp ) );
357 }
358
359 mant = value / pow( 10.0, exponent );
360
361 if ( mant != 0.0 )
362 mant = (int) ( mant * pow( 10.0, prec - 1 ) + 0.5 * mant / fabs( mant ) ) / pow( 10.0, prec - 1 );
363
364 snprintf( form, FORM_LEN, "%%.%df", prec - 1 );
365 snprintf( string, (size_t) len, form, mant );
366 snprintf( tmpstring, TMPSTRING_LEN, "#(229)10#u%d", exponent );
367 strncat( string, tmpstring, (size_t) len - strlen( string ) - 1 );
368
369 if ( abs( exponent ) < limexp || value == 0.0 )
370 {
371 value = pow( 10.0, exponent ) * mant;
372
373 if ( exponent >= 0 )
374 prec = prec - 1 - exponent;
375 else
376 prec = prec - 1 + abs( exponent );
377
378 if ( prec < 0 )
379 prec = 0;
380
381 snprintf( form, FORM_LEN, "%%.%df", (int) prec );
382 snprintf( string, (size_t) len, form, value );
383 }
384 }
385
386 // physical coords (x) to world coords
387
388 static PLFLT
389 plP_pcwcx( PLINT x )
390 {
391 return ( ( x - plsc->wpxoff ) / plsc->wpxscl );
392 }
393
394 // physical coords (y) to world coords
395
396 static PLFLT
397 plP_pcwcy( PLINT y )
398 {
399 return ( ( y - plsc->wpyoff ) / plsc->wpyscl );
400 }
401
402 //--------------------------------------------------------------------------
403 // plf2eval1()
404 //
405 // Does a lookup from a 2d function array. Array is of type (PLFLT **),
406 // and is column dominant (normal C ordering).
407 //--------------------------------------------------------------------------
408
409 PLFLT
410 plf2eval1( PLINT ix, PLINT iy, PLPointer plf2eval_data )
411 {
412 PLFLT value;
413 PLFLT **z = (PLFLT **) plf2eval_data;
414
415 value = z[ix][iy];
416
417 return value;
418 }
419
420 //--------------------------------------------------------------------------
421 // plf2eval2()
422 //
423 // Does a lookup from a 2d function array. plf2eval_data is treated as type
424 // (PLfGrid2 *).
425 //--------------------------------------------------------------------------
426
427 PLFLT
428 plf2eval2( PLINT ix, PLINT iy, PLPointer plf2eval_data )
429 {
430 PLFLT value;
431 PLfGrid2 *grid = (PLfGrid2 *) plf2eval_data;
432
433 value = grid->f[ix][iy];
434
435 return value;
436 }
437
438 //--------------------------------------------------------------------------
439 // plf2eval()
440 //
441 // Does a lookup from a 2d function array. Array is of type (PLFLT *), and
442 // is column dominant (normal C ordering). You MUST fill the ny maximum
443 // array index entry in the PLfGrid struct.
444 //--------------------------------------------------------------------------
445
446 PLFLT
447 plf2eval( PLINT ix, PLINT iy, PLPointer plf2eval_data )
448 {
449 PLFLT value;
450 PLfGrid *grid = (PLfGrid *) plf2eval_data;
451
452 value = grid->f[ix * grid->ny + iy];
453
454 return value;
455 }
456
457 //--------------------------------------------------------------------------
458 // plf2evalr()
459 //
460 // Does a lookup from a 2d function array. Array is of type (PLFLT *), and
461 // is row dominant (Fortran ordering). You MUST fill the nx maximum array
462 // index entry in the PLfGrid struct.
463 //--------------------------------------------------------------------------
464
465 PLFLT
466 plf2evalr( PLINT ix, PLINT iy, PLPointer plf2eval_data )
467 {
468 PLFLT value;
469 PLfGrid *grid = (PLfGrid *) plf2eval_data;
470
471 value = grid->f[ix + iy * grid->nx];
472
473 return value;
474 }
475
476 //--------------------------------------------------------------------------
477 //
478 // cont_store:
479 //
480 // Draw contour lines in memory.
481 // cont_clean_store() must be called after use to release allocated memory.
482 //
483 //--------------------------------------------------------------------------
484
485 void
486 cont_store( PLFLT_MATRIX f, PLINT nx, PLINT ny, PLINT kx, PLINT lx,
487 PLINT ky, PLINT ly, PLFLT_VECTOR clevel, PLINT nlevel,
488 PLTRANSFORM_callback pltr, PLPointer pltr_data,
489 CONT_LEVEL **contour )
490 {
491 cont3d = 1;
492
493 plcont( f, nx, ny, kx, lx, ky, ly, clevel, nlevel,
494 pltr, pltr_data );
495
496 *contour = startlev;
497 cont3d = 0;
498 }
499
500 //--------------------------------------------------------------------------
501 // void plcont()
502 //
503 // Draws a contour plot from data in f(nx,ny). Is just a front-end to
504 // plfcont, with a particular choice for f2eval and f2eval_data.
505 //--------------------------------------------------------------------------
506
507 void
508 c_plcont( PLFLT_MATRIX f, PLINT nx, PLINT ny, PLINT kx, PLINT lx,
509 PLINT ky, PLINT ly, PLFLT_VECTOR clevel, PLINT nlevel,
510 PLTRANSFORM_callback pltr, PLPointer pltr_data )
511 {
512 plfcont( plf2eval1, (PLPointer) f,
513 nx, ny, kx, lx, ky, ly, clevel, nlevel,
514 pltr, pltr_data );
515 }
516
517 //--------------------------------------------------------------------------
518 // void plfcont()
519 //
520 // Draws a contour plot using the function evaluator f2eval and data stored
521 // by way of the f2eval_data pointer. This allows arbitrary organizations
522 // of 2d array data to be used.
523 //
524 // The subrange of indices used for contouring is kx to lx in the x
525 // direction and from ky to ly in the y direction. The array of contour
526 // levels is clevel(nlevel), and "pltr" is the name of a function which
527 // transforms array indicies into world coordinates.
528 //
529 // Note that the fortran-like minimum and maximum indices (kx, lx, ky, ly)
530 // are translated into more C-like ones. I've only kept them as they are
531 // for the plfcont() argument list because of backward compatibility.
532 //--------------------------------------------------------------------------
533
534 void
535 plfcont( PLF2EVAL_callback f2eval, PLPointer f2eval_data,
536 PLINT nx, PLINT ny, PLINT kx, PLINT lx,
537 PLINT ky, PLINT ly, PLFLT_VECTOR clevel, PLINT nlevel,
538 PLTRANSFORM_callback pltr, PLPointer pltr_data )
539 {
540 PLINT i, **ipts;
541
542 if ( pltr == NULL )
543 {
544 // If pltr is undefined, abort with an error.
545 plabort( "plfcont: The pltr callback must be defined" );
546 return;
547 }
548
549 if ( kx < 1 || kx >= lx )
550 {
551 plabort( "plfcont: indices must satisfy 1 <= kx <= lx <= nx" );
552 return;
553 }
554 if ( ky < 1 || ky >= ly )
555 {
556 plabort( "plfcont: indices must satisfy 1 <= ky <= ly <= ny" );
557 return;
558 }
559
560 if ( ( ipts = (PLINT **) malloc( (size_t) nx * sizeof ( PLINT * ) ) ) == NULL )
561 {
562 plexit( "plfcont: Insufficient memory" );
563 }
564
565 for ( i = 0; i < nx; i++ )
566 {
567 if ( ( ipts[i] = (PLINT *) malloc( (size_t) ny * sizeof ( PLINT * ) ) ) == NULL )
568 {
569 plexit( "plfcont: Insufficient memory" );
570 }
571 }
572
573 for ( i = 0; i < nlevel; i++ )
574 {
575 plcntr( f2eval, f2eval_data,
576 nx, ny, kx - 1, lx - 1, ky - 1, ly - 1, clevel[i], ipts,
577 pltr, pltr_data );
578
579 if ( error )
580 {
581 error = 0;
582 goto done;
583 }
584 }
585
586 done:
587 for ( i = 0; i < nx; i++ )
588 {
589 free( (void *) ipts[i] );
590 }
591 free( (void *) ipts );
592 }
593
594 //--------------------------------------------------------------------------
595 // void plcntr()
596 //
597 // The contour for a given level is drawn here. Note iscan has nx
598 // elements. ixstor and iystor each have nstor elements.
599 //--------------------------------------------------------------------------
600
601 static void
602 plcntr( PLF2EVAL_callback f2eval, PLPointer f2eval_data,
603 PLINT nx, PLINT ny, PLINT kx, PLINT lx,
604 PLINT ky, PLINT ly, PLFLT flev, PLINT **ipts,
605 PLTRANSFORM_callback pltr, PLPointer pltr_data )
606 {
607 PLINT kcol, krow, lastindex;
608 PLFLT distance;
609 PLFLT save_def, save_scale;
610
611 char flabel[30];
612 plgchr( &save_def, &save_scale );
613 save_scale = save_scale / save_def;
614
615 cont_new_store( flev );
616
617 // format contour label for plptex and define the font height of the labels
618 plfloatlabel( flev, flabel, 30 );
619 plschr( 0.0, contlabel_size );
620
621 // Clear array for traversed squares
622 for ( kcol = kx; kcol < lx; kcol++ )
623 {
624 for ( krow = ky; krow < ly; krow++ )
625 {
626 ipts[kcol][krow] = 0;
627 }
628 }
629
630
631 for ( krow = ky; krow < ly; krow++ )
632 {
633 for ( kcol = kx; kcol < lx; kcol++ )
634 {
635 if ( ipts[kcol][krow] == 0 )
636 {
637 // Follow and draw a contour
638 pldrawcn( f2eval, f2eval_data,
639 nx, ny, kx, lx, ky, ly, flev, flabel, kcol, krow,
640 0.0, 0.0, -2, ipts, &distance, &lastindex,
641 pltr, pltr_data );
642
643 if ( error )
644 return;
645 }
646 }
647 }
648 plschr( save_def, save_scale );
649 }
650
651 //--------------------------------------------------------------------------
652 // void pldrawcn()
653 //
654 // Follow and draw a contour.
655 //--------------------------------------------------------------------------
656
657 static void
658 pldrawcn( PLF2EVAL_callback f2eval, PLPointer f2eval_data,
659 PLINT nx, PLINT ny, PLINT kx, PLINT lx,
660 PLINT ky, PLINT ly, PLFLT flev, char *flabel, PLINT kcol, PLINT krow,
661 PLFLT lastx, PLFLT lasty, PLINT startedge, PLINT **ipts,
662 PLFLT *distance, PLINT *lastindex,
663 PLTRANSFORM_callback pltr, PLPointer pltr_data )
664 {
665 PLFLT f[4];
666 PLFLT px[4], py[4], locx[4], locy[4];
667 PLINT iedge[4];
668 PLINT i, j, k, num, first, inext, kcolnext, krownext, sfi, sfj;
669
670
671 ( *pltr )( kcol, krow + 1, &px[0], &py[0], pltr_data );
672 ( *pltr )( kcol, krow, &px[1], &py[1], pltr_data );
673 ( *pltr )( kcol + 1, krow, &px[2], &py[2], pltr_data );
674 ( *pltr )( kcol + 1, krow + 1, &px[3], &py[3], pltr_data );
675
676 f[0] = f2eval( kcol, krow + 1, f2eval_data ) - flev;
677 f[1] = f2eval( kcol, krow, f2eval_data ) - flev;
678 f[2] = f2eval( kcol + 1, krow, f2eval_data ) - flev;
679 f[3] = f2eval( kcol + 1, krow + 1, f2eval_data ) - flev;
680
681 for ( i = 0, j = 1; i < 4; i++, j = ( j + 1 ) % 4 )
682 {
683 // Use intermediates to avoid possible floating point
684 // under / over flow during multiplication.
685 sfi = ( f[i] > 0.0 ) ? 1 : ( ( f[i] < 0.0 ) ? -1 : 0 );
686 sfj = ( f[j] > 0.0 ) ? 1 : ( ( f[j] < 0.0 ) ? -1 : 0 );
687 iedge[i] = ( sfi * sfj > 0 ) ? -1 : ( ( sfi * sfj < 0 ) ? 1 : 0 );
688 }
689
690 // Mark this square as done
691 ipts[kcol][krow] = 1;
692
693 // Check if no contour has been crossed i.e. iedge[i] = -1
694 if ( ( iedge[0] == -1 ) && ( iedge[1] == -1 ) && ( iedge[2] == -1 )
695 && ( iedge[3] == -1 ) )
696 return;
697
698 // Check if this is a completely flat square - in which case
699 // ignore it
700 if ( ( f[0] == 0.0 ) && ( f[1] == 0.0 ) && ( f[2] == 0.0 ) &&
701 ( f[3] == 0.0 ) )
702 return;
703
704 // Calculate intersection points
705 num = 0;
706 if ( startedge < 0 )
707 {
708 first = 1;
709 }
710 else
711 {
712 locx[num] = lastx;
713 locy[num] = lasty;
714 num++;
715 first = 0;
716 }
717 for ( k = 0, i = ( startedge < 0 ? 0 : startedge ); k < 4; k++, i = ( i + 1 ) % 4 )
718 {
719 if ( i == startedge )
720 continue;
721
722 // If the contour is an edge check it hasn't already been done
723 if ( f[i] == 0.0 && f[( i + 1 ) % 4] == 0.0 )
724 {
725 kcolnext = kcol;
726 krownext = krow;
727 if ( i == 0 )
728 kcolnext--;
729 if ( i == 1 )
730 krownext--;
731 if ( i == 2 )
732 kcolnext++;
733 if ( i == 3 )
734 krownext++;
735 if ( ( kcolnext < kx ) || ( kcolnext >= lx ) ||
736 ( krownext < ky ) || ( krownext >= ly ) ||
737 ( ipts[kcolnext][krownext] == 1 ) )
738 continue;
739 }
740 if ( ( iedge[i] == 1 ) || ( f[i] == 0.0 ) )
741 {
742 j = ( i + 1 ) % 4;
743 if ( f[i] != 0.0 )
744 {
745 locx[num] = ( px[i] * fabs( f[j] ) + px[j] * fabs( f[i] ) ) / fabs( f[j] - f[i] );
746 locy[num] = ( py[i] * fabs( f[j] ) + py[j] * fabs( f[i] ) ) / fabs( f[j] - f[i] );
747 }
748 else
749 {
750 locx[num] = px[i];
751 locy[num] = py[i];
752 }
753 // If this is the start of the contour then move to the point
754 if ( first == 1 )
755 {
756 cont_mv_store( locx[num], locy[num] );
757 first = 0;
758 *distance = 0;
759 *lastindex = 0;
760 }
761 else
762 {
763 // Link to the next point on the contour
764 if ( contlabel_active )
765 pl_drawcontlabel( locx[num], locy[num], flabel, distance, lastindex );
766 else
767 cont_xy_store( locx[num], locy[num] );
768 // Need to follow contour into next grid box
769 // Easy case where contour does not pass through corner
770 if ( f[i] != 0.0 )
771 {
772 kcolnext = kcol;
773 krownext = krow;
774 inext = ( i + 2 ) % 4;
775 if ( i == 0 )
776 kcolnext--;
777 if ( i == 1 )
778 krownext--;
779 if ( i == 2 )
780 kcolnext++;
781 if ( i == 3 )
782 krownext++;
783 if ( ( kcolnext >= kx ) && ( kcolnext < lx ) &&
784 ( krownext >= ky ) && ( krownext < ly ) &&
785 ( ipts[kcolnext][krownext] == 0 ) )
786 {
787 pldrawcn( f2eval, f2eval_data,
788 nx, ny, kx, lx, ky, ly, flev, flabel,
789 kcolnext, krownext,
790 locx[num], locy[num], inext, ipts,
791 distance, lastindex,
792 pltr, pltr_data );
793 }
794 }
795 // Hard case where contour passes through corner
796 // This is still not perfect - it may lose the contour
797 // which won't upset the contour itself (we can find it
798 // again later) but might upset the labelling
799 else
800 {
801 kcolnext = kcol;
802 krownext = krow;
803 inext = ( i + 2 ) % 4;
804 if ( i == 0 )
805 {
806 kcolnext--; krownext++;
807 }
808 if ( i == 1 )
809 {
810 krownext--; kcolnext--;
811 }
812 if ( i == 2 )
813 {
814 kcolnext++; krownext--;
815 }
816 if ( i == 3 )
817 {
818 krownext++; kcolnext++;
819 }
820 if ( ( kcolnext >= kx ) && ( kcolnext < lx ) &&
821 ( krownext >= ky ) && ( krownext < ly ) &&
822 ( ipts[kcolnext][krownext] == 0 ) )
823 {
824 pldrawcn( f2eval, f2eval_data,
825 nx, ny, kx, lx, ky, ly, flev, flabel,
826 kcolnext, krownext,
827 locx[num], locy[num], inext, ipts,
828 distance, lastindex,
829 pltr, pltr_data );
830 }
831 }
832 if ( first == 1 )
833 {
834 // Move back to first point
835 cont_mv_store( locx[num], locy[num] );
836 first = 0;
837 *distance = 0;
838 *lastindex = 0;
839 first = 0;
840 }
841 else
842 {
843 first = 1;
844 }
845 num++;
846 }
847 }
848 }
849 }
850
851 //--------------------------------------------------------------------------
852 // pltr0()
853 //
854 // Identity transformation.
855 //--------------------------------------------------------------------------
856
857 void
858 pltr0( PLFLT x, PLFLT y, PLFLT *tx, PLFLT *ty, PLPointer PL_UNUSED( pltr_data ) )
859 {
860 *tx = x;
861 *ty = y;
862 }
863
864 //--------------------------------------------------------------------------
865 // pltr1()
866 //
867 // Does linear interpolation from singly dimensioned coord arrays.
868 //
869 // Just abort for now if coordinates are out of bounds (don't think it's
870 // possible, but if so we could use linear extrapolation).
871 //--------------------------------------------------------------------------
872
873 void
874 pltr1( PLFLT x, PLFLT y, PLFLT *tx, PLFLT *ty, PLPointer pltr_data )
875 {
876 PLINT ul, ur, vl, vr;
877 PLFLT du, dv;
878 PLFLT xl, xr, yl, yr;
879
880 PLcGrid *grid = (PLcGrid *) pltr_data;
881 PLFLT *xg = grid->xg;
882 PLFLT *yg = grid->yg;
883 PLINT nx = grid->nx;
884 PLINT ny = grid->ny;
885
886 ul = (PLINT) x;
887 ur = ul + 1;
888 du = x - ul;
889
890 vl = (PLINT) y;
891 vr = vl + 1;
892 dv = y - vl;
893
894 if ( x < 0 || x > nx - 1 || y < 0 || y > ny - 1 )
895 {
896 plexit( "pltr1: Invalid coordinates" );
897 }
898
899 // Look up coordinates in row-dominant array.
900 // Have to handle right boundary specially -- if at the edge, we'd better
901 // not reference the out of bounds point.
902 //
903
904 xl = xg[ul];
905 yl = yg[vl];
906
907 if ( ur == nx )
908 {
909 *tx = xl;
910 }
911 else
912 {
913 xr = xg[ur];
914 *tx = xl * ( 1 - du ) + xr * du;
915 }
916 if ( vr == ny )
917 {
918 *ty = yl;
919 }
920 else
921 {
922 yr = yg[vr];
923 *ty = yl * ( 1 - dv ) + yr * dv;
924 }
925 }
926
927 //--------------------------------------------------------------------------
928 // pltr2()
929 //
930 // Does linear interpolation from doubly dimensioned coord arrays (column
931 // dominant, as per normal C 2d arrays).
932 //
933 // This routine includes lots of checks for out of bounds. This would occur
934 // occasionally due to some bugs in the contour plotter (now fixed). If an
935 // out of bounds coordinate is obtained, the boundary value is provided
936 // along with a warning. These checks should stay since no harm is done if
937 // if everything works correctly.
938 //--------------------------------------------------------------------------
939
940 void
941 pltr2( PLFLT x, PLFLT y, PLFLT *tx, PLFLT *ty, PLPointer pltr_data )
942 {
943 PLINT ul, ur, vl, vr;
944 PLFLT du, dv;
945 PLFLT xll, xlr, xrl, xrr;
946 PLFLT yll, ylr, yrl, yrr;
947 PLFLT xmin, xmax, ymin, ymax;
948
949 PLcGrid2 *grid = (PLcGrid2 *) pltr_data;
950 PLFLT **xg = grid->xg;
951 PLFLT **yg = grid->yg;
952 PLINT nx = grid->nx;
953 PLINT ny = grid->ny;
954
955 ul = (PLINT) x;
956 ur = ul + 1;
957 du = x - ul;
958
959 vl = (PLINT) y;
960 vr = vl + 1;
961 dv = y - vl;
962
963 xmin = 0;
964 xmax = nx - 1;
965 ymin = 0;
966 ymax = ny - 1;
967
968 if ( x < xmin || x > xmax || y < ymin || y > ymax )
969 {
970 plwarn( "pltr2: Invalid coordinates" );
971 if ( x < xmin )
972 {
973 if ( y < ymin )
974 {
975 *tx = xg[0][0];
976 *ty = yg[0][0];
977 }
978 else if ( y > ymax )
979 {
980 *tx = xg[0][ny - 1];
981 *ty = yg[0][ny - 1];
982 }
983 else
984 {
985 xll = xg[0][vl];
986 yll = yg[0][vl];
987 xlr = xg[0][vr];
988 ylr = yg[0][vr];
989
990 *tx = xll * ( 1 - dv ) + xlr * ( dv );
991 *ty = yll * ( 1 - dv ) + ylr * ( dv );
992 }
993 }
994 else if ( x > xmax )
995 {
996 if ( y < ymin )
997 {
998 *tx = xg[nx - 1][0];
999 *ty = yg[nx - 1][0];
1000 }
1001 else if ( y > ymax )
1002 {
1003 *tx = xg[nx - 1][ny - 1];
1004 *ty = yg[nx - 1][ny - 1];
1005 }
1006 else
1007 {
1008 xll = xg[nx - 1][vl];
1009 yll = yg[nx - 1][vl];
1010 xlr = xg[nx - 1][vr];
1011 ylr = yg[nx - 1][vr];
1012
1013 *tx = xll * ( 1 - dv ) + xlr * ( dv );
1014 *ty = yll * ( 1 - dv ) + ylr * ( dv );
1015 }
1016 }
1017 else
1018 {
1019 if ( y < ymin )
1020 {
1021 xll = xg[ul][0];
1022 xrl = xg[ur][0];
1023 yll = yg[ul][0];
1024 yrl = yg[ur][0];
1025
1026 *tx = xll * ( 1 - du ) + xrl * ( du );
1027 *ty = yll * ( 1 - du ) + yrl * ( du );
1028 }
1029 else if ( y > ymax )
1030 {
1031 xlr = xg[ul][ny - 1];
1032 xrr = xg[ur][ny - 1];
1033 ylr = yg[ul][ny - 1];
1034 yrr = yg[ur][ny - 1];
1035
1036 *tx = xlr * ( 1 - du ) + xrr * ( du );
1037 *ty = ylr * ( 1 - du ) + yrr * ( du );
1038 }
1039 }
1040 }
1041
1042 // Normal case.
1043 // Look up coordinates in row-dominant array.
1044 // Have to handle right boundary specially -- if at the edge, we'd
1045 // better not reference the out of bounds point.
1046 //
1047
1048 else
1049 {
1050 xll = xg[ul][vl];
1051 yll = yg[ul][vl];
1052
1053 // ur is out of bounds
1054
1055 if ( ur == nx && vr < ny )
1056 {
1057 xlr = xg[ul][vr];
1058 ylr = yg[ul][vr];
1059
1060 *tx = xll * ( 1 - dv ) + xlr * ( dv );
1061 *ty = yll * ( 1 - dv ) + ylr * ( dv );
1062 }
1063
1064 // vr is out of bounds
1065
1066 else if ( ur < nx && vr == ny )
1067 {
1068 xrl = xg[ur][vl];
1069 yrl = yg[ur][vl];
1070
1071 *tx = xll * ( 1 - du ) + xrl * ( du );
1072 *ty = yll * ( 1 - du ) + yrl * ( du );
1073 }
1074
1075 // both ur and vr are out of bounds
1076
1077 else if ( ur == nx && vr == ny )
1078 {
1079 *tx = xll;
1080 *ty = yll;
1081 }
1082
1083 // everything in bounds
1084
1085 else
1086 {
1087 xrl = xg[ur][vl];
1088 xlr = xg[ul][vr];
1089 xrr = xg[ur][vr];
1090
1091 yrl = yg[ur][vl];
1092 ylr = yg[ul][vr];
1093 yrr = yg[ur][vr];
1094
1095 *tx = xll * ( 1 - du ) * ( 1 - dv ) + xlr * ( 1 - du ) * ( dv ) +
1096 xrl * ( du ) * ( 1 - dv ) + xrr * ( du ) * ( dv );
1097
1098 *ty = yll * ( 1 - du ) * ( 1 - dv ) + ylr * ( 1 - du ) * ( dv ) +
1099 yrl * ( du ) * ( 1 - dv ) + yrr * ( du ) * ( dv );
1100 }
1101 }
1102 }
1103
1104 //--------------------------------------------------------------------------
1105 // pltr2p()
1106 //
1107 // Just like pltr2() but uses pointer arithmetic to get coordinates from 2d
1108 // grid tables. This form of grid tables is compatible with those from
1109 // PLplot 4.0. The grid data must be pointed to by a PLcGrid structure.
1110 //--------------------------------------------------------------------------
1111
1112 void
1113 pltr2p( PLFLT x, PLFLT y, PLFLT *tx, PLFLT *ty, PLPointer pltr_data )
1114 {
1115 PLINT ul, ur, vl, vr;
1116 PLFLT du, dv;
1117 PLFLT xll, xlr, xrl, xrr;
1118 PLFLT yll, ylr, yrl, yrr;
1119 PLFLT xmin, xmax, ymin, ymax;
1120
1121 PLcGrid *grid = (PLcGrid *) pltr_data;
1122 PLFLT *xg = grid->xg;
1123 PLFLT *yg = grid->yg;
1124 PLINT nx = grid->nx;
1125 PLINT ny = grid->ny;
1126
1127 ul = (PLINT) x;
1128 ur = ul + 1;
1129 du = x - ul;
1130
1131 vl = (PLINT) y;
1132 vr = vl + 1;
1133 dv = y - vl;
1134
1135 xmin = 0;
1136 xmax = nx - 1;
1137 ymin = 0;
1138 ymax = ny - 1;
1139
1140 if ( x < xmin || x > xmax || y < ymin || y > ymax )
1141 {
1142 plwarn( "pltr2p: Invalid coordinates" );
1143 if ( x < xmin )
1144 {
1145 if ( y < ymin )
1146 {
1147 *tx = *xg;
1148 *ty = *yg;
1149 }
1150 else if ( y > ymax )
1151 {
1152 *tx = *( xg + ( ny - 1 ) );
1153 *ty = *( yg + ( ny - 1 ) );
1154 }
1155 else
1156 {
1157 ul = 0;
1158 xll = *( xg + ul * ny + vl );
1159 yll = *( yg + ul * ny + vl );
1160 xlr = *( xg + ul * ny + vr );
1161 ylr = *( yg + ul * ny + vr );
1162
1163 *tx = xll * ( 1 - dv ) + xlr * ( dv );
1164 *ty = yll * ( 1 - dv ) + ylr * ( dv );
1165 }
1166 }
1167 else if ( x > xmax )
1168 {
1169 if ( y < ymin )
1170 {
1171 *tx = *( xg + ( ny - 1 ) * nx );
1172 *ty = *( yg + ( ny - 1 ) * nx );
1173 }
1174 else if ( y > ymax )
1175 {
1176 *tx = *( xg + ( ny - 1 ) + ( nx - 1 ) * ny );
1177 *ty = *( yg + ( ny - 1 ) + ( nx - 1 ) * ny );
1178 }
1179 else
1180 {
1181 ul = nx - 1;
1182 xll = *( xg + ul * ny + vl );
1183 yll = *( yg + ul * ny + vl );
1184 xlr = *( xg + ul * ny + vr );
1185 ylr = *( yg + ul * ny + vr );
1186
1187 *tx = xll * ( 1 - dv ) + xlr * ( dv );
1188 *ty = yll * ( 1 - dv ) + ylr * ( dv );
1189 }
1190 }
1191 else
1192 {
1193 if ( y < ymin )
1194 {
1195 vl = 0;
1196 xll = *( xg + ul * ny + vl );
1197 xrl = *( xg + ur * ny + vl );
1198 yll = *( yg + ul * ny + vl );
1199 yrl = *( yg + ur * ny + vl );
1200
1201 *tx = xll * ( 1 - du ) + xrl * ( du );
1202 *ty = yll * ( 1 - du ) + yrl * ( du );
1203 }
1204 else if ( y > ymax )
1205 {
1206 vr = ny - 1;
1207 xlr = *( xg + ul * ny + vr );
1208 xrr = *( xg + ur * ny + vr );
1209 ylr = *( yg + ul * ny + vr );
1210 yrr = *( yg + ur * ny + vr );
1211
1212 *tx = xlr * ( 1 - du ) + xrr * ( du );
1213 *ty = ylr * ( 1 - du ) + yrr * ( du );
1214 }
1215 }
1216 }
1217
1218 // Normal case.
1219 // Look up coordinates in row-dominant array.
1220 // Have to handle right boundary specially -- if at the edge, we'd better
1221 // not reference the out of bounds point.
1222 //
1223
1224 else
1225 {
1226 xll = *( xg + ul * ny + vl );
1227 yll = *( yg + ul * ny + vl );
1228
1229 // ur is out of bounds
1230
1231 if ( ur == nx && vr < ny )
1232 {
1233 xlr = *( xg + ul * ny + vr );
1234 ylr = *( yg + ul * ny + vr );
1235
1236 *tx = xll * ( 1 - dv ) + xlr * ( dv );
1237 *ty = yll * ( 1 - dv ) + ylr * ( dv );
1238 }
1239
1240 // vr is out of bounds
1241
1242 else if ( ur < nx && vr == ny )
1243 {
1244 xrl = *( xg + ur * ny + vl );
1245 yrl = *( yg + ur * ny + vl );
1246
1247 *tx = xll * ( 1 - du ) + xrl * ( du );
1248 *ty = yll * ( 1 - du ) + yrl * ( du );
1249 }
1250
1251 // both ur and vr are out of bounds
1252
1253 else if ( ur == nx && vr == ny )
1254 {
1255 *tx = xll;
1256 *ty = yll;
1257 }
1258
1259 // everything in bounds
1260
1261 else
1262 {
1263 xrl = *( xg + ur * ny + vl );
1264 xlr = *( xg + ul * ny + vr );
1265 xrr = *( xg + ur * ny + vr );
1266
1267 yrl = *( yg + ur * ny + vl );
1268 ylr = *( yg + ul * ny + vr );
1269 yrr = *( yg + ur * ny + vr );
1270
1271 *tx = xll * ( 1 - du ) * ( 1 - dv ) + xlr * ( 1 - du ) * ( dv ) +
1272 xrl * ( du ) * ( 1 - dv ) + xrr * ( du ) * ( dv );
1273
1274 *ty = yll * ( 1 - du ) * ( 1 - dv ) + ylr * ( 1 - du ) * ( dv ) +
1275 yrl * ( du ) * ( 1 - dv ) + yrr * ( du ) * ( dv );
1276 }
1277 }
1278 }
1279
1280 //--------------------------------------------------------------------------
1281 // pltr2f()
1282 //
1283 // Does linear interpolation from doubly dimensioned coord arrays
1284 // (row dominant, i.e. Fortran ordering).
1285 //
1286 // This routine includes lots of checks for out of bounds. This would
1287 // occur occasionally due to a bug in the contour plotter that is now fixed.
1288 // If an out of bounds coordinate is obtained, the boundary value is provided
1289 // along with a warning. These checks should stay since no harm is done if
1290 // if everything works correctly.
1291 //--------------------------------------------------------------------------
1292
1293 void
1294 pltr2f( PLFLT x, PLFLT y, PLFLT *tx, PLFLT *ty, void *pltr_data )
1295 {
1296 PLINT ul, ur, vl, vr;
1297 PLFLT du, dv;
1298 PLFLT xll, xlr, xrl, xrr;
1299 PLFLT yll, ylr, yrl, yrr;
1300 PLFLT xmin, xmax, ymin, ymax;
1301
1302 PLcGrid *cgrid = (PLcGrid *) pltr_data;
1303 PLFLT *xg = cgrid->xg;
1304 PLFLT *yg = cgrid->yg;
1305 PLINT nx = cgrid->nx;
1306 PLINT ny = cgrid->ny;
1307
1308 ul = (PLINT) x;
1309 ur = ul + 1;
1310 du = x - ul;
1311
1312 vl = (PLINT) y;
1313 vr = vl + 1;
1314 dv = y - vl;
1315
1316 xmin = 0;
1317 xmax = nx - 1;
1318 ymin = 0;
1319 ymax = ny - 1;
1320
1321 if ( x < xmin || x > xmax || y < ymin || y > ymax )
1322 {
1323 plwarn( "pltr2f: Invalid coordinates" );
1324
1325 if ( x < xmin )
1326 {
1327 if ( y < ymin )
1328 {
1329 *tx = *xg;
1330 *ty = *yg;
1331 }
1332 else if ( y > ymax )
1333 {
1334 *tx = *( xg + ( ny - 1 ) * nx );
1335 *ty = *( yg + ( ny - 1 ) * nx );
1336 }
1337 else
1338 {
1339 ul = 0;
1340 xll = *( xg + ul + vl * nx );
1341 yll = *( yg + ul + vl * nx );
1342 xlr = *( xg + ul + vr * nx );
1343 ylr = *( yg + ul + vr * nx );
1344
1345 *tx = xll * ( 1 - dv ) + xlr * ( dv );
1346 *ty = yll * ( 1 - dv ) + ylr * ( dv );
1347 }
1348 }
1349 else if ( x > xmax )
1350 {
1351 if ( y < ymin )
1352 {
1353 *tx = *( xg + ( nx - 1 ) );
1354 *ty = *( yg + ( nx - 1 ) );
1355 }
1356 else if ( y > ymax )
1357 {
1358 *tx = *( xg + ( nx - 1 ) + ( ny - 1 ) * nx );
1359 *ty = *( yg + ( nx - 1 ) + ( ny - 1 ) * nx );
1360 }
1361 else
1362 {
1363 ul = nx - 1;
1364 xll = *( xg + ul + vl * nx );
1365 yll = *( yg + ul + vl * nx );
1366 xlr = *( xg + ul + vr * nx );
1367 ylr = *( yg + ul + vr * nx );
1368
1369 *tx = xll * ( 1 - dv ) + xlr * ( dv );
1370 *ty = yll * ( 1 - dv ) + ylr * ( dv );
1371 }
1372 }
1373 else
1374 {
1375 if ( y < ymin )
1376 {
1377 vl = 0;
1378 xll = *( xg + ul + vl * nx );
1379 xrl = *( xg + ur + vl * nx );
1380 yll = *( yg + ul + vl * nx );
1381 yrl = *( yg + ur + vl * nx );
1382
1383 *tx = xll * ( 1 - du ) + xrl * ( du );
1384 *ty = yll * ( 1 - du ) + yrl * ( du );
1385 }
1386 else if ( y > ymax )
1387 {
1388 vr = ny - 1;
1389 xlr = *( xg + ul + vr * nx );
1390 xrr = *( xg + ur + vr * nx );
1391 ylr = *( yg + ul + vr * nx );
1392 yrr = *( yg + ur + vr * nx );
1393
1394 *tx = xlr * ( 1 - du ) + xrr * ( du );
1395 *ty = ylr * ( 1 - du ) + yrr * ( du );
1396 }
1397 }
1398 }
1399
1400 // Normal case.
1401 // Look up coordinates in row-dominant array.
1402 // Have to handle right boundary specially -- if at the edge, we'd
1403 // better not reference the out of bounds point.
1404
1405 else
1406 {
1407 xll = *( xg + ul + vl * nx );
1408 yll = *( yg + ul + vl * nx );
1409
1410 // ur is out of bounds
1411
1412 if ( ur == nx && vr < ny )
1413 {
1414 xlr = *( xg + ul + vr * nx );
1415 ylr = *( yg + ul + vr * nx );
1416
1417 *tx = xll * ( 1 - dv ) + xlr * ( dv );
1418 *ty = yll * ( 1 - dv ) + ylr * ( dv );
1419 }
1420
1421 // vr is out of bounds
1422
1423 else if ( ur < nx && vr == ny )
1424 {
1425 xrl = *( xg + ur + vl * nx );
1426 yrl = *( yg + ur + vl * nx );
1427
1428 *tx = xll * ( 1 - du ) + xrl * ( du );
1429 *ty = yll * ( 1 - du ) + yrl * ( du );
1430 }
1431
1432 // both ur and vr are out of bounds
1433
1434 else if ( ur == nx && vr == ny )
1435 {
1436 *tx = xll;
1437 *ty = yll;
1438 }
1439
1440 // everything in bounds
1441
1442 else
1443 {
1444 xrl = *( xg + ur + vl * nx );
1445 xlr = *( xg + ul + vr * nx );
1446 xrr = *( xg + ur + vr * nx );
1447
1448 yrl = *( yg + ur + vl * nx );
1449 ylr = *( yg + ul + vr * nx );
1450 yrr = *( yg + ur + vr * nx );
1451 *tx = xll * ( 1 - du ) * ( 1 - dv ) + xlr * ( 1 - du ) * ( dv ) +
1452 xrl * ( du ) * ( 1 - dv ) + xrr * ( du ) * ( dv );
1453
1454 *ty = yll * ( 1 - du ) * ( 1 - dv ) + ylr * ( 1 - du ) * ( dv ) +
1455 yrl * ( du ) * ( 1 - dv ) + yrr * ( du ) * ( dv );
1456 }
1457 }
1458 }
plplotP.h
plf2evalr
PLFLT plf2evalr(PLINT ix, PLINT iy, PLPointer plf2eval_data)
Definition: plcont.c:466
startlev
static CONT_LEVEL * startlev
Definition: plcont.c:95
pltr2f
void pltr2f(PLFLT x, PLFLT y, PLFLT *tx, PLFLT *ty, void *pltr_data)
Definition: plcont.c:1294
contlabel_offset
static PLFLT contlabel_offset
Definition: plcont.c:75
plexit
void plexit(PLCHAR_VECTOR errormsg)
Definition: plctrl.c:1958
PLTRANSFORM_callback
void(* PLTRANSFORM_callback)(PLFLT x, PLFLT y, PLFLT_NC_SCALAR xp, PLFLT_NC_SCALAR yp, PLPointer data)
Definition: plplot.h:257
plP_pcdcy
PLFLT plP_pcdcy(PLINT y)
Definition: plcvt.c:95
plP_wcpcx
PLINT plP_wcpcx(PLFLT x)
Definition: plcvt.c:63
plschr
#define plschr
Definition: plplot.h:790
cont_new_store
static void cont_new_store(PLFLT level)
Definition: plcont.c:154
plP_gprec
void plP_gprec(PLINT *p_setp, PLINT *p_prec)
Definition: plcore.c:3869
plf2eval
PLFLT plf2eval(PLINT ix, PLINT iy, PLPointer plf2eval_data)
Definition: plcont.c:447
PLfGrid::nx
PLINT nx
Definition: plplot.h:481
plP_movwor
void plP_movwor(PLFLT x, PLFLT y)
Definition: plline.c:489
PLFLT_MATRIX
const PLFLT *const * PLFLT_MATRIX
Definition: plplot.h:253
plf2eval2
PLFLT plf2eval2(PLINT ix, PLINT iy, PLPointer plf2eval_data)
Definition: plcont.c:428
pltr1
void pltr1(PLFLT x, PLFLT y, PLFLT *tx, PLFLT *ty, PLPointer pltr_data)
Definition: plcont.c:874
cont_line::next
struct cont_line * next
Definition: plplotP.h:781
cont_level::line
struct cont_line * line
Definition: plplotP.h:788
cont_level
Definition: plplotP.h:784
PLF2EVAL_callback
PLFLT(* PLF2EVAL_callback)(PLINT ix, PLINT iy, PLPointer data)
Definition: plplot.h:259
plabort
void plabort(PLCHAR_VECTOR errormsg)
Definition: plctrl.c:1894
error
static int error
Definition: plcont.c:61
PLPointer
void * PLPointer
Definition: plplot.h:209
cont_mv_store
static void cont_mv_store(PLFLT xx, PLFLT yy)
Definition: plcont.c:227
distance
static double distance(point *p1, point *p2)
Definition: csa.c:645
_state::size
size_t size
Definition: plbuf.c:1725
TMPSTRING_LEN
#define TMPSTRING_LEN
alloc_line
static CONT_LINE * alloc_line(void)
Definition: plcont.c:102
PLINT
int PLINT
Definition: plplot.h:181
PLfGrid2::f
PLFLT_NC_MATRIX f
Definition: plplot.h:491
currline
static CONT_LINE * currline
Definition: plcont.c:97
cont_line::npts
PLINT npts
Definition: plplotP.h:780
contlabel_size
static PLFLT contlabel_size
Definition: plcont.c:71
plcntr
static void plcntr(PLF2EVAL_callback plf2eval, PLPointer plf2eval_data, PLINT nx, PLINT ny, PLINT kx, PLINT lx, PLINT ky, PLINT ly, PLFLT flev, PLINT **ipts, PLTRANSFORM_callback pltr, PLPointer pltr_data)
Definition: plcont.c:602
c_plcont
void c_plcont(PLFLT_MATRIX f, 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:508
realloc_line
static void realloc_line(CONT_LINE *line)
Definition: plcont.c:142
line
Definition: plsdef.c:27
contlabel_space
static PLFLT contlabel_space
Definition: plcont.c:79
pldrawcn
static void pldrawcn(PLF2EVAL_callback plf2eval, PLPointer plf2eval_data, PLINT nx, PLINT ny, PLINT kx, PLINT lx, PLINT ky, PLINT ly, PLFLT flev, char *flabel, PLINT kcol, PLINT krow, PLFLT lastx, PLFLT lasty, PLINT startedge, PLINT **ipts, PLFLT *distance, PLINT *lastindex, PLTRANSFORM_callback pltr, PLPointer pltr_data)
Definition: plcont.c:658
snprintf
#define snprintf
Definition: plplotP.h:235
cont_line::x
PLFLT * x
Definition: plplotP.h:778
plgchr
#define plgchr
Definition: plplot.h:722
line
static struct line line[]
cont_line
Definition: plplotP.h:776
plf2eval1
PLFLT plf2eval1(PLINT ix, PLINT iy, PLPointer plf2eval_data)
Definition: plcont.c:410
plcont
#define plcont
Definition: plplot.h:706
plP_pcwcx
static PLFLT plP_pcwcx(PLINT x)
Definition: plcont.c:389
pl_drawcontlabel
static void pl_drawcontlabel(PLFLT tpx, PLFLT tpy, char *flabel, PLFLT *distance, PLINT *lastindex)
Definition: plcont.c:262
plplot::PLcGrid2
Definition: plplot.d:29
LINE_ITEMS
#define LINE_ITEMS
Definition: plplotP.h:774
plplot::PLcGrid2::yg
PLFLT [][] yg
Definition: plplot.d:32
cont_line::y
PLFLT * y
Definition: plplotP.h:779
plplot::PLcGrid::xg
PLFLT [] xg
Definition: plplot.d:25
value
static PLFLT value(double n1, double n2, double hue)
Definition: plctrl.c:1219
cont_xy_store
static void cont_xy_store(PLFLT xx, PLFLT yy)
Definition: plcont.c:209
limexp
static PLINT limexp
Definition: plcont.c:87
plP_pcdcx
PLFLT plP_pcdcx(PLINT x)
Definition: plcvt.c:87
PLfGrid::ny
PLINT ny
Definition: plplot.h:481
pltr0
void pltr0(PLFLT x, PLFLT y, PLFLT *tx, PLFLT *ty, PLPointer PL_UNUSED(pltr_data))
Definition: plcont.c:858
pltr2
void pltr2(PLFLT x, PLFLT y, PLFLT *tx, PLFLT *ty, PLPointer pltr_data)
Definition: plcont.c:941
plplot::PLcGrid2::xg
PLFLT [][] xg
Definition: plplot.d:31
FORM_LEN
#define FORM_LEN
lastx
static PLINT lastx
Definition: plline.c:29
cont3d
static int cont3d
Definition: plcont.c:99
PL_UNUSED
#define PL_UNUSED(x)
Definition: plplot.h:138
PLFLT
float PLFLT
Definition: plplot.h:163
cont_clean_store
void cont_clean_store(CONT_LEVEL *ct)
Definition: plcont.c:173
c_pl_setcontlabelparam
void c_pl_setcontlabelparam(PLFLT offset, PLFLT size, PLFLT spacing, PLINT active)
Definition: plcont.c:247
plP_drawor
void plP_drawor(PLFLT x, PLFLT y)
Definition: plline.c:505
PLfGrid2
Definition: plplot.h:489
lasty
static PLINT lasty
Definition: plline.c:29
plP_wcpcy
PLINT plP_wcpcy(PLFLT y)
Definition: plcvt.c:73
c_pl_setcontlabelformat
void c_pl_setcontlabelformat(PLINT lexp, PLINT sigdig)
Definition: plcont.c:256
plwarn
void plwarn(PLCHAR_VECTOR errormsg)
Definition: plctrl.c:1863
currlev
static CONT_LEVEL * currlev
Definition: plcont.c:96
cont_store
void cont_store(PLFLT_MATRIX f, PLINT nx, PLINT ny, PLINT kx, PLINT lx, PLINT ky, PLINT ly, PLFLT_VECTOR clevel, PLINT nlevel, PLTRANSFORM_callback pltr, PLPointer pltr_data, CONT_LEVEL **contour)
Definition: plcont.c:486
plplot::PLcGrid
Definition: plplot.d:23
plptex
#define plptex
Definition: plplot.h:785
plP_pcwcy
static PLFLT plP_pcwcy(PLINT y)
Definition: plcont.c:397
plplot::PLcGrid::yg
PLFLT [] yg
Definition: plplot.d:26
cont_level::level
PLFLT level
Definition: plplotP.h:787
PLFLT_VECTOR
const PLFLT * PLFLT_VECTOR
Definition: plplot.h:244
contlabel_active
static PLINT contlabel_active
Definition: plcont.c:83
sigprec
static PLINT sigprec
Definition: plcont.c:91
pltr2p
void pltr2p(PLFLT x, PLFLT y, PLFLT *tx, PLFLT *ty, PLPointer pltr_data)
Definition: plcont.c:1113
plfcont
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
plfloatlabel
static void plfloatlabel(PLFLT value, char *string, PLINT len)
Definition: plcont.c:318
PLfGrid
Definition: plplot.h:478
PLfGrid::f
PLFLT_FE_POINTER f
Definition: plplot.h:480
cont_level::next
struct cont_level * next
Definition: plplotP.h:789
alloc_level
static CONT_LEVEL * alloc_level(PLFLT level)
Definition: plcont.c:126