/****************************************************************************/ /* Program: Graph It II (The C Program) */ /* SubModule: func.c 1-7-87 */ /* CopyRight By Flynn D. Fishman January 1987 */ /* Feel Free to copy and alter this source */ /****************************************************************************/ /* This function includes all of the math related subroutines to solve all the graph related problems */ #include "graph.h" static char *(functions[]) = {"xx", "tt", "yy", "zz", "((", "))", "++", "--", "//", "^^", "==", "**", "ccos", "ssin", "Ttan", "eexp", "PPI", "EE", "aatan", "Sasin", "Cacos", "lln", "Aabs", "Ll", "end"}; double Solve(formula) struct Formula_Master *formula; { extern double x, y, z, t; double lop, a, b, total; char func; a = 0; b = 0; total = Value(formula); while (formula->equation[formula->position] != '0' ) { func = formula->equation[formula->position++]; if (func == 0) break; switch (func) { case '+': total = total + Value(formula); break; case '-': total = total - Value(formula); break; case '*': total = total * Value(formula); break; case '/': a = Value(formula); if (a != 0) total = total / a; else total = INFINITY; break; case '^': total = pow(total, Value(formula) ); break; case '=': total = (total == Value(formula) ); break; case '\)': return(total); break; default: formula->error = INVALID; return(0); } /* end of case */ } /* end of while */ return (total); } /* end of Solve */ double Value(formula) struct Formula_Master *formula; { extern double x, y, z, t; int whichfunc, position; double a,b; char test, bitmask, tmp, lowmask, highbit; position = formula->position; test = formula->equation[formula->position]; if (test == '\(') { formula->position++; return(Solve(formula)); } tmp = (test & HIGHBIT); if (tmp != 0) { return ( formula->constants[ LOWMASK & formula->equation[formula->position++] ] ); } formula->position++; switch (test) { case '\(': /* ( */ return(Solve(formula)); break; case 'x': /* X */ return(x); break; case 'y': /* Y */ return(y); break; case 't': /* T */ return(t); break; case 'z': /* Z */ return(z); break; case 'c': /* Cos */ return (cos ( Value (formula) ) ); break; case 's': /* Sin */ return (sin ( Value (formula) ) ); break; case 'T': /* Tan */ return (tan ( Value (formula) ) ); break; case 'e': /* E to the x */ return ( exp ( Value(formula) ) ); break; case 'P': /* PI */ return ( PI ); break; case 'E': /* E to the x */ return ( exp (1.0) ); break; case 'l': /* ln */ return ( log ( Value(formula) ) ); break; case 'a': /* Atan */ return ( atan ( Value(formula) ) ); break; case 'S': /* Asin */ return ( asin ( Value(formula) ) ); break; case 'C': /* Acos */ return ( acos ( Value(formula) ) ); break; case 'A': /* abs */ return ( abs ( Value(formula) ) ); break; default: formula->error = UNKNOWN; return(0); } /* end of switch */ } /* end of routine */ GetFunction(infile, formula) FILE *infile; struct Formula_Master *formula; { char text[50], inchar; double a; int position, lasttype, function, constants, whichfunc; position = 0; function = 0; constants = 0; while ( (inchar = getc(infile) ) == ' '); lasttype = Type(inchar); for ever { if ((lasttype == Type(inchar)) && (inchar != ' ')) { text[position++] = inchar; } else { text[position] = 0; if (lasttype == ALPHA) { for (whichfunc = 0; strcmp(text, &functions[whichfunc][1]) ; whichfunc++) { if (!strcmp( functions[whichfunc], "end") ) { return(FALSE); } } formula->equation[function++] = functions[whichfunc][0]; } if (lasttype == NUMERIC) { formula->equation[function++] = (HIGHBIT | constants); sscanf(text, "%f", &a ); formula->constants[constants++] = a; } if (lasttype == OTHER) { position = 0; while (text[position] !=0) { formula->equation[function++] = text[position++]; } } if (inchar == ' ') while ( (inchar = getc(infile) ) == ' '); position = 0; text[position++] = inchar; lasttype = Type(inchar); } /* end of else */ if (lasttype == END) break; inchar = getc(infile); } /* end of forever */ formula->equation[function] = 0; if (function == 0) { FreeFunction(formula); return(FALSE); } return(TRUE); } /* end of routine */ Type(character) char character; { if(character >= 'a' && character <= 'z') return (ALPHA); if(character >= 'A' && character <= 'Z') return (ALPHA); if(character >= '0' && character <= '9') return (NUMERIC); if(character == '.') return (NUMERIC); if(character == ';' || character == '\n' || character == '\r' || character == EOF) return(END); return(OTHER); } SetDefaults(parameters) struct Graph_Parameters *parameters; { parameters->end = FALSE; parameters->xstart = -5.0; parameters->ystart = -5.0; parameters->zstart = -5.0; parameters->tstart = -5.0; parameters->xend = 5.0; parameters->yend = 5.0; parameters->zend = 5.0; parameters->tend = 5.0; parameters->xlabels = 1.0; parameters->ylabels = 1.0; parameters->zlabels = 1.0; parameters->detail = 1.0; } GetVariables(Window, parameters, infile) struct Window *Window; struct Graph_Parameters *parameters; FILE *infile; { char inchar, variable, command; double number; long int minx, miny, maxx, maxy; minx = Window->BorderLeft; miny = Window->BorderTop; maxx = Window->Width - Window->BorderRight - XBORDER; maxy = Window->Height - Window->BorderBottom - YBORDER; for ever { DrawRectangle(Window, 1l, minx, miny, maxx, miny+110); DisplayVariables(Window, parameters); variable = getc(infile); if (variable == '\r' || variable == '\n' || variable == 'e') break; if (variable != 'd' || variable != 'h' ) command = getc(infile); if (command == '=' || variable == 'h') command = '1'; else while ( (inchar = getc(infile) ) != '=' ); if (command < '0' || command > '9') { number = GetNum(infile); if (number != 0.0) { if(variable== 'd') parameters->detail = number; if(variable== 'h') parameters->hidden = (parameters->hidden) ? FALSE : TRUE; if(variable== 'x' && command== 's')parameters->xstart = number; if(variable== 'x' && command== 'e')parameters->xend = number; if(variable== 'x' && command== 'l')parameters->xlabels =number; if(variable== 'y' && command== 's')parameters->ystart = number; if(variable== 'y' && command== 'e')parameters->yend = number; if(variable== 'y' && command== 'l')parameters->ylabels =number; if(variable== 'z' && command== 's')parameters->zstart = number; if(variable== 'z' && command== 'e')parameters->zend = number; if(variable== 'z' && command== 'l')parameters->zlabels =number; if(variable== 't' && command== 's')parameters->tstart = number; if(variable== 't' && command== 'e')parameters->tend = number; } /* end of 0.0 else */ } /* end of if not equation */ else /* Its a formula */ { if (variable == 'x') { if (!parameters->xon) parameters->x1 = AllocateFunction(); if (parameters->x1 != NULL) { if (!GetFunction(infile, parameters->x1)) { parameters->xon = FALSE; error(Window, FALSE); } else { parameters->xon = TRUE; parameters->x1->position=0; parameters->x1->error = FALSE; Solve(parameters->x1); if (parameters->x1->error != FALSE) error(Window, parameters->x1->error); } } } /* end of x = */ if (variable == 'y') { if (!parameters->yon) parameters->y1 = AllocateFunction(); if (parameters->y1 != NULL) { if (!GetFunction(infile, parameters->y1)) { parameters->yon = FALSE; error(Window, FALSE); } else { parameters->yon = TRUE; parameters->y1->position=0; parameters->y1->error = FALSE; Solve(parameters->y1); if (parameters->y1->error != FALSE) error(Window, parameters->y1->error); } } } /* end of y = */ if (variable == 'z') { if (!parameters->zon) parameters->z1 = AllocateFunction(); if (parameters->z1 != NULL) { if (!GetFunction(infile, parameters->z1)) { parameters->zon = FALSE; error(Window, FALSE); } else { parameters->zon = TRUE; parameters->z1->position=0; parameters->z1->error = FALSE; Solve(parameters->z1); if (parameters->z1->error != FALSE) error(Window, parameters->z1->error); } } } /* end of z = */ } /* end of else */ } /* end of for ever */ } /* end of command */ error(Window, error) struct Window *Window; int error; { long int minx, miny, maxx, maxy; minx = Window->BorderLeft; miny = Window->BorderTop; maxx = Window->Width - Window->BorderRight - XBORDER; maxy = Window->Height - Window->BorderBottom - YBORDER; DrawRectangle(Window, 3l, minx, miny+10, maxx, miny+115); SetAPen(Window->RPort, 1l); if (error == INVALID) Print(Window, "Invalid Function was entered", 13l); else if (error == UNKNOWN) Print(Window, "An unknown Function was entered", 13l); else if (error == FALSE) Print(Window, "An unknown Function was entered", 13l); } double GetNum(infile) FILE *infile; { char inchar, text[20]; int position; double a; position = 0; inchar = getc(infile); while (Type(inchar) != END) { text[position++] = inchar; inchar = getc(infile); } text[position] = 0; sscanf(text, "%f", &a ); return(a); } char *AllocateFunction() { struct Formula_Master *formula; formula = AllocMem( (long) sizeof(struct Formula_Master), 0); if (formula == NULL) return(0); formula->equation = AllocMem(sizeof(char) * FSIZE , 0); if (formula->equation == NULL) return(0); formula->constants = AllocMem(sizeof(double) * CONSTANTS , 0); if (formula->constants == NULL) return(0); return(formula); } FreeFunction(formula) struct Formula_Master *formula; { FreeMem(formula->equation, sizeof(char) * FSIZE); FreeMem(formula->constants, sizeof(double) * CONSTANTS); FreeMem(formula, sizeof (struct Formula_Master) ); } GetCommand(Window, parameters) struct Window *Window; struct Graph_Parameters *parameters; { FILE *infile; char list[80]; infile = fopen("con:0/140/640/36/Enter Command", "r"); if (infile == NULL) { parameters->error = WINDOW; return(0); } GetVariables(Window, parameters, infile); fclose(infile); } LoadFile(Window, parameters) struct Window *Window; struct Graph_Parameters *parameters; { FILE *infile; char line[80], file[40]; GetFileName(line); infile = fopen(line, "r"); if (infile == NULL) return(); GetVariables(Window, parameters, infile); fclose(infile); } SaveFile(Window, parameters) struct Window *Window; struct Graph_Parameters *parameters; { FILE *outfile; char line[80], file[40]; GetFileName(line); outfile = fopen(line, "w"); if (outfile == NULL) return(); fprintf(outfile, "xstart=%f\n", parameters->xstart); fprintf(outfile, "ystart=%f\n", parameters->ystart); fprintf(outfile, "zstart=%f\n", parameters->zstart); fprintf(outfile, "tstart=%f\n", parameters->tstart); fprintf(outfile, "xend=%f\n", parameters->xend); fprintf(outfile, "yend=%f\n", parameters->yend); fprintf(outfile, "zend=%f\n", parameters->zend); fprintf(outfile, "tend=%f\n", parameters->tend); fprintf(outfile, "xlabels=%f\n", parameters->xlabels); fprintf(outfile, "ylabels=%f\n", parameters->ylabels); fprintf(outfile, "zlabels=%f\n", parameters->zlabels); fprintf(outfile, "detail=%f\n", parameters->detail); if(parameters->xon) { Expand(parameters->x1, line); fprintf(outfile, "x1=%s\n", line); } if(parameters->yon) { Expand(parameters->y1, line); fprintf(outfile, "y1=%s\n", line); } if(parameters->zon) { Expand(parameters->z1, line); fprintf(outfile, "z1=%s\n", line); } fprintf(outfile,"e\n"); fclose(outfile); } GetFileName(line) char line[]; { FILE *infile; char inchar; int position; infile = fopen("con:0/140/640/24/Please Enter Filename:", "r"); if (infile == NULL) return(0); position = 0; inchar = getc(infile); while ( Type(inchar) != END) { line[position++] = inchar; inchar = getc(infile); } line[position] = 0; fclose(infile); } DisplayVariables(Window, parameters) struct Window *Window; struct Graph_Parameters *parameters; { char line[80], tmp[80]; SetAPen(Window->RPort, 3l); SetBPen(Window->RPort, 0l); SetDrMd(Window->RPort, JAM2); Print(Window, "Current Variable Settings", 0); sprintf(line, " start end labels other "); Print(Window, line, 1); sprintf(line,"x:%4.6f %4.6f %4.6f",parameters->xstart, parameters->xend, parameters->xlabels); Print(Window, line, 2); sprintf(line, "y:%4.6f %4.6f %4.6f", parameters->ystart, parameters->yend, parameters->ylabels); Print(Window, line, 3); sprintf(line, "z:%4.6f %4.6f %4.6f", parameters->zstart, parameters->zend, parameters->zlabels); Print(Window, line, 4); sprintf(line, "t:%4.6f %4.6f N/A", parameters->tstart, parameters->tend); Print(Window, line, 5); sprintf(line, "Detail is %4.6f", parameters->detail); Print(Window, line, 6); if(parameters->hidden) Print(Window, "Hidden lines is ON ", 7); else Print(Window, "Hidden lines is OFF", 7); if (parameters->xon) { Expand(parameters->x1, line); sprintf(tmp, "x="); strcat (tmp, line); strcat (tmp, " "); Print(Window, tmp, 9); } if (parameters->yon) { Expand(parameters->y1, line); sprintf(tmp, "y="); strcat (tmp, line); strcat (tmp, " "); Print(Window, tmp, 10); } if (parameters->zon) { Expand(parameters->z1, line); sprintf(tmp, "z="); strcat (tmp, line); strcat (tmp, " "); Print(Window, tmp, 11); } } Expand(formula, line) struct Formula_Master *formula; char line[]; { int loop, position; char tmp[30]; line[0]=0; for (position = 0; position < strlen(formula->equation); position++) { if ((formula->equation[position] & HIGHBIT) != 0) { sprintf(tmp, "%f", formula->constants[LOWMASK & formula->equation[position]]); strcat(line, tmp); } else { loop = 0; /* is this wrong ? */ while (strcmp(functions[loop], "end") ) { if (functions[loop][0] == formula->equation[position]) strcat(line, &functions[loop][1]); loop++; } /* end of while */ } /* end of else */ } /* end of for */ } /* end of the routine */