示例#1
0
        /*
		 * 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;
        }
示例#2
0
 private void makevertex(Site v)
 {
     v.sitenbr = nvertices;
     nvertices++;
 }