예제 #1
0
        private scg.Dictionary <Vector, scg.List <PointF> > GetRegions(VoronoiGraph graph)
        {
            scg.Dictionary <Vector, scg.List <PointF> > output = new scg.Dictionary <Vector, scg.List <PointF> >();

            int i = 0;

            foreach (Vector v in this.points)
            {
                if (!output.ContainsKey(v))
                {
                    output.Add(v, new scg.List <PointF>());

                    foreach (VoronoiEdge edge in graph.Edges)
                    {
                        AddEdgeForVectorRegion(output, edge, v);
                    }
                }

                this.progress = 30 + (int)(((float)i / (float)this.points.Count) * 55f);

                i++;
            }

            scg.Dictionary <Vector, scg.List <PointF> > newOutput = new scg.Dictionary <Vector, scg.List <PointF> >();

            foreach (scg.KeyValuePair <Vector, scg.List <PointF> > region in output)
            {
                scg.List <WPointF> sort = SortRegion(region);

                newOutput.Add(region.Key, new scg.List <PointF>());

                foreach (WPointF pointf in sort)
                {
                    newOutput[region.Key].Add(pointf.point);
                }
            }

            output = newOutput;

            return(output);
        }
예제 #2
0
        public VoronoiGraph Compute(List <Point> sites, BoundingRect bbox)
        {
            this.Reset();

            // Initialize site event queue
            var siteEvents = sites.Take(sites.Count).ToList();

            /*siteEvents.Sort((a, b) =>
             *  {
             *      float r = b.y - a.y;
             *      if (r != 0) { return Mathf.CeilToInt(r); }
             *      return Mathf.CeilToInt(b.x - a.x);
             *  });*/
            siteEvents = siteEvents.OrderByDescending(s => s.y).ToList();

            // process queue
            Point site = siteEvents.Last();

            siteEvents.Remove(site);
            int   siteid = 0;
            float xsitex = -Mathf.Infinity;
            float xsitey = -Mathf.Infinity;

            // main loop
            for (; ;)
            {
                // we need to figure whether we handle a site or circle event
                // for this we find out if there is a site event and it is
                // 'earlier' than the circle event
                CircleEvent circle = this.firstCircleEvent;

                // add beach section
                if (site && (!circle || site.y < circle.y || (site.y == circle.y && site.x < circle.x)))
                {
                    // only if site is not a duplicate
                    if (site.x != xsitex || site.y != xsitey)
                    {
                        // first create cell for new site
                        //this.cells[siteid] = new Cell(site);
                        this.cells.Insert(siteid, new Cell(site));
                        site.id = siteid++;

                        // then create a beachsection for that site
                        this.AddBeachSection(site);

                        // remember last site coords to detect duplicate
                        xsitey = site.y;
                        xsitex = site.x;
                    }

                    site = siteEvents.Count > 0 ? siteEvents.Last() : null;
                    if (siteEvents.Count > 0)
                    {
                        siteEvents.Remove(site);
                    }
                }
                // remove beach section
                else if (circle)
                {
                    this.RemoveBeachSection(circle.arc);
                }
                // all done, quit
                else
                {
                    break;
                }
            }

            // wrapping-up
            this.ClipEdges(bbox);

            this.CloseCells(bbox);

            VoronoiGraph graph = new VoronoiGraph();

            graph.sites = sites;
            graph.cells = this.cells;
            graph.edges = this.edges;

            this.Reset();

            return(graph);
        }