home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 329.lha / MultiPlot / source / plot.c < prev    next >
C/C++ Source or Header  |  1990-01-05  |  12KB  |  463 lines

  1. #include "struct.h"
  2. #include "plot.h"
  3. #include <graphics/gfxmacros.h>
  4.  
  5. extern struct Window *window;
  6. extern int CHARWIDTH;
  7. extern int CHARHEIGHT;
  8. extern int LMARGIN;  /* CHARWIDTH x 7 */
  9. extern int TMARGIN;
  10. extern int BMARGIN;    /* CHARHEIGHT x 3 */
  11. extern int XMINP;      /* LMARGIN */
  12. extern int YMAXP;   /* MAXVERT - TMARGIN */
  13. extern int YMINP;    /* BMARGIN */
  14.  
  15. extern int debug;
  16. extern int MAXVERT;
  17. extern FFP fround();
  18. extern struct Pict *Pict;
  19.  
  20. struct TextAttr xfont = { "Times.font", 14, 0, 1 };
  21. struct TextAttr yfont = { "Times.font", 14, 0, 1 };
  22.  
  23. struct TextAttr tfont = { "Times.font", 24, 0, 1 };
  24.  
  25.  
  26. struct IntuiText XITLabel = {
  27.         1,0,JAM1, /* front and back text pens, drawmode and fill byte */
  28.         0,0,    /* XY origin relative to container TopLeft */
  29.         &xfont,   /* font pointer or NULL for default */
  30.         NULL,     /* pointer to text */
  31.         NULL    /* next IntuiText structure */
  32. };
  33.  
  34. struct IntuiText YITLabel = {
  35.         1,0,JAM1, /* front and back text pens, drawmode and fill byte */
  36.         0,0,    /* XY origin relative to container TopLeft */
  37.         &yfont,   /* font pointer or NULL for default */
  38.         NULL,     /* pointer to text */
  39.         NULL    /* next IntuiText structure */
  40. };
  41.  
  42. struct IntuiText TITLabel = {
  43.         1,0,JAM1, /* front and back text pens, drawmode and fill byte */
  44.         0,0,    /* XY origin relative to container TopLeft */
  45.         &tfont,   /* font pointer or NULL for default */
  46.         NULL,     /* pointer to text */
  47.         NULL    /* next IntuiText structure */
  48. };
  49.  
  50. struct TextFont *xf;
  51. struct TextFont *yf;
  52. struct TextFont *tf;
  53.  
  54. AllowForText()
  55. {
  56.    if (Pict->XLabel!=NULL) {
  57.       xf=(struct TextFont *) OpenDiskFont(&xfont);
  58.       if (xf)  {
  59.                  YMINP = BMARGIN=( xfont.ta_YSize +CHARHEIGHT *4);
  60.                  CloseFont(xf);
  61.                }
  62.       else YMINP = BMARGIN= CHARHEIGHT *5;
  63.    }
  64.    if (Pict->Title!=NULL) {
  65.       tf=(struct TextFont *) OpenDiskFont(&tfont);
  66.       if (tf) {
  67.                 YMAXP = MAXVERT - (TMARGIN=( tfont.ta_YSize +CHARHEIGHT *2));
  68.                 CloseFont(tf);
  69.               }
  70.       else YMAXP = MAXVERT- (TMARGIN=CHARHEIGHT*3);
  71.    }
  72.    if (Pict->YLabel!=NULL) {
  73.       yf=(struct TextFont *) OpenDiskFont(&yfont);
  74.       YITLabel.IText=Pict->YLabel;
  75.       if (yf) {
  76.                  XMINP=LMARGIN=abs(IntuiTextLength(&YITLabel)/strlen(Pict->YLabel))+(9*CHARWIDTH);
  77.                  CloseFont(yf);
  78.               }
  79.       else XMINP=LMARGIN=9*CHARWIDTH;
  80.    }
  81.    return(0);
  82. }
  83.  
  84.  
  85. /**********************/
  86. void GetDataLimits(Pict)
  87. struct Pict *Pict;
  88. {
  89.    short i;
  90.    FFP *x, *y, *e;
  91.    struct Plot *Plot;
  92.    FFP xmin, xmax, ymin, ymax;
  93.  
  94.    xmin = (ymin = FFPLARGE);
  95.    xmax = (ymax = -FFPLARGE);
  96.  
  97.    Plot = Pict->Plot;
  98.    while (Plot) {
  99.       if (Plot->Enabled) {
  100.          i = 0; x = Plot->x; y = Plot->y;
  101.          if (Pict->ShowErr) e = Plot->e;
  102.          while (i++ < Plot->NPts) {
  103.             xmax = max(*x,xmax);
  104.             xmin = min(*x,xmin);
  105.             x++;
  106.             if (Pict->ShowErr) {
  107.                ymax = max((*y + *e), ymax);
  108.                ymin = min((*y - *e), ymin);
  109.                y++; e++;
  110.             }
  111.             else {
  112.                ymax = max(*y,ymax);
  113.                ymin = min(*y,ymin);
  114.                y++;
  115.             }
  116.          }
  117.       }
  118.       Plot = Plot->NextPlot;
  119.    }
  120.  
  121.    if (!Pict->XRegionLock)
  122.       {Pict->CurrReg->XMax = xmax; Pict->CurrReg->XMin = xmin;}
  123.    if (!Pict->YRegionLock)
  124.       {Pict->CurrReg->YMax = ymax; Pict->CurrReg->YMin = ymin;}
  125. }
  126.  
  127.  
  128. /*****************************************/
  129. void AdjustForTics(dmin, dmax, ntics, tics)
  130. FFP *dmin, *dmax, *tics;
  131. short ntics;
  132. {
  133.    FFP tmp, fract, f_ntics;
  134.    short i;
  135.  
  136.    f_ntics = (FFP)(ntics);
  137.    fract = (FFP)(ntics+1) / f_ntics;
  138.  
  139.    /*** adjust data limits to make "nice" numbers for tic marks ***/
  140.    tmp = *dmin - (*dmax - *dmin) / 5;
  141.    *dmin = fround( *dmin, DOWN, tmp);
  142.    tmp = (*dmax - *dmin) / f_ntics;
  143.    tmp = fround( tmp, UP, (tmp * fract) );
  144.    *dmax = *dmin + tmp * f_ntics;
  145.  
  146.    tics[0] = fround( *dmin, UP, *dmin+tmp/2);
  147.    if (debug) printf("... tic[0]=%f\n", tics[0]);
  148.    for (i=1; i<ntics; i++) {
  149.       tics[i] = tics[i-1] + tmp;
  150.       if (debug) printf("... tic[%d]=%f\n", i, tics[i]);
  151.    }
  152. }
  153.  
  154.  
  155. /**************/
  156. void Scale(Pict)
  157. struct Pict *Pict;
  158. {
  159.    struct Plot *Plot;
  160.    struct PlotRegion *Reg;
  161.    struct Tics *Tics;
  162.    register short i, *xp, *yp;
  163.    register FFP *x, *y, xmin, ymin, xscale, yscale;
  164.    short *ep, err, err_sav = TRUE;
  165.    FFP *e, xmax, ymax;
  166.  
  167.    if (debug) printf("Scale: entry\n");
  168.    Reg = Pict->CurrReg;
  169.    xmin = Reg->XMin; xmax = Reg->XMax;
  170.    ymin = Reg->YMin; ymax = Reg->YMax;
  171.  
  172.    if (FFPSAME(xmax,xmin))
  173.       {printf("Scale: xmax = xmin, xscale := 0.\n"); xscale = (FFP)0;}
  174.    else
  175.       Pict->XScale = xscale = (FFP)(XMAXP-XMINP) / (xmax - xmin);
  176.    if (FFPSAME(ymax,ymin))
  177.       {printf("Scale: ymax = ymin, yscale := 0.\n"); yscale = (FFP)0;}
  178.    else
  179.       Pict->YScale = yscale = (FFP)(YMAXP-YMINP) / (ymax - ymin);
  180.  
  181. #define NEW_X_REGION ( !FFPSAME(Reg->XMin,xmin) || !FFPSAME(Reg->XMax,xmax) )
  182. #define NEW_Y_REGION ( !FFPSAME(Reg->YMin,ymin) || !FFPSAME(Reg->YMax,ymax) )
  183.  
  184.    /* DATA */
  185.    Plot = Pict->Plot;
  186.    err = Pict->ShowErr;
  187.    while (Plot) {
  188.       if (Plot->Enabled) {
  189.          Reg = Plot->Reg;
  190.  
  191.          if (NEW_X_REGION) {
  192.             x = Plot->x; xp = Plot->xp;
  193.             for (i = 0; i < Plot->NPts; i++) {
  194.                *xp++ = XMINP + (short)((*x++ - xmin) * xscale);
  195.                if (debug) printf("*xp=%d\n", *(xp-1));
  196.             }
  197.             Reg->XMin = xmin; Reg->XMax = xmax;
  198.          }
  199.  
  200.          if ( (NEW_Y_REGION) || (err_sav!=err) ) {
  201.             y = Plot->y; yp = Plot->yp; e = Plot->e; ep = Plot->ep;
  202.             for (i = 0; i < Plot->NPts; i++) {
  203.                *yp++ = YMINP + (short)((*y++ - ymin) * yscale);
  204.                if (debug) printf("*yp=%d", *(yp-1));
  205.                if (err) {
  206.                   *ep++ = (short)(*e++ * yscale);
  207.                   if (debug) printf(", *ep=%d", *(ep-1));
  208.                }
  209.                if (debug) printf("\n");
  210.             }
  211.             Reg->YMin = ymin; Reg->YMax = ymax;
  212.          }
  213.  
  214.       }
  215.       Plot = Plot->NextPlot;
  216.    }
  217.    err_sav = err;
  218.  
  219.    /* TICS */
  220.    Tics = Pict->Tics;
  221.    for (i=0; i < Tics->NX; i++)
  222.       Tics->xp[i] = XMINP + (short)((Tics->x[i] - xmin) * xscale);
  223.  
  224.    for (i=0; i < Tics->NY; i++)
  225.       Tics->yp[i] = YMINP + (short)((Tics->y[i] - ymin) * yscale);
  226.  
  227.    if (debug) printf("Scale: entry\n");
  228. }
  229.  
  230.  
  231. /**********************/
  232. void DrawAxes(Tics,Grid)
  233. struct Tics *Tics; short Grid;
  234. {
  235.    short *xp, *yp, n, tmpx, tmpy, i;
  236.    char tmpstr[20];
  237.  
  238.  
  239.    /*** DRAW BORDER ***/
  240.    SetDrMd(rp, JAM1);
  241.    SetAPen(rp,2); SetOPen(rp,1);
  242.    PRectFill(XMINP-1,YMINP-1,XMAXP+1,YMAXP+1);
  243.    PRectFill(XMINP,YMINP,XMAXP,YMAXP);
  244.  
  245.    /*** DRAW TICS/GRID ***/
  246.    SetAPen(rp,3);
  247.    xp=Tics->xp; yp=Tics->yp;
  248.    if (Grid) SetRGB4(vp,3,0,15,15);
  249.    for (i=1; i < Tics->NX; i++) {
  250.       if (Grid) {
  251.          PMove(xp[i],YMINP+1); PDraw(xp[i],YMAXP-1);
  252.       }
  253.       else {
  254.          PMove(xp[i],YMINP+1); PDraw(xp[i],YMINP+X_TIC_SIZE);
  255.          PMove(xp[i],YMAXP-1); PDraw(xp[i],YMAXP-X_TIC_SIZE);
  256.       }
  257.    }
  258.    for (i=1; i < Tics->NY; i++) {
  259.       if (Grid) {
  260.          PMove(XMINP+1,yp[i]); PDraw(XMAXP-1,yp[i]);
  261.       }
  262.       else {
  263.          PMove(XMINP+1,yp[i]); PDraw(XMINP+Y_TIC_SIZE,yp[i]);
  264.          PMove(XMAXP-1,yp[i]); PDraw(XMAXP-Y_TIC_SIZE,yp[i]);
  265.       }
  266.    }
  267.  
  268.    /*** PRINT TIC VALUES AND TEXT ***/
  269.    SetAPen(rp,1);
  270.    for (i=0; i < Tics->NX; i++) {
  271.       n = sprintf(&tmpstr, "%-.4f", Tics->x[i]);
  272.       n = min(n, 7);
  273.       while (tmpstr[n-1] == '0') n--;
  274.       tmpx = Tics->xp[i] - ((n/2) - (FFP)1/2) * CHARWIDTH;
  275.       tmpy = max(0, YMINP-2*CHARHEIGHT);
  276.       PMove(tmpx, tmpy); Text(rp,tmpstr,n);
  277.    }
  278.  
  279.    XITLabel.IText=Pict->XLabel;
  280.    n=IntuiTextLength(&XITLabel);
  281.    tmpx=( (LMARGIN + (XMAXP-XMINP)/2) - (n/2) );
  282.    tmpy = (MAXVERT-xfont.ta_YSize-CHARHEIGHT);
  283.    PrintIText(rp,&XITLabel,tmpx,tmpy);
  284.  
  285.    TITLabel.IText=Pict->Title;
  286.    n=IntuiTextLength(&TITLabel);
  287.    tmpx=( (MAXHORIZ/2) - (n/2) );
  288.    tmpy = (CHARHEIGHT);
  289.    PrintIText(rp,&TITLabel,tmpx,tmpy);
  290.  
  291.    PrintVText(rp,&YITLabel,2,(MAXVERT/2)-( (strlen(Pict->YLabel)/2)*(yfont.ta_YSize+1)));
  292.  
  293.    for (i=0; i < Tics->NY; i++) {
  294.       n = sprintf(&tmpstr, "%-.4f", Tics->y[i]);
  295.       n = min( n, (LMARGIN/CHARWIDTH)-1 );
  296.       while (tmpstr[n-1] == '0') n--;
  297.       tmpx = max(0, XMINP-(n+1)*CHARWIDTH);
  298.       PMove(tmpx, Tics->yp[i]-CHARHEIGHT/2); Text(rp,tmpstr,n);
  299.    }
  300. }
  301.  
  302.  
  303. /*****************/
  304. void DrawPlot(Pict)
  305. struct Pict *Pict;
  306. {
  307.    struct Plot *Plot;
  308.    short *x, *y, *e, n, m, i;
  309.  
  310.    SetDrMd(rp, JAM1);
  311.  
  312.    Plot = Pict->Plot;
  313.    while (Plot) {
  314.       if (Plot->Enabled) {
  315.          SetAPen(rp, Plot->Color);
  316.  
  317.          /* PLOT POINTS */
  318.          if (Plot->PointSize != 0) {
  319.             n = Plot->PointSize;
  320.             if (abs(n) > 2) {m = (abs(n)/2)-1; SetOPen(rp, Plot->Color);}
  321.             x = Plot->xp; y = Plot->yp;
  322.             for (i=0; i<Plot->NPts; i++, x++, y++) {
  323.                switch (abs(n)) {
  324.                case 0: break;
  325.                case 1: PWritePixel(*x, *y); break;
  326.                case 2: PWritePixel(*x, *y); PWritePixel(*x, *y+1); break;
  327.                case 3: PRectFill(*x, *y, *x+1, *y+1); break;
  328.                default: PRectFill(*x-m, *y-m, *x+m, *y+m); break;
  329.                }
  330.             }
  331.          }
  332.  
  333.          /* PLOT LINES */
  334.          if (Plot->PointSize <= 0) {
  335.             PMove(*Plot->xp, *Plot->yp);
  336.             x = &(Plot->xp[1]); y = &(Plot->yp[1]);
  337.             for (i=1; i<Plot->NPts; i++, x++, y++) PDraw(*x, *y);
  338.          }
  339.  
  340.          /* PLOT ERROR BARS */
  341.          if (Pict->ShowErr) {
  342.             x = Plot->xp; y = Plot->yp; e = Plot->ep;
  343.             for (i=0; i < Plot->NPts; i++, x++, y++, e++) {
  344.                PMove(*x, *y - *e); PDraw(*x, *y + *e);
  345.             }
  346.          }
  347.  
  348.       }
  349.       Plot = Plot->NextPlot;
  350.    }
  351.    SetDrMd(rp, COMPLEMENT);
  352. }
  353.  
  354.  
  355. /*************************************************************/
  356. extern int CheckUser();
  357. extern int GetHowTo();
  358. extern void CleanUp();
  359. extern USHORT chip WaitSprite[];
  360. extern struct Window *window;
  361.  
  362.  
  363. void plot(Pict)
  364. struct Pict *Pict;
  365. {
  366.    struct PlotRegion *Reg;
  367.    struct Tics *Tics;
  368.    int req = GETDATALIMITS;
  369.  
  370.    GetHowTo(Pict);
  371.    Tics = Pict->Tics;
  372.    InitWind();
  373.  
  374.    do {
  375.       switch(req) {
  376.       case GETHOWTO:
  377.          GetHowTo(Pict); /* fall thru */
  378.       case GETDATALIMITS: AllowForText(); GetDataLimits(Pict);
  379.       case REPLOT:
  380.       default: ;
  381.       }
  382.       SetPointer(window,WaitSprite,26,14,-4,-4);
  383.  
  384.       Reg = Pict->CurrReg;
  385.       if (!Pict->XRegionLock)
  386.          AdjustForTics(&Reg->XMin, &Reg->XMax, Tics->NX, Tics->x);
  387.       if (!Pict->YRegionLock)
  388.          AdjustForTics(&Reg->YMin, &Reg->YMax, Tics->NY, Tics->y);
  389.  
  390.       Scale(Pict);
  391.       SetRast(rp,0);
  392.       if (Pict->Axes) DrawAxes(Pict->Tics,Pict->Grid);
  393.  
  394.       DrawPlot(Pict);
  395.       ClearPointer(window);
  396.  
  397.       req = CheckUser(Pict);
  398.    } while (req != QUIT);
  399.  
  400.    CleanUp();
  401. }
  402.  
  403.  
  404. /***************************/
  405. void PToU(Pict, xp, yp, x, y)
  406. struct Pict *Pict;
  407. short xp, yp;
  408. FFP *x, *y;
  409. {
  410.    if (debug) printf("PToU: entry, xp=%d, yp=%d\n", xp, yp);
  411.    *x = Pict->CurrReg->XMin + (FFP)(xp-XMINP) / Pict->XScale;
  412.    *y = Pict->CurrReg->YMin + (FFP)(yp-YMINP) / Pict->YScale;
  413.    if (debug) printf("PToU: exit, *x=%f, *y=%f\n", *x, *y);
  414. }
  415.  
  416.  
  417. PrintVText(rp,PText,X,Y)
  418. struct RastPort *rp;
  419. struct IntuiText *PText;
  420. int X;
  421. int Y;
  422. {
  423. struct TextFont *f;
  424. int height;
  425. int i,n,x,y;
  426. struct TextAttr *at;
  427. static struct TextAttr old_at;
  428. char c;
  429.  
  430.    AskFont(rp,&old_at);
  431.  
  432.    while (PText)
  433.      {
  434.         SetAPen(rp,PText->FrontPen);
  435.         SetBPen(rp,PText->BackPen);
  436.         SetDrMd(rp,PText->DrawMode);
  437.         at=PText->ITextFont;
  438.         f=NULL;
  439.         f=(struct TextFont *) OpenFont(at);
  440.         if (f) {
  441.            SetFont(rp,f);
  442.            height=at->ta_YSize+1;
  443.         }
  444.         else height=9;
  445.         x=X+PText->LeftEdge+TextLength(rp,"M",1);
  446.         y=Y+PText->TopEdge;
  447.  
  448.         n=strlen(PText->IText);
  449.         for (i=0;i<n;i++)
  450.           {
  451.              c=PText->IText[i];
  452.              Move(rp,abs(x-(TextLength(rp,&c,1)/2)),y+(i*height));
  453.              Text(rp,&c,1);
  454.           }
  455.         CloseFont(f);
  456.         PText=PText->NextText;
  457.      }
  458.    f=(struct TextFont *) OpenFont(&old_at);
  459.    SetFont(rp,f);
  460.    return(0);
  461. }
  462.  
  463.