PLplot 5.15.0
Loading...
Searching...
No Matches
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
33static void
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
39static void
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
47static void
48plfloatlabel( PLFLT value, char *string, PLINT len );
49
50static PLFLT
51plP_pcwcx( PLINT x );
52
53static PLFLT
54plP_pcwcy( PLINT y );
55
56static void
57pl_drawcontlabel( PLFLT tpx, PLFLT tpy, char *flabel, PLFLT *distance, PLINT *lastindex );
58
59// Error flag for aborts
60
61static int error;
62
63//**************************************
64//
65// Defaults for contour label printing.
66//
67//**************************************
68
69// Font height for contour labels (normalized)
70static PLFLT
72
73// Offset of label from contour line (if set to 0.0, labels are printed on the lines).
74static PLFLT
76
77// Spacing parameter for contour labels
78static PLFLT
80
81// Activate labels, default off
82static PLINT
84
85// If the contour label exceed 10^(limexp) or 10^(-limexp), the exponential format is used
86static PLINT
87 limexp = 4;
88
89// Number of significant digits
90static PLINT
92
93//******* contour lines storage ***************************
94
95static CONT_LEVEL *startlev = NULL;
98
99static int cont3d = 0;
100
101static CONT_LINE *
103{
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
125static CONT_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
141static void
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
153static void
155{
156 if ( cont3d )
157 {
158 if ( startlev == NULL )
159 {
160 startlev = alloc_level( level );
162 }
163 else
164 {
165 currlev->next = alloc_level( level );
166 currlev = currlev->next;
167 }
168 currline = currlev->line;
169 }
170}
171
172void
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
208static void
210{
211 if ( cont3d )
212 {
213 PLINT pts = currline->npts;
214
215 if ( pts % LINE_ITEMS == 0 )
217
218 currline->x[pts] = xx;
219 currline->y[pts] = yy;
220 currline->npts++;
221 }
222 else
223 plP_drawor( xx, yy );
224}
225
226static void
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
247void 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
257{
258 limexp = lexp;
259 sigprec = sigdig;
260}
261
262static 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 ) /
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
318static 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
388static PLFLT
390{
391 return ( ( x - plsc->wpxoff ) / plsc->wpxscl );
392}
393
394// physical coords (y) to world coords
395
396static PLFLT
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
409PLFLT
410plf2eval1( 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
427PLFLT
428plf2eval2( 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
446PLFLT
447plf2eval( 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
465PLFLT
466plf2evalr( 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
485void
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
507void
509 PLINT ky, PLINT ly, PLFLT_VECTOR clevel, PLINT nlevel,
510 PLTRANSFORM_callback pltr, PLPointer pltr_data )
511{
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
534void
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
586done:
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
601static void
602plcntr( 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;
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
657static void
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
857void
858pltr0( 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
873void
874pltr1( 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
940void
941pltr2( 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
1112void
1113pltr2p( 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
1293void
1294pltr2f( 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}
static double distance(point *p1, point *p2)
Definition csa.c:645
static PLFLT plP_pcwcx(PLINT x)
Definition plcont.c:389
static CONT_LEVEL * startlev
Definition plcont.c:95
void pltr2p(PLFLT x, PLFLT y, PLFLT *tx, PLFLT *ty, PLPointer pltr_data)
Definition plcont.c:1113
static PLFLT contlabel_size
Definition plcont.c:71
static CONT_LINE * currline
Definition plcont.c:97
static int error
Definition plcont.c:61
void cont_clean_store(CONT_LEVEL *ct)
Definition plcont.c:173
#define TMPSTRING_LEN
static CONT_LEVEL * alloc_level(PLFLT level)
Definition plcont.c:126
static PLFLT contlabel_offset
Definition plcont.c:75
static PLINT contlabel_active
Definition plcont.c:83
void pltr2(PLFLT x, PLFLT y, PLFLT *tx, PLFLT *ty, PLPointer pltr_data)
Definition plcont.c:941
PLFLT plf2eval(PLINT ix, PLINT iy, PLPointer plf2eval_data)
Definition plcont.c:447
static CONT_LINE * alloc_line(void)
Definition plcont.c:102
void c_pl_setcontlabelparam(PLFLT offset, PLFLT size, PLFLT spacing, PLINT active)
Definition plcont.c:247
#define FORM_LEN
static void realloc_line(CONT_LINE *line)
Definition plcont.c:142
static int cont3d
Definition plcont.c:99
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
static void cont_xy_store(PLFLT xx, PLFLT yy)
Definition plcont.c:209
static PLFLT contlabel_space
Definition plcont.c:79
static void pl_drawcontlabel(PLFLT tpx, PLFLT tpy, char *flabel, PLFLT *distance, PLINT *lastindex)
Definition plcont.c:262
static void cont_new_store(PLFLT level)
Definition plcont.c:154
static PLINT limexp
Definition plcont.c:87
PLFLT plf2eval1(PLINT ix, PLINT iy, PLPointer plf2eval_data)
Definition plcont.c:410
static CONT_LEVEL * currlev
Definition plcont.c:96
static PLFLT plP_pcwcy(PLINT y)
Definition plcont.c:397
static void cont_mv_store(PLFLT xx, PLFLT yy)
Definition plcont.c:227
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
static PLINT sigprec
Definition plcont.c:91
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
PLFLT plf2evalr(PLINT ix, PLINT iy, PLPointer plf2eval_data)
Definition plcont.c:466
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
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
static void plfloatlabel(PLFLT value, char *string, PLINT len)
Definition plcont.c:318
PLFLT plf2eval2(PLINT ix, PLINT iy, PLPointer plf2eval_data)
Definition plcont.c:428
void pltr2f(PLFLT x, PLFLT y, PLFLT *tx, PLFLT *ty, void *pltr_data)
Definition plcont.c:1294
void c_pl_setcontlabelformat(PLINT lexp, PLINT sigdig)
Definition plcont.c:256
void pltr1(PLFLT x, PLFLT y, PLFLT *tx, PLFLT *ty, PLPointer pltr_data)
Definition plcont.c:874
void pltr0(PLFLT x, PLFLT y, PLFLT *tx, PLFLT *ty, PLPointer PL_UNUSED(pltr_data))
Definition plcont.c:858
void plP_gprec(PLINT *p_setp, PLINT *p_prec)
Definition plcore.c:3869
void plwarn(PLCHAR_VECTOR errormsg)
Definition plctrl.c:1863
static PLFLT value(double n1, double n2, double hue)
Definition plctrl.c:1219
void plexit(PLCHAR_VECTOR errormsg)
Definition plctrl.c:1958
void plabort(PLCHAR_VECTOR errormsg)
Definition plctrl.c:1894
PLINT plP_wcpcy(PLFLT y)
Definition plcvt.c:73
PLFLT plP_pcdcy(PLINT y)
Definition plcvt.c:95
PLFLT plP_pcdcx(PLINT x)
Definition plcvt.c:87
PLINT plP_wcpcx(PLFLT x)
Definition plcvt.c:63
void plP_drawor(PLFLT x, PLFLT y)
Definition plline.c:505
static PLINT lasty
Definition plline.c:29
void plP_movwor(PLFLT x, PLFLT y)
Definition plline.c:489
static PLINT lastx
Definition plline.c:29
struct cont_line CONT_LINE
#define LINE_ITEMS
Definition plplotP.h:774
struct cont_level CONT_LEVEL
#define plschr
Definition plplot.h:790
PLFLT(* PLF2EVAL_callback)(PLINT ix, PLINT iy, PLPointer data)
Definition plplot.h:259
#define plgchr
Definition plplot.h:722
float PLFLT
Definition plplot.h:163
void(* PLTRANSFORM_callback)(PLFLT x, PLFLT y, PLFLT_NC_SCALAR xp, PLFLT_NC_SCALAR yp, PLPointer data)
Definition plplot.h:257
#define plptex
Definition plplot.h:785
const PLFLT * PLFLT_VECTOR
Definition plplot.h:244
const PLFLT *const * PLFLT_MATRIX
Definition plplot.h:253
#define PL_UNUSED(x)
Definition plplot.h:138
#define plcont
Definition plplot.h:706
int PLINT
Definition plplot.h:181
void * PLPointer
Definition plplot.h:209
static const char shade or gradient plots n n or n gradient plots(See pllegend for similar functionality for creating\n\ legends with discrete elements). The arguments of plcolorbar provide\n\ control over the location and size of the color bar as well as the\n\ location and characteristics of the elements(most of which are\n\ optional) within that color bar. The resulting color bar is clipped\n\ at the boundaries of the current subpage.(N.B. the adopted coordinate\n\ system used for some of the parameters is defined in the documentation\n\ of the position parameter.)\n\ \n\ Redacted form reads the desired grid location from the input vectors n xg[nptsx] and yg[nptsy]
PLINT nx
Definition plplot.h:521
PLFLT_NC_MATRIX xg
Definition plplot.h:520
PLINT ny
Definition plplot.h:521
PLFLT_NC_MATRIX yg
Definition plplot.h:520
PLFLT_NC_FE_POINTER xg
Definition plplot.h:508
PLFLT_NC_FE_POINTER yg
Definition plplot.h:508
PLINT nx
Definition plplot.h:509
PLINT ny
Definition plplot.h:509
PLFLT_NC_MATRIX f
Definition plplot.h:491
PLFLT_FE_POINTER f
Definition plplot.h:480
PLINT nx
Definition plplot.h:481
PLINT ny
Definition plplot.h:481
PLFLT level
Definition plplotP.h:787
struct cont_level * next
Definition plplotP.h:789
struct cont_line * line
Definition plplotP.h:788
PLINT npts
Definition plplotP.h:780
PLFLT * x
Definition plplotP.h:778
PLFLT * y
Definition plplotP.h:779
struct cont_line * next
Definition plplotP.h:781
Definition plsdef.c:28