[comp.sys.amiga] Graph It.c 1 of 2

fdfishman@watcgl.UUCP (Flynn D. Fishman) (01/21/87)

Well after many years of thinking about this program and making
limited versions of it in BASIC on any machine I have touched I am
happy to announce that I finally wrote (or started to) it.

But enough of my babbling what follows is a program to plot most
simple functions (i.e. no conics yet) in 2 or 3 dimensions (as well as
2d parametric equations in term of t)  The program has a fairly good
help so I won't go in much detail here, but be forwarned that this
program is not 100% finished (say 90% and I do not know if or when I
will do the last 10% since it works fine for what I need) As a result
it might crash, although is doesn't for me I am sure that some smart
fellow out there will make it crash.

So with out further ado the program
(Note I did this program using Manxe 3.30 and I hope it works on all
 other compilers but who knows)

Please send any comments, debugs or letters of appreciation to me
as I am very interested in hearing what everyone thinks of one of my
first major C projects.

      FDFISHMAN (Flynn D. Fishman) @ WATCGL

UUCP  :	...!{decvax|ihnp4|clyde|allegra|utzoo}!watmath!watcgl!fdfishman   
ARPA  :	fdfishman%watcgl%waterloo.csnet@csnet-relay.arpa 
CSNET :	fdfishman%watcgl@waterloo.csnet
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
This Cutsie saying space left intentionally left blank until such a time as
   1) The above mentioned user can think of a cutsie saying
   2) The above mentioned user with the aid of some friends can think of a 
      cutsie saying.
or 3) Sufficient time has passed such that plagerism of someone else's cutsie
      saying would not be noticed by many.
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

# This is a shell archive.  Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
#
# Wrapped by watcgl!fdfishman on Tue Jan 20 23:23:49 EST 1987
# Contents:  makefile graph.h help.c
 
echo x - makefile
sed 's/^@//' > "makefile" <<'@//E*O*F makefile//'
graph: window.o func.o main.o three-d.o help.o
	ln -o graph window.o func.o three-d.o help.o main.o -lm32 -lc32

window.o: window.c
	cc -s +l window.c

func.o: func.c
	cc -s +l func.c

three-d.o: three-d.c
	cc -s +l three-d.c

main.o: main.c
	cc -s +l main.c

help.o: help.c
	cc -s +l -z7000 help.c
@//E*O*F makefile//
chmod u=rw,g=rw,o=r makefile
 
echo x - graph.h
sed 's/^@//' > "graph.h" <<'@//E*O*F graph.h//'
/****************************************************************************/
/*   Program: Graph It II	(The C Program)									*/
/*   SubModule:	graph.h  1-20-87											*/
/*   CopyRight By Flynn D. Fishman  January 1987							*/
/*	Feel Free to copy and alter this source									*/
/****************************************************************************/
/* This is the include file for graph it.  It includes all the needed 
	constants																*/

#include <stdio.h>
#include <math.h>
#include <functions.h>
#include <exec/types.h>

#include <exec/exec.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <graphics/gfx.h>
#include <graphics/gfxmacros.h>
#include <graphics/regions.h>
#include <graphics/copper.h>
#include <graphics/gels.h>
#include <graphics/gfxbase.h>
#include <graphics/text.h>
#include <devices/keymap.h>
#include <hardware/blit.h>

/* this is close enough	*/
#define INFINITY   932768;

/* number of elements to allocate for formula */
#define PARAMETERS 90
#define FSIZE      50
#define CONSTANTS  50

/* types of characters	*/
#define ALPHA 		1
#define NUMERIC 	2
#define OTHER		3
#define END         4	/* i.e. \r, \n or a semicolon	*/

#define BITMASK     0xff 
#define HIGHBIT	    0x80	
#define LOWMASK     0x7f

/* types of formula errors	*/
#define UNKNOWN	2
#define INVALID	3
#define WINDOW	4

#define ever (;;)

struct Formula_Master 
	{
	char	*equation;
	double	*constants;
	int		 position;
	int		 error;
	};

struct Graph_Parameters
	{
	struct Formula_Master   *x1;
	struct Formula_Master	*y1;
	struct Formula_Master	*z1;
	int						yon;
	int						xon;
	int						zon;
	int						end;
	int						hidden;
	double					xstart;
	double					ystart;
	double					zstart;
	double					tstart;
	double					xend;
	double					yend;
	double					zend;
	double					tend;
	double					xlabels;
	double					ylabels;
	double					zlabels;
	double					detail;
	int						error;
	};

double x, y, t, z;
double Value(), Solve(), GetNum();
char *AllocateFunction();

#define INTUITION_REV 1l
#define GRAPHICS_REV  1l

#define XSIZE       640l
#define YSIZE       200l

#define min(x,y)	(x<y)?x:y
#define max(x,y)	(x<y)?y:x
#define abs(x)		(x<0)?-x:x

/* Icon placement constants */
#define XBORDER		28	/* pixels on right side of graph area	*/
#define YBORDER     16	/* pixels below graoh area				*/
#define XEXPANDX	56  /* Number of pixels for xstart = 		*/
#define XEXPANDY	8	/* The hieght of the xexpand area		*/
#define YEXPANDX	9	/* the width of the yexpand area		*/
#define YEXPANDY	17	/* pixels for ystart = 					*/
#define ICONX		16	/* The width of the icon				*/
#define ICONY		15	/* The hieght of the command icons		*/
#define BALLHEIGHT  5
#define BALLWIDTH	6

/* modes for graph	*/
#define ZOOM	1
#define MOVE	2
#define TOTALAREA 4.0

/* Help menu stuff	*/
#define		FORWARD		1
#define		BACKWARD	2
#define		QUIT		3

#define		FIRSTPAGE	1
#define		LASTPAGE	5
@//E*O*F graph.h//
chmod u=rw,g=rw,o=r graph.h
 
echo x - help.c
sed 's/^@//' > "help.c" <<'@//E*O*F help.c//'
/****************************************************************************/
/*   Program: Graph It II	(The C Program)									*/
/*   SubModule:	help.c  1-20-87												*/
/*   CopyRight By Flynn D. Fishman  January 1987							*/
/*	Feel Free to copy and alter this source									*/
/****************************************************************************/
/* This module contains the title page and help text as well as the
	subroutines for the help screen											*/

#include "graph.h"

static char *(HelpPages[]) =
{
"0",
"Graph It  II   The sequal In 3D",
"By Flynn D. Fishman Copyright January 1987",
" ",
"Feel free to copy this program and give it anyone you wish.",
"As long as you do not make any money on the transaction",
"Or remove this notice and my name",
" ",
"Use the ? icon for more help or the Y= icon to enter a function",
"Although load and save do not work you can also use pull down menus",
" ",
"     Please send any comments (Debugs) to:",
"        Flynn D. Fishman",
"        32 WoodBrook Court S.W. Calgary",
"        Alberta, Canada, T2W-4G1",
"   or   UseNet (UUCP):ihnp4!watmath!watcgl!fdfishman",
" ",
"Although the code is no longer recognizable as his",
"I would like to thank Richard M. Ross, Jr. for writing",
"Free Draw from which I took some Intuition code.",
"1",
"Page 1                         Introduction",
" ",
"Graph It allows you to enter almost any function",
"and see it plotted (In 2 or 3 dimensions)",
"functions are entered using the command line and",
"several paramters can be changed with the mouse",
" ",
"A couple of notes",
" 1. This program is not 100% finished yet so some of",
"    the functionality of the program may seem rough.",
" 2. Although the math parser is quite powerful it does",
"    not know about order of operations, but it does",
"    know about brakets.",
" 3. Note that 3d move and zoom are based on a 2d screen",
" 4. There are currently no error messages if you make",
"    a mistake in entering a formula or command",
"2Icon",
"Page 2                         Icons",
" ",
"The icons on the far right of the screen are as follows:",
"    ZOOM:Allows you to capture part of the graph by" ,
"      clicking, draging and then releasing the left button",
"    MOVE:Allows you to move the graph in the same method",
"      as with zoom but note the constraining boxes",
"    COMMAND:Allows you to enter the desired function or",
"      alter other variables (more later)",
"    HIDDEN SURFACE:The icon toggles between removing",
"      covered surfaces (3d Graph only)",
"    HOME:Returns the graph to 0,0 and places all the" ,
"      variables in the default setting",
"    QUIT:Exit the program",
" ",
"    HELP:Gives you these pages",
"3",
"Page 3                         Functions",
" ",
"To enter a function just click on the command icon and then",
"enter your function i.e. y=sin(x), z=x-y or x=t, y=sin(t) ",
"after entering your function you can enter another command",
"or enter a blank line to exit command mode.  Note if you enter",
"an invalid command you will not be able to exit command mode",
"until you enter a valid command.",
" ",
"Notes",
" 1. If you enter a function for z or x you are automatically",
"    placed in 3d mode or parametric mode respectively.",
" 2. To erase a function simply type z= this will put you",
"    back into 2d mode (or y= is also acceptable)",
" ",
"Current allowable functions include:",
"  cos, sin, tan, exp, PI, E, atan, asin, acos, ln",
"  + - * / ^",
"4",
"Page 4                         Other Commands",
" ",
"Other Commands include:",
"xstart=  to set the origional x value.",
"xend=     to set the last x value.",
"xlabels= to set the label values on the x-axis.",
"              (Not Implemented Yet)",
" ",
"ystart=  to set the origional y value.",
"yend=     to set the last y value.",
"ylabels= to set the label values on the y-axis.",
"              (Not Implemented Yet)",
" ",
"detail=  the number of pixels per calculated function",
    	" for example detail=1 calculates a y-value",
    	" for each pixel.",
"for example:",
"    xstart=-5,    ystart=5,     detail=5,     yl=1",
"5",
"Page 5                         Other Icons"    ,
" ",
"x-expand: (Bottom Slider) used to increase the area",
"  covered by the x area.",
" ",
"y-expand: (Right Slider) used to increase the area",
"  covered by the y area.",
" ",
"Window-Sizer:(Bottom Left) standard window resize" ,
"  gadget",
" ",
"Close Gadget:(Top Right) standard window close gadget",
" ",
"Window in front and behind",
"6",
};

Help(Window, parameters)
struct Window *Window;
struct Graph_Parameters *parameters;
    {
	int page, KeepGoing, status;

	KeepGoing = TRUE;
	page = FIRSTPAGE;

	while (KeepGoing)
		{
		PrintPage(Window, page);
		status = GetPush(Window);
		if (status == FORWARD) page++;
		if (page > LASTPAGE) page = FIRSTPAGE;
		if (status == BACKWARD) page--;
		if (page < FIRSTPAGE) page = LASTPAGE;
		if (status == QUIT) KeepGoing = FALSE;
		}

    DrawWindow(Window, parameters);
    PlotGraph(Window, parameters);
    }

PrintPage(Window, page)
struct Window *Window;
int page;
	{
	int current_line, first_line, row;
	int minx, miny, maxx, maxy;
	char line[5];

	if (page > LASTPAGE) return(FALSE);

    minx = Window->BorderLeft;
    miny = Window->BorderTop;
    maxx = Window->Width - Window->BorderRight - XBORDER;
    maxy = Window->Height - Window->BorderBottom - YBORDER;

	DrawRectangle(Window, 2l, minx, miny, maxx, maxy);

	sprintf(line, "%ld", page);

	current_line = 0;
	while(line[0] != HelpPages[current_line++][0] );

	sprintf(line, "%ld", ++page);

	row = 0;
	first_line = current_line - 1;
	while(line[0] != HelpPages[current_line][0] )
		Print(Window, HelpPages[current_line++], row++);
	if (HelpPages[first_line][1] == 'I')
		DrawImages(Window, minx+12, miny+(ICONY+2) + 10);
	}

struct TextAttr myfont =
	{
	"topaz.font",
	8, 0, 0
	};

struct IntuiText textout =
	{
	1, 0,		/* Pen Colours				*/
	JAM2,		/* Drawing mode 			*/
	0, 0,		/* Position offsets			*/
	&myfont,	/* Font						*/
	NULL,		/* Text (To insert later)	*/
	NULL		/* next string				*/
	};

Print(Window, text, line)
struct Window *Window;
char text[];
long int line;
    {
    long int minx, miny, maxx, maxy;
    long y;

    minx = Window->BorderLeft;
    miny = Window->BorderTop;
    maxx = Window->Width - Window->BorderRight - XBORDER;
    maxy = Window->Height - Window->BorderBottom - YBORDER;

	y = miny + 2 + line * (ICONY + 2) / 2;
	if ( y > maxy) y = maxy;

	textout.IText = text;
	PrintIText(Window->RPort, &textout, minx +5, y);
    }

GetPush(Window)
struct Window *Window;
    {
    struct IntuiMessage *NewMessage;    /* msg structure for GetMsg() */
    ULONG class;                        /* used in message monitor loop */
    USHORT code;    	                 /* used in message monitor loop */
    long int x, y;
    int no_button;

    long int minx, miny, maxx, maxy;

    minx = Window->BorderLeft;
    miny = Window->BorderTop;
    maxx = Window->Width - Window->BorderRight - XBORDER;
    maxy = Window->Height - Window->BorderBottom - YBORDER;

    PrintHelpIcons(Window);

    while( NewMessage=(struct IntuiMessage *)GetMsg(Window->UserPort) )
    no_button = TRUE;

    while (no_button)
    	{
    	Wait( 1 << Window->UserPort->mp_SigBit);
    	while( NewMessage=(struct IntuiMessage *)GetMsg(Window->UserPort) )
    	    {
    	    class = NewMessage->Class;
    	    ReplyMsg( NewMessage );
    	    if (class == MOUSEBUTTONS)
    	    	{
    	    	x = Window->MouseX;
    	    	y = Window->MouseY;
    	    	if (y > maxy - 10)
    	    	    {
    	    	    if ( x < maxx / 3) return (FORWARD);
    	    	    if ( x > maxx / 3 * 2) return (BACKWARD);
    	    	    else return (QUIT);
    	    	    }
    	    	}
    	    }  /* end of message lists */

    	}      /* end of nobuttons */
    }    	 /* end of routines  */

PrintHelpIcons(Window)
struct Window *Window;
    {
    long int minx, miny, maxx, maxy, x, y;

    minx = Window->BorderLeft;
    miny = Window->BorderTop;
    maxx = Window->Width - Window->BorderRight - XBORDER;
    maxy = Window->Height - Window->BorderBottom - YBORDER;

    SetDrMd(Window->RPort, JAM2);

    y = maxy - 2;
    x = minx + 6;
	SetAPen(Window->RPort, 3l);
    SetBPen(Window->RPort, 3l);
    Move(Window->RPort, x, y);
    Text(Window->RPort, " Next Page ", 11l);
    SetAPen(Window->RPort, 1l);
    SetBPen(Window->RPort, 2l);
    Move(Window->RPort, x-1, y-1);
    Text(Window->RPort, " Next Page ", 11l);

    y = maxy - 2;
    x = minx + 6 + maxx / 3;
	SetAPen(Window->RPort, 3l);
	SetBPen(Window->RPort, 3l);
	Move(Window->RPort, x, y);
	Text(Window->RPort, " Go To Graph ", 13l);
    SetAPen(Window->RPort, 1l);
	SetBPen(Window->RPort, 2l);
	Move(Window->RPort, x-1, y-1);
	Text(Window->RPort, " Go To Graph ", 13l);

	y = maxy - 2;
	x = minx + 6 + maxx / 3 * 2;
	SetAPen(Window->RPort, 3l);
	SetBPen(Window->RPort, 3l);
	Move(Window->RPort, x, y);
	Text(Window->RPort, " Previous Page ", 15l);
    SetAPen(Window->RPort, 1l);
	SetBPen(Window->RPort, 2l);
	Move(Window->RPort, x-1, y-1);
	Text(Window->RPort, " Previous Page ", 15l);
	}
@//E*O*F help.c//
chmod u=rw,g=rw,o=r help.c
 
exit 0