Esempio n. 1
0
 /* returns true if p is to right of halfedge e */
 private bool right_of(Halfedge el, DoubleVector2 p)
 {
     Edge e;
     Site topsite;
     bool right_of_site;
     bool above, fast;
     double dxp, dyp, dxs, t1, t2, t3, yl;
     
     e = el.ELedge;
     topsite = e.reg[1];
     
     if ( p.X > topsite.Coord.X )
         right_of_site = true;
     else
         right_of_site = false;
     
     if ( right_of_site && el.ELpm == LE )
         return true;
     if (!right_of_site && el.ELpm == RE )
         return false;
     
     if ( e.a == 1.0 )
     {
         dxp = p.X - topsite.Coord.X;
         dyp = p.Y - topsite.Coord.Y;
         fast = false;
         
         if ( (!right_of_site & (e.b < 0.0)) | (right_of_site & (e.b >= 0.0)) )
         {
             above = dyp >= e.b * dxp;
             fast = above;
         }
         else
         {
             above = p.X + p.Y * e.b > e.c;
             if ( e.b < 0.0 )
                 above = !above;
             if ( !above )
                 fast = true;
         }
         if ( !fast )
         {
             dxs = topsite.Coord.X - ( e.reg[0] ).Coord.X;
             above = e.b * (dxp * dxp - dyp * dyp) 
             < dxs * dyp * (1.0 + 2.0 * dxp / dxs + e.b * e.b);
             
             if ( e.b < 0 )
                 above = !above;
         }
     }
     else // e.b == 1.0
     {
         yl = e.c - e.a * p.X;
         t1 = p.Y - yl;
         t2 = p.X - topsite.Coord.X;
         t3 = yl - topsite.Coord.Y;
         above = t1 * t1 > t2 * t2 + t3 * t3;
     }
     return ( el.ELpm == LE ? above : !above );
 }
 public int Compare ( Site p1, Site p2 )
 {
     DoubleVector2 s1 = p1.Coord;
     DoubleVector2 s2 = p2.Coord;
     if ( s1.Y < s2.Y )    return -1;
     if ( s1.Y > s2.Y ) return 1;
     if ( s1.X < s2.X ) return -1;
     if ( s1.X > s2.X ) return 1;
     return 0;
 }
Esempio n. 3
0
 private DoubleVector2 PQ_min ()
 {
     DoubleVector2 answer = new DoubleVector2 ();
     
     while ( PQhash[PQmin].PQnext == null  )
     {
         PQmin++;
     }
     
     answer.X = PQhash[PQmin].PQnext.vertex.Coord.X;
     answer.Y = PQhash[PQmin].PQnext.ystar;
     return answer;
 }
        public int Compare(Site p1, Site p2)
        {
            DoubleVector2 s1 = p1.Coord;
            DoubleVector2 s2 = p2.Coord;

            if (s1.Y < s2.Y)
            {
                return(-1);
            }
            if (s1.Y > s2.Y)
            {
                return(1);
            }
            if (s1.X < s2.X)
            {
                return(-1);
            }
            if (s1.X > s2.X)
            {
                return(1);
            }
            return(0);
        }
 public Site()
 {
     Coord = new DoubleVector2();
 }
Esempio n. 6
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;
            DoubleVector2 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;
        }
Esempio n. 7
0
 private Halfedge ELleftbnd( DoubleVector2 p )
 {
     int bucket;
     Halfedge he;
     
     /* Use hash table to get close to desired halfedge */
     // use the hash function to find the place in the hash map that this
     // HalfEdge should be
     bucket = (int) ((p.X - xmin) / deltax * ELhashsize);
     
     // make sure that the bucket position is within the range of the hash
     // array
     if ( bucket < 0 ) bucket = 0;
     if ( bucket >= ELhashsize )    bucket = ELhashsize - 1;
     
     he = ELgethash ( bucket );
     
     // if the HE isn't found, search backwards and forwards in the hash map
     // for the first non-null entry
     if ( he == null )
     {
         for ( int i = 1; i < ELhashsize; i++ )
         {
             if ( (he = ELgethash ( bucket - i ) ) != null )
                 break;
             if ( (he = ELgethash ( bucket + i ) ) != null )
                 break;
         }
     }
     
     /* Now search linear list of halfedges for the correct one */
     if ( he == ELleftend || ( he != ELrightend && right_of (he, p) ) )
     {
         // keep going right on the list until either the end is reached, or
         // you find the 1st edge which the point isn't to the right of
         do
         {
             he = he.ELright;
         }
         while ( he != ELrightend && right_of(he, p) );
         he = he.ELleft;
     }
     else
         // if the point is to the left of the HalfEdge, then search left for
         // the HE just to the left of the point
     {
         do
         {
             he = he.ELleft;
         }
         while ( he != ELleftend && !right_of(he, p) );
     }
     
     /* Update hash table and reference counts */
     if ( bucket > 0 && bucket < ELhashsize - 1)
     {
         ELhash[bucket] = he;
     }
     
     return he;
 }