/*---------------- INCLUDE FILES ----------------*/ #include "common.h" /*---------------- External Variables ---------------*/ extern struct GfxBase *GfxBase; extern struct Window *win; extern struct RastPort *rastport; extern struct ViewPort *viewport; extern AllPlotData *apd; extern DOUBLE Evaluate(DOUBLE, DOUBLE); /*---------------- Global User Parameters ------------*/ LONG plottype; /* How to plot graph, see menuselect.h */ static LONG xcenter = 160, ycenter = 100, /* Center of screen */ xp, yp, vp, zplane, xp1, xp2, xp3, xp4, yp1, yp2, yp3, yp4; /* for hidden and filled */ static DOUBLE aspectratio = .927, /* to correct y-axis */ fartherest, nextfartherest, xbegin, xend, ybegin, yend, xspc, xinc, yspc, yinc, xminymin, xminymax, xmaxymin, xmaxymax, xyminmax[4], dtoplane, dmin, dmax, colorspread, RotMatrix[3][3], TempMatrix[3][3]; static BOOL plottinggraph, onscreen, backflag; /*------------ Global Color Palette Parameters -------------*/ LONG numcolors = 24, pennumbase = 4, pennummax = 27, bkgpen = 0, borderpen = 1, axespen = 2, textpen = 3, highlightpen1 = 30, highlightpen2 = 31, bkgred = 0, bkggreen = 0, bkgblue = 0, /* Black background */ axesred = 8, axesgreen = 0, axesblue = 0, /* Red axes */ borderred = 10, bordergreen = 10, borderblue = 10, /* Medium gray border */ textred = 8, textgreen = 0, textblue = 8, /* Purple text */ graphfarred = 0, graphfargreen = 0, graphfarblue = 7, /* Blue graph far color */ graphnearred = 15, graphneargreen = 15, graphnearblue = 15; /* White graph near color */ /*-------------- Temp Raster Global Parameters ------------*/ static struct TmpRas tmpras; static struct AreaInfo areainfo; static PLANEPTR myplane; static UWORD areabuffer[15]; /*------------ IsStopPlot Function ---------------*/ BOOL IsStopPlot(message) struct IntuiMessage *message; { ULONG mclass; UWORD menunum; mclass = message->Class; menunum = message->Code; ReplyMsg((struct Message *)message); if(mclass == MENUPICK) { if( (MENUNUM(menunum) == MENUFUNCTION) && (ITEMNUM(menunum) == FUNCTIONSTOPPLOT) ) return TRUE; } /* if */ return FALSE; } /* IsStopPlot */ /*------------ SetScreenColors Function --------------*/ VOID SetScreenColors() { SetRGB4(viewport,bkgpen,bkgred,bkggreen,bkgblue); SetRGB4(viewport,borderpen,borderred,bordergreen,borderblue); SetRGB4(viewport,axespen,axesred,axesgreen,axesblue); SetRGB4(viewport,textpen,textred,textgreen,textblue); SetRGB4(viewport,highlightpen1,0,4,5); SetRGB4(viewport,highlightpen2,12,12,0); } /* SetScreenColors */ /*------------ SetGraphColors Function --------------*/ VOID SetGraphColors() { LONG num, redvalue, greenvalue, bluevalue; for (num = pennumbase ; num <= pennummax ; ++num) { redvalue = graphfarred + (num-pennumbase) * (graphnearred-graphfarred) / numcolors; greenvalue = graphfargreen + (num-pennumbase) * (graphneargreen-graphfargreen) / numcolors; bluevalue = graphfarblue + (num-pennumbase) * (graphnearblue-graphfarblue) / numcolors; SetRGB4(viewport,num,redvalue,greenvalue,bluevalue); } } /* SetGraphColors */ /*------------- SetLoresColors Function --------------*/ void SetLoresColors() { SetScreenColors(); /* Set fartherest colors as group */ numcolors = 8; pennumbase = 4; pennummax = 11; graphfarred = 0; graphfargreen = 0; graphfarblue = 7; graphnearred = 0; graphneargreen = 0; graphnearblue = 15; SetGraphColors(); /* Set nearest colors as group */ numcolors = 16; pennumbase = 12; pennummax = 27; graphfarred = 0; graphfargreen = 0; graphfarblue = 15; graphnearred = 15; graphneargreen = 15; graphnearblue = 15; SetGraphColors(); /* Set values to actual range for calculations */ numcolors = 24; pennumbase = 4; } /* SetLoresColors */ /*------------- SetHiresColors Function --------------*/ void SetHiresColors() { SetScreenColors(); numcolors = 12; pennumbase = 4; pennummax = 15; graphfarred = 0; graphfargreen = 0; graphfarblue = 15; graphnearred = 15; graphneargreen = 15; graphnearblue = 15; SetGraphColors(); } /* SetHiresColors */ /*------------- ChangePlotParameters Function -------------*/ void ChangePlotParameters(scr) struct Screen *scr; { WORD scrW, scrH; Forbid(); scrW = scr->Width; scrH = scr->Height; Permit(); if(scrW == 320) { apd->dd.OriginX = xcenter = 160; if(scrH == 200) { aspectratio = .927; apd->dd.OriginY = ycenter = 100; } else { aspectratio = 1.854; apd->dd.OriginY = ycenter = 200; } SetLoresColors(); } /* if */ else { /* scrH == 640 */ apd->dd.OriginX = xcenter = 320; if(scrH == 200) { aspectratio = .4635; apd->dd.OriginY = ycenter = 100; } else { aspectratio = .927; apd->dd.OriginY = ycenter = 200; } SetHiresColors(); } /* else */ } /* ChangePlotParameters */ /*----------------- calc Function ------------------*/ static DOUBLE calc(x,y) DOUBLE x, y; { return (Evaluate(x, y)); } /* calc */ /*---------------- xcalc, ycalc, zcalc Functions ----------------*/ static DOUBLE xcalc(x,y,z) DOUBLE x, y, z; { return (RotMatrix[0][0] * x + RotMatrix[0][1] * y + RotMatrix[0][2] * z); } /* xcalc */ static DOUBLE ycalc(x,y,z) DOUBLE x, y, z; { return (RotMatrix[1][0] * x + RotMatrix[1][1] * y + RotMatrix[1][2] * z); } /* ycalc */ static DOUBLE zcalc(x,y,z) DOUBLE x, y, z; { return (RotMatrix[2][0] * x + RotMatrix[2][1] * y + RotMatrix[2][2] * z); } /* zcalc */ /*-------------------- Calculate Function -------------------*/ static VOID Calculate(x, y, z) DOUBLE x, y, z; { DOUBLE xpixels, ypixels, zpixels, zdiff; DOUBLE tforline; xpixels = (xcalc(x,y,z) * apd->dd.Scale) + (DOUBLE)(apd->dd.OriginX - xcenter); ypixels = (-ycalc(x,y,z) * apd->dd.Scale) + (DOUBLE)(apd->dd.OriginY - ycenter); zpixels = (zcalc(x,y,z) * apd->dd.Scale); zdiff = (DOUBLE)(vp + zplane) - zpixels; /* negative if behind viewer */ if (zdiff > 1) { tforline = ((DOUBLE) vp) / zdiff; xp = (LONG)(xpixels * tforline + .5) + xcenter; yp = (LONG)(ypixels * tforline * aspectratio + .5) + ycenter; onscreen = TRUE; } else { xp = -1; yp = -1; onscreen = FALSE; } } /* Calculate */ /*------------------ CalcAndPlot Function ----------------*/ static VOID CalcAndPlot(x, y) DOUBLE x, y; { LONG pennum; DOUBLE z; z = calc(x,y); Calculate(x, y, z); if (onscreen == TRUE) { dtoplane = zcalc(x,y,z); pennum = (LONG)((dtoplane - dmin)/colorspread) + pennumbase; if (pennum > pennummax) pennum = pennummax; if (pennum < pennumbase) pennum = pennumbase; SetAPen(rastport,pennum); if (backflag == TRUE) { Move(rastport,xp,yp); WritePixel(rastport,xp,yp); backflag = FALSE; } else { Draw(rastport,xp,yp); } } /* if */ } /* CalcAndPlot */ /*------------------ CalcAndPlot2 Function ----------------*/ static VOID CalcAndPlot2(x1, y1, flag) DOUBLE x1, y1; BOOL flag; { static LONG pennum; static DOUBLE x2, y2, z1; /* Assign last 2 points to first 2 points */ xp1 = xp4; xp2 = xp3; yp1 = yp4; yp2 = yp3; x2 = x1 + xspc; /* used if flag = FALSE, plot along Y-axis */ y2 = y1 + yspc; /* used if flag = TRUE , plot along X-axis */ if(flag) Calculate(x1, y2, calc(x1, y2)); else Calculate(x2, y1, calc(x2, y1)); xp3 = xp; yp3 = yp; z1 = calc(x1, y1); Calculate(x1, y1, z1); xp4 = xp; yp4 = yp; if (onscreen == TRUE) { dtoplane = zcalc(x1, y1, z1); pennum = (LONG)((dtoplane - dmin)/colorspread) + pennumbase; if (pennum > pennummax) pennum = pennummax; if (pennum < pennumbase) pennum = pennumbase; SetOPen(rastport,pennum); if(plottype == PLOTHIDDEN) SetAPen(rastport, bkgpen); else /* PLOTFILLED */ SetAPen(rastport, pennum); AreaMove(rastport, xp1, yp1); AreaDraw(rastport, xp2, yp2); AreaDraw(rastport, xp3, yp3); AreaDraw(rastport, xp4, yp4); AreaEnd(rastport); } /* if */ } /* CalcAndPlot2 */ /*------------------ AxesCalcAndPlot Function ----------------*/ static VOID AxesCalcAndPlot(x, y, z) DOUBLE x, y, z; { LONG pixelcolor, potencolor; Calculate(x, y, z); if (onscreen == TRUE) { pixelcolor = ReadPixel(rastport,xp,yp); dtoplane = zcalc(x,y,z); potencolor = (LONG)((dtoplane - dmin)/colorspread) + pennumbase; if (potencolor > pixelcolor) { SetAPen(rastport,axespen); WritePixel(rastport,xp,yp); } } } /* AxesCalcAndPlot */ /*----------------- RotateAboutX Function ----------------*/ void RotateAboutX(angle) DOUBLE angle; { DOUBLE sinx = sin(angle); DOUBLE cosx = cos(angle); RotMatrix[0][0] = TempMatrix[0][0]; RotMatrix[0][1] = TempMatrix[0][1]*cosx+TempMatrix[0][2]*sinx; RotMatrix[0][2] = TempMatrix[0][1]*(-sinx)+TempMatrix[0][2]*cosx; RotMatrix[1][0] = TempMatrix[1][0]; RotMatrix[1][1] = TempMatrix[1][1]*cosx+TempMatrix[1][2]*sinx; RotMatrix[1][2] = TempMatrix[1][1]*(-sinx)+TempMatrix[1][2]*cosx; RotMatrix[2][0] = TempMatrix[2][0]; RotMatrix[2][1] = TempMatrix[2][1]*cosx+TempMatrix[2][2]*sinx; RotMatrix[2][2] = TempMatrix[2][1]*(-sinx)+TempMatrix[2][2]*cosx; } /* RotateAboutX */ /*----------------- RotateAboutY Function ----------------*/ void RotateAboutY(angle) DOUBLE angle; { DOUBLE siny = sin(angle); DOUBLE cosy = cos(angle); RotMatrix[0][0] = TempMatrix[0][0]*cosy+TempMatrix[0][2]*(-siny); RotMatrix[0][1] = TempMatrix[0][1]; RotMatrix[0][2] = TempMatrix[0][0]*siny+TempMatrix[0][2]*cosy; RotMatrix[1][0] = TempMatrix[1][0]*cosy+TempMatrix[1][2]*(-siny); RotMatrix[1][1] = TempMatrix[1][1]; RotMatrix[1][2] = TempMatrix[1][0]*siny+TempMatrix[1][2]*cosy; RotMatrix[2][0] = TempMatrix[2][0]*cosy+TempMatrix[2][2]*(-siny); RotMatrix[2][1] = TempMatrix[2][1]; RotMatrix[2][2] = TempMatrix[2][0]*siny+TempMatrix[2][2]*cosy; } /* RotateAboutY */ /*----------------- RotateAboutZ Function ----------------*/ void RotateAboutZ(angle) DOUBLE angle; { DOUBLE sinz = sin(angle); DOUBLE cosz = cos(angle); RotMatrix[0][0] = TempMatrix[0][0]*cosz+TempMatrix[0][1]*sinz; RotMatrix[0][1] = TempMatrix[0][0]*(-sinz)+TempMatrix[0][1]*cosz; RotMatrix[0][2] = TempMatrix[0][2]; RotMatrix[1][0] = TempMatrix[1][0]*cosz+TempMatrix[1][1]*sinz; RotMatrix[1][1] = TempMatrix[1][0]*(-sinz)+TempMatrix[1][1]*cosz; RotMatrix[1][2] = TempMatrix[1][2]; RotMatrix[2][0] = TempMatrix[2][0]*cosz+TempMatrix[2][1]*sinz; RotMatrix[2][1] = TempMatrix[2][0]*(-sinz)+TempMatrix[2][1]*cosz; RotMatrix[2][2] = TempMatrix[2][2]; } /* RotateAboutZ */ /*----------------- CopyRotToTemp Function ----------------*/ void CopyRotToTemp() { LONG i, j; for(i=0 ; i<=2 ; i++) { for(j=0 ; j<=2 ; j++) { TempMatrix[i][j] = RotMatrix[i][j]; } } } /* CopytRotToTemp */ /*----------------- PutIdentityInTemp Function ----------------*/ void PutIdentityInTemp() { TempMatrix[0][0] = 1; TempMatrix[0][1] = 0; TempMatrix[0][2] = 0; TempMatrix[1][0] = 0; TempMatrix[1][1] = 1; TempMatrix[1][2] = 0; TempMatrix[2][0] = 0; TempMatrix[2][1] = 0; TempMatrix[2][2] = 1; } /* PutIdentityInTemp */ /*-------------------- DrawGraph Function -----------------*/ VOID DrawGraph() { struct IntuiMessage *message; DOUBLE calcspacex, calcspacey, calcincx, calcincy, tx, ty, tz, yminend, ymaxend, ybeginspc, xminend, xmaxend, xbeginspc, zradians, yradians, xradians; BOOL alongxflag, alongyflag; plottinggraph = TRUE; SetRast(rastport,0); /* Calculate Equation Parameter */ vp = (LONG)(apd->dd.ViewDist * apd->dd.Scale); /* Viewer distance in pixels from projection plane */ zplane = (LONG)(apd->dd.ProjPlane * apd->dd.Scale); /* Distance in pixels of projection plane from origin */ calcspacex = apd->dd.LineSpacingX; calcspacey = apd->dd.LineSpacingY; if(plottype == PLOTNORMAL) { calcincx = 5*apd->dd.PlotPrecisionX; calcincy = 5*apd->dd.PlotPrecisionY; } else { calcincx = apd->dd.LineSpacingX; calcincy = apd->dd.LineSpacingY; } /* Values to speed up min and max calcs to get colorspread */ /* Calculate Equation Coefficients */ zradians = ((DOUBLE) apd->dd.RotationZ) * PI / 180.; yradians = ((DOUBLE) apd->dd.RotationY) * PI / 180.; xradians = ((DOUBLE) apd->dd.RotationX) * PI / 180.; PutIdentityInTemp(); if((apd->pi.RotationOrder == ROTATEXYZ) || (apd->pi.RotationOrder == ROTATEXZY)) { RotateAboutX(xradians); CopyRotToTemp(); if(apd->pi.RotationOrder == ROTATEXYZ) { RotateAboutY(yradians); CopyRotToTemp(); RotateAboutZ(zradians); } else { RotateAboutZ(zradians); CopyRotToTemp(); RotateAboutY(yradians); } } else if((apd->pi.RotationOrder == ROTATEYXZ) || (apd->pi.RotationOrder == ROTATEYZX)) { RotateAboutY(yradians); CopyRotToTemp(); if(apd->pi.RotationOrder == ROTATEYXZ) { RotateAboutX(xradians); CopyRotToTemp(); RotateAboutZ(zradians); } else { RotateAboutZ(zradians); CopyRotToTemp(); RotateAboutX(xradians); } } else { RotateAboutZ(zradians); CopyRotToTemp(); if(apd->pi.RotationOrder == ROTATEZXY) { RotateAboutX(xradians); CopyRotToTemp(); RotateAboutY(yradians); } else { RotateAboutY(yradians); CopyRotToTemp(); RotateAboutX(xradians); } } /* CALCULATE MINIMUM & MAXIMUM DISTANCES FROM USER */ /* Initialize minimum & maximum */ tz = calc(apd->dd.PlotXmin,apd->dd.PlotYmin); dtoplane = zcalc(apd->dd.PlotXmin,apd->dd.PlotYmin,tz); dmax = dtoplane; dmin = dtoplane; /* Loop on X at constant Y's */ if ( (apd->pi.Surface == XONLY) || (apd->pi.Surface == XANDY) ) { for (ty = apd->dd.PlotYmin ; ty <= apd->dd.PlotYmax ; ty += calcspacey) { /* Check for Stop Plot from user */ if(message = (struct IntuiMessage *) GetMsg(win->UserPort)) { if(IsStopPlot(message) == TRUE) goto EndDrawGraph; } /* if */ for (tx = apd->dd.PlotXmin ; tx <= apd->dd.PlotXmax ; tx += calcincx) { tz = calc(tx,ty); dtoplane = zcalc(tx,ty,tz); dmax = MAX(dmax,dtoplane); dmin = MIN(dmin,dtoplane); } } } /* Loop on Y at constant X's */ if ( (apd->pi.Surface == YONLY) || (apd->pi.Surface == XANDY) ) { for (tx = apd->dd.PlotXmin ; tx <= apd->dd.PlotXmax ; tx += calcspacex) { /* Check for Stop Plot from user */ if(message = (struct IntuiMessage *) GetMsg(win->UserPort)) { if(IsStopPlot(message) == TRUE) goto EndDrawGraph; } /* if */ for (ty = apd->dd.PlotYmin ; ty <= apd->dd.PlotYmax ; ty += calcincy) { tz = calc(tx,ty); dtoplane = zcalc(tx,ty,tz); dmax = MAX(dmax,dtoplane); dmin = MIN(dmin,dtoplane); } } } /* Calculate depth of each color range */ colorspread = (dmax - dmin)/numcolors; if (colorspread == 0) colorspread = 1; /* in case all points equidistant */ /* Calculate two farthest corners from viewer */ xyminmax[0] = xminymin = zcalc(apd->dd.PlotXmin, apd->dd.PlotYmin, 0); xyminmax[1] = xminymax = zcalc(apd->dd.PlotXmin, apd->dd.PlotYmax, 0); xyminmax[2] = xmaxymin = zcalc(apd->dd.PlotXmax, apd->dd.PlotYmin, 0); xyminmax[3] = xmaxymax = zcalc(apd->dd.PlotXmax, apd->dd.PlotYmax, 0); dqsort(xyminmax, 4); /* Sort the distances */ fartherest = xyminmax[0]; nextfartherest = xyminmax[1]; /* Set plotting order along X-axis */ if( (fartherest == xminymin) || (fartherest == xminymax) ) { xbegin = apd->dd.PlotXmin; xend = apd->dd.PlotXmax; xspc = apd->dd.LineSpacingX; xinc = apd->dd.PlotPrecisionX; if( (nextfartherest == xmaxymin) || (nextfartherest == xmaxymax) ) alongxflag = TRUE; else alongxflag = FALSE; } /* if */ else { xbegin = apd->dd.PlotXmax; xend = apd->dd.PlotXmin; xspc = -apd->dd.LineSpacingX; xinc = -apd->dd.PlotPrecisionX; if( (nextfartherest == xminymin) || (nextfartherest == xminymax) ) alongxflag = TRUE; else alongxflag = FALSE; } /* else */ /* Set plotting order along Y-axis */ if( (fartherest == xminymin) || (fartherest == xmaxymin) ) { ybegin = apd->dd.PlotYmin; yend = apd->dd.PlotYmax; yspc = apd->dd.LineSpacingY; yinc = apd->dd.PlotPrecisionY; } else { ybegin = apd->dd.PlotYmax; yend = apd->dd.PlotYmin; yspc = -apd->dd.LineSpacingY; yinc = -apd->dd.PlotPrecisionY; } /* PLOT THE GRAPH */ switch(plottype) { case PLOTNORMAL: /* Plot X's at constant Y's for specified range of Y */ if (apd->pi.Surface == XONLY) { /* Only if user specified */ for (ty = ybegin ; (ty <= apd->dd.PlotYmax) && (ty >= apd->dd.PlotYmin) ; ty += yspc) { /* Check for Stop Plot from user */ if(message = (struct IntuiMessage *) GetMsg(win->UserPort)) { if(IsStopPlot(message) == TRUE) goto EndDrawGraph; } /* if */ backflag = TRUE; /* Prevent last point from connecting with the next first point */ for (tx = xbegin ; (tx <= apd->dd.PlotXmax) && (tx >= apd->dd.PlotXmin) ; tx += xinc) CalcAndPlot(tx, ty); } /* for */ } /* if */ /* Plot Y's at constant X for specified range of X */ else if (apd->pi.Surface == YONLY) { /* Do only if user specified */ for (tx = xbegin ; (tx <= apd->dd.PlotXmax) && (tx >= apd->dd.PlotXmin) ; tx += xspc) { /* Check for Stop Plot from user */ if(message = (struct IntuiMessage *) GetMsg(win->UserPort)) { if(IsStopPlot(message) == TRUE) goto EndDrawGraph; } /* if */ backflag = TRUE; /* Prevent last point from connecting with the next first point */ for (ty = ybegin ; (ty <= apd->dd.PlotYmax) && (ty >= apd->dd.PlotYmin) ; ty += yinc) CalcAndPlot(tx, ty); } /* for */ } /* else if */ else { /* Plot crosshatched */ DOUBLE ty2 = ybegin, tx2 = xbegin; alongxflag = TRUE; alongyflag = TRUE; do { if(alongxflag) { backflag = TRUE; for(tx = xbegin ; (tx <= apd->dd.PlotXmax) && (tx >= apd->dd.PlotXmin) ; tx += xinc) CalcAndPlot(tx, ty2); ty2 += yspc; if( (ty2 < apd->dd.PlotYmin) || (ty2 > apd->dd.PlotYmax) ) alongxflag = FALSE; /* Check for Stop Plot from user */ if(message = (struct IntuiMessage *) GetMsg(win->UserPort)) { if(IsStopPlot(message) == TRUE) goto EndDrawGraph; } /* if */ } /* if */ if(alongyflag) { backflag = TRUE; for(ty = ybegin ; (ty <= apd->dd.PlotYmax) && (ty >= apd->dd.PlotYmin) ; ty += yinc) CalcAndPlot(tx2, ty); tx2 += xspc; if( (tx2 < apd->dd.PlotXmin) || (tx2 > apd->dd.PlotXmax) ) alongyflag = FALSE; /* Check for Stop Plot from user */ if(message = (struct IntuiMessage *) GetMsg(win->UserPort)) { if(IsStopPlot(message) == TRUE) goto EndDrawGraph; } /* if */ } /* if */ } while (alongxflag || alongyflag); } /* else */ break; case PLOTHIDDEN: case PLOTFILLED: #if DEBUG printf("Pre-InitArea\n"); #endif InitArea(&areainfo, &areabuffer[0], 6); #if DEBUG printf("InitArea\n"); #endif rastport->AreaInfo = &areainfo; #if DEBUG printf("rastport->AreaInfo\n"); #endif myplane = (PLANEPTR)AllocRaster(320,200); #if DEBUG printf("AllocRaster\n"); #endif if(myplane == NULL) break; #if DEBUG printf("myplane == NULL\n"); #endif rastport->TmpRas = (struct TmpRas *)InitTmpRas(&tmpras, myplane, RASSIZE(320,200)); #if DEBUG printf("Allocated tmpras\n"); #endif if(alongxflag) { /* Plot along X-axis */ yminend = apd->dd.PlotYmin; ymaxend = apd->dd.PlotYmax; /* Prevent going one yspc to far at end of plot */ if(ybegin < yend) ymaxend = apd->dd.PlotYmax - yspc; else yminend = apd->dd.PlotYmin - yspc; for(ty = ybegin ; (ty <= ymaxend) && (ty >= yminend) ; ty += yspc) { /* Check for Stop Plot from user */ if(message = (struct IntuiMessage *) GetMsg(win->UserPort)) { if(IsStopPlot(message) == TRUE) goto EndDrawGraph; } /* if */ /* Initialize starting plot points */ ybeginspc = ty + yspc; Calculate(xbegin, ty, calc(xbegin, ty)); xp4 = xp; yp4 = yp; Calculate(xbegin, ybeginspc, calc(xbegin, ybeginspc)); xp3 = xp; yp3 = yp; /* Plot along X-axis */ for(tx = xbegin + xspc ; (tx <= apd->dd.PlotXmax) && (tx >= apd->dd.PlotXmin) ; tx += xspc) CalcAndPlot2(tx, ty, alongxflag); } /* for */ } /* if */ else { /* Plot along Y-axis */ xminend = apd->dd.PlotXmin; xmaxend = apd->dd.PlotXmax; /* Prevent going one xspc to far at end of plot */ if(xbegin < xend) xmaxend = apd->dd.PlotXmax - xspc; else xminend = apd->dd.PlotXmin - xspc; for(tx = xbegin ; (tx <= xmaxend) && (tx >= xminend) ; tx += xspc) { /* Check for Stop Plot from user */ if(message = (struct IntuiMessage *) GetMsg(win->UserPort)) { if(IsStopPlot(message) == TRUE) goto EndDrawGraph; } /* if */ /* Initialize starting plot points */ xbeginspc = tx + xspc; Calculate(tx, ybegin, calc(tx, ybegin)); xp4 = xp; yp4 = yp; Calculate(xbeginspc, ybegin, calc(xbeginspc, ybegin)); xp3 = xp; yp3 = yp; /* Plot along X-axis */ for(ty = ybegin + yspc ; (ty <= apd->dd.PlotYmax) && (ty >= apd->dd.PlotYmin) ; ty += yspc) CalcAndPlot2(tx, ty, alongxflag); } /* for */ } /* else */ FreeRaster(myplane, 320, 200); break; default: break; } /* switch */ /* DRAW AXES */ switch(apd->pi.AxesType) { case AXESTYPENONE: break; case AXESTYPESTAR: /* X-axis */ if (apd->ad.AxesXmax > apd->ad.AxesXmin) { /* Do not plot if equal */ ty = 0; tz = 0; for (tx = apd->ad.AxesXmin ; tx <= apd->ad.AxesXmax ; tx += apd->ad.AxesPrecision) AxesCalcAndPlot(tx, ty, tz); } /* Y-axis */ if (apd->ad.AxesYmax > apd->ad.AxesYmin) { tx = 0; tz = 0; for (ty = apd->ad.AxesYmin ; ty <= apd->ad.AxesYmax ; ty += apd->ad.AxesPrecision) AxesCalcAndPlot(tx, ty, tz); } /* Z-axis */ if (apd->ad.AxesZmax > apd->ad.AxesZmin) { tx = 0; ty = 0; for (tz = apd->ad.AxesZmin ; tz <= apd->ad.AxesZmax ; tz += apd->ad.AxesPrecision) AxesCalcAndPlot(tx, ty, tz); } break; case AXESTYPEBOX: /* X-axis */ if (apd->ad.AxesXmax > apd->ad.AxesXmin) { /* Do not plot if equal */ for (tx = apd->ad.AxesXmin ; tx <= apd->ad.AxesXmax ; tx += apd->ad.AxesPrecision) { AxesCalcAndPlot(tx, apd->ad.AxesYmin, apd->ad.AxesZmin); AxesCalcAndPlot(tx, apd->ad.AxesYmin, apd->ad.AxesZmax); AxesCalcAndPlot(tx, apd->ad.AxesYmax, apd->ad.AxesZmin); AxesCalcAndPlot(tx, apd->ad.AxesYmax, apd->ad.AxesZmax); } /* for */ } /* if */ /* Y-axis */ if (apd->ad.AxesYmax > apd->ad.AxesYmin) { for (ty = apd->ad.AxesYmin ; ty <= apd->ad.AxesYmax ; ty += apd->ad.AxesPrecision) { AxesCalcAndPlot(apd->ad.AxesXmin, ty, apd->ad.AxesZmin); AxesCalcAndPlot(apd->ad.AxesXmin, ty, apd->ad.AxesZmax); AxesCalcAndPlot(apd->ad.AxesXmax, ty, apd->ad.AxesZmin); AxesCalcAndPlot(apd->ad.AxesXmax, ty, apd->ad.AxesZmax); } /* for */ } /* if */ /* Z-axis */ if (apd->ad.AxesZmax > apd->ad.AxesZmin) { for (tz = apd->ad.AxesZmin ; tz <= apd->ad.AxesZmax ; tz += apd->ad.AxesPrecision) { AxesCalcAndPlot(apd->ad.AxesXmin, apd->ad.AxesYmin, tz); AxesCalcAndPlot(apd->ad.AxesXmin, apd->ad.AxesYmax, tz); AxesCalcAndPlot(apd->ad.AxesXmax, apd->ad.AxesYmin, tz); AxesCalcAndPlot(apd->ad.AxesXmax, apd->ad.AxesYmax, tz); } /* for */ } /* if */ break; default: break; } /* switch */ EndDrawGraph: plottinggraph = FALSE; } /* DrawGraph */ VOID DrawContour(VOID) { struct IntuiMessage *message; WORD lowX, lowY; WORD highX, highY; LONG pennum; DOUBLE tx, ty, tz; DOUBLE stepvalX, stepvalY; DOUBLE calcspacex, calcspacey; plottinggraph = TRUE; /* Set up ranges */ lowX = 0; lowY = 0; highX = win->Width - 1; highY = win->Height - 1; stepvalX = (apd->dd.PlotXmax - apd->dd.PlotXmin) / highX; stepvalY = (apd->dd.PlotYmax - apd->dd.PlotYmin) / highY; calcspacex = apd->dd.LineSpacingX; calcspacey = apd->dd.LineSpacingY; /* CALCULATE MINIMUM & MAXIMUM DISTANCES FROM USER */ /* Initialize minimum & maximum */ tz = calc(apd->dd.PlotXmin,apd->dd.PlotYmin); dmax = tz; dmin = tz; /* Loop over entire screen */ for (ty = apd->dd.PlotYmin ; ty <= apd->dd.PlotYmax ; ty += calcspacey) { /* Check for Stop Plot from user */ if(message = (struct IntuiMessage *) GetMsg(win->UserPort)) { if(IsStopPlot(message) == TRUE) goto EndDrawContour; } /* if */ for (tx = apd->dd.PlotXmin ; tx <= apd->dd.PlotXmax ; tx += calcspacex) { tz = calc(tx,ty); dmax = MAX(dmax,tz); dmin = MIN(dmin,tz); } /* for */ } /* for */ /* Calculate depth of each color range */ colorspread = (dmax - dmin)/numcolors; if (colorspread == 0) colorspread = 1; /* in case all points equidistant */ /* Plot over entire screen */ for (ty = apd->dd.PlotYmax, yp = lowY ; yp <= highY ; ty -= stepvalY, yp += 1) { /* Check for Stop Plot from user */ if(message = (struct IntuiMessage *) GetMsg(win->UserPort)) { if(IsStopPlot(message) == TRUE) goto EndDrawContour; } /* if */ for (tx = apd->dd.PlotXmin, xp = lowX ; xp <= highX ; tx += stepvalX, xp += 1) { tz = calc(tx,ty); pennum = (LONG)((tz - dmin)/colorspread) + pennumbase; if (pennum > pennummax) pennum = pennummax; if (pennum < pennumbase) pennum = pennumbase; SetAPen(rastport,pennum); WritePixel(rastport,xp,yp); } /* for */ } /* for */ EndDrawContour: plottinggraph = FALSE; } /* DrawContour */