home *** CD-ROM | disk | FTP | other *** search
- /*
-
- Plot3d -- plot3d.c, the main program
-
- By Adrian Mariano -- adrian@milton.u.washington.edu
-
-
- Copyright (c) 1991 by Adrian Mariano
-
- You may use and distribute this program as much as you like so long as you do
- not charge for this service. I am not liable for failure of this program to
- perform in any way.
-
- */
-
- #include "plot3d.h"
- #include <string.h>
-
- extern unsigned _stklen = 32000;/* stack space to make qsort happy */
-
- /* status variables */
- char stop;
-
-
- void terminate(void)
- {
- backtotext();
- exit(0);
- }
-
-
- term fstack[maxffs + 1][100]; /* function stack for ff evaluation */
-
-
- typedef struct {
- float v1start, v1end, v2start, v2end;
- char *name;
- } bound;
-
- bound *currentbound;
-
-
- /* Functions to be passed to plot3d() for different plot types */
-
- void sphererho(float *x, float *y, float *z, float rho, float phi, float theta);
- void spherephi(float *x, float *y, float *z, float phi, float rho, float theta);
- void spheretheta(float *x, float *y, float *z, float theta, float phi, float rho);
- void cartz(float *x, float *y, float *z, float zval, float xval, float yval);
- void cartx(float *x, float *y, float *z, float xval, float yval, float zval);
- void carty(float *x, float *y, float *z, float yval, float xval, float zval);
- void cylinderz(float *x, float *y, float *z, float zval, float rval, float theta);
- void cylinderr(float *x, float *y, float *z, float rval, float theta, float zval);
- void cylindertheta(float *x, float *y, float *z, float theta, float rval, float zval);
- void parametric(float *x, float *y, float *z, float dummy, float u, float v);
-
- bound sphererho_bound = {0, M_PI, 0, PI2, "sphererho"};
- bound spherephi_bound = {0, 3, 0, PI2, "spherephi"};
- bound spheretheta_bound = {0, M_PI, 0, 3, "spheretheta"};
-
- bound cartz_bound = {-3, 3, -3, 3, "cartz"};
- bound cartx_bound = {-3, 3, -3, 3, "cartx"};
- bound carty_bound = {-3, 3, -3, 3, "carty"};
-
- bound cylinderz_bound = {0, 3, 0, PI2, "cylinderz"};
- bound cylinderr_bound = {0, PI2, -3, 3, "cylinderr"};
- bound cylindertheta_bound = {0, 3, -3, 3, "cylindertheta"};
-
- char *xstr = "x";
- char *ystr = "y";
- char *zstr = "z";
- char *thetastr = "theta";
- char *rhostr = "rho";
- char *phistr = "phi";
- char *rstr = "r";
-
- char *var1str;
- char *var2str;
-
-
- void (*plottype) (float *, float *, float *, float, float, float);
-
-
- struct {
- char *st, *en;
- } replaces[] = {
- {"sinh", "sh"}, {"cosh", "ch"}, {"tanh", "th"},{"sin", "s"},
- {"cos", "c"}, {"arc", "A"}, {"ln", "n"}, {"log", "l"},{"abs","a"}
- };
-
-
-
- void setbounds(bound * newbound)
- {
- var1start = newbound->v1start;
- var2start = newbound->v2start;
- var1end = newbound->v1end;
- var2end = newbound->v2end;
- currentbound = newbound;
- }
-
- void substitute(char *str, char *start, char *end)
- {
- while (str = strstr(str, start)) {
- strnset(str, ' ', strlen(start));
- strncpy(str, end, strlen(end));
- }
- }
-
-
-
- void fixfun(char *fun)
- {
- int i;
- substitute(fun, var1str, "X");
- substitute(fun, var2str, "Y");
- substitute(fun, "X", "x");
- substitute(fun, "Y", "y");
-
- for (i = 0; i < sizeof(replaces) / (2 * sizeof(char *)); i++)
- substitute(fun, replaces[i].st, replaces[i].en);
- }
-
-
- void doreplot()
- {
- if (plot3d(plottype)) {
- getch();
- backtotext();
- }
- }
-
-
- void doplot(char *params)
- {
- char *errmesg;
- int where;
- fixfun(params);
- if ((where = convert(params, &errmesg, 0)) == -1) {
- simplify(0);
- if (plot3d(plottype)) {;
- getch();
- backtotext();
- }
- } else {
- while (where--)
- putchar(' ');
- printf(" ^\n%s\n", errmesg);
- }
- }
-
-
- float getval(char *expr, float def)
- {
- int where;
- char *errmesg;
- if ((where = convert(expr, &errmesg, maxffs)) == -1)
- return ff(def, def, maxffs);
- else {
- while (where--)
- putchar(' ');
- printf(" ^\n%s\n", errmesg);
- return def;
- }
- }
-
-
- void dotype(char *newtype)
- {
- if (!strcmp(newtype, "cartx")) {
- plottype = cartx;
- setbounds(&cartx_bound);
-
- var1str = ystr;
- var2str = zstr;
- } else if (!strcmp(newtype, "carty")) {
- plottype = carty;
- setbounds(&carty_bound);
- var1str = xstr;
- var2str = zstr;
- } else if (!strcmp(newtype, "cartz")) {
- plottype = cartz;
- setbounds(&cartz_bound);
- var1str = xstr;
- var2str = ystr;
- } else if (!strcmp(newtype, "sphererho")) {
- plottype = sphererho;
- setbounds(&sphererho_bound);
- var1str = phistr;
- var2str = thetastr;
- } else if (!strcmp(newtype, "spherephi")) {
- plottype = spherephi;
- setbounds(&spherephi_bound);
- var1str = rhostr;
- var2str = thetastr;
- } else if (!strcmp(newtype, "spheretheta")) {
- plottype = spheretheta;
- setbounds(&spheretheta_bound);
- var1str = phistr;
- var2str = rhostr;
- } else if (!strcmp(newtype, "cylinderz")) {
- plottype = cylinderz;
- setbounds(&cylinderz_bound);
- var1str = rstr;
- var2str = thetastr;
- } else if (!strcmp(newtype, "cylinderr")) {
- plottype = cylinderr;
- setbounds(&cylinderr_bound);
- var1str = thetastr;
- var2str = zstr;
- } else if (!strcmp(newtype, "cylindertheta")) {
- plottype = cylindertheta;
- setbounds(&cylindertheta_bound);
- var1str = rstr;
- var2str = zstr;
- } else
- printf("Unknown coordinate system: %s\n\n", newtype);
- }
-
-
- void doshow()
- {
- printf("Coordinate system: %s\n",currentbound->name);
- printf("%s range: [%.17g,%.17g]\n%s range: [%.17g,%.17g]\n",
- var1str, var1start, var1end, var2str, var2start, var2end);
- printf("X: [%.17g,%.17g]\nY: [%.17g,%.17g]\nZ: [%.17g,%.17g]\n",
- xmin, xmax, ymin, ymax, zmin, zmax);
- printf("%s steps: %d\t%s steps: %d\n", var1str,
- (int) var1stepcount, var2str, (int) var2stepcount);
- printf("Aspect: %.17g\tDistance: %.17g\n", aspect, distance);
- printf("Spin: %.17g \tTip: %.17g\n", spin, tip);
- }
-
- void dohelp()
- {
- printf(
- "Commands:\n\n"
- "plot <function> -- function is in terms of the current coordinate system\n"
- "replot -- plot the same function again.\n"
- "type <cartz|cartx|carty|sphererho|spheretheta|spherephi|cylinderz|\n"
- " cylindertheta|cylinderr> -- Selects coordinate system for plotting\n"
- " where the variable name specified (sphereRHO) is the dependent variable\n"
- "show -- displays current plotting parameters\n"
- "xmin, xmax, ymin, ymax, zmin, zmax <value> -- set region to display on screen\n"
- "%sstart, %send, %sstart, %send, %ssteps, %ssteps <value> --\n"
- " Set the range for the independent variables, and the number of steps at\n"
- " which to sample the function\n"
- "aspect <value> -- set aspect ratio of screen\n"
- "distance <value> -- set perspect distance, 0 for no perspective\n"
- "spin, tip <value> -- set view angle in degrees\n\n"
- "Functions supported:\n"
- " [arc]sin, [arc]cos, [arc]tan, [arc]sinh, [arc]cosh, [arc]tanh\n"
- " ln, log, abs\n",var1str,var1str,var2str,var2str,var1str,var2str);
- }
-
-
- #define IS(XX) (!strcmp(command,XX))
-
-
- void main()
- {
- char input[100], command[100], params[100];
- char xcount[15], ycount[15], xstart[15], xend[15], ystart[15], yend[15];
- initgraphics();
- plottype = cartz;
- setbounds(&cartz_bound);
- var1str = xstr;
- var2str = ystr;
- printf(" -- Plot3d Version 1.0 by Adrian Mariano --\n"
- " -- Type 'help' for help --\n");
- do {
- printf("> ");
- gets(input);
- *command = *params = 0;
- sscanf(input, "%s %[^\n\r]", command, params);
- /* printf("'%s' '%s'\n",command,params); */
- strcpy(xcount, var1str);
- strcat(xcount, "steps");
- strcpy(ycount, var2str);
- strcat(ycount, "steps");
- strcpy(xstart, var1str);
- strcat(xstart, "start");
- strcpy(ystart, var2str);
- strcat(ystart, "start");
- strcpy(xend, var1str);
- strcat(xend, "end");
- strcpy(yend, var2str);
- strcat(yend, "end");
- if IS ("quit") break;
- else if IS ("plot") doplot(params);
- else if IS ("type") dotype(params);
- else if IS ("show") doshow();
- else if IS ("help") dohelp();
- else if IS ("zmin") zmin = getval(params, zmin);
- else if IS ("zmax") zmax = getval(params, zmax);
- else if IS ("ymin") ymin = getval(params, ymin);
- else if IS ("xmin") xmin = getval(params, xmin);
- else if IS ("ymax") ymax = getval(params, ymax);
- else if IS ("xmax") xmax = getval(params, xmax);
- else if IS (xcount) var1stepcount = getval(params, var1stepcount);
- else if IS (ycount) var2stepcount = getval(params, var2stepcount);
- else if IS (xstart) {
- currentbound->v1start = getval(params, var1start);
- setbounds(currentbound);
- }
- else if IS (ystart) {
- currentbound->v2start = getval(params, var2start);
- setbounds(currentbound);
- }
- else if IS (xend) {
- currentbound->v1end = getval(params, var1end);
- setbounds(currentbound);
- }
- else if IS (yend) {
- currentbound->v2end = getval(params, var2end);
- setbounds(currentbound);
- }
- else if IS ("replot") doreplot();
- else if IS ("aspect") aspect = getval(params, aspect);
- else if IS ("tip") tip = getval(params, tip);
- else if IS ("spin") spin = getval(params, spin);
- else if IS ("distance") distance = getval(params, distance);
- else if (!*command);
- else
- printf("Unknown command: %s\n", command);
- } while (1);
- clrscr();
- }
-
-
- /* A transform function for sphere notation */
-
-
- void sphererho(float *x, float *y, float *z, float rho, float phi, float theta)
- {
- *x = rho * sin(phi);
- *y = *x;
- *x *= cos(theta);
- *y *= sin(theta);
- *z = rho * cos(phi);
- }
-
- void spherephi(float *x, float *y, float *z, float phi, float rho, float theta)
- {
- *x = rho * sin(phi);
- *y = *x;
- *x *= cos(theta);
- *y *= sin(theta);
- *z = rho * cos(phi);
- }
-
- void spheretheta(float *x, float *y, float *z, float theta, float phi, float rho)
- {
- *x = rho * sin(phi);
- *y = *x;
- *x *= cos(theta);
- *y *= sin(theta);
- *z = rho * cos(phi);
- }
-
-
- void cartz(float *x, float *y, float *z, float zval, float xval, float yval)
- {
- *x = xval;
- *y = yval;
- *z = zval;
- }
-
- void cartx(float *x, float *y, float *z, float xval, float yval, float zval)
- {
- *x = xval;
- *y = yval;
- *z = zval;
- }
-
- void carty(float *x, float *y, float *z, float yval, float xval, float zval)
- {
- *x = xval;
- *y = yval;
- *z = zval;
- }
-
-
- void cylinderz(float *x, float *y, float *z, float zval, float rval, float theta)
- {
- *x = rval * cos(theta);
- *y = rval * sin(theta);
- *z = zval;
- }
-
- void cylinderr(float *x, float *y, float *z, float rval, float theta, float zval)
- {
- *x = rval * cos(theta);
- *y = rval * sin(theta);
- *z = zval;
- }
-
-
- void cylindertheta(float *x, float *y, float *z, float theta, float rval, float zval)
- {
- *x = rval * cos(theta);
- *y = rval * sin(theta);
- *z = zval;
- }
-
-
- #pragma argsused
-
- void parametric(float *x, float *y, float *z, float dummy, float u, float v)
- {
- /* *x =1.7*cos(2*PI*u); y =1.7*sin(2*PI*u); z =v;
- *
- * x = 0.5*v*cos(2*PI*u); y = 0.5*v*sin(2*PI*u); z = 0.866*v;
- *
- * x = cos(2*PI*u)*sin(PI*v); y = sin(2*PI*u)*sin(PI*v); z = cos(PI*v);
- *
- * x = cos(PI*(2*u-1))*sin(PI*v); y = sin(PI*(2*u-1))*sin(PI*v); z = cos(PI*v);
- *
- * x = exp(u+v); y = exp(u*v); z = u*v*v;
- *
- * x = -v + 1; y = u - v; z = v; */
- float a = 2.0;
- float b = 0.8;
- *x = (a + b * cos(u)) * cos(v);
- *y = (a + b * cos(u)) * sin(v);
- *z = b * sin(u);
- }
-