home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-10-26 | 48.3 KB | 1,781 lines |
- Newsgroups: comp.sources.misc
- From: gershon%gr@cs.utah.edu (Elber Gershon)
- Subject: v24i026: gnuplot3 - interactive function plotting utility, Part04/26
- Message-ID: <1991Oct26.222204.6282@sparky.imd.sterling.com>
- X-Md4-Signature: c3149ff098bc8e28f256ddab05c10cd8
- Date: Sat, 26 Oct 1991 22:22:04 GMT
- Approved: kent@sparky.imd.sterling.com
-
- Submitted-by: gershon%gr@cs.utah.edu (Elber Gershon)
- Posting-number: Volume 24, Issue 26
- Archive-name: gnuplot3/part04
- Environment: UNIX, MS-DOS, VMS
- Supersedes: gnuplot2: Volume 11, Issue 65-79
-
- #!/bin/sh
- # this is Part.04 (part 4 of a multipart archive)
- # do not concatenate these parts, unpack them in order with /bin/sh
- # file gnuplot/bitmap.c continued
- #
- if test ! -r _shar_seq_.tmp; then
- echo 'Please unpack part 1 first!'
- exit 1
- fi
- (read Scheck
- if test "$Scheck" != 4; then
- echo Please unpack part "$Scheck" next!
- exit 1
- else
- exit 0
- fi
- ) < _shar_seq_.tmp || exit 1
- if test ! -f _shar_wnt_.tmp; then
- echo 'x - still skipping gnuplot/bitmap.c'
- else
- echo 'x - continuing file gnuplot/bitmap.c'
- sed 's/^X//' << 'SHAR_EOF' >> 'gnuplot/bitmap.c' &&
- */
- void
- b_makebitmap(x, y, planes)
- unsigned int x, y, planes;
- {
- X register unsigned j;
- X unsigned rows;
- X
- X x = 8 * (unsigned int)(x/8.0+0.9); /* round up to multiple of 8 */
- X y = 8 * (unsigned int)(y/8.0+0.9); /* round up to multiple of 8 */
- X b_psize = y/8; /* size of each plane */
- X rows = b_psize * planes; /* total number of rows of 8 pixels high */
- X b_xsize = x; b_ysize = y;
- X b_currx = b_curry = 0;
- X b_planes = planes;
- X b_value = 1;
- X b_angle = 0;
- X b_rastermode = 0;
- X /* allocate row pointers */
- X b_p = (bitmap *)alloc( rows * sizeof(pixels *), "bitmap row buffer");
- X bzero(b_p, rows * sizeof(pixels *));
- X for (j = 0; j < rows; j++) {
- X /* allocate bitmap buffers */
- X (*b_p)[j] = (pixels *)alloc(x * sizeof(pixels),(char *)NULL);
- X if ((*b_p)[j] == (pixels *)NULL) {
- X b_freebitmap(); /* free what we have already allocated */
- X int_error("out of memory for bitmap buffer", NO_CARET);
- X }
- X bzero((*b_p)[j], x * sizeof(pixels));
- X }
- }
- X
- /*
- ** free the allocated bitmap
- */
- void
- b_freebitmap()
- {
- X int j;
- X unsigned rows;
- X
- X rows = b_psize * b_planes; /* total number of rows of 8 pixels high */
- X for (j = 0; j < rows; j++)
- X {
- X (void) free((char *)(*b_p)[j]);
- X }
- X (void) free((char *)b_p);
- X b_p = (bitmap *)(NULL);
- }
- X
- /*
- ** set pixel at (x,y) with color b_value and dotted mask b_linemask.
- */
- void
- b_setmaskpixel(x,y,value)
- unsigned int x,y,value;
- {
- X /* dotted line generator */
- X if ((b_linemask>>b_maskcount)&(unsigned int)(1)) {
- X b_setpixel(x,y,value);
- X }
- X b_maskcount= (b_maskcount+1) % 16;
- X b_lastx= x; /* last pixel set with mask */
- X b_lasty= y;
- }
- X
- /*
- ** draw a line from (x1,y1) to (x2,y2)
- ** with color b_value and dotted mask b_linemask.
- */
- void
- b_line(x1,y1,x2,y2)
- unsigned int x1,y1,x2,y2;
- {
- int runcount;
- int dx,dy;
- int xinc,yinc;
- unsigned int xplot,yplot;
- X
- X runcount=0;
- X dx = abs((int)(x1)-(int)(x2));
- X if (x2>x1) xinc= 1;
- X if (x2==x1) xinc= 0;
- X if (x2<x1) xinc= -1;
- X dy = abs((int)(y1)-(int)(y2));
- X if (y2>y1) yinc= 1;
- X if (y2==y1) yinc= 0;
- X if (y2<y1) yinc= -1;
- X xplot=x1;
- X yplot=y1;
- X if (dx>dy) {
- X /* iterate x */
- X if ( (b_linemask==0xffff) ||
- X ((xplot!=b_lastx) && (yplot!=b_lasty)) )
- X b_setmaskpixel(xplot,yplot,b_value);
- X while (xplot!=x2) {
- X xplot+=xinc;
- X runcount+=dy;
- X if (runcount>=(dx-runcount)) {
- X yplot+=yinc;
- X runcount-=dx;
- X }
- X b_setmaskpixel(xplot,yplot,b_value);
- X }
- X } else {
- X /* iterate y */
- X if ( (b_linemask==0xffff) ||
- X ((xplot!=b_lastx) && (yplot!=b_lasty)) )
- X b_setmaskpixel(xplot,yplot,b_value);
- X while (yplot!=y2) {
- X yplot+=yinc;
- X runcount+=dx;
- X if (runcount>=(dy-runcount)) {
- X xplot+=xinc;
- X runcount-=dy;
- X }
- X b_setmaskpixel(xplot,yplot,b_value);
- X }
- X }
- }
- X
- /*
- ** set character size
- */
- void
- b_charsize(size)
- unsigned int size;
- {
- X int j;
- X switch(size) {
- X case FNT5X9:
- X b_hchar = FNT5X9_HCHAR;
- X b_hbits = FNT5X9_HBITS;
- X b_vchar = FNT5X9_VCHAR;
- X b_vbits = FNT5X9_VBITS;
- X for (j = 0; j < FNT_CHARS; j++ )
- X b_font[j] = &fnt5x9[j][0];
- X break;
- X case FNT9X17:
- X b_hchar = FNT9X17_HCHAR;
- X b_hbits = FNT9X17_HBITS;
- X b_vchar = FNT9X17_VCHAR;
- X b_vbits = FNT9X17_VBITS;
- X for (j = 0; j < FNT_CHARS; j++ )
- X b_font[j] = &fnt9x17[j][0];
- X break;
- X case FNT13X25:
- X b_hchar = FNT13X25_HCHAR;
- X b_hbits = FNT13X25_HBITS;
- X b_vchar = FNT13X25_VCHAR;
- X b_vbits = FNT13X25_VBITS;
- X for (j = 0; j < FNT_CHARS; j++ )
- X b_font[j] = &fnt13x25[j][0];
- X break;
- X default:
- X int_error("Unknown character size",NO_CARET);
- X }
- }
- X
- X
- /*
- ** put characater c at (x,y) rotated by angle with color b_value.
- */
- void
- b_putc(x,y,c,angle)
- unsigned int x,y;
- char c;
- unsigned int angle;
- {
- X unsigned int i, j, k;
- X char_row fc;
- X
- X j = c - ' ';
- X for ( i = 0; i < b_vbits; i++ ) {
- X fc = *( b_font[j] + i );
- X if ( c == '_' ) { /* treat underline specially */
- X if ( fc ) { /* this this the underline row ? *?
- X /* draw the under line for the full h_char width */
- X for ( k = ( b_hbits - b_hchar )/2;
- X k < ( b_hbits + b_hchar )/2; k++ ) {
- X switch(angle) {
- X case 0 : b_setpixel(x+k+1,y+i,b_value);
- X break;
- X case 1 : b_setpixel(x-i,y+k+1,b_value);
- X break;
- X }
- X }
- X }
- X }
- X else {
- X /* draw character */
- X for ( k = 0; k < b_hbits; k++ ) {
- X if ( ( fc >> k ) & 1 ) {
- X switch(angle) {
- X case 0 : b_setpixel(x+k+1,y+i,b_value);
- X break;
- X case 1 : b_setpixel(x-i,y+k+1,b_value);
- X break;
- X }
- X }
- X }
- X }
- X }
- }
- X
- X
- /*
- ** set b_linemask to b_pattern[linetype]
- */
- int
- b_setlinetype(linetype)
- int linetype;
- {
- X if (linetype>=7)
- X linetype %= 7;
- X b_linemask = b_pattern[linetype+2];
- X b_maskcount=0;
- }
- X
- /*
- ** set b_value to value
- */
- void
- b_setvalue(value)
- unsigned int value;
- {
- X b_value = value;
- }
- X
- /*
- ** move to (x,y)
- */
- int
- b_move(x, y)
- unsigned int x, y;
- {
- X b_currx = x;
- X b_curry = y;
- }
- X
- /*
- ** draw to (x,y) with color b_value
- */
- int
- b_vector(x, y)
- unsigned int x, y;
- {
- X b_line(b_currx, b_curry, x, y);
- X b_currx = x;
- X b_curry = y;
- }
- X
- X
- /*
- ** put text str at (x,y) with color b_value and rotation b_angle
- */
- int
- b_put_text(x,y,str)
- unsigned int x, y;
- char *str;
- {
- X if (b_angle == 1)
- X x += b_vchar/2;
- X else
- X y -= b_vchar/2;
- X switch (b_angle) {
- X case 0:
- X for (; *str; ++str, x += b_hchar)
- X b_putc (x, y, *str, b_angle);
- X break;
- X case 1:
- X for (; *str; ++str, y += b_hchar)
- X b_putc (x, y, *str, b_angle);
- X break;
- X }
- }
- X
- X
- int
- b_text_angle(ang)
- int ang;
- {
- X b_angle=(unsigned int)ang;
- X return TRUE;
- }
- SHAR_EOF
- echo 'File gnuplot/bitmap.c is complete' &&
- chmod 0666 gnuplot/bitmap.c ||
- echo 'restore of gnuplot/bitmap.c failed'
- Wc_c="`wc -c < 'gnuplot/bitmap.c'`"
- test 51656 -eq "$Wc_c" ||
- echo 'gnuplot/bitmap.c: original size 51656, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= gnuplot/bitmap.h ==============
- if test -f 'gnuplot/bitmap.h' -a X"$1" != X"-c"; then
- echo 'x - skipping gnuplot/bitmap.h (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting gnuplot/bitmap.h (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'gnuplot/bitmap.h' &&
- /* bitmap.h */
- X
- /* allow up to 16 bit width for character array */
- typedef unsigned int char_row;
- typedef char_row * char_box;
- X
- #define FNT_CHARS 96 /* Number of characters in the font set */
- X
- #define FNT5X9 0
- #define FNT5X9_VCHAR 11 /* vertical spacing between characters */
- #define FNT5X9_VBITS 9 /* actual number of rows of bits per char */
- #define FNT5X9_HCHAR 7 /* horizontal spacing between characters */
- #define FNT5X9_HBITS 5 /* actual number of bits per row per char */
- extern char_row fnt5x9[FNT_CHARS][FNT5X9_VBITS];
- X
- #define FNT9X17 1
- #define FNT9X17_VCHAR 21 /* vertical spacing between characters */
- #define FNT9X17_VBITS 17 /* actual number of rows of bits per char */
- #define FNT9X17_HCHAR 13 /* horizontal spacing between characters */
- #define FNT9X17_HBITS 9 /* actual number of bits per row per char */
- extern char_row fnt9x17[FNT_CHARS][FNT9X17_VBITS];
- X
- #define FNT13X25 2
- #define FNT13X25_VCHAR 31 /* vertical spacing between characters */
- #define FNT13X25_VBITS 25 /* actual number of rows of bits per char */
- #define FNT13X25_HCHAR 19 /* horizontal spacing between characters */
- #define FNT13X25_HBITS 13 /* actual number of bits per row per char */
- extern char_row fnt13x25[FNT_CHARS][FNT13X25_VBITS];
- X
- X
- typedef unsigned char pixels; /* the type of one set of 8 pixels in bitmap */
- typedef pixels *bitmap[]; /* the bitmap */
- X
- extern bitmap *b_p; /* global pointer to bitmap */
- extern unsigned int b_currx, b_curry; /* the current coordinates */
- extern unsigned int b_xsize, b_ysize; /* the size of the bitmap */
- extern unsigned int b_planes; /* number of color planes */
- extern unsigned int b_psize; /* size of each plane */
- extern unsigned int b_rastermode; /* raster mode rotates -90deg */
- extern unsigned int b_linemask; /* 16 bit mask for dotted lines */
- extern unsigned int b_value; /* colour of lines */
- extern unsigned int b_hchar; /* width of characters */
- extern unsigned int b_hbits; /* actual bits in char horizontally */
- extern unsigned int b_vchar; /* height of characters */
- extern unsigned int b_vbits; /* actual bits in char vertically */
- extern unsigned int b_angle; /* rotation of text */
- extern char_box b_font[FNT_CHARS]; /* the current font */
- extern unsigned int b_pattern[];
- extern int b_maskcount;
- extern unsigned int b_lastx, b_lasty; /* last pixel set - used by b_line */
- X
- X
- extern void b_makebitmap();
- extern void b_freebitmap();
- extern void b_setpixel();
- extern unsigned int b_getpixel();
- extern void b_line();
- extern void b_setmaskpixel();
- extern void b_putc();
- extern void b_charsize();
- extern void b_setvalue();
- X
- extern int b_setlinetype();
- extern int b_move();
- extern int b_vector();
- extern int b_put_text();
- extern int b_text_angle();
- X
- SHAR_EOF
- chmod 0666 gnuplot/bitmap.h ||
- echo 'restore of gnuplot/bitmap.h failed'
- Wc_c="`wc -c < 'gnuplot/bitmap.h'`"
- test 2726 -eq "$Wc_c" ||
- echo 'gnuplot/bitmap.h: original size 2726, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= gnuplot/buildvms.com ==============
- if test -f 'gnuplot/buildvms.com' -a X"$1" != X"-c"; then
- echo 'x - skipping gnuplot/buildvms.com (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting gnuplot/buildvms.com (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'gnuplot/buildvms.com' &&
- $ ! buildvms.com (Command file to compile/link gnuplot and doc2hlp)
- $ CFLAGS = "/NOOP/define=(NOGAMMA,MEMSET)"
- $ !TERMFLAGS = "/define=()"
- $ TERMFLAGS = ""
- $ set verify
- $ cc 'CFLAGS' bitmap.c
- $ cc 'CFLAGS' command.c
- $ cc 'CFLAGS' contour.c
- $ cc 'CFLAGS' eval.c
- $ cc 'CFLAGS' graphics.c
- $ cc 'CFLAGS' graph3d.c
- $ cc 'CFLAGS' internal.c
- $ cc 'CFLAGS' misc.c
- $ cc 'CFLAGS' parse.c
- $ cc 'CFLAGS' plot.c
- $ cc 'CFLAGS' scanner.c
- $ cc 'CFLAGS' setshow.c
- $ cc 'CFLAGS' standard.c
- $ cc 'CFLAGS' 'TERMFLAGS' term.c
- $ cc 'CFLAGS' util.c
- $ cc 'CFLAGS' version.c
- $ link /exe=gnuplot -
- X bitmap.obj,command.obj,contour.obj,eval.obj,graphics.obj,graph3d.obj, -
- X internal.obj,misc.obj,parse.obj,plot.obj,scanner.obj,setshow.obj, -
- X standard.obj,term.obj,util.obj,version.obj ,linkopt.vms/opt
- $ cc [.docs]doc2hlp.c
- $ link doc2hlp,linkopt.vms/opt
- $ @[.docs]doc2hlp.com
- $ library/create/help gnuplot.hlb gnuplot.hlp
- $ set noverify
- SHAR_EOF
- chmod 0644 gnuplot/buildvms.com ||
- echo 'restore of gnuplot/buildvms.com failed'
- Wc_c="`wc -c < 'gnuplot/buildvms.com'`"
- test 918 -eq "$Wc_c" ||
- echo 'gnuplot/buildvms.com: original size 918, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= gnuplot/misc.c ==============
- if test -f 'gnuplot/misc.c' -a X"$1" != X"-c"; then
- echo 'x - skipping gnuplot/misc.c (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting gnuplot/misc.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'gnuplot/misc.c' &&
- /* GNUPLOT - misc.c */
- /*
- X * Copyright (C) 1986, 1987, 1990, 1991 Thomas Williams, Colin Kelley
- X *
- X * Permission to use, copy, and distribute this software and its
- X * documentation for any purpose with or without fee is hereby granted,
- X * provided that the above copyright notice appear in all copies and
- X * that both that copyright notice and this permission notice appear
- X * in supporting documentation.
- X *
- X * Permission to modify the software is granted, but not the right to
- X * distribute the modified code. Modifications are to be distributed
- X * as patches to released version.
- X *
- X * This software is provided "as is" without express or implied warranty.
- X *
- X *
- X * AUTHORS
- X *
- X * Original Software:
- X * Thomas Williams, Colin Kelley.
- X *
- X * Gnuplot 2.0 additions:
- X * Russell Lang, Dave Kotz, John Campbell.
- X *
- X * Gnuplot 3.0 additions:
- X * Gershon Elber and many others.
- X *
- X * Send your comments or suggestions to
- X * pixar!info-gnuplot@sun.com.
- X * This is a mailing list; to join it send a note to
- X * pixar!info-gnuplot-request@sun.com.
- X * Send bug reports to
- X * pixar!bug-gnuplot@sun.com.
- X */
- X
- #include <stdio.h>
- #include <math.h>
- #include "plot.h"
- #include "setshow.h"
- #include "help.h"
- #ifdef __TURBOC__
- #include <graphics.h>
- #endif
- X
- #ifndef _IBMR2
- extern char *malloc();
- extern char *realloc();
- #endif
- X
- extern int c_token;
- extern char replot_line[];
- extern struct at_type at;
- extern struct ft_entry ft[];
- extern struct udft_entry *first_udf;
- extern struct udvt_entry *first_udv;
- X
- extern struct at_type *temp_at();
- X
- extern BOOLEAN interactive;
- extern char *infile_name;
- extern int inline_num;
- X
- /* State information for load_file(), to recover from errors
- X * and properly handle recursive load_file calls
- X */
- typedef struct lf_state_struct LFS;
- struct lf_state_struct {
- X FILE *fp; /* file pointer for load file */
- X char *name; /* name of file */
- X BOOLEAN interactive; /* value of interactive flag on entry */
- X int inline_num; /* inline_num on entry */
- X LFS *prev; /* defines a stack */
- } *lf_head = NULL; /* NULL if not in load_file */
- X
- static BOOLEAN lf_pop();
- static void lf_push();
- X
- /*
- X * instead of <strings.h>
- X */
- extern int strcmp();
- X
- /*
- X * Turbo C realloc does not do the right thing. Here is what it should do.
- X */
- #ifdef __TURBOC__
- char *realloc(p, new_size)
- X void *p;
- X size_t new_size;
- {
- X void *new_p = alloc(new_size, "TC realloc");
- X
- X /* Note p may have less than new_size bytes but in this unprotected
- X * environment this will work.
- X */
- X memcpy(new_p, p, new_size);
- X free(p);
- X return new_p;
- }
- #endif /* __TURBOC__ */
- X
- /*
- X * cp_alloc() allocates a curve_points structure that can hold 'num'
- X * points.
- X */
- struct curve_points *
- cp_alloc(num)
- X int num;
- {
- X struct curve_points *cp;
- X cp = (struct curve_points *) alloc(sizeof(struct curve_points), "curve");
- X cp->p_max = (num >= 0 ? num : 0);
- X if (num > 0) {
- X cp->points = (struct coordinate *)
- X alloc(num * sizeof(struct coordinate), "curve points");
- X } else
- X cp->points = (struct coordinate *) NULL;
- X cp->next_cp = NULL;
- X cp->title = NULL;
- X return(cp);
- }
- X
- X
- /*
- X * cp_extend() reallocates a curve_points structure to hold "num"
- X * points. This will either expand or shrink the storage.
- X */
- cp_extend(cp, num)
- X struct curve_points *cp;
- X int num;
- {
- X struct coordinate *new;
- X
- #ifdef PC
- X /* Make sure we do not allocate more than 64k (8088 architecture...)
- X * in msdos since we can not address more. Leave some bytes for malloc
- X * maintainance.
- X */
- X if (num > 65500L / sizeof(struct coordinate))
- X int_error("Can not allocate more than 64k in msdos", NO_CARET);
- #endif /* PC */
- X
- X if (num == cp->p_max) return;
- X
- X if (num > 0) {
- X if (cp->points == NULL) {
- X cp->points = (struct coordinate *)
- X alloc(num * sizeof(struct coordinate), "curve points");
- X } else {
- X new = (struct coordinate *)
- X realloc(cp->points, num * sizeof(struct coordinate));
- X if (new == (struct coordinate *) NULL) {
- X int_error("No memory available for expanding curve points",
- X NO_CARET);
- X /* NOTREACHED */
- X }
- X cp->points = new;
- X }
- X cp->p_max = num;
- X } else {
- X if (cp->points != (struct coordinate *) NULL)
- X free(cp->points);
- X cp->points = (struct coordinate *) NULL;
- X cp->p_max = 0;
- X }
- }
- X
- /*
- X * cp_free() releases any memory which was previously malloc()'d to hold
- X * curve points (and recursively down the linked list).
- X */
- cp_free(cp)
- struct curve_points *cp;
- {
- X if (cp) {
- X cp_free(cp->next_cp);
- X if (cp->title)
- X free((char *)cp->title);
- X if (cp->points)
- X free((char *)cp->points);
- X free((char *)cp);
- X }
- }
- X
- /*
- X * iso_alloc() allocates a iso_curve structure that can hold 'num'
- X * points.
- X */
- struct iso_curve *
- iso_alloc(num)
- X int num;
- {
- X struct iso_curve *ip;
- X ip = (struct iso_curve *) alloc(sizeof(struct iso_curve), "iso curve");
- X ip->p_max = (num >= 0 ? num : 0);
- X if (num > 0) {
- X ip->points = (struct coordinate *)
- X alloc(num * sizeof(struct coordinate), "iso curve points");
- X } else
- X ip->points = (struct coordinate *) NULL;
- X ip->next = NULL;
- X return(ip);
- }
- X
- /*
- X * iso_extend() reallocates a iso_curve structure to hold "num"
- X * points. This will either expand or shrink the storage.
- X */
- iso_extend(ip, num)
- X struct iso_curve *ip;
- X int num;
- {
- X struct coordinate *new;
- X
- X if (num == ip->p_max) return;
- X
- #ifdef PC
- X /* Make sure we do not allocate more than 64k (8088 architecture...)
- X * in msdos since we can not address more. Leave some bytes for malloc
- X * maintainance.
- X */
- X if (num > 65500L / sizeof(struct coordinate))
- X int_error("Can not allocate more than 64k in msdos", NO_CARET);
- #endif /* PC */
- X
- X if (num > 0) {
- X if (ip->points == NULL) {
- X ip->points = (struct coordinate *)
- X alloc(num * sizeof(struct coordinate), "iso curve points");
- X } else {
- X new = (struct coordinate *)
- X realloc(ip->points, num * sizeof(struct coordinate));
- X if (new == (struct coordinate *) NULL) {
- X int_error("No memory available for expanding curve points",
- X NO_CARET);
- X /* NOTREACHED */
- X }
- X ip->points = new;
- X }
- X ip->p_max = num;
- X } else {
- X if (ip->points != (struct coordinate *) NULL)
- X free(ip->points);
- X ip->points = (struct coordinate *) NULL;
- X ip->p_max = 0;
- X }
- }
- X
- /*
- X * iso_free() releases any memory which was previously malloc()'d to hold
- X * iso curve points.
- X */
- iso_free(ip)
- struct iso_curve *ip;
- {
- X if (ip) {
- X if (ip->points)
- X free((char *)ip->points);
- X free((char *)ip);
- X }
- }
- X
- /*
- X * sp_alloc() allocates a surface_points structure that can hold 'num_iso'
- X * iso-curves, each of which 'num_samp' samples.
- X * if, however num_iso or num_samp is zero no iso curves are allocated.
- X */
- struct surface_points *
- sp_alloc(num_samp,num_iso)
- X int num_samp,num_iso;
- {
- X struct surface_points *sp;
- X
- X sp = (struct surface_points *) alloc(sizeof(struct surface_points), "surface");
- X sp->next_sp = NULL;
- X sp->title = NULL;
- X sp->contours = NULL;
- X sp->iso_crvs = NULL;
- X sp->num_iso_read = 0;
- X
- X if (num_iso > 0 && num_samp > 0) {
- X int i;
- X struct iso_curve *icrv;
- X
- X for (i = 0; i < num_iso; i++) {
- X icrv = iso_alloc(num_samp);
- X icrv->next = sp->iso_crvs;
- X sp->iso_crvs = icrv;
- X }
- X } else
- X sp->iso_crvs = (struct iso_curve *) NULL;
- X
- X return(sp);
- }
- X
- /*
- X * sp_replace() updates a surface_points structure so it can hold 'num_iso'
- X * iso-curves, each of which 'num_samp' samples.
- X * if, however num_iso or num_samp is zero no iso curves are allocated.
- X */
- sp_replace(sp,num_samp,num_iso)
- X struct surface_points *sp;
- X int num_samp,num_iso;
- {
- X int i;
- X struct iso_curve *icrv, *icrvs = sp->iso_crvs;
- X
- X while ( icrvs ) {
- X icrv = icrvs;
- X icrvs = icrvs->next;
- X iso_free( icrv );
- X }
- X sp->iso_crvs = NULL;
- X
- X if (num_iso > 0 && num_samp > 0) {
- X for (i = 0; i < num_iso; i++) {
- X icrv = iso_alloc(num_samp);
- X icrv->next = sp->iso_crvs;
- X sp->iso_crvs = icrv;
- X }
- X } else
- X sp->iso_crvs = (struct iso_curve *) NULL;
- }
- X
- /*
- X * sp_free() releases any memory which was previously malloc()'d to hold
- X * surface points.
- X */
- sp_free(sp)
- struct surface_points *sp;
- {
- X if (sp) {
- X sp_free(sp->next_sp);
- X if (sp->title)
- X free((char *)sp->title);
- X if (sp->contours) {
- X struct gnuplot_contours *cntr, *cntrs = sp->contours;
- X
- X while (cntrs) {
- X cntr = cntrs;
- X cntrs = cntrs->next;
- X free(cntr->coords);
- X free(cntr);
- X }
- X }
- X if (sp->iso_crvs) {
- X struct iso_curve *icrv, *icrvs = sp->iso_crvs;
- X
- X while (icrvs) {
- X icrv = icrvs;
- X icrvs = icrvs->next;
- X iso_free(icrv);
- X }
- X }
- X free((char *)sp);
- X }
- }
- X
- X
- X
- save_functions(fp)
- FILE *fp;
- {
- register struct udft_entry *udf = first_udf;
- X
- X if (fp) {
- X while (udf) {
- X if (udf->definition)
- X fprintf(fp,"%s\n",udf->definition);
- X udf = udf->next_udf;
- X }
- X (void) fclose(fp);
- X } else
- X os_error("Cannot open save file",c_token);
- }
- X
- X
- save_variables(fp)
- FILE *fp;
- {
- register struct udvt_entry *udv = first_udv->next_udv; /* skip pi */
- X
- X if (fp) {
- X while (udv) {
- X if (!udv->udv_undef) {
- X fprintf(fp,"%s = ",udv->udv_name);
- X disp_value(fp,&(udv->udv_value));
- X (void) putc('\n',fp);
- X }
- X udv = udv->next_udv;
- X }
- X (void) fclose(fp);
- X } else
- X os_error("Cannot open save file",c_token);
- }
- X
- X
- save_all(fp)
- FILE *fp;
- {
- register struct udft_entry *udf = first_udf;
- register struct udvt_entry *udv = first_udv->next_udv; /* skip pi */
- X
- X if (fp) {
- X save_set_all(fp);
- X while (udf) {
- X if (udf->definition)
- X fprintf(fp,"%s\n",udf->definition);
- X udf = udf->next_udf;
- X }
- X while (udv) {
- X if (!udv->udv_undef) {
- X fprintf(fp,"%s = ",udv->udv_name);
- X disp_value(fp,&(udv->udv_value));
- X (void) putc('\n',fp);
- X }
- X udv = udv->next_udv;
- X }
- X fprintf(fp,"%s\n",replot_line);
- X (void) fclose(fp);
- X } else
- X os_error("Cannot open save file",c_token);
- }
- X
- X
- save_set(fp)
- FILE *fp;
- {
- X if (fp) {
- X save_set_all(fp);
- X (void) fclose(fp);
- X } else
- X os_error("Cannot open save file",c_token);
- }
- X
- X
- save_set_all(fp)
- FILE *fp;
- {
- struct text_label *this_label;
- struct arrow_def *this_arrow;
- X fprintf(fp,"set terminal %s %s\n", term_tbl[term].name, term_options);
- X fprintf(fp,"set output %s\n",strcmp(outstr,"STDOUT")? outstr : "" );
- X fprintf(fp,"set %sclip points\n", (clip_points)? "" : "no");
- X fprintf(fp,"set %sclip one\n", (clip_lines1)? "" : "no");
- X fprintf(fp,"set %sclip two\n", (clip_lines2)? "" : "no");
- X fprintf(fp,"set %sborder\n",draw_border ? "" : "no");
- X fprintf(fp,"set dummy %s,%s\n",dummy_var[0], dummy_var[1]);
- X fprintf(fp,"set format x \"%s\"\n", xformat);
- X fprintf(fp,"set format y \"%s\"\n", yformat);
- X fprintf(fp,"set format z \"%s\"\n", zformat);
- X fprintf(fp,"set %sgrid\n", (grid)? "" : "no");
- X switch (key) {
- X case -1 :
- X fprintf(fp,"set key\n");
- X break;
- X case 0 :
- X fprintf(fp,"set nokey\n");
- X break;
- X case 1 :
- X fprintf(fp,"set key %g,%g,%g\n",key_x,key_y,key_z);
- X break;
- X }
- X fprintf(fp,"set nolabel\n");
- X for (this_label = first_label; this_label != NULL;
- X this_label = this_label->next) {
- X fprintf(fp,"set label %d \"%s\" at %g,%g,%g ",
- X this_label->tag,
- X this_label->text, this_label->x,
- X this_label->y,
- X this_label->z);
- X switch(this_label->pos) {
- X case LEFT :
- X fprintf(fp,"left");
- X break;
- X case CENTRE :
- X fprintf(fp,"centre");
- X break;
- X case RIGHT :
- X fprintf(fp,"right");
- X break;
- X }
- X fputc('\n',fp);
- X }
- X fprintf(fp,"set noarrow\n");
- X for (this_arrow = first_arrow; this_arrow != NULL;
- X this_arrow = this_arrow->next) {
- X fprintf(fp,"set arrow %d from %g,%g,%g to %g,%g,%g%s\n",
- X this_arrow->tag,
- X this_arrow->sx, this_arrow->sy, this_arrow->sz,
- X this_arrow->ex, this_arrow->ey, this_arrow->ez,
- X this_arrow->head ? "" : " nohead");
- X }
- X fprintf(fp,"set nologscale\n");
- X if (log_x||log_y)
- X fprintf(fp,"set logscale %c%c\n",
- X log_x ? 'x' : ' ', log_y ? 'y' : ' ');
- X if (log_z) fprintf(fp,"set logscale z\n");
- X fprintf(fp,"set offsets %g, %g, %g, %g\n",loff,roff,toff,boff);
- X fprintf(fp,"set %spolar\n", (polar)? "" : "no");
- X fprintf(fp,"set angles %s\n", (angles_format == ANGLES_RADIANS)?
- X "radians" : "degrees");
- X fprintf(fp,"set %sparametric\n", (parametric)? "" : "no");
- X fprintf(fp,"set view %g, %g, %g, %g\n",
- X surface_rot_x, surface_rot_z, surface_scale, surface_zscale);
- X fprintf(fp,"set samples %d\n",samples);
- X fprintf(fp,"set isosamples %d\n",iso_samples);
- X fprintf(fp,"set %ssurface\n",(draw_surface) ? "" : "no");
- X fprintf(fp,"set %scontour",(draw_contour) ? "" : "no");
- X switch (draw_contour) {
- X case CONTOUR_NONE: fprintf(fp, "\n"); break;
- X case CONTOUR_BASE: fprintf(fp, " base\n"); break;
- X case CONTOUR_SRF: fprintf(fp, " surface\n"); break;
- X case CONTOUR_BOTH: fprintf(fp, " both\n"); break;
- X }
- X fprintf(fp,"set cntrparam order %d\n", contour_order);
- X fprintf(fp,"set cntrparam ");
- X switch (contour_kind) {
- X case CONTOUR_KIND_LINEAR: fprintf(fp, "linear\n"); break;
- X case CONTOUR_KIND_CUBIC_SPL: fprintf(fp, "cubicspline\n"); break;
- X case CONTOUR_KIND_BSPLINE: fprintf(fp, "bspline\n"); break;
- X }
- X fprintf(fp,"set cntrparam points %d\n", contour_pts);
- X fprintf(fp,"set size %g,%g\n",xsize,ysize);
- X fprintf(fp,"set data style ");
- X switch (data_style) {
- X case LINES: fprintf(fp,"lines\n"); break;
- X case POINTS: fprintf(fp,"points\n"); break;
- X case IMPULSES: fprintf(fp,"impulses\n"); break;
- X case LINESPOINTS: fprintf(fp,"linespoints\n"); break;
- X case DOTS: fprintf(fp,"dots\n"); break;
- X case ERRORBARS: fprintf(fp,"errorbars\n"); break;
- X }
- X fprintf(fp,"set function style ");
- X switch (func_style) {
- X case LINES: fprintf(fp,"lines\n"); break;
- X case POINTS: fprintf(fp,"points\n"); break;
- X case IMPULSES: fprintf(fp,"impulses\n"); break;
- X case LINESPOINTS: fprintf(fp,"linespoints\n"); break;
- X case DOTS: fprintf(fp,"dots\n"); break;
- X case ERRORBARS: fprintf(fp,"errorbars\n"); break;
- X }
- X fprintf(fp,"set tics %s\n", (tic_in)? "in" : "out");
- X fprintf(fp,"set ticslevel %g\n", ticslevel);
- X save_tics(fp, xtics, 'x', &xticdef);
- X save_tics(fp, ytics, 'y', &yticdef);
- X save_tics(fp, ztics, 'z', &zticdef);
- X fprintf(fp,"set title \"%s\" %d,%d\n",title,title_xoffset,title_yoffset);
- X if (timedate)
- X fprintf(fp,"set time %d,%d\n",time_xoffset,time_yoffset);
- X else
- X fprintf(fp,"set notime\n");
- X fprintf(fp,"set rrange [%g : %g]\n",rmin,rmax);
- X fprintf(fp,"set trange [%g : %g]\n",tmin,tmax);
- X fprintf(fp,"set xlabel \"%s\" %d,%d\n",xlabel,xlabel_xoffset,xlabel_yoffset);
- X fprintf(fp,"set xrange [%g : %g]\n",xmin,xmax);
- X fprintf(fp,"set ylabel \"%s\" %d,%d\n",ylabel,ylabel_xoffset,ylabel_yoffset);
- X fprintf(fp,"set yrange [%g : %g]\n",ymin,ymax);
- X fprintf(fp,"set zlabel \"%s\" %d,%d\n",zlabel,zlabel_xoffset,zlabel_yoffset);
- X fprintf(fp,"set zrange [%g : %g]\n",zmin,zmax);
- X fprintf(fp,"set %s %c\n",
- X autoscale_r ? "autoscale" : "noautoscale", 'r');
- X fprintf(fp,"set %s %c\n",
- X autoscale_t ? "autoscale" : "noautoscale", 't');
- X fprintf(fp,"set %s %c%c\n",
- X (autoscale_y||autoscale_x) ? "autoscale" : "noautoscale",
- X autoscale_x ? 'x' : ' ', autoscale_y ? 'y' : ' ');
- X fprintf(fp,"set %s %c\n",
- X autoscale_z ? "autoscale" : "noautoscale", 'z');
- X fprintf(fp,"set zero %g\n",zero);
- }
- X
- save_tics(fp, onoff, axis, tdef)
- X FILE *fp;
- X BOOLEAN onoff;
- X char axis;
- X struct ticdef *tdef;
- {
- X if (onoff) {
- X fprintf(fp,"set %ctics", axis);
- X switch(tdef->type) {
- X case TIC_COMPUTED: {
- X break;
- X }
- X case TIC_SERIES: {
- X if (tdef->def.series.end >= VERYLARGE)
- X fprintf(fp, " %g,%g", tdef->def.series.start,
- X tdef->def.series.incr);
- X else
- X fprintf(fp, " %g,%g,%g", tdef->def.series.start,
- X tdef->def.series.incr, tdef->def.series.end);
- X break;
- X }
- X case TIC_USER: {
- X register struct ticmark *t;
- X fprintf(fp, " (");
- X for (t = tdef->def.user; t != NULL; t=t->next) {
- X if (t->label)
- X fprintf(fp, "\"%s\" ", t->label);
- X if (t->next)
- X fprintf(fp, "%g, ", t->position);
- X else
- X fprintf(fp, "%g", t->position);
- X }
- X fprintf(fp, ")");
- X break;
- X }
- X }
- X fprintf(fp, "\n");
- X } else {
- X fprintf(fp,"set no%ctics\n", axis);
- X }
- }
- X
- load_file(fp, name)
- X FILE *fp;
- X char *name;
- {
- X register int len;
- X extern char input_line[];
- X
- X int start, left;
- X int more;
- X int stop = FALSE;
- X
- X lf_push(fp); /* save state for errors and recursion */
- X
- X if (fp == (FILE *)NULL) {
- X char errbuf[BUFSIZ];
- X (void) sprintf(errbuf, "Cannot open load file '%s'", name);
- X os_error(errbuf, c_token);
- X } else {
- X /* go into non-interactive mode during load */
- X /* will be undone below, or in load_file_error */
- X interactive = FALSE;
- X inline_num = 0;
- X infile_name = name;
- X
- X while (!stop) { /* read all commands in file */
- X /* read one command */
- X left = MAX_LINE_LEN;
- X start = 0;
- X more = TRUE;
- X
- X while (more) {
- X if (fgets(&(input_line[start]), left, fp) == NULL) {
- X stop = TRUE; /* EOF in file */
- X input_line[start] = '\0';
- X more = FALSE;
- X } else {
- X inline_num++;
- X len = strlen(input_line) - 1;
- X if (input_line[len] == '\n') { /* remove any newline */
- X input_line[len] = '\0';
- X /* Look, len was 1-1 = 0 before, take care here! */
- X if (len > 0) --len;
- X } else if (len+1 >= left)
- X int_error("Input line too long",NO_CARET);
- X
- X if (input_line[len] == '\\') { /* line continuation */
- X start = len;
- X left = MAX_LINE_LEN - start; /* left -=len;*/
- X } else
- X more = FALSE;
- X }
- X }
- X
- X if (strlen(input_line) > 0) {
- X screen_ok = FALSE; /* make sure command line is
- X echoed on error */
- X do_line();
- X }
- X }
- X }
- X
- X /* pop state */
- X (void) lf_pop(); /* also closes file fp */
- }
- X
- /* pop from load_file state stack */
- static BOOLEAN /* FALSE if stack was empty */
- lf_pop() /* called by load_file and load_file_error */
- {
- X LFS *lf;
- X
- X if (lf_head == NULL)
- X return(FALSE);
- X else {
- X lf = lf_head;
- X if (lf->fp != (FILE *)NULL)
- X (void) fclose(lf->fp);
- X interactive = lf->interactive;
- X inline_num = lf->inline_num;
- X infile_name = lf->name;
- X lf_head = lf->prev;
- X free((char *)lf);
- X return(TRUE);
- X }
- }
- X
- /* push onto load_file state stack */
- /* essentially, we save information needed to undo the load_file changes */
- static void
- lf_push(fp) /* called by load_file */
- X FILE *fp;
- {
- X LFS *lf;
- X
- X lf = (LFS *)alloc(sizeof(LFS), (char *)NULL);
- X if (lf == (LFS *)NULL) {
- X if (fp != (FILE *)NULL)
- X (void) fclose(fp); /* it won't be otherwise */
- X int_error("not enough memory to load file", c_token);
- X }
- X
- X lf->fp = fp; /* save this file pointer */
- X lf->name = infile_name; /* save current name */
- X lf->interactive = interactive; /* save current state */
- X lf->inline_num = inline_num; /* save current line number */
- X lf->prev = lf_head; /* link to stack */
- X lf_head = lf;
- }
- X
- load_file_error() /* called from main */
- {
- X /* clean up from error in load_file */
- X /* pop off everything on stack */
- X while(lf_pop())
- X ;
- }
- X
- /* find char c in string str; return p such that str[p]==c;
- X * if c not in str then p=strlen(str)
- X */
- int
- instring(str, c)
- X char *str;
- X char c;
- {
- X int pos = 0;
- X
- X while (str != NULL && *str != '\0' && c != *str) {
- X str++;
- X pos++;
- X }
- X return (pos);
- }
- X
- show_functions()
- {
- register struct udft_entry *udf = first_udf;
- X
- X fprintf(stderr,"\n\tUser-Defined Functions:\n");
- X
- X while (udf) {
- X if (udf->definition)
- X fprintf(stderr,"\t%s\n",udf->definition);
- X else
- X fprintf(stderr,"\t%s is undefined\n",udf->udf_name);
- X udf = udf->next_udf;
- X }
- }
- X
- X
- show_at()
- {
- X (void) putc('\n',stderr);
- X disp_at(temp_at(),0);
- }
- X
- X
- disp_at(curr_at, level)
- struct at_type *curr_at;
- int level;
- {
- register int i, j;
- register union argument *arg;
- X
- X for (i = 0; i < curr_at->a_count; i++) {
- X (void) putc('\t',stderr);
- X for (j = 0; j < level; j++)
- X (void) putc(' ',stderr); /* indent */
- X
- X /* print name of instruction */
- X
- X fputs(ft[(int)(curr_at->actions[i].index)].f_name,stderr);
- X arg = &(curr_at->actions[i].arg);
- X
- X /* now print optional argument */
- X
- X switch(curr_at->actions[i].index) {
- X case PUSH: fprintf(stderr," %s\n", arg->udv_arg->udv_name);
- X break;
- X case PUSHC: (void) putc(' ',stderr);
- X disp_value(stderr,&(arg->v_arg));
- X (void) putc('\n',stderr);
- X break;
- X case PUSHD1: fprintf(stderr," %c dummy\n",
- X arg->udf_arg->udf_name[0]);
- X break;
- X case PUSHD2: fprintf(stderr," %c dummy\n",
- X arg->udf_arg->udf_name[1]);
- X break;
- X case CALL: fprintf(stderr," %s", arg->udf_arg->udf_name);
- X if(level < 6) {
- X if (arg->udf_arg->at) {
- X (void) putc('\n',stderr);
- X disp_at(arg->udf_arg->at,level+2); /* recurse! */
- X } else
- X fputs(" (undefined)\n",stderr);
- X }
- X break;
- X case CALL2: fprintf(stderr," %s", arg->udf_arg->udf_name);
- X if(level < 6) {
- X if (arg->udf_arg->at) {
- X (void) putc('\n',stderr);
- X disp_at(arg->udf_arg->at,level+2); /* recurse! */
- X } else
- X fputs(" (undefined)\n",stderr);
- X }
- X break;
- X case JUMP:
- X case JUMPZ:
- X case JUMPNZ:
- X case JTERN:
- X fprintf(stderr," +%d\n",arg->j_arg);
- X break;
- X default:
- X (void) putc('\n',stderr);
- X }
- X }
- }
- X
- X
- /* alloc:
- X * allocate memory
- X * This is a protected version of malloc. It causes an int_error
- X * if there is not enough memory, but first it tries FreeHelp()
- X * to make some room, and tries again. If message is NULL, we
- X * allow NULL return. Otherwise, we handle the error, using the
- X * message to create the int_error string. Note cp/sp_extend uses realloc,
- X * so it depends on this using malloc().
- X */
- X
- char *
- alloc(size, message)
- X unsigned int size; /* # of bytes */
- X char *message; /* description of what is being allocated */
- {
- X char *p; /* the new allocation */
- X char errbuf[100]; /* error message string */
- X
- X p = malloc(size);
- X if (p == (char *)NULL) {
- #ifndef vms
- X FreeHelp(); /* out of memory, try to make some room */
- #endif
- X
- X p = malloc(size); /* try again */
- X if (p == (char *)NULL) {
- X /* really out of memory */
- X if (message != NULL) {
- X (void) sprintf(errbuf, "out of memory for %s", message);
- X int_error(errbuf, NO_CARET);
- X /* NOTREACHED */
- X }
- X /* else we return NULL */
- X }
- X }
- X
- X return(p);
- }
- SHAR_EOF
- chmod 0644 gnuplot/misc.c ||
- echo 'restore of gnuplot/misc.c failed'
- Wc_c="`wc -c < 'gnuplot/misc.c'`"
- test 22387 -eq "$Wc_c" ||
- echo 'gnuplot/misc.c: original size 22387, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= gnuplot/contour.c ==============
- if test -f 'gnuplot/contour.c' -a X"$1" != X"-c"; then
- echo 'x - skipping gnuplot/contour.c (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting gnuplot/contour.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'gnuplot/contour.c' &&
- /* GNUPLOT - contour.c */
- /*
- X * Copyright (C) 1986, 1987, 1990, 1991 Thomas Williams, Colin Kelley
- X *
- X * Permission to use, copy, and distribute this software and its
- X * documentation for any purpose with or without fee is hereby granted,
- X * provided that the above copyright notice appear in all copies and
- X * that both that copyright notice and this permission notice appear
- X * in supporting documentation.
- X *
- X * Permission to modify the software is granted, but not the right to
- X * distribute the modified code. Modifications are to be distributed
- X * as patches to released version.
- X *
- X * This software is provided "as is" without express or implied warranty.
- X *
- X *
- X * AUTHORS
- X *
- X * Original Software:
- X * Gershon Elber
- X *
- X * Send your comments or suggestions to
- X * pixar!info-gnuplot@sun.com.
- X * This is a mailing list; to join it send a note to
- X * pixar!info-gnuplot-request@sun.com.
- X * Send bug reports to
- X * pixar!bug-gnuplot@sun.com.
- X */
- X
- #include <stdio.h>
- #include "plot.h"
- X
- #define DEFAULT_NUM_OF_ZLEVELS 10 /* Some dflt values (setable via flags). */
- #define DEFAULT_NUM_APPROX_PTS 5
- #define DEFAULT_BSPLINE_ORDER 3
- #define MAX_NUM_OF_ZLEVELS 100 /* Some max. values (setable via flags). */
- #define MAX_NUM_APPROX_PTS 100
- #define MAX_BSPLINE_ORDER 10
- X
- #define INTERP_NOTHING 0 /* Kind of interpolations on contours. */
- #define INTERP_CUBIC 1 /* Cubic spline interp. */
- #define APPROX_BSPLINE 2 /* Bspline interpolation. */
- X
- #define ACTIVE 1 /* Status of edges at certain Z level. */
- #define INACTIVE 2
- X
- #define OPEN_CONTOUR 1 /* Contour kinds. */
- #define CLOSED_CONTOUR 2
- X
- #define EPSILON 1e-5 /* Used to decide if two float are equal. */
- #define INFINITY 1e10
- X
- #ifndef TRUE
- #define TRUE -1
- #define FALSE 0
- #endif
- X
- #define DEFAULT_NUM_CONTOURS 10
- #define MAX_POINTS_PER_CNTR 100
- #define SHIFT_Z_EPSILON 0.000301060 /* Dec. change of poly bndry hit.*/
- X
- #define abs(x) ((x) > 0 ? (x) : (-(x)))
- #define sqr(x) ((x) * (x))
- X
- typedef double tri_diag[3]; /* Used to allocate the tri-diag matrix. */
- typedef double table_entry[4]; /* Cubic spline interpolation 4 coef. */
- X
- struct vrtx_struct {
- X double X, Y, Z; /* The coordinates of this vertex. */
- X struct vrtx_struct *next; /* To chain lists. */
- };
- X
- struct edge_struct {
- X struct poly_struct *poly[2]; /* Each edge belongs to up to 2 polygons. */
- X struct vrtx_struct *vertex[2]; /* The two extreme points of this vertex. */
- X struct edge_struct *next; /* To chain lists. */
- X int status, /* Status flag to mark edges in scanning at certain Z level. */
- X boundary; /* True if this edge is on the boundary. */
- };
- X
- struct poly_struct {
- X struct edge_struct *edge[3]; /* As we do triangolation here... */
- X struct poly_struct *next; /* To chain lists. */
- };
- X
- struct cntr_struct { /* Contours are saved using this struct list. */
- X double X, Y; /* The coordinates of this vertex. */
- X struct cntr_struct *next; /* To chain lists. */
- };
- X
- static int test_boundary; /* If TRUE look for contours on boundary first. */
- static struct gnuplot_contours *contour_list = NULL;
- static double crnt_cntr[MAX_POINTS_PER_CNTR * 2];
- static int crnt_cntr_pt_index = 0;
- static double contour_level = 0.0;
- static table_entry *hermit_table = NULL; /* Hold hermite table constants. */
- static int num_of_z_levels = DEFAULT_NUM_OF_ZLEVELS; /* # Z contour levels. */
- static int num_approx_pts = DEFAULT_NUM_APPROX_PTS;/* # pts per approx/inter.*/
- static int bspline_order = DEFAULT_BSPLINE_ORDER; /* Bspline order to use. */
- static int interp_kind = INTERP_NOTHING; /* Linear, Cubic interp., Bspline. */
- X
- static void gen_contours();
- static int update_all_edges();
- static struct cntr_struct *gen_one_contour();
- static struct cntr_struct *trace_contour();
- static struct cntr_struct *update_cntr_pt();
- static int fuzzy_equal();
- static void gen_triangle();
- static struct vrtx_struct *gen_vertices();
- static struct edge_struct *gen_edges_middle();
- static struct edge_struct *gen_edges();
- static struct poly_struct *gen_polys();
- static void free_contour();
- static void put_contour();
- static put_contour_nothing();
- static put_contour_cubic();
- static put_contour_bspline();
- static calc_tangent();
- static int count_contour();
- static complete_spline_interp();
- static calc_hermit_table();
- static hermit_interp();
- static prepare_spline_interp();
- static int solve_tri_diag();
- static gen_bspline_approx();
- static double fetch_knot();
- static eval_bspline();
- X
- /*
- X * Entry routine to this whole set of contouring module.
- X */
- struct gnuplot_contours *contour(num_isolines, iso_lines,
- X ZLevels, approx_pts, kind, order1)
- int num_isolines;
- struct iso_curve *iso_lines;
- int ZLevels, approx_pts, kind, order1;
- {
- X int i;
- X struct poly_struct *p_polys, *p_poly;
- X struct edge_struct *p_edges, *p_edge;
- X struct vrtx_struct *p_vrts, *p_vrtx;
- X double x_min, y_min, z_min, x_max, y_max, z_max, z, dz, z_scale = 1.0;
- X
- X num_of_z_levels = ZLevels;
- X num_approx_pts = approx_pts;
- X bspline_order = order1 - 1;
- X interp_kind = kind;
- X
- X contour_list = NULL;
- X
- X if (interp_kind == INTERP_CUBIC) calc_hermit_table();
- X
- X gen_triangle(num_isolines, iso_lines, &p_polys, &p_edges, &p_vrts,
- X &x_min, &y_min, &z_min, &x_max, &y_max, &z_max);
- X dz = (z_max - z_min) / (num_of_z_levels+1);
- X /* Step from z_min+dz upto z_max-dz in num_of_z_levels times. */
- X z = z_min + dz;
- X crnt_cntr_pt_index = 0;
- X
- X for (i=0; i<num_of_z_levels; i++, z += dz) {
- X contour_level = z;
- X gen_contours(p_edges, z + dz * SHIFT_Z_EPSILON, x_min, x_max,
- X y_min, y_max);
- X }
- X
- X /* Free all contouring related temporary data. */
- X while (p_polys) {
- X p_poly = p_polys -> next;
- X free (p_polys);
- X p_polys = p_poly;
- X }
- X while (p_edges) {
- X p_edge = p_edges -> next;
- X free (p_edges);
- X p_edges = p_edge;
- X }
- X while (p_vrts) {
- X p_vrtx = p_vrts -> next;
- X free (p_vrts);
- X p_vrts = p_vrtx;
- X }
- X
- X if (interp_kind == INTERP_CUBIC) free(hermit_table);
- X
- X return contour_list;
- }
- X
- /*
- X * Adds another point to the currently build contour.
- X */
- add_cntr_point(x, y)
- double x, y;
- {
- X int index;
- X
- X if (crnt_cntr_pt_index >= MAX_POINTS_PER_CNTR-1) {
- X index = crnt_cntr_pt_index - 1;
- X end_crnt_cntr();
- X crnt_cntr[0] = crnt_cntr[index * 2];
- X crnt_cntr[1] = crnt_cntr[index * 2 + 1];
- X crnt_cntr_pt_index = 1; /* Keep the last point as first of this one. */
- X }
- X crnt_cntr[crnt_cntr_pt_index * 2] = x;
- X crnt_cntr[crnt_cntr_pt_index * 2 + 1] = y;
- X crnt_cntr_pt_index++;
- }
- X
- /*
- X * Done with current contour - create gnuplot data structure for it.
- X */
- end_crnt_cntr()
- {
- X int i;
- X struct gnuplot_contours *cntr = (struct gnuplot_contours *)
- X alloc(sizeof(struct gnuplot_contours),
- X "gnuplot_contour");
- X
- X cntr->coords = (struct coordinate *) alloc(sizeof(struct coordinate) *
- X crnt_cntr_pt_index,
- X "contour coords");
- X for (i=0; i<crnt_cntr_pt_index; i++) {
- X cntr->coords[i].x = crnt_cntr[i * 2];
- X cntr->coords[i].y = crnt_cntr[i * 2 + 1];
- X cntr->coords[i].z = contour_level;
- X }
- X cntr->num_pts = crnt_cntr_pt_index;
- X
- X cntr->next = contour_list;
- X contour_list = cntr;
- X
- X crnt_cntr_pt_index = 0;
- }
- X
- /*
- X * Generates all contours by tracing the intersecting triangles.
- X */
- static void gen_contours(p_edges, z_level, x_min, x_max, y_min, y_max)
- struct edge_struct *p_edges;
- double z_level, x_min, x_max, y_min, y_max;
- {
- X int num_active, /* Number of edges marked ACTIVE. */
- X contour_kind; /* One of OPEN_CONTOUR, CLOSED_CONTOUR. */
- X struct cntr_struct *p_cntr;
- X
- X num_active = update_all_edges(p_edges, z_level); /* Do pass 1. */
- X
- X test_boundary = TRUE; /* Start to look for contour on boundaries. */
- X
- X while (num_active > 0) { /* Do Pass 2. */
- X /* Generate One contour (and update MumActive as needed): */
- X p_cntr = gen_one_contour(p_edges, z_level, &contour_kind, &num_active);
- X put_contour(p_cntr, z_level, x_min, x_max, y_min, y_max,
- X contour_kind); /* Emit it in requested format. */
- X }
- }
- X
- /*
- X * Does pass 1, or marks the edges which are active (crosses this z_level)
- X * as ACTIVE, and the others as INACTIVE:
- X * Returns number of active edges (marked ACTIVE).
- X */
- static int update_all_edges(p_edges, z_level)
- struct edge_struct *p_edges;
- double z_level;
- {
- X int count = 0;
- X
- X while (p_edges) {
- X if (((p_edges -> vertex[0] -> Z >= z_level) &&
- X (p_edges -> vertex[1] -> Z <= z_level)) ||
- X ((p_edges -> vertex[1] -> Z >= z_level) &&
- X (p_edges -> vertex[0] -> Z <= z_level))) {
- X p_edges -> status = ACTIVE;
- X count++;
- X }
- X else p_edges -> status = INACTIVE;
- X p_edges = p_edges -> next;
- X }
- X
- X return count;
- }
- X
- /*
- X * Does pass 2, or find one complete contour out of the triangolation data base:
- X * Returns a pointer to the contour (as linked list), contour_kind is set to
- X * one of OPEN_CONTOUR, CLOSED_CONTOUR, and num_active is updated.
- X */
- static struct cntr_struct *gen_one_contour(p_edges, z_level, contour_kind,
- X num_active)
- struct edge_struct *p_edges;
- double z_level;
- int *contour_kind, *num_active;
- {
- X struct edge_struct *pe_temp;
- X
- X if (test_boundary) { /* Look for something to start with on boundary: */
- X pe_temp = p_edges;
- X while (pe_temp) {
- X if ((pe_temp -> status == ACTIVE) && (pe_temp -> boundary)) break;
- X pe_temp = pe_temp -> next;
- X }
- X if (!pe_temp) test_boundary = FALSE;/* No more contours on boundary. */
- X else {
- X *contour_kind = OPEN_CONTOUR;
- X return trace_contour(pe_temp, z_level, num_active, *contour_kind);
- X }
- X }
- X
- X if (!test_boundary) { /* Look for something to start with inside: */
- X pe_temp = p_edges;
- X while (pe_temp) {
- X if ((pe_temp -> status == ACTIVE) && (!(pe_temp -> boundary)))
- X break;
- X pe_temp = pe_temp -> next;
- X }
- X if (!pe_temp) {
- X *num_active = 0;
- X return NULL;
- X }
- X else {
- X *contour_kind = CLOSED_CONTOUR;
- X return trace_contour(pe_temp, z_level, num_active, *contour_kind);
- X }
- X }
- X return NULL; /* We should never be here, but lint... */
- }
- X
- /*
- X * Search the data base along a contour starts at the edge pe_start until
- X * a boundary edge is detected or until we close the loop back to pe_start.
- X * Returns a linked list of all the points on the contour
- X * Also decreases num_active by the number of points on contour.
- X */
- static struct cntr_struct *trace_contour(pe_start, z_level, num_active,
- X contour_kind)
- struct edge_struct *pe_start;
- double z_level;
- int *num_active, contour_kind;
- {
- X int i, in_middle; /* If TRUE the z_level is in the middle of edge. */
- X struct cntr_struct *p_cntr, *pc_tail;
- X struct edge_struct *p_edge = pe_start, *p_next_edge;
- X struct poly_struct *p_poly, *PLastpoly = NULL;
- X
- X /* Generate the header of the contour - the point on pe_start. */
- X if (contour_kind == OPEN_CONTOUR) pe_start -> status = INACTIVE;
- X (*num_active)--;
- X p_cntr = pc_tail = update_cntr_pt(pe_start, z_level, &in_middle);
- X if (!in_middle) {
- X return NULL;
- X }
- X
- X do {
- X /* Find polygon to continue (Not where we came from - PLastpoly): */
- X if (p_edge -> poly[0] == PLastpoly) p_poly = p_edge -> poly[1];
- X else p_poly = p_edge -> poly[0];
- X p_next_edge = NULL; /* In case of error, remains NULL. */
- X for (i=0; i<3; i++) /* Test the 3 edges of the polygon: */
- X if (p_poly -> edge[i] != p_edge)
- X if (p_poly -> edge[i] -> status == ACTIVE)
- X p_next_edge = p_poly -> edge[i];
- X if (!p_next_edge) {
- X pc_tail -> next = NULL;
- X free_contour(p_cntr);
- X return NULL;
- X }
- X p_edge = p_next_edge;
- X PLastpoly = p_poly;
- X p_edge -> status = INACTIVE;
- X (*num_active)--;
- X pc_tail -> next = update_cntr_pt(p_edge, z_level, &in_middle);
- X if (!in_middle) {
- X pc_tail -> next = NULL;
- X free_contour(p_cntr);
- X return NULL;
- X }
- X pc_tail = pc_tail -> next;
- X }
- X while ((pe_start != p_edge) && (!p_edge -> boundary));
- X pc_tail -> next = NULL;
- X
- X return p_cntr;
- }
- X
- /*
- X * Allocates one contour location and update it to to correct position
- X * according to z_level and edge p_edge. if z_level is found to be at
- X * one of the extreme points nothing is allocated (NULL is returned)
- X * and in_middle is set to FALSE.
- X */
- static struct cntr_struct *update_cntr_pt(p_edge, z_level, in_middle)
- struct edge_struct *p_edge;
- double z_level;
- int *in_middle;
- {
- X double t;
- X struct cntr_struct *p_cntr;
- X
- X t = (z_level - p_edge -> vertex[0] -> Z) /
- X (p_edge -> vertex[1] -> Z - p_edge -> vertex[0] -> Z);
- X
- X if (fuzzy_equal(t, 1.0) || fuzzy_equal(t, 0.0)) {
- X *in_middle = FALSE;
- X return NULL;
- X }
- X else {
- X *in_middle = TRUE;
- X p_cntr = (struct cntr_struct *) alloc(sizeof(struct cntr_struct),
- SHAR_EOF
- true || echo 'restore of gnuplot/contour.c failed'
- fi
- echo 'End of part 4'
- echo 'File gnuplot/contour.c is continued in part 5'
- echo 5 > _shar_seq_.tmp
- exit 0
-
- exit 0 # Just in case...
- --
- Kent Landfield INTERNET: kent@sparky.IMD.Sterling.COM
- Sterling Software, IMD UUCP: uunet!sparky!kent
- Phone: (402) 291-8300 FAX: (402) 291-4362
- Please send comp.sources.misc-related mail to kent@uunet.uu.net.
-