/* * implicit parameters: nsites, sqrt_nsites, xmin, xmax, ymin, ymax, deltax, * deltay (can all be estimates). Performance suffers if they are wrong; * better to make nsites, deltax, and deltay too big than too small. (?) */ private bool voronoi_bd() { Site newsite, bot, top, temp, p; Site v; Point newintstar = null; int pm; Halfedge lbnd, rbnd, llbnd, rrbnd, bisector; Edge e; PQinitialize(); ELinitialize(); bottomsite = nextone(); newsite = nextone(); while (true) { 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 != 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 */ // get the first HalfEdge to the LEFT of the new site lbnd = ELleftbnd((newsite.coord)); // get the first HalfEdge to the RIGHT of the new site rbnd = ELright(lbnd); // if this halfedge has no edge,bot =bottom site (whatever that // is) bot = rightreg(lbnd); // create a new edge that bisects e = bisect(bot, newsite); // create a new HalfEdge, setting its ELpm field to 0 bisector = HEcreate(e, LE); // insert this new bisector edge between the left and right // vectors in a linked list ELinsert(lbnd, bisector); // if the new bisector intersects with the left edge, // remove the left edge's vertex, and put in the new one if ((p = intersect(lbnd, bisector)) != null) { PQdelete(lbnd); PQinsert(lbnd, p, dist(p, newsite)); } lbnd = bisector; // create a new HalfEdge, setting its ELpm field to 1 bisector = HEcreate(e, RE); // insert the new HE to the right of the original bisector // earlier in the IF stmt ELinsert(lbnd, bisector); // if this new bisector intersects with the new HalfEdge if ((p = intersect(bisector, rbnd)) != null) { // push the HE into the ordered linked list of vertices PQinsert(bisector, p, dist(p, newsite)); } newsite = nextone(); } else if (!PQempty()) /* intersection is smallest - this is a vector event */ { // pop the HalfEdge with the lowest vector off the ordered list // of vectors lbnd = PQextractmin(); // get the HalfEdge to the left of the above HE llbnd = ELleft(lbnd); // get the HalfEdge to the right of the above HE rbnd = ELright(lbnd); // get the HalfEdge to the right of the HE to the right of the // lowest HE rrbnd = ELright(rbnd); // get the Site to the left of the left HE which it bisects bot = leftreg(lbnd); // get the Site to the right of the right HE which it bisects top = rightreg(rbnd); 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 // if left HE and the new bisector intersect, then delete // the left HE, and reinsert it if ((p = intersect(llbnd, bisector)) != null) { PQdelete(llbnd); PQinsert(llbnd, p, dist(p, bot)); } // if right HE and the new bisector intersect, then // reinsert it if ((p = intersect(bisector, rrbnd)) != null) { PQinsert(bisector, p, dist(p, bot)); } } else { break; } } for (lbnd = ELright(ELleftend); lbnd != ELrightend; lbnd = ELright(lbnd)) { e = lbnd.ELedge; clip_line(e); } return true; }
private void makevertex(Site v) { v.sitenbr = nvertices; nvertices++; }