public static VoronoiGraph ComputeVoronoiGraph(IEnumerable Datapoints) { BinaryPriorityQueue PQ = new BinaryPriorityQueue(); Hashtable CurrentCircles = new Hashtable(); VoronoiGraph VG = new VoronoiGraph(); VNode RootNode = null; foreach (Vector3 V in Datapoints) { PQ.Push(new VDataEvent(V)); } while (PQ.Count > 0) { VEvent VE = PQ.Pop() as VEvent; 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, VE.Y, out CircleCheckList); } else { throw new Exception("Got event of type " + VE.GetType().ToString() + "!"); } foreach (VDataNode VD in CircleCheckList) { if (CurrentCircles.ContainsKey(VD)) { ((VCircleEvent)CurrentCircles[VD]).Valid = false; CurrentCircles.Remove(VD); } VCircleEvent VCE = VNode.CircleCheckDataNode(VD, VE.Y); if (VCE != null) { PQ.Push(VCE); CurrentCircles[VD] = VCE; } } if (VE is VDataEvent) { Vector3 DP = ((VDataEvent)VE).DataPoint; foreach (VCircleEvent VCE in CurrentCircles.Values) { if (MathTools.Dist(DP[0], DP[1], VCE.Center[0], VCE.Center[1]) < VCE.Y - VCE.Center[1] && Math.Abs(MathTools.Dist(DP[0], DP[1], VCE.Center[0], VCE.Center[1]) - (VCE.Y - VCE.Center[1])) > 1e-10) { VCE.Valid = false; } } } } return(VG); }
public static VoronoiGraph ComputeVoronoiGraph(Dictionary <Point, VoronoiCell> cells) { BinaryPriorityQueue PQ = new BinaryPriorityQueue(); Hashtable CurrentCircles = new Hashtable(); VoronoiGraph VG = new VoronoiGraph(); VNode RootNode = null; foreach (Point V in cells.Keys) { PQ.Push(new VDataEvent(V)); } while (PQ.Count > 0) { VEvent VE = PQ.Pop() as VEvent; 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, VE.Y, out CircleCheckList); } else { throw new Exception("Got event of type " + VE.GetType().ToString() + "!"); } foreach (VDataNode VD in CircleCheckList) { if (CurrentCircles.ContainsKey(VD)) { ((VCircleEvent)CurrentCircles[VD]).Valid = false; CurrentCircles.Remove(VD); } VCircleEvent VCE = VNode.CircleCheckDataNode(VD, VE.Y); if (VCE != null) { PQ.Push(VCE); CurrentCircles[VD] = VCE; } } if (VE is VDataEvent) { Point DP = ((VDataEvent)VE).DataPoint; foreach (VCircleEvent VCE in CurrentCircles.Values) { if (MathF.Dist(DP.X, DP.Y, VCE.Center.X, VCE.Center.Y) < VCE.Y - VCE.Center.Y && Math.Abs(MathF.Dist(DP.X, DP.Y, VCE.Center.X, VCE.Center.Y) - (VCE.Y - VCE.Center.Y)) > 1e-10) { VCE.Valid = false; } } } } VNode.CleanUpTree(RootNode); foreach (VoronoiEdge VE in VG.Edges) { if (VE.Done) { continue; } if (VE.VVertexB.IsUndefined) { VE.AddVertex(Fortune.VVInfinite); if (Math.Abs(VE.LeftData.Y - VE.RightData.Y) < 1e-10 && VE.LeftData.X < VE.RightData.X) { Point T = VE.LeftData; VE.LeftData = VE.RightData; VE.RightData = T; } } } ArrayList MinuteEdges = new ArrayList(); foreach (var edge in VG.Edges) { double ax = Math.Round(edge.VVertexA.X, Vector.Precision), ay = Math.Round(edge.VVertexA.Y, Vector.Precision), bx = Math.Round(edge.VVertexB.X, Vector.Precision), by = Math.Round(edge.VVertexB.Y, Vector.Precision); if (ax == bx && ay == by) { MinuteEdges.Add(edge); continue; } edge.VVertexA = new Point(ax, ay); edge.VVertexB = new Point(bx, by); } foreach (VoronoiEdge VE in MinuteEdges) { VG.Edges.Remove(VE); } foreach (var edge in VG.Edges) { VoronoiCell rightCell = cells[edge.RightData], leftCell = cells[edge.LeftData]; if (!rightCell.Edges.Contains(edge)) { rightCell.Edges.Add(edge); } if (!leftCell.Edges.Contains(edge)) { leftCell.Edges.Add(edge); } } VG.Cells = cells; return(VG); }
public static VoronoiGraph ComputeVoronoiGraph(IEnumerable datapoints) { var pq = new BinaryPriorityQueue(); var currentCircles = new Hashtable(); var vg = new VoronoiGraph(); VNode rootNode = null; foreach (Vector v in datapoints) { pq.Push(new VDataEvent(v)); } while (pq.Count > 0) { var ve = pq.Pop() as VEvent; VDataNode[] circleCheckList; if (ve is VDataEvent) { rootNode = VNode.ProcessDataEvent(ve as VDataEvent, rootNode, vg, ve.Y, out circleCheckList); } else { var @event = ve as VCircleEvent; if (@event != null) { currentCircles.Remove(@event.NodeN); if ([email protected]) { continue; } rootNode = VNode.ProcessCircleEvent(@event, rootNode, vg, ve.Y, 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) { continue; } pq.Push(vce); currentCircles[vd] = vce; } var dataEvent = ve as VDataEvent; if (dataEvent == null) { continue; } var dp = dataEvent.DataPoint; foreach (var vce in currentCircles.Values.Cast <VCircleEvent>().Where(vce => MathTools.Dist(dp[0], dp[1], vce.Center[0], vce.Center[1]) < vce.Y - vce.Center[1] && Math.Abs(MathTools.Dist(dp[0], dp[1], vce.Center[0], vce.Center[1]) - (vce.Y - vce.Center[1])) > 1e-10)) { vce.Valid = false; } } VNode.CleanUpTree(rootNode); foreach (var ve in vg.Edges.Where(ve => !ve.Done).Where(ve => ve.VVertexB == VvUnkown)) { ve.AddVertex(VvInfinite); if (!(Math.Abs(ve.LeftData[1] - ve.RightData[1]) < 1e-10) || !(ve.LeftData[0] < ve.RightData[0])) { continue; } var T = ve.LeftData; ve.LeftData = ve.RightData; ve.RightData = T; } var minuteEdges = new ArrayList(); foreach (var ve in vg.Edges.Where(ve => !ve.IsPartlyInfinite && ve.VVertexA == ve.VVertexB)) { minuteEdges.Add(ve); // prevent rounding errors from expanding to holes foreach (var ve2 in vg.Edges) { if (ve2.VVertexA == ve.VVertexA) { ve2.VVertexA = ve.VVertexA; } if (ve2.VVertexB == ve.VVertexA) { ve2.VVertexB = ve.VVertexA; } } } foreach (VoronoiEdge ve in minuteEdges) { vg.Edges.Remove(ve); } return(vg); }
public static VoronoiGraph ComputeVoronoiGraph(IEnumerable Datapoints) { BinaryPriorityQueue PQ = new BinaryPriorityQueue(); Hashtable CurrentCircles = new Hashtable(); VoronoiGraph VG = new VoronoiGraph(); VNode RootNode = null; foreach (Vector V in Datapoints) { PQ.Push(new VDataEvent(V)); } while (PQ.Count > 0) { VEvent VE = PQ.Pop() as VEvent; 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, VE.Y, out CircleCheckList); } else { throw new Exception("Got event of type " + VE.GetType().ToString() + "!"); } foreach (VDataNode VD in CircleCheckList) { if (CurrentCircles.ContainsKey(VD)) { ((VCircleEvent)CurrentCircles[VD]).Valid = false; CurrentCircles.Remove(VD); } VCircleEvent VCE = VNode.CircleCheckDataNode(VD, VE.Y); if (VCE != null) { PQ.Push(VCE); CurrentCircles[VD] = VCE; } } if (VE is VDataEvent) { Vector DP = ((VDataEvent)VE).DataPoint; foreach (VCircleEvent VCE in CurrentCircles.Values) { if (MathTools.Dist(DP[0], DP[1], VCE.Center[0], VCE.Center[1]) < VCE.Y - VCE.Center[1] && Math.Abs(MathTools.Dist(DP[0], DP[1], VCE.Center[0], VCE.Center[1]) - (VCE.Y - VCE.Center[1])) > 1e-10) { VCE.Valid = false; } } } } VNode.CleanUpTree(RootNode); foreach (VoronoiEdge VE in VG.Edges) { if (VE.Done) { continue; } if (VE.VVertexB == Fortune.VVUnkown) { VE.AddVertex(Fortune.VVInfinite); if (Math.Abs(VE.LeftData[1] - VE.RightData[1]) < 1e-10 && VE.LeftData[0] < VE.RightData[0]) { Vector T = VE.LeftData; VE.LeftData = VE.RightData; VE.RightData = T; } } } ArrayList MinuteEdges = new ArrayList(); foreach (VoronoiEdge VE in VG.Edges) { if (!VE.IsPartlyInfinite && VE.VVertexA.Equals(VE.VVertexB)) { MinuteEdges.Add(VE); // prevent rounding errors from expanding to holes foreach (VoronoiEdge VE2 in VG.Edges) { if (VE2.VVertexA.Equals(VE.VVertexA)) { VE2.VVertexA = VE.VVertexA; } if (VE2.VVertexB.Equals(VE.VVertexA)) { VE2.VVertexB = VE.VVertexA; } } } } foreach (VoronoiEdge VE in MinuteEdges) { VG.Edges.Remove(VE); } return(VG); }
public static VoronoiGraph ComputeVoronoiGraph(IEnumerable <Vector2> points) { var pq = new MinHeap <VEvent>(); var currentCircles = new Dictionary <VDataNode, VCircleEvent>(); var vg = new VoronoiGraph(); VNode rootNode = null; foreach (var v in points) { pq.Add(new VDataEvent(v)); } while (pq.Count > 0) { var ve = pq.RemoveMin(); 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)) { currentCircles[vd].Valid = false; currentCircles.Remove(vd); } var vce = VNode.CircleCheckDataNode(vd, ve.Y); if (vce != null) { pq.Add(vce); currentCircles[vd] = vce; } } var evt = ve as VDataEvent; if (evt != null) { var dp = evt.DataPoint; foreach (var vce in currentCircles.Values) { if (Vector2.Distance(dp, vce.Center) < vce.Y - vce.Center.Y && Math.Abs(Vector2.Distance(dp, vce.Center) - (vce.Y - vce.Center.Y)) > 1e-10) { vce.Valid = false; } } } } VNode.CleanUpTree(rootNode as VEdgeNode); foreach (var ve in vg.Edges) { if (ve.Done) { continue; } if (!ve.VVertexB.HasValue) { ve.AddVertex(VvInfinite); if (Math.Abs(ve.LeftData.Y - ve.RightData.Y) < 1e-10 && ve.LeftData.X < ve.RightData.X) { var t = ve.LeftData; ve.LeftData = ve.RightData; ve.RightData = t; } } } var minuteEdges = new List <Edge>(); foreach (var ve in vg.Edges) { if (!ve.IsPartlyInfinite && ve.VVertexA.Equals(ve.VVertexB)) { minuteEdges.Add(ve); // prevent rounding errors from expanding to holes foreach (var ve2 in vg.Edges) { if (ve2.VVertexA.Equals(ve.VVertexA)) { ve2.VVertexA = ve.VVertexA; } if (ve2.VVertexB.Equals(ve.VVertexA)) { ve2.VVertexB = ve.VVertexA; } } } } foreach (var ve in minuteEdges) { vg.MutableEdges.Remove(ve); } return(vg); }