|
|
1.1 root 1: /*******************************************************************
2: * *
3: * File: CIFPLOT/prim.c *
4: * Written by Dan Fitzpatrick *
5: * copyright 1980 -- Regents of the University of California *
6: * *
7: ********************************************************************/
8:
9: #include <stdio.h>
10: #include "defs.h"
11: #include "globals.h"
12: #include "parser_defs.h"
13: #include "structs.h"
14: #include "out_structs.h"
15: #include "alloc.h"
16:
17: IMPORT GetQueue();
18: IMPORT PutQueue();
19: IMPORT PeekList();
20:
21: FORWARD real ECompare();
22:
23: AddEdges(xcurrent)
24: int xcurrent;
25: /* Add Edges from edge queue to active edge list */
26: {
27: int insert,i,Next;
28: register instance *p;
29: register edge *e;
30:
31: /*
32: p = (instance *) PeekHeap();
33: */
34: /* Next is the raster value of item on top of list */
35: /*
36: if(p==NIL) Next = Top;
37: else Next = CONVERT(p->min);
38: */
39: Next = xcurrent + 1;
40: NextEdge = NextUnAct;
41: for(i=0;i<UsedLayers;i++) {
42: insert = 0; /* insert is set to 1 if any edge has been inserted */
43: while( (EdgeQueue[i].QStart != NIL) &&
44: (((edge *) (EdgeQueue[i].QStart))->ix <= xcurrent) ) {
45: insert = 1;
46: /* Update the iy values if not valid */
47: if(Valid[i] != xcurrent) Validate(i,xcurrent);
48: e = (edge *) GetQueue(&(EdgeQueue[i]));
49: /* EdgeEnd[i] indicates when the next edge ends in layer i */
50: EdgeEnd[i] = MIN(EdgeEnd[i],e->ex);
51: PutList(e,&TempList,ECompare);
52: }
53: if(insert) {
54: MergeActives(i,&TempList);
55: /* change[i] is set to 1 if anything has changed in layer i */
56: change[i] = 1;
57: /* LastEdge indicates when the next edge ends for all layers */
58: LastEdge = MIN(LastEdge,EdgeEnd[i]);
59: /* Compute where the next edge intersection will occur on layer i */
60: Intersection(i,xcurrent);
61: }
62: /* Compute when the next edge will enter the active list for layer i */
63: if(EdgeQueue[i].QStart == NIL) EdgeStart[i] = NextUnAct;
64: else
65: EdgeStart[i] = ((edge *) (EdgeQueue[i].QStart))->ix;
66: /* NextEdge indicates when the next edge will become active */
67: NextEdge = MIN(NextEdge,EdgeStart[i]);
68: }
69: }
70:
71: RemoveEdges(xcurrent)
72: int xcurrent;
73: {
74: edge *e,*q;
75: int i;
76:
77: for(i=0;i<UsedLayers;i++)
78: /* For each layer check to see if time to remove edges */
79: if(xcurrent >= EdgeEnd[i]) {
80: for(e = (edge *) &(ActiveEdges[i]); e->Link != NIL; )
81: if(e->Link->ex <= xcurrent) {
82: /* If time to remove e->Link then unlink it. Record a change */
83: change[i] = 1;
84: q = e->Link;
85: e->Link = e->Link->Link;
86: /* If no more references to the PolyDesc then free it */
87: if(--(q->poly->refs) == 0) FreeDesc(q->poly);
88: FreeEdge(q);
89: }
90: else e=e->Link;
91: }
92: }
93:
94: Sort(xcurrent)
95: register xcurrent;
96: {
97: register int i;
98:
99: for(i=0;i<UsedLayers;i++) {
100: /* For each layer check to see if an intersection may
101: * have occured */
102: if(xcurrent >= EdgeIntersection[i]) {
103: /* Mark that a change has occured and update the y
104: * values in the active list */
105: if(Valid[i] != xcurrent) Validate(i,xcurrent);
106:
107: /* SortActive sets change[i] if anything was swapped */
108: SortActives(i);
109:
110: /* Compute where the next intersection will take place */
111: Intersection(i,xcurrent);
112: }
113: }
114: }
115:
116: Validate(i,xcurrent)
117: register int i;
118: int xcurrent;
119: /* Validate updates the y values of the elements in
120: * the active list for layer i */
121: {
122: register real diff;
123: register edge *e;
124:
125: diff = xcurrent - Valid[i];
126: for(e=(edge *) ActiveEdges[i].Link; e!=NIL; e=e->Link)
127: e->iy += diff*e->dy;
128: /* Valid[i] records the last update for layer i */
129: Valid[i] = xcurrent;
130: }
131:
132: Intersection(i,xcurrent)
133: int i,xcurrent;
134: /* Intersection calculates the next time to edges in the list cross */
135: {
136: register edge *e1,*e2;
137: register real diff; /* diff is the difference from the
138: * estimated next intersection and
139: * xcurrent (the current raster line) */
140:
141: e1 = (edge *) ActiveEdges[i].Link;
142: if(e1 == NIL || e1->Link == NIL) return;
143: /*
144: diff = MIN(EdgeIntersection[i],EdgeStart[i]) - xcurrent;
145: */
146: diff = Top - xcurrent;
147: for(e2=e1->Link; e2 != NIL && diff > 1.0;(e1 = e2, e2= e1->Link))
148: if( (e1->iy + e1->dy*diff) > (e2->iy + e2->dy*diff) ) {
149: /* Edges cross, compute intersection
150: * diff is reused as a temp but restored at end */
151: diff = e2->dy - e1->dy;
152: if(diff != 0.0) diff = (e1->iy - e2->iy)/diff;
153: }
154: EdgeIntersection[i] = MAX((int) (xcurrent + diff) - 1,xcurrent);
155: NextChange[i] = MIN(EdgeEnd[i],EdgeIntersection[i]);
156: NextChange[i] = MIN(NextChange[i],EdgeStart[i]);
157: }
158:
159: int *in;
160: real *it,*dt;
161:
162: ScanActives(xcurrent)
163: register int xcurrent;
164: {
165: register int i;
166: register edge *e;
167:
168: LastEdge = Top;
169: for(i=0; i<UsedLayers;i++) {
170: /* If change rescan active list, otherwise redraw from previous
171: * information by calling Draw */
172: if(change[i]) {
173: OutputTrap(i,xcurrent);
174: /* Update all the iy's */
175: if(Valid[i] != xcurrent) Validate(i,xcurrent);
176: /* Compute when next edge ends */
177: EdgeEnd[i] = Top;
178: in[i] = 0;
179:
180: for(e= (edge *) ActiveEdges[i].Link; e!=NIL; e=e->Link) {
181: if(e->poly->count == 0) {
182: e->poly->iy = e->iy;
183: e->poly->dy = e->dy;
184: if(in[e->poly->level]++ == 0) {
185: it[e->poly->level] = e->iy;
186: dt[e->poly->level] = e->dy;
187: if(extractor)
188: OutputExtEdge(e->iy,e->dy,e->poly->level,1);
189: }
190: }
191: if(0 == (e->poly->count += e->dir)) {
192: if(--in[e->poly->level] == 0) {
193: if(extractor)
194: OutputExtEdge(e->iy,e->dy,e->poly->level,0);
195: else
196: SendDisplay(it[e->poly->level],
197: dt[e->poly->level],
198: e->iy,e->dy,i);
199: }
200: }
201: EdgeEnd[i] = MIN(EdgeEnd[i],e->ex);
202: }
203: if(in[i]) {
204: fprintf(stderr,"in[%d] = %d\t",i,in[i]);
205: fprintf(stderr,"xcurrent = %d\n",xcurrent);
206: for(e=(edge *) ActiveEdges[i].Link;e!=NIL;e=e->Link) {
207: fprintf(stderr,"Edge %x: iy=%f, dy=%f, ix=%d, ex=%d;\n",e,e->iy,e->dy,e->ix,e->ex);
208: fprintf(stderr,"\t\tdir=%d, poly=%x\n",e->dir,e->poly);
209: }
210: Error("Bad Count in ScanActives",INTERNAL);
211: }
212: /* Reset change */
213: change[i] = 0;
214: NextChange[i] = MIN(EdgeEnd[i],EdgeIntersection[i]);
215: NextChange[i] = MIN(NextChange[i],EdgeStart[i]);
216: FinnishLine(i,xcurrent);
217: }
218: LastEdge = MIN(LastEdge,EdgeEnd[i]);
219: }
220: }
221:
222: InitScan() {
223: int i;
224: in = (int *) alloc(UsedLayers*sizeof(int));
225: it = (real *) alloc(UsedLayers*sizeof(real));
226: dt = (real *) alloc(UsedLayers*sizeof(real));
227: for(i=0; i<UsedLayers; i++) {
228: in[i] = 0;
229: }
230: }
231:
232: /*
233: DTest(i,xcurrent)
234: int i,xcurrent;
235: {
236: do {
237: Draw(i,xcurrent);
238: xcurrent++;
239: } while(xcurrent < NextChange[i]);
240: }
241: */
242:
243: real ECompare(a,b)
244: edge *a,*b;
245: {
246: return(a->iy - b->iy);
247: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.