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 } }
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) ; } }
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; }
/* * map() maps a M2 x M1 source image fsource[i][j] onto an N2 x N1 target * image ftarget[i][j] with the mapping * ftarget(r) += fsource(r + d) * where the deflection d = (di, dj) is supplied by function deflection() * * we use the slightly confusing notation (i,j) -> (y, x) */ void map(float **ftarget, int N1, int N2, float **fsource, int M1, int M2, int (*deflection)(float ri, float rj, float *di, float *dj)) { int i, j, index, goodtriangle; float di, dj; vert *point[3], *basevert; /* set source image globals */ gfsource = fsource; gftarget = ftarget; gM1 = M1; gM2 = M2; for (i = 0; i < N2; i++) { gtargeti = i; for (j = 0; j < N1; j++) { gtargetj = j; gfsum = gareasum = 0.0; /* do the upper triangle */ point[0] = makevertex(j, i + 1); point[1] = makevertex(j + 1, i + 1); point[2] = makevertex(j + 1, i); goodtriangle = 1; for (index = 0; index < 3; index++) { goodtriangle *= deflection(point[index]->y, point[index]->x, &di, &dj); point[index]->y += di; point[index]->x += dj; } if (goodtriangle) { makering(&basevert, point, 3); if (globalmapmode == INVERSEMAPMODE) { garea = trianglearea(basevert); } decompose(basevert); } /* do the lower triangle */ point[0] = makevertex(j, i + 1); point[1] = makevertex(j, i); point[2] = makevertex(j + 1, i); goodtriangle = 1; for (index = 0; index < 3; index++) { goodtriangle *= deflection(point[index]->y, point[index]->x, &di, &dj); point[index]->y += di; point[index]->x += dj; } if (goodtriangle) { makering(&basevert, point, 3); if (globalmapmode == INVERSEMAPMODE) { garea = trianglearea(basevert); } decompose(basevert); } /* now add the pixel value */ if ((gareasum > 0.0) && (globalmapmode == FORWARDMAPMODE)) { ftarget[i][j] = gfsum / gareasum; } freeverts(); } } }
void VoronoiDiagramGenerator::clip_line(struct Edge *e) { struct Site *s1, *s2; float x1=0,x2=0,y1=0,y2=0, temp = 0; Site *v1= 0, *v2 = 0; bool needNewVertex1 = false,needNewVertex2 = false; x1 = e->reg[0]->coord.x; x2 = e->reg[1]->coord.x; y1 = e->reg[0]->coord.y; y2 = e->reg[1]->coord.y; //if the distance between the two points this line was created from is less than //the square root of 2, then ignore it if(sqrt(((x2 - x1) * (x2 - x1)) + ((y2 - y1) * (y2 - y1))) < minDistanceBetweenSites) { return; } pxmin = borderMinX; pxmax = borderMaxX; pymin = borderMinY; pymax = borderMaxY; // printf("\nEdge (%d), minX = %f, maxX = %f, minY = %f, maxY = %f",e->edgenbr,pxmin, pxmax, pymin,pymax); if(e -> a == 1.0 && e ->b >= 0.0) { s1 = e -> ep[1]; s2 = e -> ep[0]; } else { s1 = e -> ep[0]; s2 = e -> ep[1]; }; v1 = s1; v2 = s2; if(e -> a == 1.0) { y1 = pymin; if (s1!=(struct Site *)NULL && s1->coord.y > pymin) { y1 = s1->coord.y; } else { needNewVertex1 = true; } if(y1>pymax) { y1 = pymax; needNewVertex1 = true; } x1 = e -> c - e -> b * y1; y2 = pymax; if (s2!=(struct Site *)NULL && s2->coord.y < pymax) { y2 = s2->coord.y; } else { needNewVertex2 = true; } if(y2<pymin) { y2 = pymin; needNewVertex2 = true; } x2 = (e->c) - (e->b) * y2; if (((x1> pxmax) & (x2>pxmax)) | ((x1<pxmin)&(x2<pxmin))) { return; } if(x1> pxmax) { x1 = pxmax; y1 = (e -> c - x1)/e -> b;needNewVertex1 = true;} if(x1<pxmin) { x1 = pxmin; y1 = (e -> c - x1)/e -> b;needNewVertex1 = true;} if(x2>pxmax) { x2 = pxmax; y2 = (e -> c - x2)/e -> b;needNewVertex2 = true;} if(x2<pxmin) { x2 = pxmin; y2 = (e -> c - x2)/e -> b;needNewVertex2 = true;} } else { x1 = pxmin; if (s1!=(struct Site *)NULL && s1->coord.x > pxmin) { x1 = s1->coord.x; } else { needNewVertex1 = true; } if(x1>pxmax) { x1 = pxmax; needNewVertex1 = true; } y1 = e -> c - e -> a * x1; x2 = pxmax; if (s2!=(struct Site *)NULL && s2->coord.x < pxmax) { x2 = s2->coord.x; } else { needNewVertex2 = true; } if(x2<pxmin) { x2 = pxmin; needNewVertex2 = true; } y2 = e -> c - e -> a * x2; if (((y1> pymax) & (y2>pymax)) | ((y1<pymin)&(y2<pymin))) { return; } if(y1> pymax) { y1 = pymax; x1 = (e -> c - y1)/e -> a;needNewVertex1 = true;} if(y1<pymin) { y1 = pymin; x1 = (e -> c - y1)/e -> a;needNewVertex1 = true;} if(y2>pymax) { y2 = pymax; x2 = (e -> c - y2)/e -> a;needNewVertex2 = true;} if(y2<pymin) { y2 = pymin; x2 = (e -> c - y2)/e -> a;needNewVertex2 = true;} } //printf("\nPushing line (%f,%f,%f,%f)",x1,y1,x2,y2); // if(!((x1 == x2 && x2== pxmin) || (x1 == x2 && x2 == pxmax) || (y1 == y2 && y2 == pymin) || (y1 == y2 && y2 == pymax))) { pushGraphEdge(x1,y1,x2,y2); if(needNewVertex1) { //printf("\nCreate new vertex 1 v1 = (struct Site *) getfree(&sfl); v1 -> refcnt = 0; v1 -> coord.x = x1; v1 -> coord.y = y1; makevertex(v1); } if(needNewVertex2) { v2 = (struct Site *) getfree(&sfl); v2 -> refcnt = 0; v2 -> coord.x = x2; v2 -> coord.y = y2; makevertex(v2); } insertVertexLink(v1->sitenbr,v2->sitenbr); } }