bool VoronoiDiagramGenerator::voronoi(int triangulate) { struct Site *newsite, *bot, *top, *temp, *p; struct Site *v; struct Point newintstar; int pm; struct Halfedge *lbnd, *rbnd, *llbnd, *rrbnd, *bisector; struct Edge *e; PQinitialize(); bottomsite = nextone(); out_site(bottomsite); bool retval = ELinitialize(); if(!retval) return false; newsite = nextone(); while(1) { if(!PQempty()) newintstar = PQ_min(); //if the lowest site has a smaller y value than the lowest vector intersection, process the site //otherwise process the vector intersection if (newsite != (struct Site *)NULL && (PQempty() || newsite -> coord.y < newintstar.y || (newsite->coord.y == newintstar.y && newsite->coord.x < newintstar.x))) {/* new site is smallest - this is a site event*/ out_site(newsite); //output the site lbnd = ELleftbnd(&(newsite->coord)); //get the first HalfEdge to the LEFT of the new site rbnd = ELright(lbnd); //get the first HalfEdge to the RIGHT of the new site bot = rightreg(lbnd); //if this halfedge has no edge, , bot = bottom site (whatever that is) e = bisect(bot, newsite); //create a new edge that bisects bisector = HEcreate(e, le); //create a new HalfEdge, setting its ELpm field to 0 ELinsert(lbnd, bisector); //insert this new bisector edge between the left and right vectors in a linked list if ((p = intersect(lbnd, bisector)) != (struct Site *) NULL) //if the new bisector intersects with the left edge, remove the left edge's vertex, and put in the new one { PQdelete(lbnd); PQinsert(lbnd, p, dist(p,newsite)); }; lbnd = bisector; bisector = HEcreate(e, re); //create a new HalfEdge, setting its ELpm field to 1 ELinsert(lbnd, bisector); //insert the new HE to the right of the original bisector earlier in the IF stmt if ((p = intersect(bisector, rbnd)) != (struct Site *) NULL) //if this new bisector intersects with the { PQinsert(bisector, p, dist(p,newsite)); //push the HE into the ordered linked list of vertices }; newsite = nextone(); } else if (!PQempty()) /* intersection is smallest - this is a vector event */ { lbnd = PQextractmin(); //pop the HalfEdge with the lowest vector off the ordered list of vectors llbnd = ELleft(lbnd); //get the HalfEdge to the left of the above HE rbnd = ELright(lbnd); //get the HalfEdge to the right of the above HE rrbnd = ELright(rbnd); //get the HalfEdge to the right of the HE to the right of the lowest HE bot = leftreg(lbnd); //get the Site to the left of the left HE which it bisects top = rightreg(rbnd); //get the Site to the right of the right HE which it bisects out_triple(bot, top, rightreg(lbnd)); //output the triple of sites, stating that a circle goes through them v = lbnd->vertex; //get the vertex that caused this event makevertex(v); //set the vertex number - couldn't do this earlier since we didn't know when it would be processed endpoint(lbnd->ELedge,lbnd->ELpm,v); //set the endpoint of the left HalfEdge to be this vector endpoint(rbnd->ELedge,rbnd->ELpm,v); //set the endpoint of the right HalfEdge to be this vector ELdelete(lbnd); //mark the lowest HE for deletion - can't delete yet because there might be pointers to it in Hash Map PQdelete(rbnd); //remove all vertex events to do with the right HE ELdelete(rbnd); //mark the right HE for deletion - can't delete yet because there might be pointers to it in Hash Map pm = le; //set the pm variable to zero if (bot->coord.y > top->coord.y) //if the site to the left of the event is higher than the Site { //to the right of it, then swap them and set the 'pm' variable to 1 temp = bot; bot = top; top = temp; pm = re; } e = bisect(bot, top); //create an Edge (or line) that is between the two Sites. This creates //the formula of the line, and assigns a line number to it bisector = HEcreate(e, pm); //create a HE from the Edge 'e', and make it point to that edge with its ELedge field ELinsert(llbnd, bisector); //insert the new bisector to the right of the left HE endpoint(e, re-pm, v); //set one endpoint to the new edge to be the vector point 'v'. //If the site to the left of this bisector is higher than the right //Site, then this endpoint is put in position 0; otherwise in pos 1 deref(v); //delete the vector 'v' //if left HE and the new bisector don't intersect, then delete the left HE, and reinsert it if((p = intersect(llbnd, bisector)) != (struct Site *) NULL) { PQdelete(llbnd); PQinsert(llbnd, p, dist(p,bot)); }; //if right HE and the new bisector don't intersect, then reinsert it if ((p = intersect(bisector, rrbnd)) != (struct Site *) NULL) { PQinsert(bisector, p, dist(p,bot)); }; } else break; }; for(lbnd=ELright(ELleftend); lbnd != ELrightend; lbnd=ELright(lbnd)) { e = lbnd -> ELedge; clip_line(e); }; cleanup(); return true; }
void voronoi(int triangulate, Site * (*nextsite) (void)) { Site *newsite, *bot, *top, *temp, *p; Site *v; Point newintstar = {0}; char pm; Halfedge *lbnd, *rbnd, *llbnd, *rrbnd, *bisector; Edge *e; edgeinit(); siteinit(); PQinitialize(); bottomsite = (*nextsite) (); #ifdef STANDALONE out_site(bottomsite); #endif ELinitialize(); newsite = (*nextsite) (); while (1) { if (!PQempty()) newintstar = PQ_min(); if (newsite != (struct Site *) NULL && (PQempty() || newsite->coord.y < newintstar.y || (newsite->coord.y == newintstar.y && newsite->coord.x < newintstar.x))) { /* new site is smallest */ #ifdef STANDALONE out_site(newsite); #endif lbnd = ELleftbnd(&(newsite->coord)); rbnd = ELright(lbnd); bot = rightreg(lbnd); e = gvbisect(bot, newsite); bisector = HEcreate(e, le); ELinsert(lbnd, bisector); if ((p = hintersect(lbnd, bisector)) != (struct Site *) NULL) { PQdelete(lbnd); PQinsert(lbnd, p, dist(p, newsite)); } lbnd = bisector; bisector = HEcreate(e, re); ELinsert(lbnd, bisector); if ((p = hintersect(bisector, rbnd)) != (struct Site *) NULL) PQinsert(bisector, p, dist(p, newsite)); newsite = (*nextsite) (); } else if (!PQempty()) { /* intersection is smallest */ lbnd = PQextractmin(); llbnd = ELleft(lbnd); rbnd = ELright(lbnd); rrbnd = ELright(rbnd); bot = leftreg(lbnd); top = rightreg(rbnd); #ifdef STANDALONE out_triple(bot, top, rightreg(lbnd)); #endif v = lbnd->vertex; makevertex(v); endpoint(lbnd->ELedge, lbnd->ELpm, v); endpoint(rbnd->ELedge, rbnd->ELpm, v); ELdelete(lbnd); PQdelete(rbnd); ELdelete(rbnd); pm = le; if (bot->coord.y > top->coord.y) { temp = bot; bot = top; top = temp; pm = re; } e = gvbisect(bot, top); bisector = HEcreate(e, pm); ELinsert(llbnd, bisector); endpoint(e, re - pm, v); deref(v); if ((p = hintersect(llbnd, bisector)) != (struct Site *) NULL) { PQdelete(llbnd); PQinsert(llbnd, p, dist(p, bot)); } if ((p = hintersect(bisector, rrbnd)) != (struct Site *) NULL) { PQinsert(bisector, p, dist(p, bot)); } } else break; } for (lbnd = ELright(ELleftend); lbnd != ELrightend; lbnd = ELright(lbnd)) { e = lbnd->ELedge; clip_line(e); #ifdef STANDALONE out_ep(e); #endif } }
int voronoi(struct Site *(*nextsite) (void)) { struct Site *newsite, *bot, *top, *temp, *p; struct Site *v; struct Point newintstar; int pm; struct Halfedge *lbnd, *rbnd, *llbnd, *rrbnd, *bisector; struct Edge *e; int counter = 0; PQinitialize(); bottomsite = (*nextsite) (); ELinitialize(); newsite = (*nextsite) (); while (1) { if (!PQempty()) newintstar = PQ_min(); if (newsite != (struct Site *)NULL && (PQempty() || newsite->coord.y < newintstar.y || (newsite->coord.y == newintstar.y && newsite->coord.x < newintstar.x))) { /* new site is smallest */ G_percent(counter++, nsites, 2); lbnd = ELleftbnd(&(newsite->coord)); rbnd = ELright(lbnd); bot = rightreg(lbnd); e = bisect(bot, newsite); bisector = HEcreate(e, le); ELinsert(lbnd, bisector); if ((p = intersect(lbnd, bisector)) != (struct Site *)NULL) { PQdelete(lbnd); PQinsert(lbnd, p, dist(p, newsite)); } lbnd = bisector; bisector = HEcreate(e, re); ELinsert(lbnd, bisector); if ((p = intersect(bisector, rbnd)) != (struct Site *)NULL) { PQinsert(bisector, p, dist(p, newsite)); } /* get next site, but ensure that it doesn't have the same coordinates as the previous. If so, step over to the following site. Andrea Aime 4/7/2001 */ do temp = (*nextsite) (); while (temp != (struct Site *)NULL && temp->coord.x == newsite->coord.x && temp->coord.y == newsite->coord.y); newsite = temp; } else if (!PQempty()) { /* intersection is smallest */ lbnd = PQextractmin(); llbnd = ELleft(lbnd); rbnd = ELright(lbnd); rrbnd = ELright(rbnd); bot = leftreg(lbnd); top = rightreg(rbnd); v = lbnd->vertex; makevertex(v); endpoint(lbnd->ELedge, lbnd->ELpm, v); endpoint(rbnd->ELedge, rbnd->ELpm, v); ELdelete(lbnd); PQdelete(rbnd); ELdelete(rbnd); pm = le; if (bot->coord.y > top->coord.y) { temp = bot; bot = top; top = temp; pm = re; } e = bisect(bot, top); bisector = HEcreate(e, pm); ELinsert(llbnd, bisector); endpoint(e, re - pm, v); deref(v); if ((p = intersect(llbnd, bisector)) != (struct Site *)NULL) { PQdelete(llbnd); PQinsert(llbnd, p, dist(p, bot)); } if ((p = intersect(bisector, rrbnd)) != (struct Site *)NULL) { PQinsert(bisector, p, dist(p, bot)); } } else break; } G_percent(1, 1, 1); return 0; }
void voronoi(Site *(*nextsite)(void)) { Site * newsite, * bot, * top, * temp, * p, * v ; Point newintstar ; int pm , c; Halfedge * lbnd, * rbnd, * llbnd, * rrbnd, * bisector ; Edge * e ; newintstar.x = newintstar.y = c = 0; PQinitialize() ; rubyvorState.bottomsite = (*nextsite)() ; out_site(rubyvorState.bottomsite) ; ELinitialize() ; newsite = (*nextsite)() ; while (1) { if(!PQempty()) newintstar = PQ_min() ; if (newsite != (Site *)NULL && (PQempty() || newsite -> coord.y < newintstar.y || (newsite->coord.y == newintstar.y && newsite->coord.x < newintstar.x))) { /* new site is smallest */ { out_site(newsite) ; } lbnd = ELleftbnd(&(newsite->coord)) ; rbnd = ELright(lbnd) ; bot = rightreg(lbnd) ; e = bisect(bot, newsite) ; bisector = HEcreate(e, le) ; ELinsert(lbnd, bisector) ; p = intersect(lbnd, bisector) ; if (p != (Site *)NULL) { PQdelete(lbnd) ; PQinsert(lbnd, p, dist(p,newsite)) ; } lbnd = bisector ; bisector = HEcreate(e, re) ; ELinsert(lbnd, bisector) ; p = intersect(bisector, rbnd) ; if (p != (Site *)NULL) { PQinsert(bisector, p, dist(p,newsite)) ; } newsite = (*nextsite)() ; } else if (!PQempty()) /* intersection is smallest */ { lbnd = PQextractmin() ; llbnd = ELleft(lbnd) ; rbnd = ELright(lbnd) ; rrbnd = ELright(rbnd) ; bot = leftreg(lbnd) ; top = rightreg(rbnd) ; out_triple(bot, top, rightreg(lbnd)) ; v = lbnd->vertex ; makevertex(v) ; endpoint(lbnd->ELedge, lbnd->ELpm, v); endpoint(rbnd->ELedge, rbnd->ELpm, v) ; ELdelete(lbnd) ; PQdelete(rbnd) ; ELdelete(rbnd) ; pm = le ; if (bot->coord.y > top->coord.y) { temp = bot ; bot = top ; top = temp ; pm = re ; } e = bisect(bot, top) ; bisector = HEcreate(e, pm) ; ELinsert(llbnd, bisector) ; endpoint(e, re-pm, v) ; deref(v) ; p = intersect(llbnd, bisector) ; if (p != (Site *) NULL) { PQdelete(llbnd) ; PQinsert(llbnd, p, dist(p,bot)) ; } p = intersect(bisector, rrbnd) ; if (p != (Site *) NULL) { PQinsert(bisector, p, dist(p,bot)) ; } } else { break ; } } for( lbnd = ELright(getELleftend()) ; lbnd != getELrightend() ; lbnd = ELright(lbnd)) { e = lbnd->ELedge ; out_ep(e) ; } }
// // Refine a grid into a TIN_TILgE with error < e // void refineTile(TIN_TILE *tt, double e, short delaunay, short useNodata) { BOOL complete; // is maxE < e complete = 0; TRIANGLE *t1, *t2, *t3, *s; int refineCount = 0; // Read points for initial two triangles into a file initTilePoints(tt,e,useNodata); // While there still is a triangle with max error > e while(PQ_extractMin(tt->pq, &s)){ // Triangles should no longer be marked for deletion since they // are being deleted from the PQ if(s->p1p2 == NULL && s->p1p3 == NULL && s->p2p3 == NULL){ printf(strcat("skipping deleted triangle: err=",ELEV_TYPE_PRINT_CHAR), s->maxErrorValue); fflush(stdout); assert(0); removeTri(s); } assert(s); refineCount++; // malloc the point with max error as it will become a corner R_POINT* maxError = (R_POINT*)malloc(sizeof(R_POINT)); assert(maxError); maxError->x = s->maxE->x; maxError->y = s->maxE->y; maxError->z = s->maxE->z; // Add point to the correct point pointer array assert(tt->bPointsCount < tt->ncols && tt->rPointsCount < tt->nrows && tt->bPointsCount < (tt->ncols * tt->nrows)-(tt->ncols + tt->nrows)); if(maxError->x == (tt->iOffset + tt->nrows-1) ){ tt->bPoints[tt->bPointsCount]=maxError; tt->bPointsCount++; } else if(maxError->y == (tt->jOffset + tt->ncols-1) ){ tt->rPoints[tt->rPointsCount]=maxError; tt->rPointsCount++; } else{ tt->points[tt->pointsCount]=maxError; tt->pointsCount++; } // Debug - print the point being added #ifdef REFINE_DEBUG { TRIANGLE *snext; R_POINT err = findError(s->maxE->x, s->maxE->y, s->maxE->z, s); printf("Point (%6d,%6d,%6d) error=%10ld \t", s->maxE->x, s->maxE->y, s->maxE->z, err ); printTriangleCoords(s); fflush(stdout); if(err != s->maxErrorValue){ printf("Died err= %ld maxE= %ld \n",err,s->maxErrorValue); exit(1); } PQ_min(tt->pq, &snext); assert(s->maxErrorValue >= snext->maxErrorValue); } #endif // Check for collinear points. We make the valid assumption that // MaxE cannot be collinear with > 1 tri int area12,area13,area23; area12 = areaSign(s->p1, s->p2, maxError); area13 = areaSign(s->p1, maxError, s->p3); area23 = areaSign(maxError, s->p2, s->p3); // If p1 p2 is collinear with MaxE if (!area12){ fixCollinear(s->p1,s->p2,s->p3,s,e,maxError,tt,delaunay); tt->numTris++; } else if (!area13){ fixCollinear(s->p1,s->p3,s->p2,s,e,maxError,tt,delaunay); tt->numTris++; } else if (!area23){ fixCollinear(s->p2,s->p3,s->p1,s,e,maxError,tt,delaunay); tt->numTris++; } else { // add three new triangles t1 = addTri(tt,s->p1, s->p2, maxError,s->p1p2,NULL,NULL); t2 = addTri(tt,s->p1, maxError, s->p3,t1,s->p1p3,NULL); t3 = addTri(tt,maxError, s->p2, s->p3,t1,t2,s->p2p3); DEBUG{triangleCheck(s,t1,t2,t3);} tt->numTris += 2; // create poinlists from the original tri (this will yeild the max error) distrPoints(t1,t2,t3,s,NULL,e,tt); DEBUG{checkPointList(t1);checkPointList(t2);checkPointList(t3);} // Enforce delaunay on three new edges of the new triangles if // specified if(delaunay){ // we enforce on the edge that does not have maxE as an // endpoint, so the 4th argument to enforceDelaunay should // always be the maxE point to s for that particular tri enforceDelaunay(t1,t1->p1,t1->p2,t1->p3,e,tt); enforceDelaunay(t2,t2->p1,t2->p3,t2->p2,e,tt); enforceDelaunay(t3,t3->p2,t3->p3,t3->p1,e,tt); } } // remove original tri removeTri(s); //DEBUG{printTin(tt);} extern int displayValid; displayValid = 0; } s = tt->t; // The number of points added is equal to the number of refine loops tt->numPoints += refineCount; /* The number of points should be equal to the sum of all points arrays (one center and possible 4 boundary). Since the arrays have overlap of corner points we subtract the overlaps */ int pts = 0; pts = tt->pointsCount + tt->rPointsCount + tt->bPointsCount - 1; if(tt->top != NULL) pts += tt->top->bPointsCount - 2; if(tt->left != NULL) pts += tt->left->rPointsCount - 2; //assert(tt->numPoints == pts); fix // Sort the point arrays for future use and binary searching qsort(tt->rPoints,tt->rPointsCount,sizeof(R_POINT*),(void *)QS_compPoints); qsort(tt->bPoints,tt->bPointsCount,sizeof(R_POINT*),(void *)QS_compPoints); qsort(tt->points,tt->pointsCount,sizeof(R_POINT*),(void *)QS_compPoints); // We are done with the pq PQ_free(tt->pq); }