#include "graph.h" #define ANGLEX 45 long int xcenter, ycenter; long int minx, miny, maxx, maxy; double xconversion, yconversion; double SINX, COSX; Plot3dGraph(Window, parameters) struct Graph_Parameters *parameters; struct Window *Window; { extern double x,y,z,t; extern long int xcenter, ycenter; extern double xconversion, yconversion; extern double SINX, COSX; extern long int minx, miny, maxx, maxy; double a, x1, x2, y1, y2, z1, z2, xnext, ynext, xtemp, ytemp; double xstep, ystep, minz, maxz; double xsize, ysize, top, bottom, left, right; /* the stuff needed for hidden lines */ WORD *areabuffer; struct TmpRas tmpras; struct TmpRas *lasttmp; struct AreaInfo myAreaInfo; char *raster; minx = Window->BorderLeft; miny = Window->BorderTop; maxx = Window->Width - Window->BorderRight - XBORDER; maxy = Window->Height - Window->BorderBottom - YBORDER; /* setup things for whats is needed for hidden */ if (parameters->hidden) { areabuffer = AllocMem(sizeof(WORD) * 750l, MEMF_CHIP); if (areabuffer == NULL) parameters->hidden = FALSE; else { InitArea(&myAreaInfo, areabuffer, 300l); Window->RPort->AreaInfo = &myAreaInfo; raster = AllocRaster(maxx, maxy); if (raster == NULL) parameters->hidden = FALSE; else { lasttmp = Window->RPort->TmpRas; InitTmpRas(&tmpras, raster, RASSIZE(maxx, maxy)); Window->RPort->TmpRas = &tmpras; } } } a=ANGLEX * PI / 180; /* I hate to do this but my doubles do not */ SINX = sin(a); /* work right under Manx 3.30 */ COSX = cos(a); left = 0; right = 0; if (parameters->xend > 0 ) left = parameters->xend * COSX; if (parameters->xstart < 0 ) right = -parameters->xstart * COSX; if (parameters->ystart < 0) left -= parameters->ystart; if (parameters->yend > 0) right += parameters->yend; xsize = left + right; ysize = parameters->yend - parameters->ystart; xconversion = (maxx - minx) / xsize; yconversion = (maxy - miny) / ysize; xstep = parameters->detail / xconversion; ystep = parameters->detail / yconversion; /* analyze the graph to determine the max hight and min hight */ minz = INFINITY; maxz = -INFINITY; SetAPen(Window->RPort, 1l); SetBPen(Window->RPort, 0l); SetDrMd(Window->RPort, JAM2); Print(Window, "Please Wait Analyzing Graph", 1); y = parameters->ystart; while ( y < parameters->yend ) { x = parameters->xstart; while ( x < parameters->xend ) { parameters->z1->position = 0; z1 = Solve(parameters->z1); x += xstep; z = (z1 - x * COSX); minz = min(minz, z); maxz = max(maxz, z); } /* end of xwhile */ y += parameters->ylabels; } /* end of y loop */ ysize = maxz - minz; yconversion = (maxy - miny) / ysize; ystep = parameters->detail / yconversion; if (left > 0 ) xcenter = left * xconversion + minx + 2; else xcenter = -left * xconversion + minx + 2; ycenter = maxy + minz * yconversion; /* Draw the Graph rectangle area */ SetAPen(Window->RPort, 0); SetOPen(Window->RPort, 2); SetDrMd(Window->RPort, JAM2); DrawRectangle(Window, 1, minx, miny, maxx, maxy); xconversion *= 0.90; yconversion *= 0.90; Line3d(Window, 2l, 0.0, 0.0, 0.0, parameters->xend, 0.0, 0.0); Line3d(Window, 2l, 0.0, 0.0, 0.0, 0.0, parameters->yend, 0.0); Line3d(Window, 2l, 0.0, 0.0, 0.0, 0.0, 0.0, parameters->zend); ynext = parameters->ystart; while (ynext < parameters->yend) { xnext = parameters->xstart; while (xnext < parameters->xend) { parameters->z1->position = 0; x = xnext; y = ynext; x1 = x; y1 = y; z1 = Solve(parameters->z1); InitVertices(Window, parameters, 1l, x1, y1, z1); while (x < xnext + parameters->xlabels) { parameters->z1->position = 0; x += xstep; x1 = x; y1 = y; z1 = Solve(parameters->z1); AddVertice(Window, parameters, x1, y1, z1); } /* end of xblock while */ xtemp = x1; while (y < ynext + parameters->ylabels) { parameters->z1->position = 0; y += ystep; x1 = x; y1 = y; z1 = Solve(parameters->z1); AddVertice(Window, parameters, x1, y1, z1); } /* end of yblock while */ ytemp = y1; if (parameters->hidden || xnext == parameters->xstart || y >= parameters->yend) { while (x > xnext) { parameters->z1->position = 0; x -= xstep; x1 = x; y1 = y; z1 = Solve(parameters->z1); AddVertice(Window, parameters, x1, y1, z1); } /* end of xblock while */ } /* end of the check to see if valid */ if (parameters->hidden || xnext == parameters->xstart) { while (y > ynext) { parameters->z1->position = 0; y -= ystep; x1 = x; y1 = y; z1 = Solve(parameters->z1); AddVertice(Window, parameters, x1, y1, z1); } /* end of yblock while */ } /* end of the if */ DrawVertices(Window, parameters); xnext = xtemp; } /* end of xmaster */ ynext = ytemp; } /* end of ymaster */ if (parameters->hidden) { FreeRaster(raster, maxx, maxy); FreeMem(areabuffer, sizeof(WORD) * 750l); Window->RPort->TmpRas = lasttmp; } return(); } Line3d(Window, colour, x1, y1, z1, x2, y2, z2) struct Window *Window; long int colour; double x1, y1, z1, x2, y2, z2; { extern long int xcenter, ycenter; extern double xconversion, yconversion; extern double SINX, COSX; long int xa, ya, xb, yb; xa = xcenter + (x1 * SINX - y1) * xconversion; ya = ycenter - (x1 * COSX - z1) * yconversion; xb = xcenter + (x2 * SINX - y2) * xconversion; yb = ycenter - (x2 * COSX - z2) * yconversion; Line(Window, colour, xa, ya, xb, yb); } long int lastx, lasty; int points; InitVertices(Window, parameters, colour, x1, y1, z1) struct Window *Window; struct Graph_Parameters *parameters; long int colour; double x1, y1, z1; { extern long int xcenter, ycenter; extern double xconversion, yconversion; extern double SINX, COSX; extern long minx, miny, maxx, maxy; extern int lastx, lasty; extern int points; long int xa, ya; xa = xcenter + (x1 * SINX - y1) * xconversion; ya = ycenter - (x1 * COSX - z1) * yconversion; lastx = xa; lasty = ya; if (!(xa > minx && xa < maxx && ya > miny && ya < maxy) ) return(); SetOPen(Window->RPort, colour); SetAPen(Window->RPort, 0l); points = 1; if (parameters->hidden) AreaMove(Window->RPort, xa, ya); else { Move(Window->RPort, xa, ya); SetAPen(Window->RPort, colour); } } AddVertice(Window, parameters, x1, y1, z1) struct Window *Window; struct Graph_Parameters *parameters; double x1, y1, z1; { extern long int xcenter, ycenter; extern double xconversion, yconversion; extern double SINX, COSX; extern long minx, miny, maxx, maxy; extern long int lastx, lasty; extern int points; long int xa, ya; xa = xcenter + (x1 * SINX - y1) * xconversion; ya = ycenter - (x1 * COSX - z1) * yconversion; if (lastx == xa && lasty == ya) return(); lastx = xa; lasty = ya; if (!(xa > minx && xa < maxx && ya > miny && ya < maxy) ) return(); if (parameters->hidden) { AreaDraw(Window->RPort, xa, ya); points++; } else Draw(Window->RPort, xa, ya); } DrawVertices(Window, parameters) struct Window *Window; struct Graph_Parameters *parameters; { extern int points; if (parameters->hidden) AreaEnd(Window->RPort); }