예제 #1
0
        public static void main(IEnumerable <Point> points)
        {
            Output.LineCollection.Clear();

            sorted = triangulate = plot = debug = false;
            Func <Site> next;

            if (sorted)
            {
                //**
            }
            else
            {
                ReadSites(points);
                next    = () => NextOne();
                siteidx = 0;
                VoronoiGeometry.geominit();
                if (plot)
                {
                    Output.plotinit();
                }

                VoronoiAlgorithm.voronoi(() =>
                {
                    Site nextSite = next();
                    return(nextSite);
                });
            }
        }
예제 #2
0
        internal static Edge bisect(Site s1, Site s2)
        {
            if (s1 == null)
            {
                throw new ArgumentNullException("s1");
            }
            if (s2 == null)
            {
                throw new ArgumentNullException("s2");
            }


            double dx, dy;
            double adx, ady;             // absolute dx and dy - |.|
            Edge   newedge = new Edge(); //** getfree

            newedge.reg[0] = s1;
            newedge.reg[1] = s2;

            VoronoiGeometry.Ref(s1);
            VoronoiGeometry.Ref(s2);

            newedge.EndPoints[0] = null;
            newedge.EndPoints[1] = null;

            dx  = s2.Coord.X - s1.Coord.X;
            dy  = s2.Coord.Y - s1.Coord.Y;
            adx = Math.Abs(dx);
            ady = Math.Abs(dy);

            newedge.c = s1.Coord.X * dx + s1.Coord.Y * dy + 0.5 * (dx * dx + dy * dy);

            if (adx > ady)
            {
                newedge.a  = 1;
                newedge.b  = dy / dx;
                newedge.c /= dx;
            }
            else
            {
                newedge.b  = 1;
                newedge.a  = dx / dy;
                newedge.c /= dy;
            }

            newedge.edgeNumber = nedges;
            Output.out_bisector(newedge);
            nedges++;

            return(newedge);
        }
예제 #3
0
        internal static void endpoint(Edge e, int lr, Site s)
        {
            e.EndPoints[lr] = s;
            VoronoiGeometry.Ref(s);

            if (e.EndPoints[EndPoint.Right - lr] == null)
            {
                return;
            }

            Output.OutputEndPoint(e);
            VoronoiGeometry.deref(e.reg[EndPoint.Left]);
            VoronoiGeometry.deref(e.reg[EndPoint.Right]);

            //** makefree((Freenode)e, (Freelist)efl);
        }
예제 #4
0
        public static void PQdelete(HalfEdge he)
        {
            HalfEdge last;

            if (he.Vertex != null)
            {
                last = PQhash[PQbucket(he)];
                while (last.PQnext != he)
                {
                    last = last.PQnext;
                }
                last.PQnext = he.PQnext;
                PQcount--;
                VoronoiGeometry.deref(he.Vertex);
                he.Vertex = null;
            }
        }
예제 #5
0
        public static void PQinsert(HalfEdge he, Site v, double offset)
        {
            he.Vertex = v;
            VoronoiGeometry.Ref(v);
            he.ystar = v.Coord.Y + offset;
            HalfEdge last = PQhash[PQbucket(he)];

            HalfEdge next;

            while ((next = last.PQnext) != null &&
                   (he.ystar > next.ystar || he.ystar == next.ystar && v.Coord.X > next.Vertex.Coord.X))
            {
                last = next;
            }

            he.PQnext   = last.PQnext;
            last.PQnext = he;
            PQcount++;
        }
예제 #6
0
        public static void voronoi(Func <Site> nextsite)
        {
            Heap.PQinitialize();
            EdgeList.Bottomsite = nextsite();
            Output.OutputSite(EdgeList.Bottomsite);
            EdgeList.ELinitialize();
            Site newsite = nextsite();

            HalfEdge lbnd, rbnd, llbnd, rrbnd, bisector;
            Site     bottom, top, temp, p, v;
            Point    newintstar = new Point();
            int      pm;
            Edge     e;

            while (true)
            {
                if (!Heap.PQempty())
                {
                    newintstar = Heap.PQ_min();
                }

                if (newsite != null && (Heap.PQempty() || newsite.Coord.Y < newintstar.Y ||
                                        (newsite.Coord.Y == newintstar.Y && newsite.Coord.X < newintstar.X)))
                {
                    // new site is smallest
                    Output.OutputSite(newsite);

                    lbnd     = EdgeList.ELleftbnd(newsite.Coord);
                    rbnd     = EdgeList.ELright(lbnd);
                    bottom   = EdgeList.rightreg(lbnd);
                    e        = VoronoiGeometry.bisect(bottom, newsite);
                    bisector = EdgeList.HEcreate(e, EndPoint.Left);
                    EdgeList.ELinsert(lbnd, bisector);
                    p = VoronoiGeometry.intersect(lbnd, bisector);
                    if (p != null)
                    {
                        Heap.PQdelete(lbnd);
                        Heap.PQinsert(lbnd, p, VoronoiGeometry.dist(p, newsite));
                    }
                    lbnd     = bisector;
                    bisector = EdgeList.HEcreate(e, EndPoint.Right);
                    EdgeList.ELinsert(lbnd, bisector);
                    p = VoronoiGeometry.intersect(bisector, rbnd);
                    if (p != null)
                    {
                        Heap.PQinsert(bisector, p, VoronoiGeometry.dist(p, newsite));
                    }

                    newsite = nextsite();
                }
                else if (!Heap.PQempty())                   /* intersection is smallest */
                {
                    lbnd   = Heap.PQextractmin();
                    llbnd  = EdgeList.ELleft(lbnd);
                    rbnd   = EdgeList.ELright(lbnd);
                    rrbnd  = EdgeList.ELright(rbnd);
                    bottom = EdgeList.leftreg(lbnd);
                    top    = EdgeList.rightreg(rbnd);

                    Output.out_triple(bottom, top, EdgeList.rightreg(lbnd));

                    v = lbnd.Vertex;
                    VoronoiGeometry.makevertex(v);
                    VoronoiGeometry.endpoint(lbnd.Edge, lbnd.ELpm, v);
                    VoronoiGeometry.endpoint(rbnd.Edge, rbnd.ELpm, v);
                    EdgeList.ELdelete(lbnd);
                    Heap.PQdelete(rbnd);
                    EdgeList.ELdelete(rbnd);
                    pm = EndPoint.Left;
                    if (bottom.Coord.Y > top.Coord.Y)
                    {
                        temp   = bottom;
                        bottom = top;
                        top    = temp;
                        pm     = EndPoint.Right;
                    }
                    e        = VoronoiGeometry.bisect(bottom, top);
                    bisector = EdgeList.HEcreate(e, pm);
                    EdgeList.ELinsert(llbnd, bisector);
                    VoronoiGeometry.endpoint(e, EndPoint.Right - pm, v);
                    VoronoiGeometry.deref(v);
                    p = VoronoiGeometry.intersect(llbnd, bisector);
                    if (p != null)
                    {
                        Heap.PQdelete(llbnd);
                        Heap.PQinsert(llbnd, p, VoronoiGeometry.dist(p, bottom));
                    }
                    p = VoronoiGeometry.intersect(bisector, rrbnd);
                    if (p != null)
                    {
                        Heap.PQinsert(bisector, p, VoronoiGeometry.dist(p, bottom));
                    }
                }
                else
                {
                    break;
                }
            }

            for (lbnd = EdgeList.ELright(EdgeList.ELleftend);
                 lbnd != EdgeList.ELrightend;
                 lbnd = EdgeList.ELright(lbnd))
            {
                e = lbnd.Edge;
                Output.OutputEndPoint(e);
            }
        }         // end of while
예제 #7
0
        public static HalfEdge ELleftbnd(Point p)
        {
            int bucket = (int)((p.X - VoronoiMain.xmin) / VoronoiGeometry.deltax * ELhashsize);

            if (bucket < 0)
            {
                bucket = 0;
            }
            if (bucket >= ELhashsize)
            {
                bucket = ELhashsize - 1;
            }

            HalfEdge he = ELgethash(bucket);

            if (he == null)
            {
                int i = 1;
                while (true)
                {
                    he = ELgethash(bucket - i);
                    if (he != null)
                    {
                        break;
                    }

                    he = ELgethash(bucket + i);
                    if (he != null)
                    {
                        break;
                    }
                    i++;
                }
                totalsearch += i;
            }

            ntry++;

            // Now search linear list of halfedges for the correct one
            if (he == ELleftend || (he != ELrightend && VoronoiGeometry.right_of(he, p)))
            {
                do
                {
                    he = he.Right;
                } while (he != ELrightend && VoronoiGeometry.right_of(he, p));
                he = he.Left;
            }
            else
            {
                do
                {
                    he = he.Left;
                } while (he != ELleftend && !VoronoiGeometry.right_of(he, p));
            }

            // Update hash table and reference count
            if (bucket > 0 && bucket < (ELhashsize - 1))
            {
                if (ELhash[bucket] != null)
                {
                    ELhash[bucket].RefCount--;
                }

                ELhash[bucket] = he;
                ELhash[bucket].RefCount++;
            }

            return(he);
        }