home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 344b.lha / plplot_v2.6 / src / plfill.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-01-27  |  5.1 KB  |  225 lines

  1. #include "plplot.h"
  2. #include "declare.h"
  3. #include <math.h>
  4. #ifdef PLSTDC
  5. #include <stdlib.h>
  6. #else
  7. extern char *malloc();
  8. extern char *realloc();
  9. extern void free();
  10. #endif
  11.  
  12. #define betw(ix,ia,ib)  (((ix)<=(ia)&&(ix)>=(ib)) || ((ix)>=(ia)&&(ix)<=(ib)))
  13. #define ssqr(a,b)       sqrt((a)*(a)+(b)*(b))
  14. #define sign(a)         ((a)<0 ? -1 : 1)
  15. #define DTOR            0.0174533
  16. #define BINC            50
  17.  
  18. struct point {
  19.    short x, y;
  20. };
  21.  
  22. static short bufferleng, buffersize, *buffer;
  23.  
  24. void plfill(n,x,y)
  25. PLINT n;
  26. PLFLT *x, *y;
  27. {
  28.    PLINT i,level;
  29.    PLINT xmin, ymin, x1, y1, x2, y2, x3, y3;
  30.    PLINT k, dinc;
  31.    PLFLT ci, si, thetd;
  32.    short swap;
  33.    int compare();
  34.    void buildlist(), qsort(), tran();
  35.  
  36.    glev(&level);
  37.    if (level<3) plexit("Please set up window before calling plfill.");
  38.    if (n<3) plexit("Not enough points in plfill object!");
  39.  
  40.    buffersize = 2*BINC;
  41.    buffer = (short *)malloc(buffersize*sizeof(short));
  42.    if(!buffer)
  43.       plexit("Out of memory in plfill.");
  44.  
  45.    for(k=0; k<nps; k++) {
  46.       bufferleng = 0;
  47.  
  48.       if(abs(inclin[k]) <= 450) {
  49.          thetd = atan(tan(DTOR*inclin[k]/10.)*ypmm/xpmm);
  50.          swap = 0;
  51.       }
  52.       else {
  53.          thetd = atan(tan(DTOR*sign(inclin[k])*
  54.                           (abs(inclin[k])-900)/10.)*xpmm/ypmm);
  55.          swap = 1;
  56.       }
  57.       ci = cos(thetd);
  58.       si = sin(thetd);
  59.       if(swap)
  60.          dinc = delta[k]*ssqr(xpmm*abs(ci),ypmm*abs(si))/1000.;
  61.       else
  62.          dinc = delta[k]*ssqr(ypmm*abs(ci),xpmm*abs(si))/1000.;
  63.  
  64.       xmin = wcpcx(x[0]); ymin = wcpcy(y[0]);
  65.       for(i=1; i<n; i++) {
  66.          xmin = min(xmin,wcpcx(x[i]));
  67.          ymin = min(ymin,wcpcy(y[i]));
  68.       }
  69.  
  70.       x1 = wcpcx(x[0]) - xmin;
  71.       y1 = wcpcy(y[0]) - ymin;
  72.       tran(&x1,&y1,ci,si);
  73.       x2 = wcpcx(x[1]) - xmin;
  74.       y2 = wcpcy(y[1]) - ymin;
  75.       tran(&x2,&y2,ci,si);
  76.       for(i=2; i<n; i++) {
  77.          x3 = wcpcx(x[i]) - xmin;
  78.          y3 = wcpcy(y[i]) - ymin;
  79.          tran(&x3,&y3,ci,si);
  80.          if(swap)
  81.             buildlist(y1,x1,y2,x2,y3,x3,dinc);
  82.          else
  83.             buildlist(x1,y1,x2,y2,x3,y3,dinc);
  84.          x1 = x2; y1 = y2;
  85.          x2 = x3; y2 = y3;
  86.       }
  87.       x3 = wcpcx(x[0]) - xmin;
  88.       y3 = wcpcy(y[0]) - ymin;
  89.       tran(&x3,&y3,ci,si);
  90.       if(swap)
  91.          buildlist(y1,x1,y2,x2,y3,x3,dinc);
  92.       else
  93.          buildlist(x1,y1,x2,y2,x3,y3,dinc);
  94.  
  95.       x1 = x2; y1 = y2;
  96.       x2 = x3; y2 = y3;
  97.       x3 = wcpcx(x[1]) - xmin;
  98.       y3 = wcpcy(y[1]) - ymin;
  99.       tran(&x3,&y3,ci,si);
  100.       if(swap)
  101.          buildlist(y1,x1,y2,x2,y3,x3,dinc);
  102.       else
  103.          buildlist(x1,y1,x2,y2,x3,y3,dinc);
  104.  
  105.       /* Sort list by y then x */
  106.       qsort((char *)buffer,bufferleng/2,sizeof(struct point),compare);
  107.  
  108.       /* OK, now do the hatching */
  109.       i = 0;
  110.       while(i<bufferleng) {
  111.          if(swap) {
  112.             x1 = buffer[i+1]; y1 = buffer[i];
  113.          }
  114.          else {
  115.             x1 = buffer[i]; y1 = buffer[i+1];
  116.          }
  117.          i += 2;
  118.          x2 = x1; y2 = y1;
  119.          tran(&x1,&y1,ci,-si);
  120.          movphy(x1+xmin,y1+ymin);
  121.          if(swap) {
  122.             x1 = buffer[i+1]; y1 = buffer[i];
  123.          }
  124.          else {
  125.             x1 = buffer[i]; y1 = buffer[i+1];
  126.          }
  127.          i += 2;
  128.          if((swap && x2 != x1) || (!swap && y2 != y1))
  129.             continue;          /* Uh oh we're lost */
  130.          tran(&x1,&y1,ci,-si);
  131.          draphy(x1+xmin,y1+ymin);
  132.       }
  133.  
  134.    }
  135.    free((VOID *)buffer);
  136. }
  137.  
  138. void tran(a,b,c,d)
  139. PLINT *a, *b;
  140. PLFLT c, d;
  141. {
  142.    PLINT ta, tb;
  143.  
  144.    ta = *a;
  145.    tb = *b;
  146.  
  147.    *a = round(ta*c + tb*d);
  148.    *b = round(tb*c - ta*d);
  149. }
  150.  
  151. void buildlist(x1,y1,x2,y2,x3,y3,dinc)
  152. int x1, y1, x2, y2, x3, y3;
  153. {
  154.    int i;
  155.    int dx, dy, cstep, nstep, lines, ploty, plotx;
  156.    void addcoord();
  157.  
  158.    dx = x2 - x1; dy = y2 - y1;
  159.  
  160.    if(dy == 0) return;
  161.  
  162.    cstep = (y2>y1 ? 1 : -1);
  163.    nstep = (y3>y2 ? 1 : -1);
  164.    if(y3 == y2) nstep = 0;
  165.  
  166.    /* Build coordinate list */
  167.    lines = abs(dy)/dinc + 1;
  168.    if(cstep == 1  && y1 > 0)
  169.       ploty = (y1/dinc + 1)*dinc;
  170.    else if (cstep == -1 && y1 < 0)
  171.       ploty = (y1/dinc - 1)*dinc;
  172.    else
  173.       ploty = (y1/dinc)*dinc;
  174.  
  175.    for(i=0; i<lines; i++) {
  176.       if(!betw(ploty,y1,y2)) break;
  177.       plotx = x1 + round(((float)(ploty-y1)*dx)/dy + .5);
  178.       /* Check for extremum at end point, otherwise add to coord list */
  179.       if(!((ploty == y1) || (ploty == y2 && nstep != cstep)))
  180.          addcoord(plotx,ploty);
  181.       ploty += cstep*dinc;
  182.    }
  183. }
  184.  
  185. void addcoord(x1, y1)
  186. int x1, y1;
  187. {
  188.    short *temp;
  189.  
  190.    if(bufferleng + 2 > buffersize) {
  191.       buffersize += 2*BINC;
  192.       temp = (short *)realloc((VOID *)buffer,buffersize*sizeof(short));
  193.       if(!temp) {
  194.          free((VOID *)buffer);
  195.          plexit("Out of memory in plfill!");
  196.       }
  197.       buffer = temp;
  198.    }
  199.  
  200.    buffer[bufferleng++] = x1;
  201.    buffer[bufferleng++] = y1;
  202. }
  203.  
  204. int compare(pnum1, pnum2)
  205. char *pnum1, *pnum2;
  206. {
  207.    struct point *pnt1, *pnt2;
  208.  
  209.    pnt1 = (struct point *)pnum1;
  210.    pnt2 = (struct point *)pnum2;
  211.  
  212.    if(pnt1->y < pnt2->y)
  213.       return(-1);
  214.    else if(pnt1->y > pnt2->y)
  215.       return(1);
  216.  
  217.    /* Only reach here if y coords are equal, so sort by x */
  218.    if(pnt1->x < pnt2->x)
  219.       return(-1);
  220.    else if(pnt1->x > pnt2->x)
  221.       return(1);
  222.  
  223.    return(0);
  224. }
  225.