home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************
- * Routines to get new function to draw from file or user (keyboard). *
- * *
- * Written by: Gershon Elber Ver 0.1, Apr. 1988 *
- *****************************************************************************/
-
- #include <stdio.h>
- #include <graphics.h>
- #include <string.h>
- #include <math.h>
- #include <ctype.h>
- #include <dir.h>
- #include <dos.h>
- #include "GraphGnG.h"
- #include "Expr2TrG.h"
- #include "GenMat.h"
- #include "Dir-Graf.h"
- #include "Program.h"
-
- #define READ_COLOR CYAN /* Color from requesting input. */
-
- static int GetFunction(ExprNode *PFunc[3], char SFunc[3][LINE_LEN_LONG],
- double *UMin, double *UMax, double *VMin, double *VMax,
- int *NumOfIsoLines, int *NumOfSamples, MatrixType TransMat,
- char FileName[]);
- static ExprNode *GetOneFunction(FILE *f, int ReadStdin,
- char Header[], char DefaultFunc[], char SFunc[]);
-
- /*****************************************************************************
- * Main routine of the GetFunc module - set the Menu and call the *
- * requested routines. *
- * Returns some statistics on the data - domain of surface function and *
- * transformation matrix. if function is loaded from file then type extention *
- * '.fun is looked for the surface itself, and '.mat' for the transformation *
- * matrix to start with. The '.fun' file must exists, but if the '.mat' is *
- * not found, a default view is selected (isometric view). On user input, *
- * only the function is required (same as '.fun' file) and default (isometric)*
- * view is allways selected to start with. *
- * Returns the 3 functions (X, Y, Z) of (u, v) as binary trees (PFunc) and *
- * as strings in infix form (SFunc), (u, v) domain and Transformation mat *
- * TransMat. *
- *****************************************************************************/
- void DoGetFunc(ExprNode *PFunc[3], char SFunc[3][LINE_LEN_LONG],
- int *InputExists,
- double *UMin, double *UMax, double *VMin, double *VMax,
- int *NumOfIsoLines, int *NumOfSamples,
- struct IsoLine *IsoLinesU[MAX_ISO_LINES],
- struct IsoLine *IsoLinesV[MAX_ISO_LINES], MatrixType TransMat)
- {
- static struct MenuItem GetFuncMenu[] = { /* Load Data Menu. */
- YELLOW, "Get Function",
- MAGENTA, "Stdin -> F(u, v)",
- MAGENTA, "File -> F(u, v)",
- MAGENTA, "",
- MAGENTA, "List Files",
- MAGENTA, "Change Dir",
- MAGENTA, "",
- CYAN, "Help",
- BLUE, "Exit"
- };
- int i, OldSamples, OldIsoLines;
- char FileName[LINE_LEN];
-
- GGMenuDraw(8, GetFuncMenu, TRUE); /* Draw Menu. */
- while (TRUE) {
- switch (GGMenuPick()) {
- case 1: /* Get function: F(u, v) from user */
- OldSamples = (*NumOfSamples); /* So that we can see if they */
- OldIsoLines = (*NumOfIsoLines);/* where changed by DoGetFunc.*/
-
- if (GetFunction(PFunc, SFunc, UMin, UMax, VMin, VMax,
- NumOfIsoLines, NumOfSamples, TransMat, "")) {
- for (i=0; i<3; i++) PrintTree(PFunc[i], SFunc[i]);
- if ((OldIsoLines != (*NumOfIsoLines)) ||
- (OldSamples != (*NumOfSamples))) /* See SetParam.c. */
- UpdateDataStruct(OldSamples, OldIsoLines,
- NumOfSamples, NumOfIsoLines,
- IsoLinesU, IsoLinesV);
- RedrawScreen(PFunc, SFunc, *UMin, *UMax, *VMin, *VMax,
- TransMat, *NumOfSamples, *NumOfIsoLines,
- IsoLinesU, IsoLinesV);
- *InputExists = TRUE;
- }
- else *InputExists = FALSE;
- break;
- case 2: /* Get function: F(u, v) from file. */
- FileName[0] = 0;
- GetLine(stdin, TRUE, "Enter File Name:", FileName);
- if (strlen(FileName) == 0) break;
-
- OldSamples = (*NumOfSamples); /* So that we can see if they */
- OldIsoLines = (*NumOfIsoLines);/* where changed by DoGetFunc.*/
-
- if (GetFunction(PFunc, SFunc, UMin, UMax, VMin, VMax,
- NumOfIsoLines , NumOfSamples, TransMat, FileName)) {
- for (i=0; i<3; i++) PrintTree(PFunc[i], SFunc[i]);
- if ((OldIsoLines != (*NumOfIsoLines)) ||
- (OldSamples != (*NumOfSamples))) /* See SetParam.c. */
- UpdateDataStruct(OldSamples, OldIsoLines,
- NumOfSamples, NumOfIsoLines,
- IsoLinesU, IsoLinesV);
- RedrawScreen(PFunc, SFunc, *UMin, *UMax, *VMin, *VMax,
- TransMat, *NumOfSamples, *NumOfIsoLines,
- IsoLinesU, IsoLinesV);
- *InputExists = TRUE;
- }
- else *InputExists = FALSE;
- break;
- case 4: /* Print current directory content. */
- PrintDir(FILES_TO_DIR);
- GGMenuDraw(8, GetFuncMenu, TRUE); /* Draw Menu. */
- break;
- case 5: /* Change current directory. */
- ChangeDir();
- break;
- case 7: /* Help. */
- GGPrintHelpMenu("DrawFn3D.hlp", "GETFUNCTION");
- GGMenuDraw(8, GetFuncMenu, TRUE); /* Draw Menu. */
- break;
- case 8: /* Exit. */
- return;
- }
- }
- }
-
- /*****************************************************************************
- * Routine to get X(u, v), Y(u, v), Z(u, v) functions, and (u, v) domain. *
- * Return TRUE if successfull. *
- *****************************************************************************/
- static int GetFunction(ExprNode *PFunc[3], char SFunc[3][LINE_LEN_LONG],
- double *UMin, double *UMax, double *VMin, double *VMax,
- int *NumOfIsoLines, int *NumOfSamples, MatrixType TransMat,
- char FileName[])
- {
- int i, j, ReadStdin = TRUE;
- char s[LINE_LEN], FileNameFunc[LINE_LEN], FileNameMat[LINE_LEN], *Pchar;
- FILE *f;
-
- /* Prepare the input file - stdin or real file (if FileName is given). */
- if (strlen(FileName) == 0) f = stdin;
- else {
- if ((Pchar = strchr(FileName, '.')) != (char *) NULL)
- *Pchar = NULL; /* Make sure no file type is given. */
- strcpy(FileNameFunc, FileName);
- strcpy(FileNameMat, FileName);
- strcat(FileNameFunc, ".fun");
- strcat(FileNameMat, ".mat");
- if ((f = fopen(FileNameFunc, "rt")) == (FILE *) NULL) {
- GGPutErrorMsg("File not found");
- return FALSE;
- }
- ReadStdin = FALSE;
- }
-
- if (ReadStdin) {
- GGMySetColor(READ_COLOR);
- GGPutMsgXY("Enter Function:", MSG_AREA_X, MSG_AREA_Y + 0.4);
- }
- else {
- /* Test if first char of first line is a '#'. If so its a comment */
- /* line, so delete it. */
- char c;
-
- if ((c = fgetc(f)) == '#') fgets(SFunc[0], LINE_LEN_LONG-1, f);
- else ungetc(c, f);
- }
-
- if ((PFunc[0] = GetOneFunction(f, ReadStdin, "X(u, v) =", "u", SFunc[0]))
- == (ExprNode *) NULL) return FALSE;
- if ((PFunc[1] = GetOneFunction(f, ReadStdin, "Y(u, v) =", "v", SFunc[1]))
- == (ExprNode *) NULL) return FALSE;
- if ((PFunc[2] = GetOneFunction(f, ReadStdin, "Z(u, v) =", "", SFunc[2]))
- == (ExprNode *) NULL) return FALSE;
-
- if (ReadStdin) {
- GGMySetColor(READ_COLOR);
- GGPutMsgXY("Set U interval:", MSG_AREA_X, MSG_AREA_Y + 0.3);
- }
- sprintf(s, "%lf", *UMin);
- do if (!GetLine(f, ReadStdin, "U minimum :", s)) return FALSE;
- while (sscanf(s, "%lf", UMin) != 1);
- sprintf(s, "%lf", *UMax);
- do if (!GetLine(f, ReadStdin, "U maximum :", s)) return FALSE;
- while ((sscanf(s, "%lf", UMax) != 1) || (*UMax <= *UMin));
- if (ReadStdin) {
- GGMySetColor(BLACK);
- GGPutMsgXY("Set U interval:", MSG_AREA_X, MSG_AREA_Y + 0.3);
-
- GGMySetColor(READ_COLOR);
- GGPutMsgXY("Set V interval:", MSG_AREA_X, MSG_AREA_Y + 0.3);
- }
- sprintf(s, "%lf", *VMin);
- do if (!GetLine(f, ReadStdin, "V minimum :", s)) return FALSE;
- while (sscanf(s, "%lf", VMin) != 1);
- sprintf(s, "%lf", *VMax);
- do if (!GetLine(f, ReadStdin, "V maximum :", s)) return FALSE;
- while ((sscanf(s, "%lf", VMax) != 1) || (*VMax <= *VMin));
- if (ReadStdin) {
- GGMySetColor(BLACK);
- GGPutMsgXY("Set V interval:", MSG_AREA_X, MSG_AREA_Y + 0.3);
-
- GGMySetColor(BLACK);
- GGPutMsgXY("Enter Function:", MSG_AREA_X, MSG_AREA_Y + 0.4);
- }
-
- if (!ReadStdin) {
- if (fscanf(f, "%d %d", &i, &j) == 2) { /* Try read num. of isolines */
- *NumOfIsoLines = i; /* and number of samples as last */
- *NumOfSamples = j; /* file parameters. */
- }
- fclose(f);
- }
-
- GenIsometricView(TransMat);
-
- if ((!ReadStdin) && ((f = fopen(FileNameMat, "rt")) != (FILE *) NULL)) {
- /* Read the matrix from the given file: */
- for (i=0; i<4; i++) for (j=0; j<4; j++)
- fscanf(f, "%lf", &TransMat[i][j]);
- fclose(f);
- }
- return TRUE;
- }
-
- /*****************************************************************************
- * Routine to get one function of (u, v) : *
- *****************************************************************************/
- static ExprNode *GetOneFunction(FILE *f, int ReadStdin,
- char Header[], char DefaultFunc[], char SFunc[])
- {
- int i;
- char *Pchar;
- ExprNode *p;
-
- ParserError(); /* Clear binary tree parser error flags. */
- do {
- /* Get function name - from file f. */
- if (SFunc[0] == 0) strcpy(SFunc, DefaultFunc); /* If default given. */
- if (!GetLine(f, ReadStdin, Header, SFunc)) return NULL;
- if (SFunc[0] == 0) strcpy(SFunc, DefaultFunc); /* If default given. */
- for (i=strlen(SFunc); i<LINE_LEN_LONG; i++) SFunc[i] = 0;
-
- if ((p = Expr2Tree(SFunc)) == NULL) {/*Convert expr into binary tree.*/
- /* Error in expression - print error message. */
- GGMySetColor(YELLOW);
- GGPutMsgXY(SFunc, MSG_AREA_X, MSG_AREA_Y + 0.2);
- switch(ParserError()) {
- case P_ERR_WrongSyntax:
- GGPutErrorMsg("Wrong syntax");
- break;
- case P_ERR_ParamExpect:
- GGPutErrorMsg("Param. expected");
- break;
- case P_ERR_OneOperand:
- GGPutErrorMsg("One Operand Method!");
- break;
- case P_ERR_TwoOperand:
- GGPutErrorMsg("Two Operands Method!");
- break;
- case P_ERR_StackOV:
- GGPutErrorMsg("Internal Stack O.F.");
- break;
- case P_ERR_ParaMatch:
- GGPutErrorMsg("Mismatch paranth.");
- break;
- case P_ERR_UndefToken:
- GGPutErrorMsg("Undef. func, used");
- break;
- }
- GGMySetColor(BLACK);
- GGPutMsgXY(SFunc, MSG_AREA_X, MSG_AREA_Y + 0.2);
- }
- else for (i=PARAMETER_A; i<=PARAMETER_Z; i++)/* Check if other param.*/
- if ((i != PARAMETER_U) && (i != PARAMETER_V)
- && (ParamInTree(p, i))) { /* exists in tree. */
- FreeTree(p);
- p = NULL;
- Pchar = " - Invalid Parameter";
- Pchar[0] = 'A' + i; /* Set the wrong parameter number. */
- GGPutErrorMsg(Pchar);
- break; /* Print this error only once! */
- }
- }
- while (!p);
-
- return p;
- }
-
- /*****************************************************************************
- * Routine to read one line from file f at bottom of screen: *
- * Note that if ReadStdin is false then nothing is printed on screen... *
- * Return TRUE on successfull reading. *
- *****************************************************************************/
- int GetLine(FILE *f, int ReadStdin, char *Header, char *s)
- {
- int Succeed;
- char *fgets();
-
- if (ReadStdin) {
- GGMySetColor(READ_COLOR);
- GGPutMsgXY(Header, MSG_AREA_X, MSG_AREA_Y + 0.2);
- }
-
- if (ReadStdin) {
- GGGetGraphicLine(MSG_AREA_X, MSG_AREA_Y, s, READ_COLOR);
- Succeed = TRUE;
- }
- else {
- /* Note the following is not %100 safe as we might call GetLine */
- /* with string of LINE_LEN characters only! */
- Succeed = (fgets(s, LINE_LEN_LONG, f) != (char *) NULL);
- if (Succeed) s[strlen(s)-1] = 0; /* Clear off the /n char. */
- }
-
- if (ReadStdin) {
- GGMySetColor(BLACK);
- GGPutMsgXY(Header, MSG_AREA_X, MSG_AREA_Y + 0.2);
- }
-
- return Succeed;
- }