/* "boxify", is a simple filter for cleaning up quite general CIF and make it readable for "WOL" Copyright (C) 1990 Tor Sverre Lande Author's address: bassen@ifi.uio.no This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation (any version). This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include "poly.h" #include "trapes.h" struct edge_head *new_head() { struct edge_head *h; h=(struct edge_head *)malloc(sizeof(struct edge_head)); h->first=NULL; h->last=NULL; return(h); } struct edge *new_edge() { struct edge *e; e=(struct edge *)malloc(sizeof(struct edge)); e->id=0; e->wind=0; e->next=NULL; e->mate=NULL; return(e); } #ifdef EDEBUG displayedges(eh) struct edge_head *eh; { struct edge *e; e=eh->first; if (e==NULL) fprintf(stderr,"Empty list\n"); else { while (e!=NULL) { fprintf(stderr,"Edge: %f,%f %f,%f x:%f\n",e->xl,e->yl,e->xh,e->yh,e->xx); fprintf(stderr,"Id: %d wind: %d\n",e->id,e->wind); e=e->next; } } } #endif makeedges(eh) struct edge_head *eh; /**************************************************************\ * * * Reads polygons from pl using global variable unread and * * assumes unread always contains the next polygonhead. * * Transforms a polygon into a sorted list on y of edges. * * Edges parallell to the x-axsis are dropped. * * ID and windingnumber are updated. * * Updates eh. returns value of read-statement * * * \**************************************************************/ { /* start of makeedges */ extern struct polygon *unread; extern FILE *pfile; extern long id; extern int currentmin; struct polygon x1,x2,f; struct polygon *pl; struct edge *e,*q; int i,er; #ifdef EDEBUG fprintf(stderr,"makeedges: id:%d, #%d, min:%d\n",id,unread->a,unread->b); #endif if (unread!=NULL) { id++; if ((-unread->a)<3) fprintf(stderr,"***Too few points in polygon < 3\n"); else { /* at least 3 points */ pl = unread+1; x1 = *pl; pl++; f.a=x1.a; f.b=x1.b; for (i=1;i<=-(unread->a);i++) { /* for-loop */ if (i==-(unread->a)) { /* first and last point */ x2.a=f.a; x2.b=f.b; } else { x2 = *pl; pl++; } #ifdef EDEBUG fprintf(stderr,"insert %d,%d %d,%d\n",x1.a,x1.b,x2.a,x2.b); #endif if (x1.b!=x2.b)/* should it be dropped? */ { e=new_edge(); e->wind= x1.bid=id; if (x1.bxl=x1.a; e->yl=x1.b; e->xh=x2.a; e->yh=x2.b; } else { e->xl=x2.a; e->yl=x2.b; e->xh=x1.a; e->yh=x1.b; } /* put into list */ if (eh->first==NULL) { /* first element */ eh->first=e; eh->last=e; } else { /* at least one element */ q=eh->first; if (e->yl<=q->yl) { /* put in first */ e->next=q; eh->first=e; } else { /* not first element */ while ((q->next!=NULL) && (q->next->ylyl)) q=q->next; if (q->next==NULL) { /* last element */ q->next=e; eh->last=e; e->next=NULL; } else { /* in the middle */ e->next=q->next; q->next=e; } } } } x1.a=x2.a; x1.b=x2.b; } }; return(0); } else { fprintf(stderr,"unread==NULL\n"); return(-1); } } /* end of makeedges */ mergeedges(e1,e2) struct edge_head *e1,*e2; /***********************************************************\ * * * Merges two sorted lists (e1,e2) of edges into one (e1). * * * * * \***********************************************************/ { struct edge *a,*b,*n; #ifdef EDEBUG fprintf(stderr,"mergeedges\n"); #endif a=e1->first; b=e2->first; if (a == NULL) { e1->first = b; b = b->next; } /* put in elements first */ if ((b!=NULL) && (b->ylyl)) { #ifdef EDEBUG fprintf(stderr,"inserting first\n"); #endif n=b->next; b->next=e1->first; e1->first=b; b=n; } a=e1->first; /* a.yl<=b.yl */ while (b!=NULL) { n=b->next; while ((a->next!=NULL) && (a->next->ylyl)) a=a->next; if (e1->last==a) { e1->last=b; a->next=b; b->next=NULL; } else { b->next=a->next; a->next=b; } b=n; } e2->first=NULL; e2->last=NULL; #ifdef EDEBUG fprintf(stderr,"end mergeedges\n"); #endif } updateactive(ah,eh,alt) struct edge_head *ah,*eh; /* ah - active, eh - edges */ double alt; /*********************************************************\ * * * Updates the active-list sorted on x by fetching edges * * from the edge-list sorted on y. * * * \*********************************************************/ { struct edge *a,*b; int i; #ifdef EDEBUG fprintf(stderr,"updateactive alt: %f ",alt ); #endif /* compute new crossing */ a=ah->first; while (a!=NULL) { a->xx=(fabs(alt-a->yl)xl: ((a->xh-a->xl)*(alt-a->yl))/(a->yh-a->yl)+a->xl; a=a->next; } /* resorting not nessesary because edges are splitted in crossings */ while ((eh->first!=NULL) && ((eh->first->yl<=alt) || (fabs(eh->first->yl-alt)first; /* remove from eh */ eh->first=eh->first->next; if (eh->first==NULL) { /* empty list */ eh->last=NULL; } /* compute x-value of crosspoint */ a->xx=(fabs(a->yl-alt)xl: ((a->xh-a->xl)*(alt-a->yl))/(a->yh-a->yl)+a->xl; /* add to list sorted on xx */ if (ah->first==NULL) { #ifdef EDEBUG fprintf(stderr,"first element in active\n"); #endif /* first element */ ah->first=a; ah->last=a; a->next=NULL; } else { /* at least one element */ b=ah->first; #ifdef EDEBUG if (a->xx == b->xx) { fprintf(stderr,"a->xh: %f b->xing:%f\n",a->xh,((b->xh-b->xl)*(a->yh-b->yl))/(b->yh-b->yl)+b->xl); } #endif if ((a->xx < b->xx) || ((fabs(a->xx - b->xx)xh<( ((b->xh-b->xl)*(a->yh-b->yl))/(b->yh-b->yl) +b->xl)))) { /* insert first in list */ #ifdef EDEBUG fprintf(stderr,"first el. in nonempty list\n"); #endif a->next=b; ah->first=a; } else { while ((b->next!=NULL) && (b->next->xx < a->xx)) b=b->next; #ifdef EDEBUG /*if (a->xx == b->xx) { fprintf(stderr,"b->next->xh: %f a->xing:%f\n",b->next->xh,((a->xh-a->xl)*(b->next->yh-a->yl))/(a->yh-a->yl)+a->xl); }*/ #endif while ((b->next!=NULL) && (b->next->xh< ( ((a->xh-a->xl)*(b->next->yh-a->yl))/ (a->yh-a->yl)+a->xl)) && (fabs(b->next->xx-a->xx)next->xh: %f a->xing:%f\n",b->next->xh,((a->xh-a->xl)*(b->next->yh-a->yl))/(a->yh-a->yl)+a->xl); #endif b=b->next; } if (b->next==NULL) {/* last element */ #ifdef EDEBUG fprintf(stderr,"lastelement i active\n"); #endif b->next=a; ah->last=a; a->next=NULL; } else {/* after b */ #ifdef EDEBUG fprintf(stderr,"in the middle\n"); #endif a->next=b->next; b->next=a; } } } } #ifdef EDEBUG fprintf(stderr,"end updateactive\n"); #endif return(0); }