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); }
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); }