home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-10-28 | 38.6 KB | 1,367 lines |
- Newsgroups: comp.sources.misc
- From: gershon%gr@cs.utah.edu (Elber Gershon)
- Subject: v24i048: gnuplot3 - interactive function plotting utility, Part26/26
- Message-ID: <1991Oct29.031148.4386@sparky.imd.sterling.com>
- X-Md4-Signature: 39aaf473530c7e95ec35c1b5854ea431
- Date: Tue, 29 Oct 1991 03:11:48 GMT
- Approved: kent@sparky.imd.sterling.com
-
- Submitted-by: gershon%gr@cs.utah.edu (Elber Gershon)
- Posting-number: Volume 24, Issue 48
- Archive-name: gnuplot3/part26
- Environment: UNIX, MS-DOS, VMS
- Supersedes: gnuplot2: Volume 11, Issue 65-79
-
- #!/bin/sh
- # this is Part.26 (part 26 of a multipart archive)
- # do not concatenate these parts, unpack them in order with /bin/sh
- # file gnuplot/graphics.c continued
- #
- if test ! -r _shar_seq_.tmp; then
- echo 'Please unpack part 1 first!'
- exit 1
- fi
- (read Scheck
- if test "$Scheck" != 26; 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/graphics.c'
- else
- echo 'x - continuing file gnuplot/graphics.c'
- sed 's/^X//' << 'SHAR_EOF' >> 'gnuplot/graphics.c' &&
- X }
- X
- X
- /* DRAW CURVES */
- X if (key == -1) {
- X xl = xright - (t->h_tic) - (t->h_char)*5;
- X yl = ytop - (t->v_tic) - (t->v_char);
- X }
- X if (key == 1) {
- X xl = map_x( LogScale(key_x, log_x, "key", "x") );
- X yl = map_y( LogScale(key_y, log_y, "key", "y") );
- X }
- X
- X this_plot = plots;
- X for (curve = 0; curve < pcount; this_plot = this_plot->next_cp, curve++) {
- X (*t->linetype)(this_plot->line_type);
- X if (key != 0) {
- X if ((*t->justify_text)(RIGHT)) {
- X (*t->put_text)(xl,
- X yl,this_plot->title);
- X }
- X else {
- X if (inrange(xl-(t->h_char)*strlen(this_plot->title),
- X xleft, xright))
- X (*t->put_text)(xl-(t->h_char)*strlen(this_plot->title),
- X yl,this_plot->title);
- X }
- X }
- X
- X switch(this_plot->plot_style) {
- X case IMPULSES: {
- X if (key != 0) {
- X (*t->move)(xl+(t->h_char),yl);
- X (*t->vector)(xl+4*(t->h_char),yl);
- X }
- X plot_impulses(this_plot, yaxis_x, xaxis_y);
- X break;
- X }
- X case LINES: {
- X if (key != 0) {
- X (*t->move)(xl+(int)(t->h_char),yl);
- X (*t->vector)(xl+(int)(4*(t->h_char)),yl);
- X }
- X plot_lines(this_plot);
- X break;
- X }
- X case POINTS: {
- X if (key != 0) {
- X (*t->point)(xl+2*(t->h_char),yl,
- X this_plot->point_type);
- X }
- X plot_points(this_plot);
- X break;
- X }
- X case LINESPOINTS: {
- X /* put lines */
- X if (key != 0) {
- X (*t->move)(xl+(t->h_char),yl);
- X (*t->vector)(xl+4*(t->h_char),yl);
- X }
- X plot_lines(this_plot);
- X
- X /* put points */
- X if (key != 0) {
- X (*t->point)(xl+2*(t->h_char),yl,
- X this_plot->point_type);
- X }
- X plot_points(this_plot);
- X break;
- X }
- X case DOTS: {
- X if (key != 0) {
- X (*t->point)(xl+2*(t->h_char),yl, -1);
- X }
- X plot_dots(this_plot);
- X break;
- X }
- X case ERRORBARS: {
- X if (key != 0) {
- X (*t->point)(xl+2*(t->h_char),yl,
- X this_plot->point_type);
- X }
- X plot_points(this_plot);
- X
- X /* for functions, just like POINTS */
- X if (this_plot->plot_type == DATA) {
- X if (key != 0) {
- X (*t->move)(xl+(t->h_char),yl);
- X (*t->vector)(xl+4*(t->h_char),yl);
- X (*t->move)(xl+(t->h_char),yl+ERRORBARTIC);
- X (*t->vector)(xl+(t->h_char),yl-ERRORBARTIC);
- X (*t->move)(xl+4*(t->h_char),yl+ERRORBARTIC);
- X (*t->vector)(xl+4*(t->h_char),yl-ERRORBARTIC);
- X }
- X plot_bars(this_plot);
- X }
- X break;
- X }
- X }
- X yl = yl - (t->v_char);
- X }
- X (*t->text)();
- X (void) fflush(outfile);
- }
- X
- /* plot_impulses:
- X * Plot the curves in IMPULSES style
- X */
- void
- plot_impulses(plot, yaxis_x, xaxis_y)
- X struct curve_points *plot;
- X int yaxis_x, xaxis_y;
- {
- X int i;
- X int x,y;
- X struct termentry *t = &term_tbl[term];
- X
- X for (i = 0; i < plot->p_count; i++) {
- X switch (plot->points[i].type) {
- X case INRANGE: {
- X x = map_x(plot->points[i].x);
- X y = map_y(plot->points[i].y);
- X break;
- X }
- X case OUTRANGE: {
- X if (!inrange(plot->points[i].x, x_min,x_max))
- X continue;
- X x = map_x(plot->points[i].x);
- X if ((y_min < y_max
- X && plot->points[i].y < y_min)
- X || (y_max < y_min
- X && plot->points[i].y > y_min))
- X y = map_y(y_min);
- X if ((y_min < y_max
- X && plot->points[i].y > y_max)
- X || (y_max<y_min
- X && plot->points[i].y < y_max))
- X y = map_y(y_max);
- X break;
- X }
- X default: /* just a safety */
- X case UNDEFINED: {
- X continue;
- X }
- X }
- X
- X if (polar)
- X (*t->move)(yaxis_x,xaxis_y);
- X else
- X (*t->move)(x,xaxis_y);
- X (*t->vector)(x,y);
- X }
- X
- }
- X
- /* plot_lines:
- X * Plot the curves in LINES style
- X */
- void
- plot_lines(plot)
- X struct curve_points *plot;
- {
- X int i; /* point index */
- X int x,y; /* point in terminal coordinates */
- X struct termentry *t = &term_tbl[term];
- X enum coord_type prev = UNDEFINED; /* type of previous point */
- X double ex, ey; /* an edge point */
- X double lx[2], ly[2]; /* two edge points */
- X
- X for (i = 0; i < plot->p_count; i++) {
- X switch (plot->points[i].type) {
- X case INRANGE: {
- X x = map_x(plot->points[i].x);
- X y = map_y(plot->points[i].y);
- X
- X if (prev == INRANGE) {
- X (*t->vector)(x,y);
- X } else if (prev == OUTRANGE) {
- X /* from outrange to inrange */
- X if (!clip_lines1) {
- X (*t->move)(x,y);
- X } else {
- X edge_intersect(plot->points, i, &ex, &ey);
- X (*t->move)(map_x(ex), map_y(ey));
- X (*t->vector)(x,y);
- X }
- X } else { /* prev == UNDEFINED */
- X (*t->move)(x,y);
- X (*t->vector)(x,y);
- X }
- X
- X break;
- X }
- X case OUTRANGE: {
- X if (prev == INRANGE) {
- X /* from inrange to outrange */
- X if (clip_lines1) {
- X edge_intersect(plot->points, i, &ex, &ey);
- X (*t->vector)(map_x(ex), map_y(ey));
- X }
- X } else if (prev == OUTRANGE) {
- X /* from outrange to outrange */
- X if (clip_lines2) {
- X if (two_edge_intersect(plot->points, i, lx, ly)) {
- X (*t->move)(map_x(lx[0]), map_y(ly[0]));
- X (*t->vector)(map_x(lx[1]), map_y(ly[1]));
- X }
- X }
- X }
- X break;
- X }
- X default: /* just a safety */
- X case UNDEFINED: {
- X break;
- X }
- X }
- X prev = plot->points[i].type;
- X }
- }
- X
- /* plot_bars:
- X * Plot the curves in ERRORBARS style
- X * we just plot the bars; the points are plotted in plot_points
- X */
- void
- plot_bars(plot)
- X struct curve_points *plot;
- {
- X int i; /* point index */
- X struct termentry *t = &term_tbl[term];
- X double x; /* position of the bar */
- X double ylow, yhigh; /* the ends of the bars */
- X unsigned int xM, ylowM, yhighM; /* the mapped version of above */
- X BOOLEAN low_inrange, high_inrange;
- X int tic = ERRORBARTIC;
- X
- X for (i = 0; i < plot->p_count; i++) {
- X /* undefined points don't count */
- X if (plot->points[i].type == UNDEFINED)
- X continue;
- X
- X /* check to see if in xrange */
- X x = plot->points[i].x;
- X if (! inrange(x, x_min, x_max))
- X continue;
- X xM = map_x(x);
- X
- X /* find low and high points of bar, and check yrange */
- X yhigh = plot->points[i].yhigh;
- X ylow = plot->points[i].ylow;
- X
- X high_inrange = inrange(yhigh, y_min,y_max);
- X low_inrange = inrange(ylow, y_min,y_max);
- X
- X /* compute the plot position of yhigh */
- X if (high_inrange)
- X yhighM = map_y(yhigh);
- X else if (samesign(yhigh-y_max, y_max-y_min))
- X yhighM = map_y(y_max);
- X else
- X yhighM = map_y(y_min);
- X
- X /* compute the plot position of ylow */
- X if (low_inrange)
- X ylowM = map_y(ylow);
- X else if (samesign(ylow-y_max, y_max-y_min))
- X ylowM = map_y(y_max);
- X else
- X ylowM = map_y(y_min);
- X
- X if (!high_inrange && !low_inrange && ylowM == yhighM)
- X /* both out of range on the same side */
- X continue;
- X
- X /* by here everything has been mapped */
- X (*t->move)(xM, ylowM);
- X (*t->vector)(xM, yhighM); /* draw the main bar */
- X (*t->move)(xM-tic, ylowM); /* draw the bottom tic */
- X (*t->vector)(xM+tic, ylowM);
- X (*t->move)(xM-tic, yhighM); /* draw the top tic */
- X (*t->vector)(xM+tic, yhighM);
- X }
- }
- X
- /* plot_points:
- X * Plot the curves in POINTS style
- X */
- void
- plot_points(plot)
- X struct curve_points *plot;
- {
- X int i;
- X int x,y;
- X struct termentry *t = &term_tbl[term];
- X
- X for (i = 0; i < plot->p_count; i++) {
- X if (plot->points[i].type == INRANGE) {
- X x = map_x(plot->points[i].x);
- X y = map_y(plot->points[i].y);
- X /* do clipping if necessary */
- X if (!clip_points ||
- X ( x >= xleft + t->h_tic && y >= ybot + t->v_tic
- X && x <= xright - t->h_tic && y <= ytop - t->v_tic))
- X (*t->point)(x,y, plot->point_type);
- X }
- X }
- }
- X
- /* plot_dots:
- X * Plot the curves in DOTS style
- X */
- void
- plot_dots(plot)
- X struct curve_points *plot;
- {
- X int i;
- X int x,y;
- X struct termentry *t = &term_tbl[term];
- X
- X for (i = 0; i < plot->p_count; i++) {
- X if (plot->points[i].type == INRANGE) {
- X x = map_x(plot->points[i].x);
- X y = map_y(plot->points[i].y);
- X /* point type -1 is a dot */
- X (*t->point)(x,y, -1);
- X }
- X }
- }
- X
- /* single edge intersection algorithm */
- /* Given two points, one inside and one outside the plot, return
- X * the point where an edge of the plot intersects the line segment defined
- X * by the two points.
- X */
- void
- edge_intersect(points, i, ex, ey)
- X struct coordinate *points; /* the points array */
- X int i; /* line segment from point i-1 to point i */
- X double *ex, *ey; /* the point where it crosses an edge */
- {
- X /* global x_min, x_max, y_min, x_max */
- X double ax = points[i-1].x;
- X double ay = points[i-1].y;
- X double bx = points[i].x;
- X double by = points[i].y;
- X double x, y; /* possible intersection point */
- X
- X if (by == ay) {
- X /* horizontal line */
- X /* assume inrange(by, y_min, y_max) */
- X *ey = by; /* == ay */
- X
- X if (inrange(x_max, ax, bx))
- X *ex = x_max;
- X else if (inrange(x_min, ax, bx))
- X *ex = x_min;
- X else {
- X (*term_tbl[term].text)();
- X (void) fflush(outfile);
- X int_error("error in edge_intersect", NO_CARET);
- X }
- X return;
- X } else if (bx == ax) {
- X /* vertical line */
- X /* assume inrange(bx, x_min, x_max) */
- X *ex = bx; /* == ax */
- X
- X if (inrange(y_max, ay, by))
- X *ey = y_max;
- X else if (inrange(y_min, ay, by))
- X *ey = y_min;
- X else {
- X (*term_tbl[term].text)();
- X (void) fflush(outfile);
- X int_error("error in edge_intersect", NO_CARET);
- X }
- X return;
- X }
- X
- X /* slanted line of some kind */
- X
- X /* does it intersect y_min edge */
- X if (inrange(y_min, ay, by) && y_min != ay && y_min != by) {
- X x = ax + (y_min-ay) * ((bx-ax) / (by-ay));
- X if (inrange(x, x_min, x_max)) {
- X *ex = x;
- X *ey = y_min;
- X return; /* yes */
- X }
- X }
- X
- X /* does it intersect y_max edge */
- X if (inrange(y_max, ay, by) && y_max != ay && y_max != by) {
- X x = ax + (y_max-ay) * ((bx-ax) / (by-ay));
- X if (inrange(x, x_min, x_max)) {
- X *ex = x;
- X *ey = y_max;
- X return; /* yes */
- X }
- X }
- X
- X /* does it intersect x_min edge */
- X if (inrange(x_min, ax, bx) && x_min != ax && x_min != bx) {
- X y = ay + (x_min-ax) * ((by-ay) / (bx-ax));
- X if (inrange(y, y_min, y_max)) {
- X *ex = x_min;
- X *ey = y;
- X return;
- X }
- X }
- X
- X /* does it intersect x_max edge */
- X if (inrange(x_max, ax, bx) && x_max != ax && x_max != bx) {
- X y = ay + (x_max-ax) * ((by-ay) / (bx-ax));
- X if (inrange(y, y_min, y_max)) {
- X *ex = x_max;
- X *ey = y;
- X return;
- X }
- X }
- X
- X /* It is possible for one or two of the [ab][xy] values to be -VERYLARGE.
- X * If ax=bx=-VERYLARGE or ay=by=-VERYLARGE we have already returned
- X * FALSE above. Otherwise we fall through all the tests above.
- X * If two are -VERYLARGE, it is ax=ay=-VERYLARGE or bx=by=-VERYLARGE
- X * since either a or b must be INRANGE.
- X * Note that for ax=ay=-VERYLARGE or bx=by=-VERYLARGE we can do nothing.
- X * Handle them carefully here. As yet we have no way for them to be
- X * +VERYLARGE.
- X */
- X if (ax == -VERYLARGE) {
- X if (ay != -VERYLARGE) {
- X *ex = min(x_min, x_max);
- X *ey = by;
- X return;
- X }
- X } else if (bx == -VERYLARGE) {
- X if (by != -VERYLARGE) {
- X *ex = min(x_min, x_max);
- X *ey = ay;
- X return;
- X }
- X } else if (ay == -VERYLARGE) {
- X /* note we know ax != -VERYLARGE */
- X *ex = bx;
- X *ey = min(y_min, y_max);
- X return;
- X } else if (by == -VERYLARGE) {
- X /* note we know bx != -VERYLARGE */
- X *ex = ax;
- X *ey = min(y_min, y_max);
- X return;
- X }
- X
- X /* If we reach here, then either one point is (-VERYLARGE,-VERYLARGE),
- X * or the inrange point is on the edge, and
- X * the line segment from the outrange point does not cross any
- X * other edges to get there. In either case, we return the inrange
- X * point as the 'edge' intersection point. This will basically draw
- X * line.
- X */
- X if (points[i].type == INRANGE) {
- X *ex = bx;
- X *ey = by;
- X } else {
- X *ex = ax;
- X *ey = ay;
- X }
- X return;
- }
- X
- /* double edge intersection algorithm */
- /* Given two points, both outside the plot, return
- X * the points where an edge of the plot intersects the line segment defined
- X * by the two points. There may be zero, one, two, or an infinite number
- X * of intersection points. (One means an intersection at a corner, infinite
- X * means overlaying the edge itself). We return FALSE when there is nothing
- X * to draw (zero intersections), and TRUE when there is something to
- X * draw (the one-point case is a degenerate of the two-point case and we do
- X * not distinguish it - we draw it anyway).
- X */
- BOOLEAN /* any intersection? */
- two_edge_intersect(points, i, lx, ly)
- X struct coordinate *points; /* the points array */
- X int i; /* line segment from point i-1 to point i */
- X double *lx, *ly; /* lx[2], ly[2]: points where it crosses edges */
- {
- X /* global x_min, x_max, y_min, x_max */
- X double ax = points[i-1].x;
- X double ay = points[i-1].y;
- X double bx = points[i].x;
- X double by = points[i].y;
- X double x, y; /* possible intersection point */
- X BOOLEAN intersect = FALSE;
- X
- X if (by == ay) {
- X /* horizontal line */
- X /* y coord must be in range, and line must span both x_min and x_max */
- X /* note that spanning x_min implies spanning x_max */
- X if (inrange(by, y_min, y_max) && inrange(x_min, ax, bx)) {
- X *lx++ = x_min;
- X *ly++ = by;
- X *lx++ = x_max;
- X *ly++ = by;
- X return(TRUE);
- X } else
- X return(FALSE);
- X } else if (bx == ax) {
- X /* vertical line */
- X /* x coord must be in range, and line must span both y_min and y_max */
- X /* note that spanning y_min implies spanning y_max */
- X if (inrange(bx, x_min, x_max) && inrange(y_min, ay, by)) {
- X *lx++ = bx;
- X *ly++ = y_min;
- X *lx++ = bx;
- X *ly++ = y_max;
- X return(TRUE);
- X } else
- X return(FALSE);
- X }
- X
- X /* slanted line of some kind */
- X /* there can be only zero or two intersections below */
- X
- X /* does it intersect y_min edge */
- X if (inrange(y_min, ay, by)) {
- X x = ax + (y_min-ay) * ((bx-ax) / (by-ay));
- X if (inrange(x, x_min, x_max)) {
- X *lx++ = x;
- X *ly++ = y_min;
- X intersect = TRUE;
- X }
- X }
- X
- X /* does it intersect y_max edge */
- X if (inrange(y_max, ay, by)) {
- X x = ax + (y_max-ay) * ((bx-ax) / (by-ay));
- X if (inrange(x, x_min, x_max)) {
- X *lx++ = x;
- X *ly++ = y_max;
- X intersect = TRUE;
- X }
- X }
- X
- X /* does it intersect x_min edge */
- X if (inrange(x_min, ax, bx)) {
- X y = ay + (x_min-ax) * ((by-ay) / (bx-ax));
- X if (inrange(y, y_min, y_max)) {
- X *lx++ = x_min;
- X *ly++ = y;
- X intersect = TRUE;
- X }
- X }
- X
- X /* does it intersect x_max edge */
- X if (inrange(x_max, ax, bx)) {
- X y = ay + (x_max-ax) * ((by-ay) / (bx-ax));
- X if (inrange(y, y_min, y_max)) {
- X *lx++ = x_max;
- X *ly++ = y;
- X intersect = TRUE;
- X }
- X }
- X
- X if (intersect)
- X return(TRUE);
- X
- X /* It is possible for one or more of the [ab][xy] values to be -VERYLARGE.
- X * If ax=bx=-VERYLARGE or ay=by=-VERYLARGE we have already returned
- X * FALSE above.
- X * Note that for ax=ay=-VERYLARGE or bx=by=-VERYLARGE we can do nothing.
- X * Otherwise we fall through all the tests above.
- X * Handle them carefully here. As yet we have no way for them to be +VERYLARGE.
- X */
- X if (ax == -VERYLARGE) {
- X if (ay != -VERYLARGE
- X && inrange(by, y_min, y_max) && inrange(x_max, ax, bx)) {
- X *lx++ = x_min;
- X *ly = by;
- X *lx++ = x_max;
- X *ly = by;
- X intersect = TRUE;
- X }
- X } else if (bx == -VERYLARGE) {
- X if (by != -VERYLARGE
- X && inrange(ay, y_min, y_max) && inrange(x_max, ax, bx)) {
- X *lx++ = x_min;
- X *ly = ay;
- X *lx++ = x_max;
- X *ly = ay;
- X intersect = TRUE;
- X }
- X } else if (ay == -VERYLARGE) {
- X /* note we know ax != -VERYLARGE */
- X if (inrange(bx, x_min, x_max) && inrange(y_max, ay, by)) {
- X *lx++ = bx;
- X *ly = y_min;
- X *lx++ = bx;
- X *ly = y_max;
- X intersect = TRUE;
- X }
- X } else if (by == -VERYLARGE) {
- X /* note we know bx != -VERYLARGE */
- X if (inrange(ax, x_min, x_max) && inrange(y_max, ay, by)) {
- X *lx++ = ax;
- X *ly = y_min;
- X *lx++ = ax;
- X *ly = y_max;
- X intersect = TRUE;
- X }
- X }
- X
- X return(intersect);
- }
- X
- /* Polar transform of all curves */
- /* Original code by John Campbell (CAMPBELL@NAUVAX.bitnet) */
- polar_xform (plots, pcount)
- X struct curve_points *plots;
- X int pcount; /* count of curves in plots array */
- {
- X struct curve_points *this_plot;
- X int curve; /* loop var, for curves */
- X register int i, p_cnt; /* loop/limit var, for points */
- X struct coordinate *pnts; /* abbrev. for points array */
- X double x, y; /* new cartesian value */
- X BOOLEAN anydefined = FALSE;
- X double d2r;
- X
- X if(angles_format == ANGLES_DEGREES){
- X d2r = DEG2RAD;
- X } else {
- X d2r = 1.0;
- X }
- X
- /*
- X Cycle through all the plots converting polar to rectangular.
- X If autoscaling, adjust max and mins. Ignore previous values.
- X If not autoscaling, use the yrange for both x and y ranges.
- */
- X if (autoscale_ly) {
- X x_min = VERYLARGE;
- X y_min = VERYLARGE;
- X x_max = -VERYLARGE;
- X y_max = -VERYLARGE;
- X autoscale_lx = TRUE;
- X } else {
- X x_min = y_min;
- X x_max = y_max;
- X }
- X
- X this_plot = plots;
- X for (curve = 0; curve < pcount; this_plot = this_plot->next_cp, curve++) {
- X p_cnt = this_plot->p_count;
- X pnts = &(this_plot->points[0]);
- X
- X /* Convert to cartesian all points in this curve. */
- X for (i = 0; i < p_cnt; i++) {
- X if (pnts[i].type != UNDEFINED) {
- X anydefined = TRUE;
- X /* modify points to reset origin and from degrees */
- X pnts[i].y -= rmin;
- X pnts[i].x *= d2r;
- X /* convert to cartesian coordinates */
- X x = pnts[i].y*cos(pnts[i].x);
- X y = pnts[i].y*sin(pnts[i].x);
- X pnts[i].x = x;
- X pnts[i].y = y;
- X if (autoscale_ly) {
- X if (x_min > x) x_min = x;
- X if (x_max < x) x_max = x;
- X if (y_min > y) y_min = y;
- X if (y_max < y) y_max = y;
- X pnts[i].type = INRANGE;
- X } else if(inrange(x, x_min, x_max) && inrange(y, y_min, y_max))
- X pnts[i].type = INRANGE;
- X else
- X pnts[i].type = OUTRANGE;
- X }
- X }
- X }
- X
- X if (autoscale_lx && anydefined && fabs(x_max - x_min) < zero) {
- X /* This happens at least for the plot of 1/cos(x) (vertical line). */
- X fprintf(stderr, "Warning: empty x range [%g:%g], ", x_min,x_max);
- X if (x_min == 0.0) {
- X x_min = -1;
- X x_max = 1;
- X } else {
- X x_min *= 0.9;
- X x_max *= 1.1;
- X }
- X fprintf(stderr, "adjusting to [%g:%g]\n", x_min,x_max);
- X }
- X if (autoscale_ly && anydefined && fabs(y_max - y_min) < zero) {
- X /* This happens at least for the plot of 1/sin(x) (horiz. line). */
- X fprintf(stderr, "Warning: empty y range [%g:%g], ", y_min, y_max);
- X if (y_min == 0.0) {
- X y_min = -1;
- X y_max = 1;
- X } else {
- X y_min *= 0.9;
- X y_max *= 1.1;
- X }
- X fprintf(stderr, "adjusting to [%g:%g]\n", y_min, y_max);
- X }
- }
- X
- /* DRAW_YTICS: draw a regular tic series, y axis */
- draw_ytics(start, incr, end)
- X double start, incr, end; /* tic series definition */
- X /* assume start < end, incr > 0 */
- {
- X double ticplace;
- X int ltic; /* for mini log tics */
- X double lticplace; /* for mini log tics */
- X double ticmin, ticmax; /* for checking if tic is almost inrange */
- X
- X if (end == VERYLARGE) /* for user-def series */
- X end = max(y_min,y_max);
- X
- X /* limit to right side of plot */
- X end = min(end, max(y_min,y_max));
- X
- X /* to allow for rounding errors */
- X ticmin = min(y_min,y_max) - SIGNIF*incr;
- X ticmax = max(y_min,y_max) + SIGNIF*incr;
- X end = end + SIGNIF*incr;
- X
- X for (ticplace = start; ticplace <= end; ticplace +=incr) {
- X if ( inrange(ticplace,ticmin,ticmax) )
- X ytick(ticplace, yformat, incr, 1.0);
- X if (log_y && incr == 1.0) {
- X /* add mini-ticks to log scale ticmarks */
- X int lstart, linc;
- X if ((end - start) >= 10)
- X {
- X lstart = 10; /* No little ticks */
- X linc = 5;
- X }
- X else if((end - start) >= 5)
- X {
- X lstart = 4; /* 3 per decade */
- X linc = 3;
- X }
- X else
- X {
- X lstart = 2; /* 9 per decade */
- X linc = 1;
- X }
- X for (ltic = 2; ltic <= 9; ltic++) {
- X lticplace = ticplace+log10((double)ltic);
- X if ( inrange(lticplace,ticmin,ticmax) )
- X ytick(lticplace, "\0", incr, 0.5);
- X }
- X }
- X }
- }
- X
- /* DRAW_XTICS: draw a regular tic series, x axis */
- draw_xtics(start, incr, end)
- X double start, incr, end; /* tic series definition */
- X /* assume start < end, incr > 0 */
- {
- X double ticplace;
- X int ltic; /* for mini log tics */
- X double lticplace; /* for mini log tics */
- X double ticmin, ticmax; /* for checking if tic is almost inrange */
- X
- X if (end == VERYLARGE) /* for user-def series */
- X end = max(x_min,x_max);
- X
- X /* limit to right side of plot */
- X end = min(end, max(x_min,x_max));
- X
- X /* to allow for rounding errors */
- X ticmin = min(x_min,x_max) - SIGNIF*incr;
- X ticmax = max(x_min,x_max) + SIGNIF*incr;
- X end = end + SIGNIF*incr;
- X
- X for (ticplace = start; ticplace <= end; ticplace +=incr) {
- X if ( inrange(ticplace,ticmin,ticmax) )
- X xtick(ticplace, xformat, incr, 1.0);
- X if (log_x && incr == 1.0) {
- X /* add mini-ticks to log scale ticmarks */
- X int lstart, linc;
- X if ((end - start) >= 10)
- X {
- X lstart = 10; /* No little ticks */
- X linc = 5;
- X }
- X else if((end - start) >= 5)
- X {
- X lstart = 4; /* 3 per decade */
- X linc = 3;
- X }
- X else
- X {
- X lstart = 2; /* 9 per decade */
- X linc = 1;
- X }
- X for (ltic = lstart; ltic <= 9; ltic += linc) {
- X lticplace = ticplace+log10((double)ltic);
- X if ( inrange(lticplace,ticmin,ticmax) )
- X xtick(lticplace, "\0", incr, 0.5);
- X }
- X }
- X }
- }
- X
- /* DRAW_SERIES_YTICS: draw a user tic series, y axis */
- draw_series_ytics(start, incr, end)
- X double start, incr, end; /* tic series definition */
- X /* assume start < end, incr > 0 */
- {
- X double ticplace, place;
- X double ticmin, ticmax; /* for checking if tic is almost inrange */
- X double spacing = log_y ? log10(incr) : incr;
- X
- X if (end == VERYLARGE)
- X end = max(CheckLog(log_y, y_min), CheckLog(log_y, y_max));
- X else
- X /* limit to right side of plot */
- X end = min(end, max(CheckLog(log_y, y_min), CheckLog(log_y, y_max)));
- X
- X /* to allow for rounding errors */
- X ticmin = min(y_min,y_max) - SIGNIF*incr;
- X ticmax = max(y_min,y_max) + SIGNIF*incr;
- X end = end + SIGNIF*incr;
- X
- X for (ticplace = start; ticplace <= end; ticplace +=incr) {
- X place = (log_y ? log10(ticplace) : ticplace);
- X if ( inrange(place,ticmin,ticmax) )
- X ytick(place, yformat, spacing, 1.0);
- X }
- }
- X
- X
- /* DRAW_SERIES_XTICS: draw a user tic series, x axis */
- draw_series_xtics(start, incr, end)
- X double start, incr, end; /* tic series definition */
- X /* assume start < end, incr > 0 */
- {
- X double ticplace, place;
- X double ticmin, ticmax; /* for checking if tic is almost inrange */
- X double spacing = log_x ? log10(incr) : incr;
- X
- X if (end == VERYLARGE)
- X end = max(CheckLog(log_x, x_min), CheckLog(log_x, x_max));
- X else
- X /* limit to right side of plot */
- X end = min(end, max(CheckLog(log_x, x_min), CheckLog(log_x, x_max)));
- X
- X /* to allow for rounding errors */
- X ticmin = min(x_min,x_max) - SIGNIF*incr;
- X ticmax = max(x_min,x_max) + SIGNIF*incr;
- X end = end + SIGNIF*incr;
- X
- X for (ticplace = start; ticplace <= end; ticplace +=incr) {
- X place = (log_x ? log10(ticplace) : ticplace);
- X if ( inrange(place,ticmin,ticmax) )
- X xtick(place, xformat, spacing, 1.0);
- X }
- }
- X
- /* DRAW_SET_YTICS: draw a user tic set, y axis */
- draw_set_ytics(list)
- X struct ticmark *list; /* list of tic marks */
- {
- X double ticplace;
- X double incr = (y_max - y_min) / 10;
- X /* global x_min, x_max, xscale, y_min, y_max, yscale */
- X
- X while (list != NULL) {
- X ticplace = (log_y ? log10(list->position) : list->position);
- X if ( inrange(ticplace, y_min, y_max) /* in range */
- X || NearlyEqual(ticplace, y_min, incr) /* == y_min */
- X || NearlyEqual(ticplace, y_max, incr)) /* == y_max */
- X ytick(ticplace, list->label, incr, 1.0);
- X
- X list = list->next;
- X }
- }
- X
- /* DRAW_SET_XTICS: draw a user tic set, x axis */
- draw_set_xtics(list)
- X struct ticmark *list; /* list of tic marks */
- {
- X double ticplace;
- X double incr = (x_max - x_min) / 10;
- X /* global x_min, x_max, xscale, y_min, y_max, yscale */
- X
- X while (list != NULL) {
- X ticplace = (log_x ? log10(list->position) : list->position);
- X if ( inrange(ticplace, x_min, x_max) /* in range */
- X || NearlyEqual(ticplace, x_min, incr) /* == x_min */
- X || NearlyEqual(ticplace, x_max, incr)) /* == x_max */
- X xtick(ticplace, list->label, incr, 1.0);
- X
- X list = list->next;
- X }
- }
- X
- /* draw and label a y-axis ticmark */
- ytick(place, text, spacing, ticscale)
- X double place; /* where on axis to put it */
- X char *text; /* optional text label */
- X double spacing; /* something to use with checkzero */
- X double ticscale; /* scale factor for tic mark (0..1] */
- {
- X register struct termentry *t = &term_tbl[term];
- X char ticlabel[101];
- X int ticsize = (int)((t->h_tic) * ticscale);
- X
- X place = CheckZero(place,spacing); /* to fix rounding error near zero */
- X if (grid) {
- X (*t->linetype)(-1); /* axis line type */
- X /* do not put a rectangular grid on a polar plot */
- X if( !polar){
- X (*t->move)(xleft, map_y(place));
- X (*t->vector)(xright, map_y(place));
- X }
- X (*t->linetype)(-2); /* border linetype */
- X }
- X if (tic_in) {
- X /* if polar plot, put the tics along the axes */
- X if( polar){
- X (*t->move)(map_x(ZERO),map_y(place));
- X (*t->vector)(map_x(ZERO) + ticsize, map_y(place));
- X (*t->move)(map_x(ZERO), map_y(place));
- X (*t->vector)(map_x(ZERO) - ticsize, map_y(place));
- X } else {
- X (*t->move)(xleft, map_y(place));
- X (*t->vector)(xleft + ticsize, map_y(place));
- X (*t->move)(xright, map_y(place));
- X (*t->vector)(xright - ticsize, map_y(place));
- X }
- X } else {
- X if( polar){
- X (*t->move)(map_x(ZERO), map_y(place));
- X (*t->vector)(map_x(ZERO) - ticsize, map_y(place));
- X }else{
- X (*t->move)(xleft, map_y(place));
- X (*t->vector)(xleft - ticsize, map_y(place));
- X }
- X }
- X
- X /* label the ticmark */
- X if (text == NULL)
- X text = yformat;
- X
- X if( polar){
- X (void) sprintf(ticlabel, text, CheckLog(log_y,fabs( place)+rmin));
- X if ((*t->justify_text)(RIGHT)) {
- X (*t->put_text)(map_x(ZERO)-(t->h_char),
- X map_y(place), ticlabel);
- X } else {
- X (*t->put_text)(map_x(ZERO)-(t->h_char)*(strlen(ticlabel)+1),
- X map_y(place), ticlabel);
- X }
- X } else {
- X
- X (void) sprintf(ticlabel, text, CheckLog(log_y, place));
- X if ((*t->justify_text)(RIGHT)) {
- X (*t->put_text)(xleft-(t->h_char),
- X map_y(place), ticlabel);
- X } else {
- X (*t->put_text)(xleft-(t->h_char)*(strlen(ticlabel)+1),
- X map_y(place), ticlabel);
- X }
- X }
- }
- X
- /* draw and label an x-axis ticmark */
- xtick(place, text, spacing, ticscale)
- X double place; /* where on axis to put it */
- X char *text; /* optional text label */
- X double spacing; /* something to use with checkzero */
- X double ticscale; /* scale factor for tic mark (0..1] */
- {
- X register struct termentry *t = &term_tbl[term];
- X char ticlabel[101];
- X int ticsize = (int)((t->v_tic) * ticscale);
- X
- X place = CheckZero(place,spacing); /* to fix rounding error near zero */
- X if (grid) {
- X (*t->linetype)(-1); /* axis line type */
- X if( !polar){
- X (*t->move)(map_x(place), ybot);
- X (*t->vector)(map_x(place), ytop);
- X }
- X (*t->linetype)(-2); /* border linetype */
- X }
- X if (tic_in) {
- X if( polar){
- X (*t->move)(map_x(place), map_y(ZERO));
- X (*t->vector)(map_x(place), map_y(ZERO) + ticsize);
- X (*t->move)(map_x(place), map_y(ZERO));
- X (*t->vector)(map_x(place), map_y(ZERO) - ticsize);
- X } else{
- X (*t->move)(map_x(place), ybot);
- X (*t->vector)(map_x(place), ybot + ticsize);
- X (*t->move)(map_x(place), ytop);
- X (*t->vector)(map_x(place), ytop - ticsize);
- X }
- X } else {
- X if( polar){
- X (*t->move)(map_x(place), map_y(ZERO));
- X (*t->vector)(map_x(place), map_y(ZERO) - ticsize);
- X }else{
- X (*t->move)(map_x(place), ybot);
- X (*t->vector)(map_x(place), ybot - ticsize);
- X }
- X }
- X
- X /* label the ticmark */
- X if (text == NULL)
- X text = xformat;
- X
- X if(polar){
- X (void) sprintf(ticlabel, text, CheckLog(log_x, fabs(place)+rmin));
- X if ((*t->justify_text)(CENTRE)) {
- X (*t->put_text)(map_x(place),
- X map_y(ZERO)-(t->v_char), ticlabel);
- X } else {
- X (*t->put_text)(map_x(place)-(t->h_char)*strlen(ticlabel)/2,
- X map_y(ZERO)-(t->v_char), ticlabel);
- X }
- X }else{
- X
- X (void) sprintf(ticlabel, text, CheckLog(log_x, place));
- X if ((*t->justify_text)(CENTRE)) {
- X (*t->put_text)(map_x(place),
- X ybot-(t->v_char), ticlabel);
- X } else {
- X (*t->put_text)(map_x(place)-(t->h_char)*strlen(ticlabel)/2,
- X ybot-(t->v_char), ticlabel);
- X }
- X }
- }
- SHAR_EOF
- echo 'File gnuplot/graphics.c is complete' &&
- chmod 0644 gnuplot/graphics.c ||
- echo 'restore of gnuplot/graphics.c failed'
- Wc_c="`wc -c < 'gnuplot/graphics.c'`"
- test 42004 -eq "$Wc_c" ||
- echo 'gnuplot/graphics.c: original size 42004, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= gnuplot/makefile.ami ==============
- if test -f 'gnuplot/makefile.ami' -a X"$1" != X"-c"; then
- echo 'x - skipping gnuplot/makefile.ami (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting gnuplot/makefile.ami (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'gnuplot/makefile.ami' &&
- #
- # Makefile for the Amiga Pat R. Empleo
- # Sept 1991
- # Manx Aztec C 5.2 beta version
- #
- # Usage:
- #
- # make -f makefile.ami
- #
- #
- X
- # where to install help file gnuplot.gih
- HELPDEST=GNUPLOT:docs/gnuplot.gih
- # Where to send email about bugs and comments (locally)
- EMAIL="pixar\!bug-gnuplot@sun.com"
- X
- #
- # Manx Aztec C v5.2 compiler options
- #
- # -DVFORK We use this switch to invoke fexecv()
- #
- CC = cc
- CFLAGS = -DVFORK -DNOGAMMA -DMEMSET -DMEMCPY -DAMIGA_AC_5 -fa -sab -wosw -MR
- X
- #
- # Manx Aztec C v5.2 linker options
- #
- LD = ln
- LIBS = -lma -lc
- X
- #
- # Terminal (device) support --- see term.h
- #
- TERMFLAGS = -Iterm
- X
- #
- # List of object files except term.o, version.o
- #
- OBJS = bitmap.o command.o contour.o eval.o graphics.o graph3d.o help.o \
- X internal.o misc.o parse.o plot.o scanner.o \
- X setshow.o standard.o util.o
- X
- #
- # List of sources
- #
- CSOURCE1 = command.c setshow.c
- CSOURCE2 = help.c graphics.c graph3d.c internal.c
- CSOURCE3 = misc.c eval.c parse.c plot.c readline.c scanner.c standard.c
- CSOURCE4 = bitmap.c term.c util.c version.c
- CSOURCE5 = term/amiga.trm term/aed.trm term/cgi.trm term/dumb.trm term/dxf.trm \
- X term/dxy.trm term/eepic.trm term/epson.trm term/fig.trm \
- X term/hp26.trm term/hp2648.trm term/hpgl.trm term/hpljii.trm \
- X term/apollo.trm term/gpr.trm
- CSOURCE6 = term/impcodes.h term/imagen.trm term/object.h \
- X term/iris4d.trm term/kyo.trm term/latex.trm term/pc.trm
- CSOURCE7 = term/post.trm term/qms.trm term/regis.trm term/sun.trm \
- X term/t410x.trm term/tek.trm term/unixpc.trm term/unixplot.trm \
- X term/v384.trm term/x11.trm term/bigfig.trm term/vws.trm gnuplot_x11.c
- CSOURCE8 = contour.c
- X
- #
- # Docs
- #
- DOCS1 = docs/Makefile docs/README docs/checkdoc.c docs/doc2gih.c \
- X docs/doc2hlp.c docs/doc2hlp.com docs/doc2ms.c docs/doc2tex.c \
- X docs/gnuplot.1 docs/lasergnu.1 docs/toc_entry.sty \
- X docs/titlepage.ms docs/titlepage.tex
- DOCS2 = docs/gnuplot.doc
- DOCS3 = docs/latextut/Makefile docs/latextut/eg1.plt \
- X docs/latextut/eg2.plt docs/latextut/eg3.dat docs/latextut/eg3.plt \
- X docs/latextut/eg4.plt docs/latextut/eg5.plt docs/latextut/eg6.plt \
- X docs/latextut/header.tex docs/latextut/tutorial.tex \
- X docs/latextut/linepoint.plt
- X
- #
- # Targets
- #
- X
- default: gnuplot doc
- X
- gnuplot: $(OBJS) term.o version.o
- X $(LD) $(OBJS) term.o version.o $(LIBS) -o gnuplot
- X
- doc:
- X cd docs
- X make -f makefile.ami gih
- X
- #
- # Dependencies
- #
- plot.o: plot.c
- X $(CC) $(CFLAGS) plot.c
- X
- term.o: term.h term.c $(CSOURCE5) $(CSOURCE6) $(CSOURCE7)
- X $(CC) $(CFLAGS) $(TERMFLAGS) term.c
- X
- version.o:
- X $(CC) $(CFLAGS) -DCONTACT=$(EMAIL) version.c
- X
- $(OBJS): plot.h
- X $(CC) $(CFLAGS) $*.c
- X
- command.o:
- X $(CC) $(CFLAGS) -c command.c -DHELPFILE="$(HELPDEST)"
- X
- command.o help.o misc.o: help.h
- X
- command.o graphics.o graph3d.o misc.o plot.o setshow.o term.o: setshow.h
- X
- bitmap.o term.o: bitmap.h
- X
- #
- # misc
- #
- clean:
- X delete #?.o
- X
- veryclean: spotless
- X
- spotless:
- X delete #?.o gnuplot
- X
- SHAR_EOF
- chmod 0644 gnuplot/makefile.ami ||
- echo 'restore of gnuplot/makefile.ami failed'
- Wc_c="`wc -c < 'gnuplot/makefile.ami'`"
- test 2916 -eq "$Wc_c" ||
- echo 'gnuplot/makefile.ami: original size 2916, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= gnuplot/term.h ==============
- if test -f 'gnuplot/term.h' -a X"$1" != X"-c"; then
- echo 'x - skipping gnuplot/term.h (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting gnuplot/term.h (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'gnuplot/term.h' &&
- /* GNUPLOT - term.h */
- /*
- 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
- /*
- X * term.h: terminal support definitions
- X * Edit this file depending on the set of terminals you wish to support.
- X * Comment out the terminal types that you don't want or don't have, and
- X * uncomment those that you want included. Be aware that some terminal
- X * types (eg, SUN, UNIXPLOT) will require changes in the makefile
- X * LIBS definition.
- X */
- X
- /* These terminals are not relevant for MSDOS */
- #ifndef MSDOS
- X
- #ifdef AMIGA_LC_5_1
- #define AMIGASCREEN /* Amiga custom screen */
- X
- #else /* AMIGA_LC_5_1 */
- X
- #ifdef AMIGA_AC_5
- #define AMIGASCREEN /* Amiga custom screen */
- #endif
- #define AED /* AED 512 and AED 767 */
- #define BITGRAPH /* BBN BitGraph */
- /* #define CGI /* SCO CGI */
- /* #define IRIS4D /* IRIS4D series computer */
- #define KERMIT /* MS-Kermit Tektronix 4010 emulator */
- #define FIG /* Fig graphics language */
- #define REGIS /* ReGis graphics (vt125, vt220, vt240, Gigis...) */
- #define SELANAR /* Selanar */
- /* #define SUN /* Sun Microsystems Workstation */
- #define T410X /* Tektronix 4106, 4107, 4109 and 420x terminals */
- #define TEK /* Tektronix 4010, and probably others */
- /* #define UNIXPC /* unixpc (ATT 3b1 or ATT 7300) */
- /* #define UNIXPLOT /* unixplot */
- #define VTTEK /* VT-like tek40xx emulators */
- /* #define X11 /* X11R4 window system */
- X
- #endif /* AMIGA_LC_5_1 */
- X
- #define DXY800A /* Roland DXY800A plotter */
- X
- #define HP2648 /* HP2648, HP2647 */
- #define HP26 /* HP2623A and maybe others */
- #define HP75 /* HP7580, and probably other HPs */
- #define IMAGEN /* Imagen laser printers (300dpi) (requires -Iterm also) */
- X
- #define NEC /* NEC CP6 pinwriter printer */
- #define PRESCRIBE /* Kyocera Laser printer */
- #define QMS /* QMS/QUIC laserprinter (Talaris 1200 and others) */
- #define STARC /* Star Color Printer */
- #define TANDY60 /* Tandy DMP-130 series 60-dot per inch graphics */
- #define V384 /* Vectrix 384 and tandy color printer */
- X
- #endif /* MSDOS */
- X
- /* These terminals can be used on any system */
- #define DUMB
- X
- #define HPGL /* HP7475, HP7220 plotters, and (hopefully) lots of others */
- X
- #define POSTSCRIPT /* Postscript */
- X
- /* #define DXF /* DXF format for use with AutoCad (Release 10.x) */
- X
- #define EEPIC /* EEPIC-extended LaTeX driver, for EEPIC users */
- #define EMTEX /* LATEX picture environment with EMTEX specials */
- #define EPS60 /* Epson-style 60-dot per inch printers */
- #define EPSONP /* Epson LX-800, Star NL-10, NX-1000 and lots of others */
- #define HPLJII /* HP LaserJet II */
- #define LATEX /* LATEX picture environment */
- X
- /* These are for MSDOS only */
- #ifdef MSDOS
- #ifdef __TURBOC__
- #define ATT6300 /* AT&T 6300 graphics */
- #else
- #define ATT6300 /* AT&T 6300 graphics */
- #define CORONA /* Corona graphics 325 */
- #define HERCULES /* IBM PC/Clone with Hercules graphics board */
- #endif /* __TURBOC__ */
- #endif /* MSDOS */
- X
- SHAR_EOF
- chmod 0644 gnuplot/term.h ||
- echo 'restore of gnuplot/term.h failed'
- Wc_c="`wc -c < 'gnuplot/term.h'`"
- test 3953 -eq "$Wc_c" ||
- echo 'gnuplot/term.h: original size 3953, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- rm -f _shar_seq_.tmp
- echo You have unpacked the last part
- 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.
-