home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-10-28 | 48.3 KB | 1,872 lines |
- Newsgroups: comp.sources.misc
- From: gershon%gr@cs.utah.edu (Elber Gershon)
- Subject: v24i042: gnuplot3 - interactive function plotting utility, Part20/26
- Message-ID: <1991Oct29.030924.3984@sparky.imd.sterling.com>
- X-Md4-Signature: 8626dc11a59b66e8d5d5a2cf7da53f48
- Date: Tue, 29 Oct 1991 03:09:24 GMT
- Approved: kent@sparky.imd.sterling.com
-
- Submitted-by: gershon%gr@cs.utah.edu (Elber Gershon)
- Posting-number: Volume 24, Issue 42
- Archive-name: gnuplot3/part20
- Environment: UNIX, MS-DOS, VMS
- Supersedes: gnuplot2: Volume 11, Issue 65-79
-
- #!/bin/sh
- # this is Part.20 (part 20 of a multipart archive)
- # do not concatenate these parts, unpack them in order with /bin/sh
- # file gnuplot/term/apollo.trm continued
- #
- if test ! -r _shar_seq_.tmp; then
- echo 'Please unpack part 1 first!'
- exit 1
- fi
- (read Scheck
- if test "$Scheck" != 20; 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/term/apollo.trm'
- else
- echo 'x - continuing file gnuplot/term/apollo.trm'
- sed 's/^X//' << 'SHAR_EOF' >> 'gnuplot/term/apollo.trm' &&
- X
- X Ray Lischner (uunet!mntgfx!lisch)
- X 4 October 1989 file created for GNUplot 1.1
- X 26 March 1990 updated for GNUplot 2.0
- */
- X
- #include <apollo/base.h>
- #include <apollo/error.h>
- #include <apollo/pad.h>
- #include <apollo/gpr.h>
- X
- /* default tick sizes for small windows */
- #define APOLLO_VTIC 6
- #define APOLLO_HTIC 6
- X
- /* issue an error message, using additional text "s" */
- #define apollo_error(s) error_$print_name(status, (s), strlen(s))
- X
- /* if "status" indicates an error, then issue an error message */
- #define apollo_check(s) if (status.all != status_$ok) apollo_error(s)
- X
- static ios_$id_t stream = -1; /* the stream for the pad */
- static gpr_$bitmap_desc_t screen_desc; /* the screen's bitmap */
- static gpr_$bitmap_desc_t bitmap_desc; /* the graphics bitmap */
- static gpr_$attribute_desc_t attr; /* attribute block for saved bitmap */
- static short draw_width; /* default GPR draw width */
- static name_$long_pname_t font_name; /* font path name */
- static int APOLLO_XMAX, APOLLO_YMAX; /* window size */
- static boolean use_bitmap; /* use a separate bitmap? */
- X
- /* return whether stdout is a DM pad */
- apollo_isa_pad()
- {
- X status_$t status;
- X pad_$isa(1, &status);
- X return (status.all == status_$ok);
- }
- X
- /*
- X Find out what the default font is for the pad, and save the
- X character height and width information.
- X
- X Note that we must save the font file name because we need
- X to reload the font file everytime the window changes size.
- */
- static void apollo_font_info(struct termentry* tbl, char* fname)
- {
- X short fwidth, fheight, flen;
- X status_$t status;
- X
- X /* get the font size & update the termentry table */
- X pad_$inq_font(stream, &fwidth, &fheight, fname, name_$long_pnamlen_max,
- X &flen, &status);
- X apollo_check("inq_font");
- X fname[flen] = '\0';
- X
- X tbl->v_char = fheight;
- X tbl->h_char = fwidth;
- }
- X
- /*
- X Initialize all the GPR stuff. To save time, we draw into a separate
- X bitmap, and then blt it onto the screen all at once. This results
- X in 5-10 times speed-up in the graphics, with only a little
- X complication. Most of the complication is right here, making sure
- X we allocate the right bitmaps, etc., in the right order. The rest
- X is in APOLLO_text(), where we actually BLT the bitmap onto the screen.
- X Everything else is the same.
- X
- X The bitmaps have the same size as the window. If the window changes
- X size, then the bitmaps retain the same size, so the user sees part
- X of the plot or a lot of space around the plot. Drawing a new plot,
- X or replotting the previous one causes APOLLO_graphics() to see if
- X the window has changed size, in which case the GPR is terminated,
- X and this routine is called again. Thus, make sure any changes
- X preserve this ability. Anything that should only be done once
- X to the pad should be handled by APOLLO_init().
- X
- X By the way, we save the current draw width, to be used later
- X for drawing extra wide lines. This way we don't need to know
- X anything about the current output device characteristics;
- X we can just draw the default width, or twice the default width, etc.
- */
- static void apollo_gpr_init(struct termentry* tbl, pad_$window_desc_t* window)
- {
- X gpr_$offset_t size;
- X short fontid;
- X status_$t status;
- X
- X size.x_size = APOLLO_XMAX = tbl->xmax = window->width;
- X size.y_size = APOLLO_YMAX = tbl->ymax = window->height;
- X
- X /* now initialize GPR */
- X gpr_$init(gpr_$frame, stream, size, 1, &screen_desc, &status);
- X apollo_check("gpr_$init");
- X
- X if (use_bitmap)
- X {
- X /* allocate the bitmap and its attribute block */
- X gpr_$allocate_attribute_block(&attr, &status);
- X apollo_check("allocate_attribute_block");
- X
- X gpr_$allocate_bitmap(size, 1, attr, &bitmap_desc, &status);
- X apollo_check("allocate_bitmap");
- X
- X gpr_$set_bitmap(bitmap_desc, &status);
- X apollo_check("set_bitmap");
- X }
- X
- X /* set the font file */
- X gpr_$load_font_file(font_name, strlen(font_name), &fontid, &status);
- X apollo_check(font_name);
- X
- X gpr_$set_text_font(fontid, &status);
- X apollo_check("set_text_font");
- X
- X gpr_$inq_draw_width(&draw_width, &status);
- X apollo_check("inq_draw_width");
- }
- X
- /*
- X Determine the tick sizes to be used for labelling borders.
- X By default, we use 1/50 of the window size, which looks nice to me.
- X If this makes the ticks too small, however, we use a minimum
- X size, to make sure they are visible. The minimum size was also
- X determined experimentally.
- X
- X Feel free to changes the sizes to something you feel looks better.
- X
- X This routine must be called after apollo_gpr_init(), because we
- X need to know the window size, as stored in the termentry table.
- */
- static void apollo_tic_sizes(struct termentry* tbl)
- {
- X /* base the tick size on the window size */
- X tbl->v_tic = tbl->ymax / 50;
- X if (tbl->v_tic < APOLLO_VTIC)
- X tbl->v_tic = APOLLO_VTIC;
- X tbl->h_tic = tbl->xmax / 50;
- X if (tbl->v_tic < APOLLO_HTIC)
- X tbl->v_tic = APOLLO_HTIC;
- }
- X
- /*
- X Terminate the GPR. This is called whenever the window size
- X changes, and we need to reinitialize the GPR. I assume that
- X calling gpr_$terminate() also deallocates the bitmaps and
- X attribute blocks because deallocating the screen's bitmap
- X causes terminate() to think GPR has already been terminated.
- X
- X Since this can be called many times, make sure nothing
- X drastic is done here, like closing the stream to the pad.
- X The only actions should be those that will be reinitialized
- X by apollo_gpr_init().
- */
- static void apollo_gpr_terminate()
- {
- X status_$t status;
- X
- X gpr_$terminate(false, &status);
- X apollo_check("terminate");
- }
- X
- /*
- X Initialize the graphics. This is called once, so we do things
- X here that should be done exactly once, such as opening the window.
- X I like to give windows names, so it is obvious what the window's
- X contents are, but this causes a transcript to be kept in a file
- X whose name is the window's name. This might be nice in some
- X circumstances, but to me it is a nuisance, so the file is
- X deleted immediately. The name is unlikely to appear normally,
- X so there should be little interference with users' normal files.
- X If the user has explicitly set the output file, however, then
- X we use that name, and do not delete the file. Thus, the
- X user can get a metafile of the plot. We can tell if the
- X output file has been set because outstr is "STDOUT". Otherwise,
- X outstr is the filename, in single quotes. We need to strip
- X the quotes to make the file name.
- X
- X The DM defaults are used for window sizes and positions. If
- X the user doesn't like it, he or she can change is and issue
- X a replot command (assuming a plot has already been generated).
- X
- X Note, also, that we must call pad_$set_scale() or else
- X pad_$inq_windows() returns scaled values, which is not what
- X we want. Setting the scale to one (1) turns off the scaling,
- X so we get real pixel sizes.
- X
- X Finally, we get the name and size of the default font. The
- X name is kept, as explained earlier. Then we can initialize
- X the GPR stuff.
- X
- X Note that there is a way that APOLLO_init() gets called more
- X than once. If the user issues the "set terminal apollo" command
- X more than once, then this is called, so we need to make sure
- X that we do not keep creating windows.
- X
- X An alternative strategy would be to interpret multiple "set term
- X apollo"s to mean create multiple windows. The user could only
- X access the most recent window because GNUplot has no concept of
- X multiple terminals. The user would, in fact, have no way of
- X removing old windows because they are still active. We could try
- X catching keyboard events to see if the user presses EXIT, but I do
- X not want to start getting into that mess. If the user really
- X wants this kind of functionality, then he or she can run gnuplot
- X multiple times. I think that is a lot cleaner, don't you?
- */
- APOLLO_init()
- {
- X /* only initialize once */
- X if (stream == -1)
- X {
- X extern char outstr[];
- X struct termentry* tbl;
- X pad_$window_desc_t window;
- X name_$long_name_t wname;
- X short wnum; /* junk needed by pad_$inq_windows() */
- X boolean unlink_wname;
- X status_$t status;
- X
- X tbl = &term_tbl[term];
- X
- X /* make the window name unique, with "gnuplot" in the label */
- X if (strcmp(outstr, "STDOUT") == 0)
- X {
- X sprintf(wname, "gnuplot-%d", getpid());
- X unlink_wname = true;
- X }
- X else
- X {
- X /* strip the single quotes around the file name */
- X strcpy(wname, outstr + 1);
- X wname[strlen(wname) - 1] = '\0';
- X unlink_wname = false;
- X }
- X
- X use_bitmap = unlink_wname;
- X
- X /* use the default window position and size */
- X window.top = window.left = window.width = window.height = 0;
- X pad_$create_window(wname, strlen(wname), pad_$transcript, 1, window,
- X &stream, &status);
- X apollo_check("create_window");
- X
- X /* if this is not the user's name, then delete the file */
- X if (unlink_wname)
- X unlink(wname);
- X
- X /* remove all scaling, to revert to pixel units, not char. units */
- X pad_$set_scale(stream, 1, 1, &status);
- X apollo_check("set_scale");
- X
- X /* get rid of the window when the program exits */
- X pad_$set_auto_close(stream, 1, true, &status);
- X apollo_check("set_auto_close");
- X
- X /* now determine the window size & update the termentry table */
- X pad_$inq_windows(stream, &window, 1, &wnum, &status);
- X apollo_check("inq_windows");
- X
- X /* the order of the next three calls is important */
- X apollo_font_info(tbl, font_name);
- X apollo_gpr_init(tbl, &window);
- X apollo_tic_sizes(tbl);
- X }
- }
- X
- /*
- X Prepare for graphics output. Since this is what the user wants to
- X do when preparing a new plot, this is a meaningful time to see if
- X the window has changed size. Thus, we avoid mucking about with
- X asynchronous traps, and we avoid the bigger problem of dealing
- X with a half-finished plot when the window changes size.
- X
- X Simply put, get the current window size, and if it has changed,
- X then get rid of the old bitmaps, etc., and allocate new ones at
- X the new size. We also need to update the termentry table.
- X If the window stays the same size, then just clear it.
- */
- static void apollo_redo_window(pad_$window_desc_t* window)
- {
- X struct termentry* tbl = &term_tbl[term];
- X status_$t status;
- X
- X /* the order of the following calls is important */
- X apollo_gpr_terminate();
- X apollo_gpr_init(tbl, window);
- X apollo_tic_sizes(tbl);
- }
- X
- APOLLO_graphics()
- {
- X pad_$window_desc_t window;
- X short wnum;
- X status_$t status;
- X
- X pad_$inq_windows(stream, &window, 1, &wnum, &status);
- X apollo_check("inq_windows");
- X
- X if (window.width != APOLLO_XMAX || window.height != APOLLO_YMAX)
- X apollo_redo_window(&window);
- X else
- X {
- X gpr_$clear(0, &status);
- X apollo_check("clear");
- X }
- }
- X
- /* set a line type:
- X -2 heavy, solid (border)
- X -1 heavy, dotted (axis)
- X 0 solid (normal)
- X 1 dots (other curves)
- X 2 short dash
- X 3 long dash
- X 4 dash dot
- X
- X Apparently, GPUplot draws a lot of short line segments, and each
- X one starts a new pattern. This makes the patterns somewhat useless,
- X but one can still tell the difference between solid, dotted, and
- X dashed lines. The utility of fancier styles is limited, however.
- X
- X On a color workstation, we should use different colors, but I
- X don't have one.
- */
- X
- /*
- X To draw different line styles on an Apollo, we use two different
- X parameters. One is a line thickness, which is just an integral
- X multiple of the default line thickness. The second is a 16-bit
- X pattern that is repeated. We could use fancier patterns, since
- X GPR supports up to 64-bits, but, as I explained earlier, this
- X really does not buy us anything.
- X
- X I used patterns that do not start with all bits on because
- X GNUplot seems to use lots of short line segments to draw
- X a curve, and this might make a very curvey plot seem like
- X a solid line, regardless of pattern. I don't want to start
- X with too many zeros, however, or else the curve might not
- X appear at all! All the patterns, therefore, start with one
- X bit on. The rest of the bits determine the true pattern.
- X
- X By examining graphics.c, we see that linetype -2 is used exclusively
- X for the border, -1 for the axes, and the non-negative integers for
- X the curves. We use heavy lines for the border and axes, and normal
- X width lines for the curves.
- X
- X Since C arrays start at zero, make sure all the offsets are correct,
- X so that it is easy to access the array with -2...n linetypes.
- */
- X
- typedef struct {
- X short width;
- X short pattern;
- } APOLLO_LINE;
- X
- static APOLLO_LINE apollo_lines[] = {
- X { 2, ~0 }, /* heavy, solid */
- X { 2, 0x6666 }, /* heavy, dotted */
- X { 1, ~0 }, /* normal */
- X { 1, 0xAAAA }, /* dotted */
- X { 1, 0xC3C3 }, /* short dash */
- X { 1, 0xE01F }, /* long dash */
- X { 1, 0x87F8 }, /* dash dot */
- X { 1, 0x6666 }, /* big dots */
- };
- X
- #define BITS_PER_LINETYPE 16
- X
- /* apollo_line(-2) is the border style, etc. */
- #define apollo_line(x) apollo_lines[(x)+2]
- #define apollo_pattern(x) &apollo_line(x).pattern
- #define apollo_width(x) apollo_line(x).width
- X
- #define APOLLO_MIN_LINE (-2)
- #define APOLLO_MAX_LINE (sizeof(apollo_lines)/sizeof(*apollo_lines)-2)
- X
- /* set the line style */
- APOLLO_linetype(ltype)
- int ltype;
- {
- X status_$t status;
- X
- X if (ltype < APOLLO_MIN_LINE)
- X ltype = APOLLO_MIN_LINE;
- X if (ltype >= APOLLO_MAX_LINE)
- X ltype %= APOLLO_MAX_LINE;
- X
- X gpr_$set_line_pattern(1, apollo_pattern(ltype), BITS_PER_LINETYPE, &status);
- X apollo_check("set_line_pattern");
- X
- X gpr_$set_draw_width(draw_width * apollo_width(ltype), &status);
- X apollo_check("set_draw_width");
- }
- X
- /* issue an error message that includes an (x, y) coordinate */
- static void apollo_xy_error(char* s, int x, int y, status_$t status)
- {
- X char buffer[128];
- X
- X sprintf(buffer, "%s(%d, %d)", s, x, y);
- X apollo_error(buffer);
- }
- X
- #define apollo_xy_check(s) \
- X if (status.all != status_$ok) apollo_xy_error((s), x, y, status)
- X
- /*
- X Note that GNUplot and GPR have reversed ideas of where the Y origin is.
- X This means subtracting the Y coordinate from Y max.
- */
- #define plot_to_gpr(y) (APOLLO_YMAX - (y))
- X
- /* move to a new position */
- APOLLO_move(unsigned int x, unsigned int y)
- {
- X status_$t status;
- X
- X gpr_$move((gpr_$coordinate_t) x, plot_to_gpr(y), &status);
- X apollo_xy_check("move");
- }
- X
- /* draw a line to a new position */
- APOLLO_vector(unsigned int x, unsigned int y)
- {
- X status_$t status;
- X
- X gpr_$line((gpr_$coordinate_t) x, plot_to_gpr(y), &status);
- X apollo_xy_check("line");
- }
- X
- /*
- X On terminals, this switches to text mode. The real meaning,
- X however, is that the graphics are finished. This means we can
- X now display the saved bitmap.
- */
- APOLLO_text()
- {
- X if (use_bitmap)
- X {
- X static gpr_$position_t pos; /* always zero */
- X gpr_$window_t window;
- X status_$t status;
- X
- X /* bitblt the entire bitmap to the entire window */
- X window.window_base.x_coord = 0;
- X window.window_base.y_coord = 0;
- X window.window_size.x_size = APOLLO_XMAX;
- X window.window_size.y_size = APOLLO_YMAX;
- X
- X gpr_$set_bitmap(screen_desc, &status);
- X apollo_check("set_bitmap(screen_desc)");
- X
- X gpr_$pixel_blt(bitmap_desc, window, pos, &status);
- X apollo_check("bitblt");
- X
- X gpr_$set_bitmap(bitmap_desc, &status);
- X apollo_check("set_bitmap(bitmap_desc)");
- X }
- }
- X
- APOLLO_text_angle(ang)
- int ang;
- {
- X status_$t status;
- X
- X gpr_$set_text_path(ang ? gpr_$up : gpr_$right, &status);
- X apollo_check("set_text_path");
- X return TRUE;
- }
- X
- static enum JUSTIFY apollo_text_mode;
- X
- APOLLO_justify_text(mode)
- enum JUSTIFY mode;
- {
- X apollo_text_mode = mode;
- X return TRUE;
- }
- X
- /*
- X Write "str" right justified on row "row". A row is assumed to
- X have whatever height the current text has. Make sure the
- X text does not cover the tick marks.
- */
- APOLLO_put_text(x, y, str)
- unsigned int x, y;
- char str[];
- {
- X gpr_$offset_t size;
- X status_$t status;
- X
- X gpr_$inq_text_extent(str, strlen(str), &size, &status);
- X apollo_check("inq_text_extent");
- X
- X y -= size.y_size / 2; /* center around "y" */
- X switch (apollo_text_mode)
- X {
- X case LEFT:
- X break;
- X case CENTRE:
- X x -= size.x_size / 2;
- X break;
- X case RIGHT:
- X x -= size.x_size;
- X break;
- X }
- X APOLLO_move(x, y);
- X
- X gpr_$text(str, strlen(str), &status);
- X apollo_check("put_text");
- }
- X
- /* reset the graphics state and terminate */
- APOLLO_reset()
- {
- X if (stream != -1)
- X {
- X apollo_gpr_terminate();
- X stream = -1;
- X }
- }
- SHAR_EOF
- echo 'File gnuplot/term/apollo.trm is complete' &&
- chmod 0644 gnuplot/term/apollo.trm ||
- echo 'restore of gnuplot/term/apollo.trm failed'
- Wc_c="`wc -c < 'gnuplot/term/apollo.trm'`"
- test 17013 -eq "$Wc_c" ||
- echo 'gnuplot/term/apollo.trm: original size 17013, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= gnuplot/term/impcodes.h ==============
- if test -f 'gnuplot/term/impcodes.h' -a X"$1" != X"-c"; then
- echo 'x - skipping gnuplot/term/impcodes.h (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting gnuplot/term/impcodes.h (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'gnuplot/term/impcodes.h' &&
- /*
- X * Copyright (c) 1985 Regents of the University of California.
- X * All rights reserved. The Berkeley software License Agreement
- X * specifies the terms and conditions for redistribution.
- X *
- X * @(#)imPcodes.h 5.1 (Berkeley) 9/21/85
- X */
- X
- #define imP_SP 128
- #define imP_SP1 129
- #define imP_OLD_MMOVE 130
- #define imP_MPLUS 131
- #define imP_MMINUS 132
- #define imP_MMOVE 133
- #define imP_SMOVE 134
- X
- #define imP_SET_ABS_H 135
- #define imP_SET_REL_H 136
- #define imP_SET_ABS_V 137
- #define imP_SET_REL_V 138
- X
- #define imP_SRULE 192
- #define imP_BRULE 193
- X
- #define imP_SET_HPOS 195
- #define imP_SET_VPOS 196
- #define imP_CRLF 197
- #define imP_SGLY 198
- #define imP_BGLY 199
- #define imP_DELG 200
- #define imP_DELC 201
- #define imP_DELF 202
- X
- #define imP_SET_HV_SYSTEM 205
- #define imP_SET_ADV_DIRS 206
- #define imP_SET_FAMILY 207
- #define imP_SET_IL 208
- #define imP_SET_BOL 209
- #define imP_SET_SP 210
- #define imP_PUSH 211
- #define imP_POP 212
- #define imP_PAGE 213
- #define imP_SET_PUSH_MASK 214
- #define imP_ENDPAGE 219
- X
- #define imP_CREATE_FAMILY_TABLE 221
- #define imP_CREATE_MAP 222
- X
- #define imP_CREATE_PATH 230
- #define imP_SET_TEXTURE 231
- #define imP_SET_PEN 232
- #define imP_FILL_PATH 233
- #define imP_DRAW_PATH 234
- #define imP_BITMAP 235
- #define imP_SET_MAGN 236
- X
- #define imP_EOF 255
- X
- X
- SHAR_EOF
- chmod 0666 gnuplot/term/impcodes.h ||
- echo 'restore of gnuplot/term/impcodes.h failed'
- Wc_c="`wc -c < 'gnuplot/term/impcodes.h'`"
- test 1260 -eq "$Wc_c" ||
- echo 'gnuplot/term/impcodes.h: original size 1260, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= gnuplot/parse.c ==============
- if test -f 'gnuplot/parse.c' -a X"$1" != X"-c"; then
- echo 'x - skipping gnuplot/parse.c (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting gnuplot/parse.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'gnuplot/parse.c' &&
- /* GNUPLOT - parse.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 <setjmp.h>
- #include <signal.h>
- #include <errno.h>
- #include <math.h>
- #include "plot.h"
- X
- #ifndef vms
- #ifndef __ZTC__
- extern int errno;
- #endif
- #endif
- X
- extern int num_tokens,c_token;
- extern struct lexical_unit token[];
- extern char c_dummy_var[MAX_NUM_VAR][MAX_ID_LEN+1]; /* name of current dummy vars */
- extern struct udft_entry *dummy_func; /* pointer to dummy variable's func */
- X
- struct value *pop(),*integer(),*complex();
- struct at_type *temp_at(), *perm_at();
- struct udft_entry *add_udf();
- struct udvt_entry *add_udv();
- union argument *add_action();
- X
- struct at_type at;
- static jmp_buf fpe_env;
- X
- #define dummy (struct value *) 0
- X
- #ifdef __TURBOC__
- void fpe()
- #else
- #ifdef __ZTC__
- void fpe(an_int)
- int an_int;
- #else
- #ifdef _CRAY
- void fpe(an_int)
- int an_int;
- #else
- fpe()
- #endif
- #endif
- #endif
- {
- #ifdef PC /* thanks to lotto@wjh12.UUCP for telling us about this */
- X _fpreset();
- #endif
- X (void) signal(SIGFPE, fpe);
- X undefined = TRUE;
- X longjmp(fpe_env, TRUE);
- }
- X
- X
- #ifdef apollo
- #include <apollo/base.h>
- #include <apollo/pfm.h>
- #include <apollo/fault.h>
- X
- /*
- X On an Apollo, the OS can signal a couple errors that are not mapped
- X into SIGFPE, namely signalling NaN and branch on an unordered
- X comparison. I suppose there are others, but none of these are documented,
- X so I handle them as they arise.
- X
- X Anyway, we need to catch these faults and signal SIGFPE.
- */
- X
- pfm_$fh_func_val_t apollo_sigfpe(pfm_$fault_rec_t& fault_rec)
- {
- X kill(getpid(), SIGFPE);
- X return pfm_$continue_fault_handling;
- }
- X
- apollo_pfm_catch()
- {
- X status_$t status;
- X pfm_$establish_fault_handler(fault_$fp_bsun, pfm_$fh_backstop,
- X apollo_sigfpe, &status);
- X pfm_$establish_fault_handler(fault_$fp_sig_nan, pfm_$fh_backstop,
- X apollo_sigfpe, &status);
- }
- #endif
- X
- X
- evaluate_at(at_ptr,val_ptr)
- struct at_type *at_ptr;
- struct value *val_ptr;
- {
- X double temp, real();
- X
- X undefined = FALSE;
- X errno = 0;
- X reset_stack();
- X if (setjmp(fpe_env))
- X return; /* just bail out */
- X (void) signal(SIGFPE, fpe); /* catch core dumps on FPEs */
- X
- X execute_at(at_ptr);
- X
- X (void) signal(SIGFPE, SIG_DFL);
- X
- X if (errno == EDOM || errno == ERANGE) {
- X undefined = TRUE;
- X } else {
- X (void) pop(val_ptr);
- X check_stack();
- X }
- /* At least one machine (ATT 3b1) computes Inf without a SIGFPE */
- X temp = real(val_ptr);
- X if (temp > VERYLARGE || temp < -VERYLARGE) {
- X undefined = TRUE;
- X }
- }
- X
- X
- struct value *
- const_express(valptr)
- struct value *valptr;
- {
- register int tkn = c_token;
- X if (END_OF_COMMAND)
- X int_error("constant expression required",c_token);
- X evaluate_at(temp_at(),valptr); /* run it and send answer back */
- X if (undefined) {
- X int_error("undefined value",tkn);
- X }
- X return(valptr);
- }
- X
- X
- struct at_type *
- temp_at() /* build a static action table and return its pointer */
- {
- X at.a_count = 0; /* reset action table !!! */
- X express();
- X return(&at);
- }
- X
- X
- /* build an action table, put it in dynamic memory, and return its pointer */
- X
- struct at_type *
- perm_at()
- {
- register struct at_type *at_ptr;
- register unsigned int len;
- X
- X (void) temp_at();
- X len = sizeof(struct at_type) -
- X (MAX_AT_LEN - at.a_count)*sizeof(struct at_entry);
- X at_ptr = (struct at_type *) alloc(len, "action table");
- X (void) memcpy(at_ptr,&at,len);
- X return(at_ptr);
- }
- X
- X
- #ifdef NOCOPY
- /*
- X * cheap and slow version of memcpy() in case you don't have one
- X */
- memcpy(dest,src,len)
- char *dest,*src;
- unsigned int len;
- {
- X while (len--)
- X *dest++ = *src++;
- }
- #endif /* NOCOPY */
- X
- X
- express() /* full expressions */
- {
- X xterm();
- X xterms();
- }
- X
- xterm() /* ? : expressions */
- {
- X aterm();
- X aterms();
- }
- X
- X
- aterm()
- {
- X bterm();
- X bterms();
- }
- X
- X
- bterm()
- {
- X cterm();
- X cterms();
- }
- X
- X
- cterm()
- {
- X dterm();
- X dterms();
- }
- X
- X
- dterm()
- {
- X eterm();
- X eterms();
- }
- X
- X
- eterm()
- {
- X fterm();
- X fterms();
- }
- X
- X
- fterm()
- {
- X gterm();
- X gterms();
- }
- X
- X
- gterm()
- {
- X hterm();
- X hterms();
- }
- X
- X
- hterm()
- {
- X unary(); /* - things */
- X iterms(); /* * / % */
- }
- X
- X
- factor()
- {
- register int value;
- X
- X if (equals(c_token,"(")) {
- X c_token++;
- X express();
- X if (!equals(c_token,")"))
- X int_error("')' expected",c_token);
- X c_token++;
- X }
- X else if (isnumber(c_token)) {
- X convert(&(add_action(PUSHC)->v_arg),c_token);
- X c_token++;
- X }
- X else if (isletter(c_token)) {
- X if ((c_token+1 < num_tokens) && equals(c_token+1,"(")) {
- X value = standard(c_token);
- X if (value) { /* it's a standard function */
- X c_token += 2;
- X express();
- X if (!equals(c_token,")"))
- X int_error("')' expected",c_token);
- X c_token++;
- X (void) add_action(value);
- X }
- X else {
- X int call_type = (int )CALL;
- X value = c_token;
- X c_token += 2;
- X express();
- X if (equals(c_token, ",")) {
- X c_token += 1;
- X express();
- X call_type = (int )CALL2;
- X }
- X if (!equals(c_token,")"))
- X int_error("')' expected",c_token);
- X c_token++;
- X add_action(call_type)->udf_arg = add_udf(value);
- X }
- X }
- X else {
- X if (equals(c_token,c_dummy_var[0])) {
- X c_token++;
- X add_action(PUSHD1)->udf_arg = dummy_func;
- X }
- X else if (equals(c_token,c_dummy_var[1])) {
- X c_token++;
- X add_action(PUSHD2)->udf_arg = dummy_func;
- X }
- X else {
- X add_action(PUSH)->udv_arg = add_udv(c_token);
- X c_token++;
- X }
- X }
- X } /* end if letter */
- X else
- X int_error("invalid expression ",c_token);
- X
- X /* add action code for ! (factorial) operator */
- X while (equals(c_token,"!")) {
- X c_token++;
- X (void) add_action(FACTORIAL);
- X }
- X /* add action code for ** operator */
- X if (equals(c_token,"**")) {
- X c_token++;
- X unary();
- X (void) add_action(POWER);
- X }
- X
- }
- X
- X
- X
- xterms()
- { /* create action code for ? : expressions */
- X
- X if (equals(c_token,"?")) {
- X register int savepc1, savepc2;
- X register union argument *argptr1,*argptr2;
- X c_token++;
- X savepc1 = at.a_count;
- X argptr1 = add_action(JTERN);
- X express();
- X if (!equals(c_token,":"))
- X int_error("expecting ':'",c_token);
- X c_token++;
- X savepc2 = at.a_count;
- X argptr2 = add_action(JUMP);
- X argptr1->j_arg = at.a_count - savepc1;
- X express();
- X argptr2->j_arg = at.a_count - savepc2;
- X }
- }
- X
- X
- aterms()
- { /* create action codes for || operator */
- X
- X while (equals(c_token,"||")) {
- X register int savepc;
- X register union argument *argptr;
- X c_token++;
- X savepc = at.a_count;
- X argptr = add_action(JUMPNZ); /* short-circuit if already TRUE */
- X aterm();
- X argptr->j_arg = at.a_count - savepc;/* offset for jump */
- #if defined(AMIGA_LC_5_1) || defined(AMIGA_AC_5)
- X (void) add_action(ABOOL);
- #else
- X (void) add_action(BOOL);
- #endif
- X }
- }
- X
- X
- bterms()
- { /* create action code for && operator */
- X
- X while (equals(c_token,"&&")) {
- X register int savepc;
- X register union argument *argptr;
- X c_token++;
- X savepc = at.a_count;
- X argptr = add_action(JUMPZ); /* short-circuit if already FALSE */
- X bterm();
- X argptr->j_arg = at.a_count - savepc;/* offset for jump */
- #if defined(AMIGA_LC_5_1) || defined(AMIGA_AC_5)
- X (void) add_action(ABOOL);
- #else
- X (void) add_action(BOOL);
- #endif
- X }
- }
- X
- X
- cterms()
- { /* create action code for | operator */
- X
- X while (equals(c_token,"|")) {
- X c_token++;
- X cterm();
- X (void) add_action(BOR);
- X }
- }
- X
- X
- dterms()
- { /* create action code for ^ operator */
- X
- X while (equals(c_token,"^")) {
- X c_token++;
- X dterm();
- X (void) add_action(XOR);
- X }
- }
- X
- X
- eterms()
- { /* create action code for & operator */
- X
- X while (equals(c_token,"&")) {
- X c_token++;
- X eterm();
- X (void) add_action(BAND);
- X }
- }
- X
- X
- fterms()
- { /* create action codes for == and != operators */
- X
- X while (TRUE) {
- X if (equals(c_token,"==")) {
- X c_token++;
- X fterm();
- X (void) add_action(EQ);
- X }
- X else if (equals(c_token,"!=")) {
- X c_token++;
- X fterm();
- X (void) add_action(NE);
- X }
- X else break;
- X }
- }
- X
- X
- gterms()
- { /* create action code for < > >= or <= operators */
- X
- X while (TRUE) {
- X /* I hate "else if" statements */
- X if (equals(c_token,">")) {
- X c_token++;
- X gterm();
- X (void) add_action(GT);
- X }
- X else if (equals(c_token,"<")) {
- X c_token++;
- X gterm();
- X (void) add_action(LT);
- X }
- X else if (equals(c_token,">=")) {
- X c_token++;
- X gterm();
- X (void) add_action(GE);
- X }
- X else if (equals(c_token,"<=")) {
- X c_token++;
- X gterm();
- X (void) add_action(LE);
- X }
- X else break;
- X }
- X
- }
- X
- X
- X
- hterms()
- { /* create action codes for + and - operators */
- X
- X while (TRUE) {
- X if (equals(c_token,"+")) {
- X c_token++;
- X hterm();
- X (void) add_action(PLUS);
- X }
- X else if (equals(c_token,"-")) {
- X c_token++;
- X hterm();
- X (void) add_action(MINUS);
- X }
- X else break;
- X }
- }
- X
- X
- iterms()
- { /* add action code for * / and % operators */
- X
- X while (TRUE) {
- X if (equals(c_token,"*")) {
- X c_token++;
- X unary();
- X (void) add_action(MULT);
- X }
- X else if (equals(c_token,"/")) {
- X c_token++;
- X unary();
- X (void) add_action(DIV);
- X }
- X else if (equals(c_token,"%")) {
- X c_token++;
- X unary();
- X (void) add_action(MOD);
- X }
- X else break;
- X }
- }
- X
- X
- unary()
- { /* add code for unary operators */
- X if (equals(c_token,"!")) {
- X c_token++;
- X unary();
- X (void) add_action(LNOT);
- X }
- X else if (equals(c_token,"~")) {
- X c_token++;
- X unary();
- X (void) add_action(BNOT);
- X }
- X else if (equals(c_token,"-")) {
- X c_token++;
- X unary();
- X (void) add_action(UMINUS);
- X }
- X else
- X factor();
- }
- SHAR_EOF
- chmod 0644 gnuplot/parse.c ||
- echo 'restore of gnuplot/parse.c failed'
- Wc_c="`wc -c < 'gnuplot/parse.c'`"
- test 10144 -eq "$Wc_c" ||
- echo 'gnuplot/parse.c: original size 10144, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= gnuplot/makefile.msc ==============
- if test -f 'gnuplot/makefile.msc' -a X"$1" != X"-c"; then
- echo 'x - skipping gnuplot/makefile.msc (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting gnuplot/makefile.msc (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'gnuplot/makefile.msc' &&
- # Make file for use with Microsoft C Version 5.10
- # and Microsoft Program Maintenance Utility Version 4.07
- #
- X
- # where to place gnuplot.gih helpfile
- HELPFILE = gnuplot.gih
- X
- # /c means don't link
- # /AL means large memory model (large code, large data)
- # /DPC means define symbol PC
- CFLAGS = /c /AL /DPC #/DMSDOS #/Zi #/Od
- X
- # see other terminal defines in term.h
- TERMFLAGS =
- X
- # /NOE means NO EXTernal Dictionary
- # /EX means pack EXE file
- # /ST:10000 means stack size 10000 bytes
- LINKFLAGS = /NOE /EX /ST:10000 #/codeview
- X
- OBJS = bitmap.obj command.obj contour.obj eval.obj graphics.obj graph3d.obj \
- X help.obj internal.obj misc.obj parse.obj plot.obj readline.obj \
- X scanner.obj setshow.obj standard.obj term.obj util.obj version.obj \
- X pcgraph.obj hrcgraph.obj corgraph.obj
- X
- CSOURCE5 = term\aed.trm term\cgi.trm term/dumb.trm term/dxf.trm term\dxy.trm \
- X term\eepic.trm term\epson.trm term\fig.trm term\hp26.trm \
- X term\hp2648.trm term\hpgl.trm term\hpljii.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
- CSOURCE8 = contour.c
- X
- # default rules
- .c.obj:
- X cl $(CFLAGS) $*.c
- X
- .asm.obj:
- X masm $*;
- X
- pcgraph.obj: pcgraph.asm header.mac lineproc.mac
- X
- corgraph.obj: corgraph.asm header.mac lineproc.mac
- X
- hrcgraph.obj: hrcgraph.asm header.mac lineproc.mac
- X
- bitmap.obj: bitmap.c bitmap.h plot.h
- X
- command.obj: command.c plot.h setshow.h help.h
- X cl $(CFLAGS) /DHELPFILE=\"$(HELPFILE)\" command.c
- X
- contour.obj: contour.c plot.h
- X
- eval.obj: eval.c plot.h
- X
- graphics.obj: graphics.c plot.h setshow.h
- X
- graph3d.obj: graphics.c plot.h setshow.h
- X
- help.obj: help.c plot.h help.h
- X
- internal.obj: internal.c plot.h
- X
- misc.obj: misc.c plot.h setshow.h
- X
- parse.obj: parse.c plot.h
- X
- plot.obj: plot.c plot.h setshow.h
- X
- readline.obj: readline.c
- X
- scanner.obj: scanner.c plot.h
- X
- setshow.obj: setshow.c plot.h setshow.h
- X
- standard.obj: standard.c plot.h
- X
- term.obj: term.c term.h plot.h setshow.h bitmap.h $(CSOURCE5) $(CSOURCE6) $(CSOURCE7)
- X cl $(CFLAGS) $(TERMFLAGS) /Iterm term.c
- X
- util.obj: util.c plot.h
- X
- version.obj: version.c
- X
- # convert gnuplot.doc to gnuplot.gih
- doc2gih.exe: docs\doc2gih.c
- X cl docs\doc2gih.c
- X
- $(HELPFILE): doc2gih.exe docs\gnuplot.doc
- X doc2gih docs\gnuplot.doc $(HELPFILE)
- X
- # Object files in link command line are ordered to avoid far jumps.
- # use linkopt.msc to avoid command-line overflow
- X
- gnuplot.exe: $(OBJS)
- X link $(LINKFLAGS) @linkopt.msc
- SHAR_EOF
- chmod 0644 gnuplot/makefile.msc ||
- echo 'restore of gnuplot/makefile.msc failed'
- Wc_c="`wc -c < 'gnuplot/makefile.msc'`"
- test 2572 -eq "$Wc_c" ||
- echo 'gnuplot/makefile.msc: original size 2572, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= gnuplot/copyright ==============
- if test -f 'gnuplot/copyright' -a X"$1" != X"-c"; then
- echo 'x - skipping gnuplot/copyright (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting gnuplot/copyright (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'gnuplot/copyright' &&
- /*
- 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 */
- SHAR_EOF
- chmod 0644 gnuplot/copyright ||
- echo 'restore of gnuplot/copyright failed'
- Wc_c="`wc -c < 'gnuplot/copyright'`"
- test 1114 -eq "$Wc_c" ||
- echo 'gnuplot/copyright: original size 1114, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= gnuplot/graph3d.c ==============
- if test -f 'gnuplot/graph3d.c' -a X"$1" != X"-c"; then
- echo 'x - skipping gnuplot/graph3d.c (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting gnuplot/graph3d.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'gnuplot/graph3d.c' &&
- /* GNUPLOT - graph3d.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 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 <assert.h>
- #include <time.h>
- #include "plot.h"
- #include "setshow.h"
- X
- extern char *strcpy(),*strncpy(),*strcat(),*ctime(),*tdate;
- #ifdef AMIGA_AC_5
- extern time_t dated;
- #else
- #ifdef VMS
- extern time_t dated,time();
- #else
- extern long dated,time();
- #endif
- #endif
- X
- static plot3d_impulses();
- static plot3d_lines();
- static plot3d_points();
- static plot3d_dots();
- static cntr3d_impulses();
- static cntr3d_lines();
- static cntr3d_points();
- static cntr3d_dots();
- static update_extrema_pts();
- static draw_parametric_grid();
- static draw_non_param_grid();
- static draw_bottom_grid();
- static draw_3dxtics();
- static draw_3dytics();
- static draw_3dztics();
- static draw_series_3dxtics();
- static draw_series_3dytics();
- static draw_series_3dztics();
- static draw_set_3dxtics();
- static draw_set_3dytics();
- static draw_set_3dztics();
- static xtick();
- static ytick();
- static ztick();
- X
- #ifndef max /* Lattice C has max() in math.h, but shouldn't! */
- #define max(a,b) ((a > b) ? a : b)
- #endif
- X
- #ifndef min
- #define min(a,b) ((a < b) ? a : b)
- #endif
- X
- #define inrange(z,min,max) ((min<max) ? ((z>=min)&&(z<=max)) : ((z>=max)&&(z<=min)) )
- X
- #define apx_eq(x,y) (fabs(x-y) < 0.001)
- #define abs(x) ((x) >= 0 ? (x) : -(x))
- #define sqr(x) ((x) * (x))
- X
- /* Define the boundary of the plot
- X * These are computed at each call to do_plot, and are constant over
- X * the period of one do_plot. They actually only change when the term
- X * type changes and when the 'set size' factors change.
- X */
- static int xleft, xright, ybot, ytop, xmiddle, ymiddle, xscaler, yscaler;
- X
- /* Boundary and scale factors, in user coordinates */
- /* x_min3d, x_max3d, y_min3d, y_max3d, z_min3d, z_max3d are local to this
- X * file and are not the same as variables of the same names in other files
- X */
- static double x_min3d, x_max3d, y_min3d, y_max3d, z_min3d, z_max3d;
- static double xscale3d, yscale3d, zscale3d;
- static double real_z_min3d, real_z_max3d;
- static double min_sy_ox,min_sy_oy; /* obj. coords. for xy tics placement. */
- static double min_sx_ox,min_sx_oy; /* obj. coords. for z tics placement. */
- X
- typedef double transform_matrix[4][4];
- static transform_matrix trans_mat;
- X
- /* (DFK) Watch for cancellation error near zero on axes labels */
- #define SIGNIF (0.01) /* less than one hundredth of a tic mark */
- #define CheckZero(x,tic) (fabs(x) < ((tic) * SIGNIF) ? 0.0 : (x))
- #define NearlyEqual(x,y,tic) (fabs((x)-(y)) < ((tic) * SIGNIF))
- X
- /* And the functions to map from user to terminal coordinates */
- #define map_x(x) (int)(x+0.5) /* maps floating point x to screen */
- #define map_y(y) (int)(y+0.5) /* same for y */
- X
- /* And the functions to map from user 3D space into normalized -1..1 */
- #define map_x3d(x) ((x-x_min3d)*xscale3d-1.0)
- #define map_y3d(y) ((y-y_min3d)*yscale3d-1.0)
- #define map_z3d(z) ((z-z_min3d)*zscale3d-1.0)
- X
- static mat_unit(mat)
- transform_matrix mat;
- {
- X int i, j;
- X
- X for (i = 0; i < 4; i++) for (j = 0; j < 4; j++)
- X if (i == j)
- X mat[i][j] = 1.0;
- X else
- X mat[i][j] = 0.0;
- }
- X
- static mat_trans(tx, ty, tz, mat)
- double tx, ty, tz;
- transform_matrix mat;
- {
- X mat_unit(mat); /* Make it unit matrix. */
- X mat[3][0] = tx;
- X mat[3][1] = ty;
- X mat[3][2] = tz;
- }
- X
- static mat_scale(sx, sy, sz, mat)
- double sx, sy, sz;
- transform_matrix mat;
- {
- X mat_unit(mat); /* Make it unit matrix. */
- X mat[0][0] = sx;
- X mat[1][1] = sy;
- X mat[2][2] = sz;
- }
- X
- static mat_rot_x(teta, mat)
- double teta;
- transform_matrix mat;
- {
- X double cos_teta, sin_teta;
- X
- X teta *= Pi / 180.0;
- X cos_teta = cos(teta);
- X sin_teta = sin(teta);
- X
- X mat_unit(mat); /* Make it unit matrix. */
- X mat[1][1] = cos_teta;
- X mat[1][2] = -sin_teta;
- X mat[2][1] = sin_teta;
- X mat[2][2] = cos_teta;
- }
- X
- static mat_rot_y(teta, mat)
- double teta;
- transform_matrix mat;
- {
- X double cos_teta, sin_teta;
- X
- X teta *= Pi / 180.0;
- X cos_teta = cos(teta);
- X sin_teta = sin(teta);
- X
- X mat_unit(mat); /* Make it unit matrix. */
- X mat[0][0] = cos_teta;
- X mat[0][2] = -sin_teta;
- X mat[2][0] = sin_teta;
- X mat[2][2] = cos_teta;
- }
- X
- static mat_rot_z(teta, mat)
- double teta;
- transform_matrix mat;
- {
- X double cos_teta, sin_teta;
- X
- X teta *= Pi / 180.0;
- X cos_teta = cos(teta);
- X sin_teta = sin(teta);
- X
- X mat_unit(mat); /* Make it unit matrix. */
- X mat[0][0] = cos_teta;
- X mat[0][1] = -sin_teta;
- X mat[1][0] = sin_teta;
- X mat[1][1] = cos_teta;
- }
- X
- /* Multiply two transform_matrix. Result can be one of two operands. */
- void mat_mult(mat_res, mat1, mat2)
- transform_matrix mat_res, mat1, mat2;
- {
- X int i, j, k;
- X transform_matrix mat_res_temp;
- X
- X for (i = 0; i < 4; i++) for (j = 0; j < 4; j++) {
- X mat_res_temp[i][j] = 0;
- X for (k = 0; k < 4; k++) mat_res_temp[i][j] += mat1[i][k] * mat2[k][j];
- X }
- X for (i = 0; i < 4; i++) for (j = 0; j < 4; j++)
- X mat_res[i][j] = mat_res_temp[i][j];
- }
- X
- /* And the functions to map from user 3D space to terminal coordinates */
- static int map3d_xy(x, y, z, xt, yt)
- double x, y, z;
- int *xt, *yt;
- {
- X int i,j;
- X double v[4], res[4], /* Homogeneous coords. vectors. */
- X w = trans_mat[3][3];
- X
- X v[0] = map_x3d(x); /* Normalize object space to -1..1 */
- X v[1] = map_y3d(y);
- X v[2] = map_z3d(z);
- X v[3] = 1.0;
- X
- X for (i = 0; i < 2; i++) { /* Dont use the third axes (z). */
- X res[i] = trans_mat[3][i]; /* Initiate it with the weight factor. */
- X for (j = 0; j < 3; j++) res[i] += v[j] * trans_mat[j][i];
- X }
- X
- X for (i = 0; i < 3; i++) w += v[i] * trans_mat[i][3];
- X if (w == 0) w = 1e-5;
- X
- X *xt = ((int) (res[0] * xscaler / w)) + xmiddle;
- X *yt = ((int) (res[1] * yscaler / w)) + ymiddle;
- }
- X
- /* Test a single point to be within the xleft,xright,ybot,ytop bbox.
- X * Sets the returned integers 4 l.s.b. as follows:
- X * bit 0 if to the left of xleft.
- X * bit 1 if to the right of xright.
- X * bit 2 if above of ytop.
- X * bit 3 if below of ybot.
- X * 0 is returned if inside.
- X */
- static int clip_point(x, y)
- int x, y;
- {
- X int ret_val = 0;
- X
- X if (x < xleft) ret_val |= 0x01;
- X if (x > xright) ret_val |= 0x02;
- X if (y < ybot) ret_val |= 0x04;
- X if (y > ytop) ret_val |= 0x08;
- X
- X return ret_val;
- }
- X
- /* Clip the given line to drawing coords defined as xleft,xright,ybot,ytop.
- X * This routine uses the cohen & sutherland bit mapping for fast clipping -
- X * see "Principles of Interactive Computer Graphics" Newman & Sproull page 65.
- X */
- static void draw_clip_line(x1, y1, x2, y2)
- int x1, y1, x2, y2;
- {
- X int x, y, dx, dy, x_intr[2], y_intr[2], count, pos1, pos2;
- X register struct termentry *t = &term_tbl[term];
- X
- X pos1 = clip_point(x1, y1);
- X pos2 = clip_point(x2, y2);
- X if (pos1 || pos2) {
- X if (pos1 & pos2) return; /* segment is totally out. */
- X
- X /* Here part of the segment MAY be inside. test the intersection
- X * of this segment with the 4 boundaries for hopefully 2 intersections
- X * in. If non found segment is totaly out.
- X */
- X count = 0;
- X dx = x2 - x1;
- X dy = y2 - y1;
- X
- X /* Find intersections with the x parallel bbox lines: */
- X if (dy != 0) {
- X x = (ybot - y2) * dx / dy + x2; /* Test for ybot boundary. */
- X if (x >= xleft && x <= xright) {
- X x_intr[count] = x;
- X y_intr[count++] = ybot;
- X }
- X x = (ytop - y2) * dx / dy + x2; /* Test for ytop boundary. */
- X if (x >= xleft && x <= xright) {
- X x_intr[count] = x;
- X y_intr[count++] = ytop;
- X }
- X }
- X
- X /* Find intersections with the y parallel bbox lines: */
- X if (dx != 0) {
- X y = (xleft - x2) * dy / dx + y2; /* Test for xleft boundary. */
- X if (y >= ybot && y <= ytop) {
- X x_intr[count] = xleft;
- X y_intr[count++] = y;
- X }
- X y = (xright - x2) * dy / dx + y2; /* Test for xright boundary. */
- X if (y >= ybot && y <= ytop) {
- X x_intr[count] = xright;
- X y_intr[count++] = y;
- X }
- X }
- X
- X if (count == 2) {
- X int x_max, x_min, y_max, y_min;
- X
- X x_min = min(x1, x2);
- X x_max = max(x1, x2);
- X y_min = min(y1, y2);
- X y_max = max(y1, y2);
- X
- X if (pos1 && pos2) { /* Both were out - update both */
- X x1 = x_intr[0];
- X y1 = y_intr[0];
- X x2 = x_intr[1];
- X y2 = y_intr[1];
- X }
- X else if (pos1) { /* Only x1/y1 was out - update only it */
- X if (dx * (x2 - x_intr[0]) + dy * (y2 - y_intr[0]) > 0) {
- X x1 = x_intr[0];
- X y1 = y_intr[0];
- X }
- X else {
- X x1 = x_intr[1];
- X y1 = y_intr[1];
- X }
- X }
- X else { /* Only x2/y2 was out - update only it */
- X if (dx * (x_intr[0] - x1) + dy * (y_intr[0] - x1) > 0) {
- X x2 = x_intr[0];
- X y2 = y_intr[0];
- X }
- X else {
- X x2 = x_intr[1];
- X y2 = y_intr[1];
- X }
- X }
- X
- X if (x1 < x_min || x1 > x_max ||
- X x2 < x_min || x2 > x_max ||
- X y1 < y_min || y1 > y_max ||
- X y2 < y_min || y2 > y_max) return;
- X }
- X else
- X return;
- X }
- X
- X (*t->move)(x1,y1);
- X (*t->vector)(x2,y2);
- }
- X
- /* Two routine to emulate move/vector sequence using line drawing routine. */
- static int move_pos_x, move_pos_y;
- X
- static void clip_move(x,y)
- int x,y;
- {
- X move_pos_x = x;
- X move_pos_y = y;
- }
- X
- static void clip_vector(x,y)
- int x,y;
- {
- X draw_clip_line(move_pos_x,move_pos_y, x, y);
- X move_pos_x = x;
- X move_pos_y = y;
- }
- X
- /* And text clipping routine. */
- static void clip_put_text(x, y, str)
- int x,y;
- char *str;
- {
- X register struct termentry *t = &term_tbl[term];
- X
- X if (clip_point(x, y)) return;
- X
- X (*t->put_text)(x,y,str);
- }
- X
- /* (DFK) For some reason, the Sun386i compiler screws up with the CheckLog
- X * macro, so I write it as a function on that machine.
- X */
- #ifndef sun386
- /* (DFK) Use 10^x if logscale is in effect, else x */
- #define CheckLog(log, x) ((log) ? pow(10., (x)) : (x))
- #else
- static double
- CheckLog(log, x)
- X BOOLEAN log;
- X double x;
- {
- X if (log)
- X return(pow(10., x));
- X else
- X return(x);
- }
- #endif /* sun386 */
- X
- static double
- LogScale(coord, islog, what, axis)
- X double coord; /* the value */
- X BOOLEAN islog; /* is this axis in logscale? */
- X char *what; /* what is the coord for? */
- X char *axis; /* which axis is this for ("x" or "y")? */
- {
- X if (islog) {
- X if (coord <= 0.0) {
- X char errbuf[100]; /* place to write error message */
- X (void) sprintf(errbuf,"%s has %s coord of %g; must be above 0 for log scale!",
- X what, axis, coord);
- X (*term_tbl[term].text)();
- X (void) fflush(outfile);
- X int_error(errbuf, NO_CARET);
- X } else
- X return(log10(coord));
- X }
- X return(coord);
- }
- X
- /* borders of plotting area */
- /* computed once on every call to do_plot */
- static boundary3d(scaling)
- X BOOLEAN scaling; /* TRUE if terminal is doing the scaling */
- {
- X register struct termentry *t = &term_tbl[term];
- X xleft = (t->h_char)*2 + (t->h_tic);
- X xright = (scaling ? 1 : xsize) * (t->xmax) - (t->h_char)*2 - (t->h_tic);
- X ybot = (t->v_char)*5/2 + 1;
- X ytop = (scaling ? 1 : ysize) * (t->ymax) - (t->v_char)*5/2 - 1;
- X xmiddle = (xright + xleft) / 2;
- X ymiddle = (ytop + ybot) / 2;
- X xscaler = (xright - xleft) / 2;
- X yscaler = (ytop - ybot) / 2;
- }
- X
- static double dbl_raise(x,y)
- double x;
- int y;
- {
- register int i;
- double val;
- X
- X val = 1.0;
- X for (i=0; i < abs(y); i++)
- X val *= x;
- X if (y < 0 ) return (1.0/val);
- X return(val);
- }
- X
- X
- SHAR_EOF
- true || echo 'restore of gnuplot/graph3d.c failed'
- fi
- echo 'End of part 20'
- echo 'File gnuplot/graph3d.c is continued in part 21'
- echo 21 > _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.
-