home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fish 'n' More 2
/
fishmore-publicdomainlibraryvol.ii1991xetec.iso
/
fish
/
math
/
3dplot
/
src
/
plot15.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-01-19
|
26KB
|
1,077 lines
/*---------------- 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 */