home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / PLOT / PLOT3D_A.ZIP / PLOT3D.C < prev    next >
Encoding:
C/C++ Source or Header  |  1991-02-24  |  11.8 KB  |  427 lines

  1. /*
  2.  
  3. Plot3d -- plot3d.c, the main program
  4.  
  5. By Adrian Mariano -- adrian@milton.u.washington.edu
  6.  
  7.  
  8. Copyright (c) 1991 by Adrian Mariano
  9.  
  10. You may use and distribute this program as much as you like so long as you do 
  11. not charge for this service.  I am not liable for failure of this program to 
  12. perform in any way.  
  13.  
  14. */
  15.  
  16. #include "plot3d.h"
  17. #include <string.h>
  18.  
  19. extern unsigned _stklen = 32000;/* stack space to make qsort happy */
  20.  
  21. /* status variables */
  22. char stop;
  23.  
  24.  
  25. void terminate(void)
  26. {
  27.    backtotext();
  28.    exit(0);
  29. }
  30.  
  31.  
  32. term fstack[maxffs + 1][100];  /* function stack for ff evaluation */
  33.  
  34.  
  35. typedef struct {
  36.    float v1start, v1end, v2start, v2end;
  37.    char *name;
  38. }  bound;
  39.  
  40. bound *currentbound;
  41.  
  42.  
  43. /* Functions to be passed to plot3d() for different plot types */
  44.  
  45. void sphererho(float *x, float *y, float *z, float rho, float phi, float theta);
  46. void spherephi(float *x, float *y, float *z, float phi, float rho, float theta);
  47. void spheretheta(float *x, float *y, float *z, float theta, float phi, float rho);
  48. void cartz(float *x, float *y, float *z, float zval, float xval, float yval);
  49. void cartx(float *x, float *y, float *z, float xval, float yval, float zval);
  50. void carty(float *x, float *y, float *z, float yval, float xval, float zval);
  51. void cylinderz(float *x, float *y, float *z, float zval, float rval, float theta);
  52. void cylinderr(float *x, float *y, float *z, float rval, float theta, float zval);
  53. void cylindertheta(float *x, float *y, float *z, float theta, float rval, float zval);
  54. void parametric(float *x, float *y, float *z, float dummy, float u, float v);
  55.  
  56. bound sphererho_bound =   {0, M_PI, 0, PI2, "sphererho"};
  57. bound spherephi_bound =   {0, 3, 0, PI2, "spherephi"};
  58. bound spheretheta_bound = {0, M_PI, 0, 3, "spheretheta"};
  59.  
  60. bound cartz_bound = {-3, 3, -3, 3, "cartz"};
  61. bound cartx_bound = {-3, 3, -3, 3, "cartx"};
  62. bound carty_bound = {-3, 3, -3, 3, "carty"};
  63.  
  64. bound cylinderz_bound = {0, 3, 0, PI2, "cylinderz"};
  65. bound cylinderr_bound = {0, PI2, -3, 3, "cylinderr"};
  66. bound cylindertheta_bound = {0, 3, -3, 3, "cylindertheta"};
  67.  
  68. char *xstr = "x";
  69. char *ystr = "y";
  70. char *zstr = "z";
  71. char *thetastr = "theta";
  72. char *rhostr = "rho";
  73. char *phistr = "phi";
  74. char *rstr = "r";
  75.  
  76. char *var1str;
  77. char *var2str;
  78.  
  79.  
  80. void (*plottype) (float *, float *, float *, float, float, float);
  81.  
  82.  
  83. struct {
  84.    char *st, *en;
  85. }  replaces[] = {
  86.     {"sinh", "sh"}, {"cosh", "ch"}, {"tanh", "th"},{"sin", "s"},
  87.     {"cos", "c"}, {"arc", "A"}, {"ln", "n"}, {"log", "l"},{"abs","a"}
  88. };
  89.  
  90.  
  91.  
  92. void setbounds(bound * newbound)
  93. {
  94.    var1start = newbound->v1start;
  95.    var2start = newbound->v2start;
  96.    var1end = newbound->v1end;
  97.    var2end = newbound->v2end;
  98.    currentbound = newbound;
  99. }
  100.  
  101. void substitute(char *str, char *start, char *end)
  102. {
  103.    while (str = strstr(str, start)) {
  104.       strnset(str, ' ', strlen(start));
  105.       strncpy(str, end, strlen(end));
  106.    }
  107. }
  108.  
  109.  
  110.  
  111. void fixfun(char *fun)
  112. {
  113.    int i;
  114.    substitute(fun, var1str, "X");
  115.    substitute(fun, var2str, "Y");
  116.    substitute(fun, "X", "x");
  117.    substitute(fun, "Y", "y");
  118.  
  119.    for (i = 0; i < sizeof(replaces) / (2 * sizeof(char *)); i++)
  120.       substitute(fun, replaces[i].st, replaces[i].en);
  121. }
  122.  
  123.  
  124. void doreplot()
  125. {
  126.    if (plot3d(plottype)) {
  127.       getch();
  128.       backtotext();
  129.    }
  130. }
  131.  
  132.  
  133. void doplot(char *params)
  134. {
  135.    char *errmesg;
  136.    int where;
  137.    fixfun(params);
  138.    if ((where = convert(params, &errmesg, 0)) == -1) {
  139.       simplify(0);
  140.       if (plot3d(plottype)) {;
  141.          getch();
  142.          backtotext();
  143.       }
  144.    } else {
  145.       while (where--)
  146.          putchar(' ');
  147.       printf("       ^\n%s\n", errmesg);
  148.    }
  149. }
  150.  
  151.  
  152. float getval(char *expr, float def)
  153. {
  154.    int where;
  155.    char *errmesg;
  156.    if ((where = convert(expr, &errmesg, maxffs)) == -1)
  157.       return ff(def, def, maxffs);
  158.    else {
  159.       while (where--)
  160.          putchar(' ');
  161.       printf("       ^\n%s\n", errmesg);
  162.       return def;
  163.    }
  164. }
  165.  
  166.  
  167. void dotype(char *newtype)
  168. {
  169.    if (!strcmp(newtype, "cartx")) {
  170.       plottype = cartx;
  171.       setbounds(&cartx_bound);
  172.  
  173.       var1str = ystr;
  174.       var2str = zstr;
  175.    } else if (!strcmp(newtype, "carty")) {
  176.       plottype = carty;
  177.       setbounds(&carty_bound);
  178.       var1str = xstr;
  179.       var2str = zstr;
  180.    } else if (!strcmp(newtype, "cartz")) {
  181.       plottype = cartz;
  182.       setbounds(&cartz_bound);
  183.       var1str = xstr;
  184.       var2str = ystr;
  185.    } else if (!strcmp(newtype, "sphererho")) {
  186.       plottype = sphererho;
  187.       setbounds(&sphererho_bound);
  188.       var1str = phistr;
  189.       var2str = thetastr;
  190.    } else if (!strcmp(newtype, "spherephi")) {
  191.       plottype = spherephi;
  192.       setbounds(&spherephi_bound);
  193.       var1str = rhostr;
  194.       var2str = thetastr;
  195.    } else if (!strcmp(newtype, "spheretheta")) {
  196.       plottype = spheretheta;
  197.       setbounds(&spheretheta_bound);
  198.       var1str = phistr;
  199.       var2str = rhostr;
  200.    } else if (!strcmp(newtype, "cylinderz")) {
  201.       plottype = cylinderz;
  202.       setbounds(&cylinderz_bound);
  203.       var1str = rstr;
  204.       var2str = thetastr;
  205.    } else if (!strcmp(newtype, "cylinderr")) {
  206.       plottype = cylinderr;
  207.       setbounds(&cylinderr_bound);
  208.       var1str = thetastr;
  209.       var2str = zstr;
  210.    } else if (!strcmp(newtype, "cylindertheta")) {
  211.       plottype = cylindertheta;
  212.       setbounds(&cylindertheta_bound);
  213.       var1str = rstr;
  214.       var2str = zstr;
  215.    } else
  216.       printf("Unknown coordinate system: %s\n\n", newtype);
  217. }
  218.  
  219.  
  220. void doshow()
  221. {
  222.    printf("Coordinate system: %s\n",currentbound->name);
  223.    printf("%s range: [%.17g,%.17g]\n%s range: [%.17g,%.17g]\n",
  224.          var1str, var1start, var1end, var2str, var2start, var2end);
  225.    printf("X: [%.17g,%.17g]\nY: [%.17g,%.17g]\nZ: [%.17g,%.17g]\n",
  226.          xmin, xmax, ymin, ymax, zmin, zmax);
  227.    printf("%s steps: %d\t%s steps: %d\n", var1str,
  228.          (int) var1stepcount, var2str, (int) var2stepcount);
  229.    printf("Aspect: %.17g\tDistance: %.17g\n", aspect, distance);
  230.    printf("Spin: %.17g \tTip: %.17g\n", spin, tip);
  231. }
  232.  
  233. void dohelp()
  234. {
  235.    printf(
  236.    "Commands:\n\n"
  237.    "plot <function> -- function is in terms of the current coordinate system\n"
  238.    "replot -- plot the same function again.\n"
  239.    "type <cartz|cartx|carty|sphererho|spheretheta|spherephi|cylinderz|\n"
  240.    "      cylindertheta|cylinderr> -- Selects coordinate system for plotting\n"
  241.    "      where the variable name specified (sphereRHO) is the dependent variable\n"
  242.    "show -- displays current plotting parameters\n"
  243.    "xmin, xmax, ymin, ymax, zmin, zmax <value> -- set region to display on screen\n"
  244.    "%sstart, %send, %sstart, %send, %ssteps, %ssteps <value> --\n"
  245.    "      Set the range for the independent variables, and the number of steps at\n"
  246.    "      which to sample the function\n"
  247.    "aspect <value> -- set aspect ratio of screen\n"
  248.    "distance <value> -- set perspect distance, 0 for no perspective\n"
  249.    "spin, tip <value> -- set view angle in degrees\n\n"
  250.    "Functions supported:\n"
  251.    "   [arc]sin, [arc]cos, [arc]tan, [arc]sinh, [arc]cosh, [arc]tanh\n"
  252.    "   ln, log, abs\n",var1str,var1str,var2str,var2str,var1str,var2str);
  253. }
  254.  
  255.  
  256. #define IS(XX) (!strcmp(command,XX))
  257.  
  258.  
  259. void main()
  260. {
  261.    char input[100], command[100], params[100];
  262.    char xcount[15], ycount[15], xstart[15], xend[15], ystart[15], yend[15];
  263.    initgraphics();
  264.    plottype = cartz;
  265.    setbounds(&cartz_bound);
  266.    var1str = xstr;
  267.    var2str = ystr;
  268.    printf("                  -- Plot3d Version 1.0 by Adrian Mariano --\n"
  269.           "                          -- Type 'help' for help --\n");
  270.    do {
  271.       printf("> ");
  272.       gets(input);
  273.       *command = *params = 0;
  274.       sscanf(input, "%s %[^\n\r]", command, params);
  275.       /* printf("'%s' '%s'\n",command,params);         */
  276.       strcpy(xcount, var1str);
  277.       strcat(xcount, "steps");
  278.       strcpy(ycount, var2str);
  279.       strcat(ycount, "steps");
  280.       strcpy(xstart, var1str);
  281.       strcat(xstart, "start");
  282.       strcpy(ystart, var2str);
  283.       strcat(ystart, "start");
  284.       strcpy(xend, var1str);
  285.       strcat(xend, "end");
  286.       strcpy(yend, var2str);
  287.       strcat(yend, "end");
  288.       if IS ("quit") break;
  289.       else if IS ("plot") doplot(params);
  290.       else if IS ("type") dotype(params);
  291.       else if IS ("show") doshow();
  292.       else if IS ("help") dohelp();
  293.       else if IS ("zmin") zmin = getval(params, zmin);
  294.       else if IS ("zmax") zmax = getval(params, zmax);
  295.       else if IS ("ymin") ymin = getval(params, ymin);
  296.       else if IS ("xmin") xmin = getval(params, xmin);
  297.       else if IS ("ymax") ymax = getval(params, ymax);
  298.       else if IS ("xmax") xmax = getval(params, xmax);
  299.       else if IS (xcount) var1stepcount = getval(params, var1stepcount);
  300.       else if IS (ycount) var2stepcount = getval(params, var2stepcount);
  301.       else if IS (xstart) {
  302.         currentbound->v1start = getval(params, var1start);
  303.         setbounds(currentbound);
  304.         }
  305.       else if IS (ystart) {
  306.         currentbound->v2start = getval(params, var2start);
  307.         setbounds(currentbound);
  308.         }
  309.       else if IS (xend) {
  310.         currentbound->v1end = getval(params, var1end);
  311.         setbounds(currentbound);
  312.         }
  313.       else if IS (yend) {
  314.         currentbound->v2end = getval(params, var2end);
  315.         setbounds(currentbound);
  316.         }
  317.       else if IS ("replot") doreplot();
  318.       else if IS ("aspect") aspect = getval(params, aspect);
  319.       else if IS ("tip") tip = getval(params, tip);
  320.       else if IS ("spin") spin = getval(params, spin);
  321.       else if IS ("distance") distance = getval(params, distance);
  322.       else if (!*command);
  323.       else
  324.         printf("Unknown command: %s\n", command);
  325.    } while (1);
  326.    clrscr();
  327. }
  328.  
  329.  
  330. /* A transform function for sphere notation */
  331.  
  332.  
  333. void sphererho(float *x, float *y, float *z, float rho, float phi, float theta)
  334. {
  335.    *x = rho * sin(phi);
  336.    *y = *x;
  337.    *x *= cos(theta);
  338.    *y *= sin(theta);
  339.    *z = rho * cos(phi);
  340. }
  341.  
  342. void spherephi(float *x, float *y, float *z, float phi, float rho, float theta)
  343. {
  344.    *x = rho * sin(phi);
  345.    *y = *x;
  346.    *x *= cos(theta);
  347.    *y *= sin(theta);
  348.    *z = rho * cos(phi);
  349. }
  350.  
  351. void spheretheta(float *x, float *y, float *z, float theta, float phi, float rho)
  352. {
  353.    *x = rho * sin(phi);
  354.    *y = *x;
  355.    *x *= cos(theta);
  356.    *y *= sin(theta);
  357.    *z = rho * cos(phi);
  358. }
  359.  
  360.  
  361. void cartz(float *x, float *y, float *z, float zval, float xval, float yval)
  362. {
  363.    *x = xval;
  364.    *y = yval;
  365.    *z = zval;
  366. }
  367.  
  368. void cartx(float *x, float *y, float *z, float xval, float yval, float zval)
  369. {
  370.    *x = xval;
  371.    *y = yval;
  372.    *z = zval;
  373. }
  374.  
  375. void carty(float *x, float *y, float *z, float yval, float xval, float zval)
  376. {
  377.    *x = xval;
  378.    *y = yval;
  379.    *z = zval;
  380. }
  381.  
  382.  
  383. void cylinderz(float *x, float *y, float *z, float zval, float rval, float theta)
  384. {
  385.    *x = rval * cos(theta);
  386.    *y = rval * sin(theta);
  387.    *z = zval;
  388. }
  389.  
  390. void cylinderr(float *x, float *y, float *z, float rval, float theta, float zval)
  391. {
  392.    *x = rval * cos(theta);
  393.    *y = rval * sin(theta);
  394.    *z = zval;
  395. }
  396.  
  397.  
  398. void cylindertheta(float *x, float *y, float *z, float theta, float rval, float zval)
  399. {
  400.    *x = rval * cos(theta);
  401.    *y = rval * sin(theta);
  402.    *z = zval;
  403. }
  404.  
  405.  
  406. #pragma argsused
  407.  
  408. void parametric(float *x, float *y, float *z, float dummy, float u, float v)
  409. {
  410.    /* *x =1.7*cos(2*PI*u); y =1.7*sin(2*PI*u); z =v;
  411.     * 
  412.     * x = 0.5*v*cos(2*PI*u); y = 0.5*v*sin(2*PI*u); z = 0.866*v;
  413.     * 
  414.     * x = cos(2*PI*u)*sin(PI*v); y = sin(2*PI*u)*sin(PI*v); z = cos(PI*v);
  415.     * 
  416.     * x = cos(PI*(2*u-1))*sin(PI*v); y = sin(PI*(2*u-1))*sin(PI*v); z = cos(PI*v);
  417.     * 
  418.     * x = exp(u+v); y = exp(u*v); z = u*v*v;
  419.     * 
  420.     * x = -v + 1; y = u - v; z = v; */
  421.    float a = 2.0;
  422.    float b = 0.8;
  423.    *x = (a + b * cos(u)) * cos(v);
  424.    *y = (a + b * cos(u)) * sin(v);
  425.    *z = b * sin(u);
  426. }
  427.