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
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 );
167 }
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 {
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
#define snprintf
Definition: plplotP.h:235
#define LINE_ITEMS
Definition: plplotP.h:774
#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 accounting for coordinate transforms n n n y1 to(\n\ x2,\n\ y2) . If a global coordinate transform is defined then the line is\n\ broken in to n segments to approximate the path. If no transform is\n\ defined then this simply acts like a call to pljoin.\n\ \n\ Redacted form reads the desired grid location from the input vectors n xg[nptsx] and yg[nptsy]
static struct line line[]
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