private void RemoveEdges() { foreach (var voronoiEdge in _graph.GetEdges().ToArray().Where(voronoiEdge => voronoiEdge.IsPartlyInfinite || voronoiEdge.IsInfinite)) { _graph.RemoveEdge(voronoiEdge, true); } var amount = new Dictionary <Vector2, int>(); foreach (var voronoiEdge in _graph.GetEdges()) { if (!amount.ContainsKey(voronoiEdge.V1)) { amount.Add(voronoiEdge.V1, 0); } if (!amount.ContainsKey(voronoiEdge.V2)) { amount.Add(voronoiEdge.V2, 0); } amount[voronoiEdge.V1]++; amount[voronoiEdge.V2]++; } while (amount.Any(x => x.Value <= 1)) { var killIt = amount.FirstOrDefault(x => x.Value <= 1); if (amount[killIt.Key] == 0) { amount.Remove(killIt.Key); continue; } var edge = _graph.GetEdges().First(x => x.V1.Equals(killIt.Key) || x.V2.Equals(killIt.Key)); _graph.RemoveEdge(edge, true); amount[edge.V1]--; amount[edge.V2]--; if (amount[killIt.Key] == 0) { amount.Remove(killIt.Key); } } }
public static VoronoiGraph ComputeVoronoiGraph(IEnumerable <Vector2> datapoints) { var pq = new List <VEvent>(); var currentCircles = new Hashtable(); var vg = new VoronoiGraph(); VNode rootNode = null; foreach (var v in datapoints) { pq.Add(new VDataEvent(v)); } pq.Sort(); while (pq.Count > 0) { var ve = pq.First(); pq.Remove(ve); if (ve == null) { return(null); } VDataNode[] circleCheckList; if (ve is VDataEvent) { rootNode = VNode.ProcessDataEvent(ve as VDataEvent, rootNode, vg, ve.Y, out circleCheckList); } else if (ve is VCircleEvent) { currentCircles.Remove(((VCircleEvent)ve).NodeN); if (!((VCircleEvent)ve).Valid) { continue; } rootNode = VNode.ProcessCircleEvent(ve as VCircleEvent, rootNode, vg, out circleCheckList); } else { throw new Exception("Got event of type " + ve.GetType() + "!"); } foreach (var vd in circleCheckList) { if (currentCircles.ContainsKey(vd)) { ((VCircleEvent)currentCircles[vd]).Valid = false; currentCircles.Remove(vd); } var vce = VNode.CircleCheckDataNode(vd, ve.Y); if (vce != null) { pq.Add(vce); pq.Sort(); currentCircles[vd] = vce; } } if (ve is VDataEvent) { var dp = ((VDataEvent)ve).DataPoint; foreach (VCircleEvent vce in currentCircles.Values) { if (Dist(dp[0], dp[1], vce.CenterX, vce.CenterY) < vce.Y - vce.CenterY && Math.Abs(Dist(dp[0], dp[1], vce.CenterX, vce.CenterY) - (vce.Y - vce.CenterY)) > 1e-10) { vce.Valid = false; } } } } VNode.CleanUpTree(rootNode); foreach (var ve in vg.GetEdges().Select(edge => edge as VoronoiEdge)) { if (Edge.IsUnknownVertex(ve.V2)) { ve.AddVertex(Edge.GetInfiniteVertex()); if (Math.Abs(ve.LeftData[1] - ve.RightData[1]) < 1e-10 && ve.LeftData[0] < ve.RightData[0]) { var T = ve.LeftData; ve.LeftData = ve.RightData; ve.RightData = T; } } } var minuteEdges = new ArrayList(); foreach (var ve in vg.GetEdges()) { if (!ve.IsPartlyInfinite && ve.V1.Equals(ve.V2)) { minuteEdges.Add(ve); foreach (var ve2 in vg.GetEdges()) { if (ve2.V1.Equals(ve.V1)) { ve2.V1 = ve.V1; } if (ve2.V2.Equals(ve.V1)) { ve2.V2 = ve.V1; } } } } foreach (VoronoiEdge ve in minuteEdges) { vg.RemoveEdge(ve, false); } return(vg); }