home *** CD-ROM | disk | FTP | other *** search
- #include "plplot.h"
- #include "declare.h"
- #include <math.h>
- #ifdef PLSTDC
- #include <stdlib.h>
- #else
- extern char *malloc();
- extern char *realloc();
- extern void free();
- #endif
-
- #define betw(ix,ia,ib) (((ix)<=(ia)&&(ix)>=(ib)) || ((ix)>=(ia)&&(ix)<=(ib)))
- #define ssqr(a,b) sqrt((a)*(a)+(b)*(b))
- #define sign(a) ((a)<0 ? -1 : 1)
- #define DTOR 0.0174533
- #define BINC 50
-
- struct point {
- short x, y;
- };
-
- static short bufferleng, buffersize, *buffer;
-
- void plfill(n,x,y)
- PLINT n;
- PLFLT *x, *y;
- {
- PLINT i,level;
- PLINT xmin, ymin, x1, y1, x2, y2, x3, y3;
- PLINT k, dinc;
- PLFLT ci, si, thetd;
- short swap;
- int compare();
- void buildlist(), qsort(), tran();
-
- glev(&level);
- if (level<3) plexit("Please set up window before calling plfill.");
- if (n<3) plexit("Not enough points in plfill object!");
-
- buffersize = 2*BINC;
- buffer = (short *)malloc(buffersize*sizeof(short));
- if(!buffer)
- plexit("Out of memory in plfill.");
-
- for(k=0; k<nps; k++) {
- bufferleng = 0;
-
- if(abs(inclin[k]) <= 450) {
- thetd = atan(tan(DTOR*inclin[k]/10.)*ypmm/xpmm);
- swap = 0;
- }
- else {
- thetd = atan(tan(DTOR*sign(inclin[k])*
- (abs(inclin[k])-900)/10.)*xpmm/ypmm);
- swap = 1;
- }
- ci = cos(thetd);
- si = sin(thetd);
- if(swap)
- dinc = delta[k]*ssqr(xpmm*abs(ci),ypmm*abs(si))/1000.;
- else
- dinc = delta[k]*ssqr(ypmm*abs(ci),xpmm*abs(si))/1000.;
-
- xmin = wcpcx(x[0]); ymin = wcpcy(y[0]);
- for(i=1; i<n; i++) {
- xmin = min(xmin,wcpcx(x[i]));
- ymin = min(ymin,wcpcy(y[i]));
- }
-
- x1 = wcpcx(x[0]) - xmin;
- y1 = wcpcy(y[0]) - ymin;
- tran(&x1,&y1,ci,si);
- x2 = wcpcx(x[1]) - xmin;
- y2 = wcpcy(y[1]) - ymin;
- tran(&x2,&y2,ci,si);
- for(i=2; i<n; i++) {
- x3 = wcpcx(x[i]) - xmin;
- y3 = wcpcy(y[i]) - ymin;
- tran(&x3,&y3,ci,si);
- if(swap)
- buildlist(y1,x1,y2,x2,y3,x3,dinc);
- else
- buildlist(x1,y1,x2,y2,x3,y3,dinc);
- x1 = x2; y1 = y2;
- x2 = x3; y2 = y3;
- }
- x3 = wcpcx(x[0]) - xmin;
- y3 = wcpcy(y[0]) - ymin;
- tran(&x3,&y3,ci,si);
- if(swap)
- buildlist(y1,x1,y2,x2,y3,x3,dinc);
- else
- buildlist(x1,y1,x2,y2,x3,y3,dinc);
-
- x1 = x2; y1 = y2;
- x2 = x3; y2 = y3;
- x3 = wcpcx(x[1]) - xmin;
- y3 = wcpcy(y[1]) - ymin;
- tran(&x3,&y3,ci,si);
- if(swap)
- buildlist(y1,x1,y2,x2,y3,x3,dinc);
- else
- buildlist(x1,y1,x2,y2,x3,y3,dinc);
-
- /* Sort list by y then x */
- qsort((char *)buffer,bufferleng/2,sizeof(struct point),compare);
-
- /* OK, now do the hatching */
- i = 0;
- while(i<bufferleng) {
- if(swap) {
- x1 = buffer[i+1]; y1 = buffer[i];
- }
- else {
- x1 = buffer[i]; y1 = buffer[i+1];
- }
- i += 2;
- x2 = x1; y2 = y1;
- tran(&x1,&y1,ci,-si);
- movphy(x1+xmin,y1+ymin);
- if(swap) {
- x1 = buffer[i+1]; y1 = buffer[i];
- }
- else {
- x1 = buffer[i]; y1 = buffer[i+1];
- }
- i += 2;
- if((swap && x2 != x1) || (!swap && y2 != y1))
- continue; /* Uh oh we're lost */
- tran(&x1,&y1,ci,-si);
- draphy(x1+xmin,y1+ymin);
- }
-
- }
- free((VOID *)buffer);
- }
-
- void tran(a,b,c,d)
- PLINT *a, *b;
- PLFLT c, d;
- {
- PLINT ta, tb;
-
- ta = *a;
- tb = *b;
-
- *a = round(ta*c + tb*d);
- *b = round(tb*c - ta*d);
- }
-
- void buildlist(x1,y1,x2,y2,x3,y3,dinc)
- int x1, y1, x2, y2, x3, y3;
- {
- int i;
- int dx, dy, cstep, nstep, lines, ploty, plotx;
- void addcoord();
-
- dx = x2 - x1; dy = y2 - y1;
-
- if(dy == 0) return;
-
- cstep = (y2>y1 ? 1 : -1);
- nstep = (y3>y2 ? 1 : -1);
- if(y3 == y2) nstep = 0;
-
- /* Build coordinate list */
- lines = abs(dy)/dinc + 1;
- if(cstep == 1 && y1 > 0)
- ploty = (y1/dinc + 1)*dinc;
- else if (cstep == -1 && y1 < 0)
- ploty = (y1/dinc - 1)*dinc;
- else
- ploty = (y1/dinc)*dinc;
-
- for(i=0; i<lines; i++) {
- if(!betw(ploty,y1,y2)) break;
- plotx = x1 + round(((float)(ploty-y1)*dx)/dy + .5);
- /* Check for extremum at end point, otherwise add to coord list */
- if(!((ploty == y1) || (ploty == y2 && nstep != cstep)))
- addcoord(plotx,ploty);
- ploty += cstep*dinc;
- }
- }
-
- void addcoord(x1, y1)
- int x1, y1;
- {
- short *temp;
-
- if(bufferleng + 2 > buffersize) {
- buffersize += 2*BINC;
- temp = (short *)realloc((VOID *)buffer,buffersize*sizeof(short));
- if(!temp) {
- free((VOID *)buffer);
- plexit("Out of memory in plfill!");
- }
- buffer = temp;
- }
-
- buffer[bufferleng++] = x1;
- buffer[bufferleng++] = y1;
- }
-
- int compare(pnum1, pnum2)
- char *pnum1, *pnum2;
- {
- struct point *pnt1, *pnt2;
-
- pnt1 = (struct point *)pnum1;
- pnt2 = (struct point *)pnum2;
-
- if(pnt1->y < pnt2->y)
- return(-1);
- else if(pnt1->y > pnt2->y)
- return(1);
-
- /* Only reach here if y coords are equal, so sort by x */
- if(pnt1->x < pnt2->x)
- return(-1);
- else if(pnt1->x > pnt2->x)
- return(1);
-
- return(0);
- }
-