Annotation of 40BSD/cmd/cifplot/prim.c, revision 1.1.1.1

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:     }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.