home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / IRIT / DRAWFN3S.ZIP / GETFUNC.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-05-06  |  11.4 KB  |  322 lines

  1. /*****************************************************************************
  2. *  Routines to get new function    to draw    from file or user (keyboard).        *
  3. *                                         *
  4. * Written by:  Gershon Elber                   Ver 0.1,    Apr. 1988    *
  5. *****************************************************************************/
  6.  
  7. #include <stdio.h>
  8. #include <graphics.h>
  9. #include <string.h>
  10. #include <math.h>
  11. #include <ctype.h>
  12. #include <dir.h>
  13. #include <dos.h>
  14. #include "GraphGnG.h"
  15. #include "Expr2TrG.h"
  16. #include "GenMat.h"
  17. #include "Dir-Graf.h"
  18. #include "Program.h"
  19.  
  20. #define     READ_COLOR    CYAN             /* Color from requesting input. */
  21.  
  22. static int GetFunction(ExprNode *PFunc[3], char SFunc[3][LINE_LEN_LONG],
  23.     double *UMin, double *UMax, double *VMin, double *VMax,
  24.     int *NumOfIsoLines, int *NumOfSamples, MatrixType TransMat,
  25.     char FileName[]);
  26. static ExprNode *GetOneFunction(FILE *f, int ReadStdin,
  27.     char Header[], char DefaultFunc[], char SFunc[]);
  28.  
  29. /*****************************************************************************
  30. *   Main routine of the    GetFunc    module - set the Menu and call the         *
  31. * requested routines.                                 *
  32. * Returns some statistics on the data -    domain of surface function and         *
  33. * transformation matrix. if function is    loaded from file then type extention *
  34. * '.fun is looked for the surface itself, and '.mat' for the transformation  *
  35. * matrix to start with.    The '.fun' file    must exists, but if the    '.mat' is    *
  36. * not found, a default view is selected    (isometric view). On user input,     *
  37. * only the function is required    (same as '.fun'    file) and default (isometric)*
  38. * view is allways selected to start with.                     *
  39. *  Returns the 3 functions (X, Y, Z) of (u, v) as binary trees (PFunc) and   *
  40. * as strings in infix form (SFunc), (u, v) domain and Transformation mat     *
  41. * TransMat.                                     *
  42. *****************************************************************************/
  43. void DoGetFunc(ExprNode *PFunc[3], char SFunc[3][LINE_LEN_LONG],
  44.     int *InputExists,
  45.     double *UMin, double *UMax, double *VMin, double *VMax,
  46.     int *NumOfIsoLines, int *NumOfSamples,
  47.     struct IsoLine *IsoLinesU[MAX_ISO_LINES],
  48.     struct IsoLine *IsoLinesV[MAX_ISO_LINES], MatrixType TransMat)
  49. {
  50.     static struct MenuItem GetFuncMenu[] = {          /* Load Data Menu. */
  51.     YELLOW,    "Get Function",
  52.     MAGENTA, "Stdin -> F(u, v)",
  53.     MAGENTA, "File -> F(u, v)",
  54.     MAGENTA, "",
  55.     MAGENTA, "List Files",
  56.     MAGENTA, "Change Dir",
  57.     MAGENTA, "",
  58.     CYAN,    "Help",
  59.     BLUE,    "Exit"
  60.     };
  61.     int    i, OldSamples, OldIsoLines;
  62.     char FileName[LINE_LEN];
  63.  
  64.     GGMenuDraw(8, GetFuncMenu, TRUE);                   /* Draw Menu. */
  65.     while (TRUE) {
  66.     switch (GGMenuPick()) {
  67.         case 1:              /* Get function: F(u, v) from user */
  68.         OldSamples = (*NumOfSamples);  /* So that we can see if they */
  69.         OldIsoLines = (*NumOfIsoLines);/* where changed by DoGetFunc.*/
  70.  
  71.         if (GetFunction(PFunc, SFunc, UMin, UMax, VMin, VMax,
  72.             NumOfIsoLines, NumOfSamples, TransMat, "")) {
  73.             for    (i=0; i<3; i++)    PrintTree(PFunc[i], SFunc[i]);
  74.             if ((OldIsoLines != (*NumOfIsoLines)) ||
  75.             (OldSamples != (*NumOfSamples)))  /* See SetParam.c. */
  76.             UpdateDataStruct(OldSamples, OldIsoLines,
  77.                 NumOfSamples, NumOfIsoLines,
  78.                 IsoLinesU, IsoLinesV);
  79.             RedrawScreen(PFunc, SFunc, *UMin, *UMax, *VMin, *VMax,
  80.             TransMat, *NumOfSamples, *NumOfIsoLines,
  81.             IsoLinesU, IsoLinesV);
  82.             *InputExists = TRUE;
  83.         }
  84.         else *InputExists = FALSE;
  85.         break;
  86.         case 2:             /* Get function: F(u, v) from file. */
  87.         FileName[0] = 0;
  88.         GetLine(stdin, TRUE, "Enter File Name:", FileName);
  89.         if (strlen(FileName) ==    0) break;
  90.  
  91.         OldSamples = (*NumOfSamples);  /* So that we can see if they */
  92.         OldIsoLines = (*NumOfIsoLines);/* where changed by DoGetFunc.*/
  93.  
  94.         if (GetFunction(PFunc, SFunc, UMin, UMax, VMin, VMax,
  95.             NumOfIsoLines , NumOfSamples, TransMat, FileName)) {
  96.             for    (i=0; i<3; i++)    PrintTree(PFunc[i], SFunc[i]);
  97.             if ((OldIsoLines != (*NumOfIsoLines)) ||
  98.             (OldSamples != (*NumOfSamples)))  /* See SetParam.c. */
  99.             UpdateDataStruct(OldSamples, OldIsoLines,
  100.                 NumOfSamples, NumOfIsoLines,
  101.                 IsoLinesU, IsoLinesV);
  102.             RedrawScreen(PFunc, SFunc, *UMin, *UMax, *VMin, *VMax,
  103.             TransMat, *NumOfSamples, *NumOfIsoLines,
  104.             IsoLinesU, IsoLinesV);
  105.             *InputExists = TRUE;
  106.         }
  107.         else *InputExists = FALSE;
  108.         break;
  109.         case 4:             /* Print current directory content. */
  110.         PrintDir(FILES_TO_DIR);
  111.         GGMenuDraw(8, GetFuncMenu, TRUE);           /* Draw Menu. */
  112.         break;
  113.         case 5:                /* Change current directory. */
  114.         ChangeDir();
  115.         break;
  116.         case 7:                            /* Help. */
  117.         GGPrintHelpMenu("DrawFn3D.hlp", "GETFUNCTION");
  118.         GGMenuDraw(8, GetFuncMenu, TRUE);           /* Draw Menu. */
  119.         break;
  120.         case 8:                            /* Exit. */
  121.         return;
  122.     }
  123.     }
  124. }
  125.  
  126. /*****************************************************************************
  127. * Routine to get X(u, v), Y(u, v), Z(u, v) functions,  and (u, v) domain.    *
  128. * Return TRUE if successfull.                             *
  129. *****************************************************************************/
  130. static int GetFunction(ExprNode *PFunc[3], char SFunc[3][LINE_LEN_LONG],
  131.     double *UMin, double *UMax, double *VMin, double *VMax,
  132.     int *NumOfIsoLines, int *NumOfSamples, MatrixType TransMat,
  133.     char FileName[])
  134. {
  135.     int    i, j, ReadStdin = TRUE;
  136.     char s[LINE_LEN], FileNameFunc[LINE_LEN], FileNameMat[LINE_LEN], *Pchar;
  137.     FILE *f;
  138.  
  139.     /* Prepare the input file - stdin or real file (if FileName is given). */
  140.     if (strlen(FileName) == 0) f = stdin;
  141.     else {
  142.     if ((Pchar = strchr(FileName, '.')) != (char *) NULL)
  143.         *Pchar = NULL;         /* Make sure no file type is given. */
  144.     strcpy(FileNameFunc, FileName);
  145.     strcpy(FileNameMat, FileName);
  146.     strcat(FileNameFunc, ".fun");
  147.     strcat(FileNameMat, ".mat");
  148.     if ((f = fopen(FileNameFunc, "rt")) == (FILE *) NULL) {
  149.         GGPutErrorMsg("File not found");
  150.         return FALSE;
  151.     }
  152.     ReadStdin = FALSE;
  153.     }
  154.  
  155.     if (ReadStdin) {
  156.     GGMySetColor(READ_COLOR);
  157.     GGPutMsgXY("Enter Function:", MSG_AREA_X, MSG_AREA_Y + 0.4);
  158.     }
  159.     else {
  160.     /* Test if first char of first line is a '#'. If so its a comment    */
  161.     /* line, so delete it.                             */
  162.     char c;
  163.  
  164.     if ((c = fgetc(f)) == '#') fgets(SFunc[0], LINE_LEN_LONG-1, f);
  165.     else ungetc(c, f);
  166.     }
  167.  
  168.     if ((PFunc[0] = GetOneFunction(f, ReadStdin, "X(u, v) =", "u", SFunc[0]))
  169.     == (ExprNode *) NULL) return FALSE;
  170.     if ((PFunc[1] = GetOneFunction(f, ReadStdin, "Y(u, v) =", "v", SFunc[1]))
  171.     == (ExprNode *) NULL) return FALSE;
  172.     if ((PFunc[2] = GetOneFunction(f, ReadStdin, "Z(u, v) =", "", SFunc[2]))
  173.     == (ExprNode *) NULL) return FALSE;
  174.  
  175.     if (ReadStdin) {
  176.     GGMySetColor(READ_COLOR);
  177.     GGPutMsgXY("Set U interval:", MSG_AREA_X, MSG_AREA_Y + 0.3);
  178.     }
  179.     sprintf(s, "%lf", *UMin);
  180.     do if (!GetLine(f, ReadStdin, "U minimum :", s)) return FALSE;
  181.     while (sscanf(s, "%lf", UMin) != 1);
  182.     sprintf(s, "%lf", *UMax);
  183.     do if (!GetLine(f, ReadStdin, "U maximum :", s)) return FALSE;
  184.     while ((sscanf(s, "%lf", UMax) != 1) || (*UMax <= *UMin));
  185.     if (ReadStdin) {
  186.     GGMySetColor(BLACK);
  187.     GGPutMsgXY("Set U interval:", MSG_AREA_X, MSG_AREA_Y + 0.3);
  188.  
  189.     GGMySetColor(READ_COLOR);
  190.     GGPutMsgXY("Set V interval:", MSG_AREA_X, MSG_AREA_Y + 0.3);
  191.     }
  192.     sprintf(s, "%lf", *VMin);
  193.     do if (!GetLine(f, ReadStdin, "V minimum :", s)) return FALSE;
  194.     while (sscanf(s, "%lf", VMin) != 1);
  195.     sprintf(s, "%lf", *VMax);
  196.     do if (!GetLine(f, ReadStdin, "V maximum :", s)) return FALSE;
  197.     while ((sscanf(s, "%lf", VMax) != 1) || (*VMax <= *VMin));
  198.     if (ReadStdin) {
  199.     GGMySetColor(BLACK);
  200.     GGPutMsgXY("Set V interval:", MSG_AREA_X, MSG_AREA_Y + 0.3);
  201.  
  202.     GGMySetColor(BLACK);
  203.     GGPutMsgXY("Enter Function:", MSG_AREA_X, MSG_AREA_Y + 0.4);
  204.     }
  205.  
  206.     if (!ReadStdin) {
  207.     if (fscanf(f, "%d %d", &i, &j) == 2) {  /* Try read num. of isolines */
  208.         *NumOfIsoLines = i;            /* and number of samples as    last */
  209.         *NumOfSamples = j;            /* file parameters.             */
  210.     }
  211.     fclose(f);
  212.     }
  213.  
  214.     GenIsometricView(TransMat);
  215.  
  216.     if ((!ReadStdin) &&     ((f = fopen(FileNameMat, "rt")) != (FILE *) NULL)) {
  217.     /* Read    the matrix from    the given file: */
  218.     for (i=0; i<4; i++) for    (j=0; j<4; j++)
  219.         fscanf(f, "%lf", &TransMat[i][j]);
  220.     fclose(f);
  221.     }
  222.     return TRUE;
  223. }
  224.  
  225. /*****************************************************************************
  226. * Routine to get one function of (u, v) :                     *
  227. *****************************************************************************/
  228. static ExprNode *GetOneFunction(FILE *f, int ReadStdin,
  229.     char Header[], char DefaultFunc[], char SFunc[])
  230. {
  231.     int    i;
  232.     char *Pchar;
  233.     ExprNode *p;
  234.  
  235.     ParserError();            /* Clear binary tree parser error flags. */
  236.     do {
  237.     /* Get function    name - from file f. */
  238.     if (SFunc[0] == 0) strcpy(SFunc, DefaultFunc);  /* If default given. */
  239.     if (!GetLine(f, ReadStdin, Header, SFunc)) return NULL;
  240.     if (SFunc[0] == 0) strcpy(SFunc, DefaultFunc);  /* If default given. */
  241.     for (i=strlen(SFunc); i<LINE_LEN_LONG; i++) SFunc[i] = 0;
  242.  
  243.     if ((p = Expr2Tree(SFunc)) == NULL) {/*Convert expr into binary tree.*/
  244.         /* Error in    expression - print error message. */
  245.         GGMySetColor(YELLOW);
  246.         GGPutMsgXY(SFunc, MSG_AREA_X, MSG_AREA_Y + 0.2);
  247.         switch(ParserError()) {
  248.          case P_ERR_WrongSyntax:
  249.              GGPutErrorMsg("Wrong syntax");
  250.              break;
  251.          case P_ERR_ParamExpect:
  252.              GGPutErrorMsg("Param. expected");
  253.              break;
  254.          case P_ERR_OneOperand:
  255.              GGPutErrorMsg("One Operand Method!");
  256.              break;
  257.          case P_ERR_TwoOperand:
  258.              GGPutErrorMsg("Two Operands Method!");
  259.              break;
  260.          case P_ERR_StackOV:
  261.              GGPutErrorMsg("Internal Stack O.F.");
  262.              break;
  263.          case P_ERR_ParaMatch:
  264.              GGPutErrorMsg("Mismatch paranth.");
  265.              break;
  266.          case P_ERR_UndefToken:
  267.              GGPutErrorMsg("Undef. func, used");
  268.              break;
  269.         }
  270.         GGMySetColor(BLACK);
  271.         GGPutMsgXY(SFunc, MSG_AREA_X, MSG_AREA_Y + 0.2);
  272.     }
  273.     else for (i=PARAMETER_A; i<=PARAMETER_Z; i++)/* Check if other param.*/
  274.        if ((i != PARAMETER_U) && (i != PARAMETER_V)
  275.            && (ParamInTree(p, i))) {          /* exists in tree. */
  276.            FreeTree(p);
  277.            p = NULL;
  278.            Pchar = "  - Invalid Parameter";
  279.            Pchar[0]    = 'A' +    i;      /* Set the wrong parameter number. */
  280.            GGPutErrorMsg(Pchar);
  281.            break;                  /* Print this error only once! */
  282.        }
  283.     }
  284.     while (!p);
  285.  
  286.     return p;
  287. }
  288.  
  289. /*****************************************************************************
  290. * Routine to read one line from    file f at bottom of screen:             *
  291. * Note that if ReadStdin is false then nothing is printed on screen...         *
  292. * Return TRUE on successfull reading.                         *
  293. *****************************************************************************/
  294. int GetLine(FILE *f, int ReadStdin, char *Header, char *s)
  295. {
  296.     int    Succeed;
  297.     char *fgets();
  298.  
  299.     if (ReadStdin) {
  300.     GGMySetColor(READ_COLOR);
  301.     GGPutMsgXY(Header, MSG_AREA_X, MSG_AREA_Y + 0.2);
  302.     }
  303.  
  304.     if (ReadStdin) {
  305.     GGGetGraphicLine(MSG_AREA_X, MSG_AREA_Y, s, READ_COLOR);
  306.     Succeed    = TRUE;
  307.     }
  308.     else {
  309.     /* Note    the following is not %100 safe as we might call    GetLine    */
  310.     /* with    string of LINE_LEN characters only!            */
  311.     Succeed    = (fgets(s, LINE_LEN_LONG, f) != (char *) NULL);
  312.     if (Succeed) s[strlen(s)-1] = 0;       /* Clear off the /n char. */
  313.     }
  314.  
  315.     if (ReadStdin) {
  316.     GGMySetColor(BLACK);
  317.     GGPutMsgXY(Header, MSG_AREA_X, MSG_AREA_Y + 0.2);
  318.     }
  319.  
  320.     return Succeed;
  321. }
  322.