home *** CD-ROM | disk | FTP | other *** search
- Subject: v18i064: GL Graphics Library for AT-clone Unix, Part06/07
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: umix!m-net!dtlewis!lewis
- Posting-number: Volume 18, Issue 64
- Archive-name: gl_plot/part06
-
- # To recover, type "sh archive"
- echo restoring config.h
- sed 's/^X//' > config.h <<XxX--EOF--XxX
- X/* @(#) config.h 5.1 89/02/20 */
- X/*
- X * Copyright (c) David T. Lewis 1987, 1988
- X * All rights reserved.
- X *
- X * Permission is granted to use this for any personal noncommercial use.
- X * You may not distribute source or executable code for profit, nor
- X * may you distribute it with a commercial product without the written
- X * consent of the author. Please send modifications to the author for
- X * inclusion in updates to the program. Thanks.
- X */
- X
- X/* User modifiable parameters for GL graphics library. */
- X/* ===> BEGIN USER MODIFIABLE PARAMETERS <=== */
- X
- X/* Select one of the following to specify your target system (Xenix */
- X/* cross compile to MS_DOS should select MS_DOS). */
- X
- X#define SVAT 1
- X#define XENIX_286 0
- X#define MS_DOS 0
- X#define UNIX_386 0 /* (not yet supported) */
- X#define XENIX_386 0 /* (not yet supported) */
- X
- X/* If you defined MS_DOS 1, then specify your compiler here. */
- X
- X#if MS_DOS
- X#define XEN2DOS 1 /* Compile on Xenix 286 for DOS target system */
- X#define USOFT 0 /* Microsoft C under DOS */
- X#define TCC 0 /* Borland Turbo-C */
- X#define MIX_C 0 /* The old CP/M derived MIX-C compiler */
- X#endif /* MS_DOS */
- X
- X/* The following should be defined if you do NOT have a numeric */
- X/* coprocessor. It will cause some trig functions to be done with */
- X/* integer math (see trig.c). */
- X
- X#define NOFLOAT 1
- X
- X/* The following should be defined if you want the gl library to handle */
- X/* interrupt signals. This will clear the screen and return to text */
- X/* mode when the interrupt key (or ^C, for MS-DOS) is pressed. If you */
- X/* need to do your own signal routine (to close files, for example), */
- X/* you may prefer not to have this defined. */
- X
- X#define DO_CLEANUP 1
- X
- X/* VIDEO stuff: */
- X
- X/* Define the name of the program or shell script which will be used */
- X/* to switch video modes (UNIX only). This will be made from either */
- X/* the mode.c program, or the mode.sh shell script, or some equivalent */
- X/* program that works with your system and video adapter. */
- X
- X#define MODEPROG "mode"
- X/* Another possible choice: */
- X/* #define MODEPROG "/usr/local/bin/mode" */
- X
- X/* Define the name of the environment variable that you wish to use to */
- X/* indicate your default graphics mode. If we call g_init(ENV_MODE), */
- X/* then we will use this environment variable to set the graphics mode. */
- X
- X#define GL_ENV_MODE "GLMODE"
- X
- X/* If the environment variable is not set, then fall back to */
- X/* DEFAULT_MODE as a last resort. Mode 4 is CGA color mode, a safe */
- X/* choice for most systems. */
- X
- X#define DEFAULT_MODE 4
- X
- X/* PRINTER stuff: */
- X
- X/* Define name of the environment variable that you wish to set to */
- X/* indicate your default print device. */
- X
- X#define GL_PLOT_DEV "PLOTDEV"
- X
- X/* For MS-DOS, define your printer device name (and ignore the rest */
- X/* of the printer stuff that follows). Note: Microsoft compilers will */
- X/* send output to "stdprn" regardless of how you define this; other */
- X/* compilers will use the device you define below. See code in */
- X/* g_finish.c if you need to change this. */
- X
- X#define DOSPRINTER "PRN:"
- X
- X/* Define the standard print spooler program for your system (UNIX). */
- X
- X#define PRINTPROG "/usr/bin/lp"
- X#define LP_DEV_FLAG "-d"
- X
- X/* Define the device to use if GL_PLOT_DEV is not set. */
- X/* Note: Use "lp" only if you plan to manually put the printer */
- X/* driver in transparency mode (see lpset(1M)). */
- X/* On Microport, your printer devices might look something like the */
- X/* following, where /dev/lp is the standard printer driver, and */
- X/* /dev/lpt is the transparency mode printer driver. See the "Readme" */
- X/* file for more information. */
- X/* */
- X/* \$ ls -li /dev/lp* */
- X/* 82 crw-rw-rw- 2 root sys 7, 0 Oct 9 18:03 /dev/lp */
- X/* 82 crw-rw-rw- 2 root sys 7, 0 Oct 9 18:03 /dev/lp0 */
- X/* 83 crw-rw-rw- 1 root sys 7, 1 Feb 11 1988 /dev/lp1 */
- X/* 295 crw-rw-rw- 2 root sys 7,128 Oct 9 18:08 /dev/lpt */
- X/* 295 crw-rw-rw- 2 root sys 7,128 Oct 9 18:08 /dev/lpt0 */
- X/* 291 crw-rw-rw- 1 root sys 7,129 May 22 18:42 /dev/lpt1 */
- X
- X#define PRINTDEV "lpt"
- X
- X/* You may need to tweak the following in order to get round circles. */
- X
- X#define HERC_ASPECT_RATIO 0.7
- X#define CGA_ASPECT_RATIO 0.85
- X#define EGA_ASPECT_RATIO 0.6
- X#define IBM_PR_ASPECT_RATIO 0.7
- X#define LJ_PR_ASPECT_RATIO 0.81
- X
- X/* For Xenix System V 286, you must indicate the video adapter you */
- X/* are using. Microport users can ignore this (they must, however, */
- X/* create a shared memory key with shmcreate(1). MS-DOS users may */
- X/* also ignore this. */
- X
- X#define GL_CGA 0
- X#define GL_EGA 1
- X#define GL_HERC 0
- X#define GL_PGA 0 /* (not implemented) */
- X#define GL_VGA 0 /* (easy to do, but not implemented) */
- X
- X/* The following definitions specify the shared memory key identifiers */
- X/* which are used by Microport System V/AT. You are free to use any */
- X/* identifiers you want to map to video memory with shmcreate(1). */
- X/* The following are the recommended values. If you use these, the */
- X/* key values will be the same as the physical memory addresses. */
- X/* Change these definitions only if you are using different shared */
- X/* memory keys for your system. Xenix users may ignore this. */
- X
- X#define MCA_KEY 0xB0000L
- X#define CGA_KEY 0xB8000L
- X#define HERC_P0KEY 0xB0000L
- X#define HERC_P1KEY 0xB8000L
- X#define EGA_KEY 0xA0000L
- X
- X/* ===> END USER MODIFIABLE PARAMETERS <=== */
- X
- X/* The following definitions specify the physical memory locations of */
- X/* video memory, for use with MS-DOS. */
- X
- X#define DOS_MCA 0xB0000000L
- X#define DOS_CGA 0xB8000000L
- X#define DOS_H_P0 0xB0000000L
- X#define DOS_H_P1 0xB8000000L
- X#define DOS_EGA 0xA0000000L
- X
- X/* Some specific system dependent characteristics. */
- X
- X#if MIX_C
- X#define HAS_SIG 0 /* System does not have ^C interrupt handling */
- X#else
- X#if USOFT
- X#define HAS_SIG 0 /* System does not have ^C interrupt handling */
- X#else
- X#if XEN2DOS
- X#define HAS_SIG 0 /* System does not have ^C interrupt handling */
- X#else
- X#define HAS_SIG 1 /* System has ^C interrupt handling */
- X#endif /* XEN2DOS */
- X#endif /* USOFT */
- X#endif /* MIX_C */
- X
- X#if MIX_C
- X#define HAS_ENV 0 /* System does not have getenv() call */
- X#else
- X#define HAS_ENV 1 /* System has getenv() call */
- X#endif /* MIX_C */
- X
- X#if MS_DOS
- X#define HAS_PIPES 0 /* System does not have popen() call */
- X#else
- X#define HAS_PIPES 1 /* System has popen() call */
- X#endif /* MS_DOS */
- X
- X#if USOFT
- X#define HAS_SLEEP 0 /* System does not have sleep() call */
- X#else
- X#if XEN2DOS
- X#define HAS_SLEEP 0 /* System does not have sleep() call */
- X#else
- X#if MIX_C
- X#define HAS_SLEEP 0 /* System does not have sleep() call */
- X#else
- X#define HAS_SLEEP 1 /* System has sleep() call */
- X#endif /* MIX_C */
- X#endif /* XEN2DOS */
- X#endif /* USOFT */
- X
- X#if MIX_C
- X#define HAS_FMOD 0 /* System does not have fmod() call */
- X#else
- X#define HAS_FMOD 1 /* System has fmod() call */
- X#endif /* MIX_C */
- X
- X#if MIX_C
- X#define HAS_ATAN2 0 /* System does not have atan2() call */
- X#else
- X#define HAS_ATAN2 1 /* System has atan2() call */
- X#endif /* MIX_C */
- X
- X/* Some MS-DOS compilers have "stdprn" predefined for stream output to */
- X/* the printer. */
- X
- X#if USOFT
- X#define HAS_STDPRN 1
- X#else
- X#if XEN2DOS
- X#define HAS_STDPRN 1
- X#else
- X#if TCC
- X#define HAS_STDPRN 1
- X#else /* "stdprn" is not predefined */
- X#define HAS_STDPRN 0
- X#endif /* TCC */
- X#endif /* XEN2DOS */
- X#endif /* USOFT */
- X
- X/* The following should be defined for 286 versions, in which an */
- X/* integer is 16 bits. Other machines must do extra work to check */
- X/* for out of range on the normalized 2-D screen space (0 through */
- X/* 32767). */
- X
- X#if MS_DOS
- X#else
- X#if XENIX_286
- X#else
- X#if SVAT
- X#define INT16 1
- X#else /* Not a 16 bit integer machine */
- X#define INT16 0
- X#endif /* SVAT */
- X#endif /* XENIX_286 */
- X#endif /* MS_DOS */
- X
- X/* Parameter to signal call is system dependent. Define a macro to */
- X/* handle the difference between pointer to void and pointer to int. */
- X
- X#if TCC
- X#define SIG_TYPE void
- X#else
- X#define SIG_TYPE int
- X#endif /* TCC */
- X
- X/* Some compilers can use a macro for the calculation for transform */
- X/* from normalized 2-D to screen coordinates. If yours can't, then */
- X/* define N_TO_P_MACRO as 0. */
- X/* (All the compilers I've tried are working now with the macro. Leave */
- X/* this here just in case...) */
- X
- X#define N_TO_P_MACRO 1
- X
- X/* Compiler specific stuff for MS-DOS. */
- X
- X/* For MS-DOS, use the DO_BIOS macro to point to the library routine */
- X/* that invokes a BIOS call. Int is the interrupt number, and reg */
- X/* is a pointer to a structure representing machine registers. */
- X/* Define REGISTERS as the name of the data structure for machine */
- X/* registers (probably declared in <stdlib.h>). */
- X/* The remaining macros (AL, AH ...) specify individual registers */
- X/* within the REGISTERS data structure, as they would be referenced */
- X/* in a REGISTERS structure (e.g. "inreg.AH"). */
- X
- X#if MIX_C
- X#define DO_BIOS(int,inreg,outreg) bios(int,inreg)
- X#define REGISTERS REGS
- X#define AL byte.al
- X#define AH byte.ah
- X#define BL byte.bl
- X#define BH byte.bh
- X#define CL byte.cl
- X#define CH byte.ch
- X#define DL byte.dl
- X#define DH byte.dh
- X#endif /* MIX_C */
- X
- X#if USOFT
- X#define DO_BIOS(int,inreg,outreg) int86(int,inreg,outreg)
- X#define REGISTERS union REGS
- X#define AL h.al
- X#define AH h.ah
- X#define BL h.bl
- X#define BH h.bh
- X#define CL h.cl
- X#define CH h.ch
- X#define DL h.dl
- X#define DH h.dh
- X#endif /* USOFT */
- X
- X#if XEN2DOS
- X#define DO_BIOS(int,inreg,outreg) int86(int,inreg,outreg)
- X#define REGISTERS union REGS
- X#define AL h.al
- X#define AH h.ah
- X#define BL h.bl
- X#define BH h.bh
- X#define CL h.cl
- X#define CH h.ch
- X#define DL h.dl
- X#define DH h.dh
- X#endif /* XEN2DOS */
- X
- X#if TCC
- X#define DO_BIOS(int,inreg,outreg) int86(int,inreg,outreg)
- X#define REGISTERS union REGS
- X#define AL h.al
- X#define AH h.ah
- X#define BL h.bl
- X#define BH h.bh
- X#define CL h.cl
- X#define CH h.ch
- X#define DL h.dl
- X#define DH h.dh
- X#endif /* TCC */
- X
- XxX--EOF--XxX
- echo restoring g_fntctl.c
- sed 's/^X//' > g_fntctl.c <<XxX--EOF--XxX
- X#ifndef lint
- Xstatic char sccsid[] = "@(#) g_fntctl.c 5.1 89/02/20";
- X#endif
- X
- X/*
- X * Copyright (c) David T. Lewis 1988
- X * All rights reserved.
- X *
- X * Permission is granted to use this for any personal noncommercial use.
- X * You may not distribute source or executable code for profit, nor
- X * may you distribute it with a commercial product without the written
- X * consent of the author. Please send modifications to the author for
- X * inclusion in updates to the program. Thanks.
- X */
- X
- X/* Control size, aspect ratio, spacing, angle and slant of stroke font. */
- X/* Size, aspect ratio and spacing control height, relative width and */
- X/* relative spacing of characters, with 1.0 selecting default values. */
- X/* Changing size will change the width and spacing appropriately. */
- X/* Changing width will change the spacing. */
- X/* Angle is the angle of a text string in radians, with positive */
- X/* values rotating the text clockwise. Slant is the character slant */
- X/* in radians (typically a number on the order of 0.2), with positive */
- X/* values slanting the text to the "right," as in italics. */
- X
- X#include "config.h"
- X#include "bitmaps.h"
- X#include "graphics.h"
- X
- Xextern struct GL_graphics graphics;
- X
- Xint g_fontctl(size, aspect_ratio, spacing, angle, slant)
- Xfloat size, aspect_ratio, spacing, angle, slant;
- X
- X{
- X graphics.strokefont.xtic
- X = (int)(size * aspect_ratio * spacing *
- X (float)graphics.default_strokefont.xtic);
- X graphics.strokefont.ytic
- X = (int)(size * (float)graphics.default_strokefont.ytic);
- X graphics.strokefont.xsize
- X = (int)(size * aspect_ratio *
- X (float)graphics.default_strokefont.xsize);
- X graphics.strokefont.ysize
- X = (int)(size * (float)graphics.default_strokefont.ysize);
- X graphics.strokefont.angle = angle;
- X graphics.strokefont.slant = slant;
- X
- X if (angle == 0.0) graphics.strokefont.angle_flag = FALSE;
- X else graphics.strokefont.angle_flag = TRUE;
- X
- X if (slant == 0.0) graphics.strokefont.slant_flag = FALSE;
- X else graphics.strokefont.slant_flag = TRUE;
- X
- X return(0);
- X}
- X
- XxX--EOF--XxX
- echo restoring gf_types.h
- sed 's/^X//' > gf_types.h <<XxX--EOF--XxX
- X/****** Warning! Do not alter this file without updating gl.h! *******/
- X
- X/* @(#) gf_types.h 5.1 89/02/20 */
- X/*
- X * Copyright (c) David T. Lewis 1988
- X * All rights reserved.
- X *
- X * Permission is granted to use this for any personal noncommercial use.
- X * You may not distribute source or executable code for profit, nor
- X * may you distribute it with a commercial product without the written
- X * consent of the author. Please send modifications to the author for
- X * inclusion in updates to the program. Thanks.
- X */
- X
- X/* Definition(s) required for more than one include file.
- X */
- X
- X/* Define pixel setting modes. */
- X
- X#define CLEAR 0
- X#define AND 1
- X#define OR 2
- X#define XOR 3
- X
- X/* Define colors. */
- X
- X#define BLACK 0
- X#define BLUE 1
- X#define GREEN 2
- X#define CYAN 3
- X#define RED 4
- X#define MAGENTA 5
- X#define BROWN 6
- X#define WHITE 7
- X#define GREY 8
- X#define LT_BLUE 9
- X#define LT_GREEN 10
- X#define LT_CYAN 11
- X#define LT_RED 12
- X#define LT_MAGENTA 13
- X#define YELLOW 14
- X#define LT_WHITE 15
- X
- X/* Define line styles (not yet implemented). */
- X
- X#define SOLID 0xffffffffL /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
- X#define DOTTED 0x66666666L /* XX..XX..XX..XX..XX..XX..XX..XX.. */
- X#define DASHED 0xffe0ffe0L /* XXXXXXXXXXX.....XXXXXXXXXXX..... */
- X#define SHORTDASHED 0xf8f8f8f8L /* XXXXX...XXXXX...XXXXX...XXXXX... */
- X#define LONGDASHED 0xffffff00L /* XXXXXXXXXXXXXXXXXXXXXXXX........ */
- X#define DOTDASHED 0xfc30fc30L /* XXXXXX....XX....XXXXXX....XX.... */
- X
- X/* Define line weights (not yet implemented). */
- X
- X#define LIGHT 1
- X#define MEDIUM 2
- X#define HEAVY 4
- X
- X
- XxX--EOF--XxX
- echo restoring gl.h
- sed 's/^X//' > gl.h <<XxX--EOF--XxX
- X/* @(#) gl.h 5.1 89/02/20 */
- X/*
- X * Copyright (c) David T. Lewis 1988
- X * All rights reserved.
- X *
- X * Permission is granted to use this for any personal noncommercial use.
- X * You may not distribute source or executable code for profit, nor
- X * may you distribute it with a commercial product without the written
- X * consent of the author. Please send modifications to the author for
- X * inclusion in updates to the program. Thanks.
- X */
- X
- X/* This file defines the interface to the graphics library, and should
- X * be included in user programs.
- X */
- X
- X/* Definition of programming interface to gl library. */
- X
- Xextern int g_clear();
- Xextern int g_init();
- Xextern int g_finish();
- Xextern int g_pix_mode();
- Xextern int g_pix_color();
- Xextern int g_fontctl();
- Xextern long g_style();
- Xextern int g_weight();
- Xextern int p_wr_pix();
- Xextern int c_cellchar();
- Xextern int c_cellstr();
- Xextern int c_cursor();
- Xextern int n_movepen();
- Xextern int n_box();
- Xextern int n_line();
- Xextern int n_draw();
- Xextern int n_grafchar();
- Xextern int n_grafstr();
- Xextern int n_arc();
- Xextern int n_ellipse();
- Xextern int n_point();
- X
- X/* Everything that follows should be identical to gf_types.h and modes.h. */
- X
- X/* @(#) gf_types.h 1.4 88/12/26 */
- X
- X/* Define pixel setting modes. */
- X
- X#define CLEAR 0
- X#define AND 1
- X#define OR 2
- X#define XOR 3
- X
- X/* Define colors. */
- X
- X#define BLACK 0
- X#define BLUE 1
- X#define GREEN 2
- X#define CYAN 3
- X#define RED 4
- X#define MAGENTA 5
- X#define BROWN 6
- X#define WHITE 7
- X#define GREY 8
- X#define LT_BLUE 9
- X#define LT_GREEN 10
- X#define LT_CYAN 11
- X#define LT_RED 12
- X#define LT_MAGENTA 13
- X#define YELLOW 14
- X#define LT_WHITE 15
- X
- X/* Define line styles. */
- X
- X#define SOLID 0xffffffffL /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
- X#define DOTTED 0x66666666L /* XX..XX..XX..XX..XX..XX..XX..XX.. */
- X#define DASHED 0xffe0ffe0L /* XXXXXXXXXXX.....XXXXXXXXXXX..... */
- X#define SHORTDASHED 0xf8f8f8f8L /* XXXXX...XXXXX...XXXXX...XXXXX... */
- X#define LONGDASHED 0xffffff00L /* XXXXXXXXXXXXXXXXXXXXXXXX........ */
- X#define DOTDASHED 0xfc30fc30L /* XXXXXX....XX....XXXXXX....XX.... */
- X
- X/* Define line weights (not yet implemented). */
- X
- X#define LIGHT 1
- X#define MEDIUM 2
- X#define HEAVY 4
- X
- X/* @(#) modes.h 1.4 89/01/10 */
- X
- X/*
- X * Mode definitions. These will be used by init(), and by the mode
- X * program or shell script. As much as possible, the numeric mode
- X * values should correspond to those used by the uPort screen driver
- X * and by DOS. The values given for hercules and for printers are
- X * arbitrary, but should not conflict with other "standard" assignments.
- X */
- X
- X/* ENV_MODE means take the mode setting from an environment variable. */
- X#define ENV_MODE 0
- X
- X/* CGA text modes */
- X#define MONO_TEXT 0x02
- X#define COLOR_TEXT 0x03
- X
- X/* CGA modes (for CGA or EGA) */
- X#define CGA_COLOR_MODE 0x04
- X#define CGA_HI_RES_MODE 0x06
- X
- X/* Monochrome text mode */
- X#define MDA_TEXT 0x07
- X
- X/* Hercules mono graphics, page 0 and page 1 */
- X/* Note: Modes 8 and 9 were used by the IBM PC Junior. I trust that */
- X/* they will not be found on your machine. */
- X#define HERC_P0_MODE 0x08
- X#define HERC_P1_MODE 0x09
- X
- X/* EGA 640 x 350 color mode */
- X#define EGA_COLOR_MODE 0x010
- X
- X/* Anything beyond MAXVIDEO is not a video board. Printers and other */
- X/* hardcopy would fall in this category. */
- X
- X#define MAXVIDEO 0x0FF
- X
- X/* Non-video modes follow. */
- X
- X#define IBM_PRINTER 0x100
- X
- X
- XxX--EOF--XxX
- echo restoring modes.h
- sed 's/^X//' > modes.h <<XxX--EOF--XxX
- X/****** Warning! Do not alter this file without updating gl.h! *******/
- X
- X/* @(#) modes.h 5.1 89/02/20 */
- X/*
- X * Copyright (c) David T. Lewis 1987, 1988
- X * All rights reserved.
- X *
- X * Permission is granted to use this for any personal noncommercial use.
- X * You may not distribute source or executable code for profit, nor
- X * may you distribute it with a commercial product without the written
- X * consent of the author. Please send modifications to the author for
- X * inclusion in updates to the program. Thanks.
- X */
- X
- X/*
- X * Mode definitions. These will be used by init(), and by the mode
- X * program or shell script. As much as possible, the numeric mode
- X * values should correspond to those used by the uPort screen driver
- X * and by DOS. The values given for hercules and for printers are
- X * arbitrary, but should not conflict with other "standard" assignments.
- X */
- X
- X/* ENV_MODE means take the mode setting from an environment variable. */
- X#define ENV_MODE 0
- X
- X/* CGA text modes */
- X#define MONO_TEXT 0x02
- X#define COLOR_TEXT 0x03
- X
- X/* CGA modes (for CGA or EGA) */
- X#define CGA_COLOR_MODE 0x04
- X#define CGA_HI_RES_MODE 0x06
- X
- X/* Monochrome text mode */
- X#define MDA_TEXT 0x07
- X
- X/* Hercules mono graphics, page 0 and page 1 */
- X/* Note: Modes 8 and 9 were used by the IBM PC Junior. I trust that */
- X/* they will not be found on your machine. */
- X#define HERC_P0_MODE 0x08
- X#define HERC_P1_MODE 0x09
- X
- X/* EGA 640 x 350 color mode */
- X#define EGA_COLOR_MODE 0x010
- X
- X/* Anything beyond MAXVIDEO is not a video board. Printers and other */
- X/* hardcopy would fall in this category. */
- X
- X#define MAXVIDEO 0x0FF
- X
- X/* Non-video modes follow. */
- X
- X#define IBM_PRINTER 0x100
- X#define LJ_PRINTER 0x101
- X
- X
- XxX--EOF--XxX
- echo restoring n_curves.c
- sed 's/^X//' > n_curves.c <<XxX--EOF--XxX
- X#ifndef lint
- Xstatic char sccsid[] = "@(#) n_curves.c 5.1 89/02/20";
- X#endif
- X
- X/*
- X * Copyright (c) David T. Lewis 1988
- X * All rights reserved.
- X *
- X * Permission is granted to use this for any personal noncommercial use.
- X * You may not distribute source or executable code for profit, nor
- X * may you distribute it with a commercial product without the written
- X * consent of the author. Please send modifications to the author for
- X * inclusion in updates to the program. Thanks.
- X */
- X
- X/* Sat Aug 6 20:38:14 EDT 1988
- X**
- X** n_arc():
- X**
- X** Routine to draw an arc as a partial ellipse. This routine uses
- X** parts of the ellipse() routine to generate the curve.
- X** The arc is drawn around an ellipse located at (x,y) with axes a and b.
- X** The arc begins at the angle angle1 and traverses counterclockwise to
- X** angle2. "Counterclockwise" is in the sense of the normalized coordinate
- X** system, with an inverted Y axis, so the arcs are actually drawn clockwise
- X** on the display screen.
- X** The values of angle1 and angle2 are given in radians, with 0 being to the
- X** right of the center of the ellipse.
- X**
- X** n_ellipse():
- X**
- X** Routine to draw an ellipse in normalized 2-d coordinates. Uses a line
- X** segment approximation to the ellipse. The trig is done with hard coded
- X** tables of cos and sin values for speed. The number of vertices on the
- X** ellipse varies according to the size of the ellipse. The eliminates
- X** unnecessary calculations of endpoints for small images.
- X** Another method for ellipe drawing would be to do a modified Bresenham
- X** type algorithm, but this would be less adaptable for drawing partial arcs.
- X**
- X** NOTE: This is an ellipse routine, and not a circle, because the PC display
- X** adapters do not generally have square pixels. A circle routine should be
- X** done at a higher level, and should take the screen aspect ration into
- X** account (see graphics->aspect_ratio in the graphics.h file).
- X**
- X** The basic idea is:
- X**
- X** Equation of an ellipse:
- X**
- X** x^2 / a^2 + y^2 / b^2 = 1
- X**
- X** Therefore the X and Y values are:
- X**
- X** X = a * cos(theta)
- X** Y = b * sin(theta)
- X**
- X** For some angle theta.
- X**
- X** By stepping through values of theta, we can generate a list of
- X** line segment endpoints on the ellipse. Then call n_movepen() and
- X** n_draw() to display the ellipse.
- X**
- X** Note: The macros PTS_PER_QUADRANT and TRIG_SCALE are defined
- X** in graphics.h.
- X*/
- X
- X#include "config.h"
- X#if MIX_C
- X#else
- X#include <math.h>
- X#endif /* MIX_C */
- X#include "bitmaps.h"
- X#include "graphics.h"
- X
- X#ifndef M_PI
- X#define M_PI 3.1415926536
- X#endif /* M_PI */
- X#ifndef M_PI_2
- X#define M_PI_2 1.5707963268
- X#endif /* M_PI_2 */
- X
- X#define XINDEX 0 /* For specifying array indices. */
- X#define YINDEX 1
- X
- X/* The following two arrays are tables of values for cos and sin */
- X/* for one quadrant of a circle, divided into PTS_PER_QUADRANT slices. */
- X/* They are found in source file trig.c. */
- X
- Xextern long cos_table[PTS_PER_QUADRANT];
- Xextern long sin_table[PTS_PER_QUADRANT];
- Xextern long longsin(), longcos();
- Xextern int n_movepen(), n_draw();
- X
- Xstatic void make_endpoints(x,y,a,b,endpoints,step)
- Xint x,y,a,b,step;
- Xint endpoints[4][PTS_PER_QUADRANT][2];
- X{
- X int idx; /* Loop index. */
- X int value; /* Temporary storage of values */
- X
- X /* Set the values for points on the ellipse. While we're */
- X /* at it, scale the values back down using TRIG_SCALE, and do */
- X /* the x and y translation to the center point of the ellipse. */
- X /* Calculations are done with long ints to preserve precision, */
- X /* then cast back to short ints in the endpoints array. */
- X /* Use the value of step to skip unnecessary points (for small */
- X /* ellipes and arcs). */
- X
- X for(idx=step-1; idx<PTS_PER_QUADRANT; idx+= step) {
- X value = (cos_table[idx] * (long)a) / TRIG_SCALE;
- X endpoints[0][idx][XINDEX] = value + x;
- X value = -value;
- X endpoints[2][idx][XINDEX] = value + x;
- X value = (sin_table[idx] * (long)a) / TRIG_SCALE;
- X endpoints[3][idx][XINDEX] = value + x;
- X value = -value;
- X endpoints[1][idx][XINDEX] = value + x;
- X value = (cos_table[idx] * (long)b) / TRIG_SCALE;
- X endpoints[1][idx][YINDEX] = value + y;
- X value = -value;
- X endpoints[3][idx][YINDEX] = value + y;
- X value = (sin_table[idx] * (long)b) / TRIG_SCALE;
- X endpoints[0][idx][YINDEX] = value + y;
- X value = -value;
- X endpoints[2][idx][YINDEX] = value + y;
- X }
- X return;
- X}
- X
- Xstatic int make_step(a,b)
- Xint a,b;
- X{
- X int size;
- X size = a + b; /* an indication of the "size" of the ellipse. */
- X if (size <= 0) return(1); /* Check for integer overflow. */
- X else if (size < 2000) return(16);
- X else if (size < 8000) return(8);
- X else if (size < 16000) return(4);
- X else if (size < 32000) return(2);
- X else return(1);
- X}
- X
- Xint n_arc(x,y,a,b,angle1,angle2)
- Xint x,y,a,b;
- Xfloat angle1,angle2;
- X{
- X int endpoints[4][PTS_PER_QUADRANT][2];
- X int x_1,y_1,x_2,y_2; /* The start and end points of the arc. */
- X int quadrant; /* Quadrant of first point. */
- X int endquadrant; /* Quadrant of second point. */
- X int index; /* First index into endpoints array. */
- X int endindex; /* Last index into endpoints array. */
- X int istat = 0; /* Function call return status. */
- X int step; /* Amount by which to step through array. */
- X
- X /* Size of a circle, in radians. */
- X float cir_size = M_PI * 2;
- X
- X /* Don't feed huge numbers to the trig functions. */
- X if (fabs(angle1) > cir_size)
- X angle1 = fmod((double)angle1,(double)cir_size);
- X if (fabs(angle2) > cir_size)
- X angle2 = fmod((double)angle2,(double)cir_size);
- X
- X /* Make the angles positive. */
- X while (angle1 < 0) angle1 += cir_size;
- X while (angle2 < 0) angle2 += cir_size;
- X
- X /* Calculate a value for step, so we can use fewer endpoints */
- X /* for small arcs. */
- X step = make_step(a,b);
- X
- X#ifdef DEBUG
- X printf("step is %d\n",step);
- X#endif /* DEBUG */
- X
- X /* Calculate the end points. */
- X
- X#if NOFLOAT
- X x_1 = x + (int)((longcos(angle1) * a) / TRIG_SCALE);
- X y_1 = y + (int)((longsin(angle1) * b) / TRIG_SCALE);
- X x_2 = x + (int)((longcos(angle2) * a) / TRIG_SCALE);
- X y_2 = y + (int)((longsin(angle2) * b) / TRIG_SCALE);
- X#else
- X x_1 = x + (int)(a * cos((double)angle1));
- X y_1 = y + (int)(b * sin((double)angle1));
- X x_2 = x + (int)(a * cos((double)angle2));
- X y_2 = y + (int)(b * sin((double)angle2));
- X#endif /* NOFLOAT */
- X
- X /* Generate the array of arc endpoints. */
- X make_endpoints(x,y,a,b,endpoints,step);
- X
- X /* Deduce the first and last element of interest in the */
- X /* endpoint array. */
- X
- X /* First calculate the initial index value. */
- X index = (int)(angle1 / M_PI_2 * (float)PTS_PER_QUADRANT);
- X /* Now figure the quadrant. */
- X quadrant = (index / PTS_PER_QUADRANT) % 4;
- X /* Wrap around so we point at the array. */
- X index = (index % PTS_PER_QUADRANT);
- X index = index + step - (index % step) - 1;
- X
- X#ifdef DEBUG
- X printf("In n_arc(), index is %d\n",index);
- X#endif /* DEBUG */
- X
- X /* Calculate the final index value. */
- X endindex = (int)(angle2 / M_PI_2 * (float)PTS_PER_QUADRANT);
- X /* Now figure the quadrant. */
- X endquadrant = (endindex / PTS_PER_QUADRANT) % 4;
- X /* Wrap around so we point at the array. */
- X endindex = (endindex % PTS_PER_QUADRANT);
- X endindex = endindex + step - (endindex % step) - 1;
- X
- X#ifdef DEBUG
- X printf("In n_arc(), endindex is %d\n",endindex);
- X#endif /* DEBUG */
- X
- X /* Move pen to start point. */
- X
- X#ifdef DEBUG
- X printf("Move pen to %d %d\n",x_1,y_1);
- X#endif /* DEBUG */
- X
- X if(n_movepen(x_1,y_1)) istat = 1;
- X
- X /* Start drawing, beginning with the first point of interest. */
- X /* Wrap around the array if needed. */
- X
- X while ((index != endindex) || (quadrant != endquadrant)) {
- X
- X#ifdef DEBUG
- X printf("Draw to %d %d -- quadrant %d index %d\n",
- X endpoints[quadrant][index][XINDEX],
- X endpoints[quadrant][index][YINDEX],quadrant,index);
- X#endif /* DEBUG */
- X
- X if(n_draw(endpoints[quadrant][index][XINDEX],
- X endpoints[quadrant][index][YINDEX])) {
- X istat = 1;
- X /* This is just for cleaner error recovery: */
- X n_movepen(endpoints[quadrant][index][XINDEX],
- X endpoints[quadrant][index][YINDEX]);
- X }
- X /* Increment the indices. */
- X if ((index+=step) >= PTS_PER_QUADRANT) {
- X index = step - 1;
- X if ((++quadrant) >= 4) {
- X quadrant = 0;
- X }
- X }
- X };
- X
- X /* Finish at last point of interest. */
- X
- X#ifdef DEBUG
- X printf("Finish by drawing to %d %d\n",x_2,y_2);
- X#endif /* DEBUG */
- X
- X if(n_draw(x_2,y_2)) {
- X istat = 1;
- X /* This is just for cleaner error recovery: */
- X n_movepen(x_2,y_2);
- X }
- X return(istat);
- X}
- X
- Xint n_ellipse(x,y,a,b)
- Xint x,y,a,b;
- X{
- X /* The endpoints array will hold line segment (x,y) end points. */
- X /* There are four quadrants, each with PTS_PER_QUADRANT points, */
- X /* with two values (X and Y) each. */
- X int endpoints[4][PTS_PER_QUADRANT][2];
- X int pointindex, quadrant; /* Loop index. */
- X int istat = 0; /* Function call return status. */
- X int step; /* Amount by which to step through array. */
- X
- X /* Calculate a value for step, so we can use fewer endpoints */
- X /* for small ellipses. */
- X step = make_step(a,b);
- X
- X /* Build the array of endpoints. */
- X make_endpoints(x,y,a,b,endpoints,step);
- X
- X /* Display the result, drawing all four quadrants. */
- X
- X /* Start the pen at the location of the last endpoint. This */
- X /* is the point we want to end up on. */
- X if(n_movepen(endpoints[3][PTS_PER_QUADRANT-1][XINDEX],
- X endpoints[3][PTS_PER_QUADRANT-1][YINDEX]))
- X istat = 1;
- X
- X for (quadrant=0; quadrant<=3; quadrant++) {
- X
- X for (pointindex = step -1; pointindex < PTS_PER_QUADRANT;
- X pointindex += step) {
- X if(n_draw(endpoints[quadrant][pointindex][XINDEX],
- X endpoints[quadrant][pointindex][YINDEX])) {
- X istat = 1;
- X /* This is just for cleaner error recovery: */
- X n_movepen(endpoints[quadrant][pointindex]
- X [XINDEX],
- X endpoints[quadrant][pointindex]
- X [YINDEX]);
- X }
- X }
- X }
- X return(istat);
- X}
- X
- XxX--EOF--XxX
- echo restoring plot.c
- sed 's/^X//' > plot.c <<XxX--EOF--XxX
- X#ifndef lint
- Xstatic char sccsid[] = "@(#) plot.c 5.1 89/02/20";
- X#endif
- X
- X/*
- X * Copyright (c) David T. Lewis 1988
- X * All rights reserved.
- X *
- X * Permission is granted to use this for any personal noncommercial use.
- X * You may not distribute source or executable code for profit, nor
- X * may you distribute it with a commercial product without the written
- X * consent of the author. Please send modifications to the author for
- X * inclusion in updates to the program. Thanks.
- X */
- X
- X#include "config.h"
- X#include "gf_types.h"
- X#include <stdio.h>
- X#if MIX_C
- X#else
- X#include <math.h>
- X#endif /* MIX_C */
- X#include "modes.h"
- X#include "bitmaps.h"
- X#include "graphics.h"
- X
- X/* The following declarations copied from gl.h. */
- Xextern int g_clear();
- Xextern int g_init();
- Xextern int g_finish();
- Xextern long g_style();
- Xextern int c_cellstr();
- Xextern int n_movepen();
- Xextern int n_line();
- Xextern int n_draw();
- Xextern int n_arc();
- Xextern int n_ellipse();
- Xextern int n_point();
- X
- Xextern struct GL_graphics graphics;
- X
- X/* These routines emulate the BSD plot(3) library.
- X *
- X * The arc() routine may vary slightly from the BSD version,
- X * in that it calculates start and end angles with trig
- X * functions, rather than with simple integer approximations
- X * used in the BSD routine.
- X *
- X * plot: openpl, erase, label, line, circle, arc, move, cont,
- X * point, linemod, space, closepl - graphics interface
- X *
- X * Coordinate transformations, using X0, X1, Y0, Y1 set in space():
- X * X:
- X * x' = x * (NRM_X_RANGE)/(X1-X0) - (X0*NRM_X_RANGE)/(X1-X0)
- X * x' = (X0*NRM_X_RANGE + x*NRM_X_RANGE) / (X1-X0)
- X *
- X * xconst = X0*NRM_X_RANGE;
- X * xdiv = X1-X0;
- X * x' = (xconst+x*NRM_X_RANGE)/xdiv;
- X *
- X * Y:
- X * y' = y * (-NRM_Y_RANGE)/(Y1-Y0) + (Y1*NRM_Y_RANGE)/(Y1-Y0)
- X * y' = (Y1*NRM_Y_RANGE - y*NRM_Y_RANGE) / (Y1-Y0)
- X *
- X * yconst = Y1*NRM_Y_RANGE;
- X * ydiv = Y1-Y0;
- X * y' = (yconst-y*NRM_Y_RANGE)/ydiv;
- X */
- X
- X/* X_TO_NORM(x) and Y_TO_NORM(y) are used to translate from the plot() */
- X/* coordinate system, as defined by scale(), to the normalized 2-D */
- X/* coordinate system of the screen. */
- X
- X#define X_TO_NORM(x) ((int)((xconst+x*NRM_X_RANGE)/xdiv))
- X#define Y_TO_NORM(y) ((int)((yconst-y*NRM_Y_RANGE)/ydiv))
- X
- X/* X_SCALE_NORM() and Y_SCALE_NORM() are used for scaling magnitudes. */
- X
- X#define X_SCALE_NORM(x) (((x)*(NRM_X_RANGE))/(xdiv))
- X#define Y_SCALE_NORM(y) (((y)*(NRM_Y_RANGE))/(ydiv))
- X
- Xstatic long xconst,xdiv,yconst,ydiv; /* Used in space() transforms. */
- X
- Xint openpl()
- X{
- X /* Try to get the mode from the environment. */
- X /* If no environment variable, use a default. */
- X if((g_init(ENV_MODE)) == 0) return(0);
- X else {
- X /* Put warning message to standard error, then */
- X /* continue. */
- X fprintf(stderr,"Use environment variable %s to control mode.\n",
- X GL_ENV_MODE);
- X fprintf(stderr,"Continuing with default mode %d\n",
- X DEFAULT_MODE);
- X sleep(2);
- X return(g_init(DEFAULT_MODE));
- X }
- X}
- X
- Xint erase()
- X{
- X return(g_clear());
- X}
- X
- Xint label(s)
- Xchar s[];
- X{
- X return(c_cellstr(s));
- X}
- X
- Xint line(x_1, y_1, x_2, y_2)
- Xint x_1,y_1,x_2,y_2;
- X{
- X return(n_line(
- X X_TO_NORM(x_1),Y_TO_NORM(y_1),X_TO_NORM(x_2),Y_TO_NORM(y_2)));
- X}
- X
- Xint circle(x, y, r)
- X{
- X int x_axis=X_SCALE_NORM(r);
- X int y_axis=Y_SCALE_NORM(r);
- X return(n_ellipse(X_TO_NORM(x), Y_TO_NORM(y), x_axis, y_axis));
- X}
- X
- Xint arc(x, y, x_0, y_0, x_1, y_1)
- X{
- X int x_axis, y_axis; /* Major and minor axes. */
- X float angle1, angle2; /* Start and end angles. */
- X int radius; /* Radius, as calculated from sqrt(x**2+y**2). */
- X long dx_0 = x_0 - x;
- X long dy_0 = y_0 - y;
- X long dx_1 = x_1 - x;
- X long dy_1 = y_1 - y;
- X
- X /* We will draw a section of elliptical arc with major and */
- X /* minor axes such that it appears as a circle on the screen. */
- X /* We know the center of the arc (x and y), and the ratio of */
- X /* the major and minor axes (b/a equals graphics.aspect_ratio). */
- X /* Given the start and end points of the arc, we need to solve */
- X /* for the first and second angle, and then for major and minor */
- X /* axes. */
- X /* These values can be used to call the n_arc() routine. */
- X
- X /* WARNING: The value of angle2 is calculated directly as the */
- X /* angle of the vector from (x,y) to (x_1,y_1). The original */
- X /* versions of plot(3) from the BSD code apparently use */
- X /* a simplistic approximation to this, which may lead to */
- X /* different screen displays for arcs drawn with the BSD */
- X /* code. The basic idea for the user, however, should be to */
- X /* specify x_1 and y_1 such that they fall very close to the */
- X /* intended angle. */
- X
- X angle1 = (float)(-atan2((double)dy_0,(double)dx_0));
- X angle2 = (float)(-atan2((double)dy_1,(double)dx_1));
- X
- X radius = ((int)(sqrt(fabs((double)(dx_0*dx_0+dy_0*dy_0)))));
- X x_axis = X_SCALE_NORM(radius);
- X y_axis = Y_SCALE_NORM(radius);
- X
- X return(n_arc(X_TO_NORM(x),Y_TO_NORM(y),x_axis,y_axis,angle2,angle1));
- X}
- X
- Xint move(x, y)
- Xint x,y;
- X{
- X return(n_movepen(X_TO_NORM(x),Y_TO_NORM(y)));
- X}
- X
- Xint cont(x, y)
- Xint x,y;
- X{
- X return(n_draw(X_TO_NORM(x),Y_TO_NORM(y)));
- X}
- X
- Xint point(x, y)
- Xint x, y;
- X{
- X return(n_point(X_TO_NORM(x),Y_TO_NORM(y)));
- X}
- X
- Xint linemod(s)
- Xchar s[];
- X{
- X if (strncmp(s, "dotted", 6) == 0) {
- X g_style(DOTTED);
- X }
- X else if (strncmp(s, "dotdashed", 9) == 0) {
- X g_style(DOTDASHED);
- X }
- X else if (strncmp(s, "longdashed", 10) == 0) {
- X g_style(LONGDASHED);
- X }
- X else if (strncmp(s, "shortdashed", 11) == 0) {
- X g_style(SHORTDASHED);
- X }
- X else if (strncmp(s, "solid", 5) == 0) {
- X g_style(SOLID);
- X }
- X else {
- X g_style(SOLID);
- X }
- X return(0);
- X}
- X
- Xint space(x_0, y_0, x_1, y_1)
- X{
- X /* Set constants for coordinate transformations. */
- X /* Adjust x axis for aspect ratio so that output is square. */
- X
- X xconst = (long)(x_0) * NRM_X_RANGE;
- X xdiv = (long)((float)(x_1-x_0) / graphics.aspect_ratio);
- X yconst = y_1*NRM_Y_RANGE;
- X ydiv = y_1-y_0;
- X}
- X
- Xint closepl()
- X{
- X return(g_finish());
- X}
- X
- XxX--EOF--XxX
- echo restoring trig.c
- sed 's/^X//' > trig.c <<XxX--EOF--XxX
- X#ifndef lint
- Xstatic char sccsid[] = "@(#) trig.c 5.1 89/02/20";
- X#endif
- X
- X/*
- X * Copyright (c) David T. Lewis 1988
- X * All rights reserved.
- X *
- X * Permission is granted to use this for any personal noncommercial use.
- X * You may not distribute source or executable code for profit, nor
- X * may you distribute it with a commercial product without the written
- X * consent of the author. Please send modifications to the author for
- X * inclusion in updates to the program. Thanks.
- X */
- X
- X/* Integer approximations to simple trig functions. Results are scaled */
- X/* by a factor of TRIG_SCALE. */
- X
- X/* The macro TRIG_SCALE is defined in graphics.h so that other routines */
- X/* can use it. F_TRIG_SCALE is the same value, but in floating point */
- X/* format. The defines should look like this: */
- X/* */
- X/* #define TRIG_SCALE 32768 */
- X/* #define F_TRIG_SCALE 32768.0 */
- X/* */
- X/* The macro PTS_PER_QUADRANT defines the size of the sin_table and */
- X/* cos_table arrays. It is defined in graphics.h and should look */
- X/* like this: */
- X/* */
- X/* #define PTS_PER_QUADRANT 64 */
- X/* */
- X
- X#include "config.h"
- X#if MIX_C
- X#else
- X#include <math.h>
- X#endif /* MIX_C */
- X#include "bitmaps.h"
- X#include "graphics.h"
- X
- X#define L_PI 102944L /* Value of pi times TRIG_SCALE. */
- X#define L_PI_2 51472L /* Value of pi/2 times TRIG_SCALE. */
- X#define L_PI_4 25736L /* Value of pi/4 times TRIG_SCALE. */
- X
- X#define CIRCLE_SIZE 205887L /* Value of pi * 2 * TRIG_SCALE. */
- X
- X#define TABLESLICE 804L /* (L_PI_2 / PTS_PER_QUADRANT) */
- X
- X#define XINDEX 0 /* For specifying array indices. */
- X#define YINDEX 1
- X
- X/* The following two arrays are tables of values for cos and sin */
- X/* for one quadrant of a circle, divided into PTS_PER_QUADRANT slices. */
- X
- Xlong cos_table[PTS_PER_QUADRANT] = {
- X 32758L, 32729L, 32679L, 32610L, 32522L, 32413L, 32286L, 32138L,
- X 31972L, 31786L, 31581L, 31357L, 31114L, 30853L, 30572L, 30274L,
- X 29957L, 29622L, 29269L, 28899L, 28511L, 28106L, 27684L, 27246L,
- X 26791L, 26320L, 25833L, 25330L, 24812L, 24279L, 23732L, 23170L,
- X 22595L, 22006L, 21403L, 20788L, 20160L, 19520L, 18868L, 18205L,
- X 17531L, 16846L, 16151L, 15447L, 14733L, 14010L, 13279L, 12540L,
- X 11793L, 11039L, 10279L, 9512L, 8740L, 7962L, 7180L, 6393L,
- X 5602L, 4808L, 4011L, 3212L, 2411L, 1608L, 804L, 0L
- X};
- X
- Xlong sin_table[PTS_PER_QUADRANT] = {
- X 804L, 1608L, 2411L, 3212L, 4011L, 4808L, 5602L, 6393L,
- X 7180L, 7962L, 8740L, 9512L, 10279L, 11039L, 11793L, 12540L,
- X 13279L, 14010L, 14733L, 15447L, 16151L, 16846L, 17531L, 18205L,
- X 18868L, 19520L, 20160L, 20788L, 21403L, 22006L, 22595L, 23170L,
- X 23732L, 24279L, 24812L, 25330L, 25833L, 26320L, 26791L, 27246L,
- X 27684L, 28106L, 28511L, 28899L, 29269L, 29622L, 29957L, 30274L,
- X 30572L, 30853L, 31114L, 31357L, 31581L, 31786L, 31972L, 32138L,
- X 32286L, 32413L, 32522L, 32610L, 32679L, 32729L, 32758L, 32768L
- X};
- X
- X/* Estimate sin by interpolation. Return long integer value. */
- X
- Xlong longsin(theta)
- Xfloat theta;
- X{
- X long longtheta;
- X int quadrant;
- X long value1, value2;
- X long value;
- X long intpart;
- X long fractionpart;
- X
- X /* We have a floating point value for theta. Put theta */
- X /* into a long integer for the rest of the processing. */
- X /* Keep everything scaled by a factor of TRIG_SCALE. */
- X
- X longtheta = (long)(theta * F_TRIG_SCALE);
- X
- X /* Make angle positive. */
- X
- X while (longtheta < 0) longtheta += CIRCLE_SIZE;
- X
- X /* Figure quadrant while making it less than PI/2. */
- X
- X quadrant = 1;
- X
- X while (longtheta > L_PI_2) {
- X longtheta -= L_PI_2;
- X quadrant++;
- X if (quadrant > 4) quadrant = 1;
- X }
- X
- X /* If Quadrant 2 or 4 we need to use the reverse of the */
- X /* interpolation table. */
- X
- X if (quadrant == 2 || quadrant == 4) longtheta = L_PI_2 - longtheta;
- X
- X /* Express angle in terms of number of table increments. */
- X
- X intpart = longtheta / TABLESLICE;
- X
- X fractionpart = longtheta % TABLESLICE;
- X
- X /* This looks like a kludge, but it isn't. When TABLESLICE is */
- X /* set to TABLESLICE, we have the smallest error in the result. */
- X /* This just rounds back down when we overshoot the table. */
- X
- X if (intpart >= PTS_PER_QUADRANT) {
- X intpart = PTS_PER_QUADRANT - 1;
- X fractionpart = TABLESLICE;
- X }
- X
- X /* Interpolate. */
- X
- X if (intpart <= 0) {
- X value1 = 0;
- X value2 = sin_table[0];
- X }
- X else {
- X value2 = sin_table[(int)(intpart--)];
- X value1 = sin_table[(int)intpart];
- X }
- X
- X value = value1 + (fractionpart * (value2 - value1)) / TABLESLICE;
- X
- X /* If Quadrant 3 or 4 the result should be negative. */
- X
- X if (quadrant == 3 || quadrant == 4) return(-value);
- X else return(value);
- X}
- X
- X
- X/* Estimate cos by interpolation. Return long integer value. */
- X
- Xlong longcos(theta)
- Xfloat theta;
- X{
- X long longtheta;
- X int quadrant;
- X long value1, value2;
- X long value;
- X long intpart;
- X long fractionpart;
- X
- X /* We have a floating point value for theta. Put theta */
- X /* into a long integer for the rest of the processing. */
- X /* Keep everything scaled by a factor of TRIG_SCALE. */
- X
- X longtheta = (long)(theta * F_TRIG_SCALE);
- X
- X /* Make angle positive. */
- X
- X while (longtheta < 0) longtheta += CIRCLE_SIZE;
- X
- X /* Figure quadrant while making it less than PI/2. */
- X
- X quadrant = 1;
- X
- X while (longtheta > L_PI_2) {
- X longtheta -= L_PI_2;
- X quadrant++;
- X if (quadrant > 4) quadrant = 1;
- X }
- X
- X /* If Quadrant 2 or 4 we need to use the reverse of the */
- X /* interpolation table. */
- X
- X if (quadrant == 2 || quadrant == 4) longtheta = L_PI_2 - longtheta;
- X
- X /* Express angle in terms of number of table increments. */
- X
- X intpart = longtheta / TABLESLICE;
- X
- X fractionpart = longtheta % TABLESLICE;
- X
- X /* This looks like a kludge, but it isn't. When TABLESLICE is */
- X /* set to TABLESLICE, we have the smallest error in the result. */
- X /* This just rounds back down when we overshoot the table. */
- X
- X if (intpart >= PTS_PER_QUADRANT) {
- X intpart = PTS_PER_QUADRANT - 1;
- X fractionpart = TABLESLICE;
- X }
- X
- X /* Interpolate. */
- X
- X if (intpart <= 0) {
- X value1 = 32768L;
- X value2 = cos_table[0];
- X }
- X else {
- X value2 = cos_table[(int)(intpart--)];
- X value1 = cos_table[(int)intpart];
- X }
- X
- X value = value1 + (fractionpart * (value2 - value1)) / TABLESLICE;
- X
- X /* If Quadrant 2 or 3 the result should be negative. */
- X
- X if (quadrant == 2 || quadrant == 3) return(-value);
- X else return(value);
- X}
- X
- X/* Test program:
- Xmain() {
- X float theta;
- X
- Xfloat sinval;
- Xfloat lsinval;
- Xfloat cosval;
- Xfloat lcosval;
- X
- X for (theta = -8.3; theta < 100.0; theta += 0.1) {
- X
- X sinval = sin((double)theta);
- X lsinval = longsin(theta) / F_TRIG_SCALE;
- X cosval = cos((double)theta);
- X lcosval = longcos(theta) / F_TRIG_SCALE;
- X
- X printf("SIN: angle %g %lg %g err %g\n",theta,sinval,
- X lsinval,sinval-lsinval);
- X printf("COS: angle %g %lg %g err %g\n",theta,cosval,
- X lcosval,cosval-lcosval);
- X }
- X}
- X*/
- X
- XxX--EOF--XxX
-
-
-