public static VoronoiDiagram MakeVoronoiSF(List <Vector2> seeds, Vector2 boundry) { tiles = new VTile[seeds.Count]; currentTileIndex = 0; vertices = new List <Vector2>(); halfEdges = new List <VHalfEdge>(); priorityQueue = new PriorityQueue(); events = new Dictionary <VEvent, VEventInfo>(); foreach (Vector2 seed in seeds) { VEvent newEvent = new VEvent(seed, EventType.VertexEvent); priorityQueue.Enqueue(newEvent); events.Add(newEvent, null); } beachLine = new BeachLine(); while (priorityQueue.NotEmpty) { VEvent nextEvent = priorityQueue.Dequeue(); VEventInfo evtInfo = events[nextEvent]; if (evtInfo == null || evtInfo.Deleted != true) { handleEvent(nextEvent, nextEvent.EventType, halfEdges); } } VoronoiDiagram retVal = new VoronoiDiagram() { Verticies = vertices.ToArray(), Tiles = tiles, HalfEdges = halfEdges }; tiles = null; vertices = null; halfEdges = null; priorityQueue = null; events = null; beachLine = null; return(retVal); }
internal void HandleCircleEvent(VEvent circleEvent, List <VHalfEdge> halfEdges, ref Dictionary <VEvent, VEventInfo> events, ref List <Vector2> vertices, ref PriorityQueue priorityQueue) { //Add vertex to corresponding edge record VEventInfo evnt = events[circleEvent]; VEdge vEdgeOne = edges[beachTree[evnt.VEdgeOneIndex].EdgeIndex]; //(VEdge)beachTree[evnt.VEdgeOneIndex]; VEdge vEdgeTwo = edges[beachTree[evnt.VEdgeTwoIndex].EdgeIndex]; //(VEdge)beachTree[evnt.VEdgeTwoIndex]; Vector2 vertex = new Vector2(circleEvent.EventLocation.X, circleEvent.EventLocation.Y + evnt.Radius); vertices.Add(vertex); //The two halfEdges that are colliding VHalfEdge halfEdgeOne = vEdgeOne.HalfEdge; halfEdgeOne.End = vertex; VHalfEdge halfEdgeTwo = vEdgeTwo.HalfEdge; halfEdgeTwo.End = vertex; //Deleting disappearing arc //Create new edge record //replace edgeOne with the new edge //replace edgeTwo with the opposite branch //VEdge newEdge = new VEdge(vEdgeOne.LeftArcIndex, vEdgeTwo.RightArcIndex); //beachTree[evnt.VEdgeOneIndex].EdgeIndex = edges.Count; //edges.Add(newEdge); //copyTree(evnt.VEdgeTwoIndex, getSibling(evnt.VEdgeTwoIndex)); VEdge newEdge; VHalfEdge newHalfEdge = new VHalfEdge(); VHalfEdge newHalfEdgeTwin = new VHalfEdge() { End = vertex, Twin = newHalfEdge }; newHalfEdge.Twin = newHalfEdgeTwin; halfEdges.Add(newHalfEdge); halfEdges.Add(newHalfEdgeTwin); if (halfEdgeOne.Tile == halfEdgeTwo.Twin.Tile) { halfEdgeOne.Next = halfEdgeTwo.Twin; halfEdgeTwo.Twin.Prev = halfEdgeOne; halfEdgeTwo.Next = newHalfEdge; newHalfEdge.Prev = halfEdgeTwo; newHalfEdge.Tile = halfEdgeTwo.Tile; newHalfEdgeTwin.Next = halfEdgeOne.Twin; halfEdgeOne.Twin.Prev = newHalfEdgeTwin; newHalfEdgeTwin.Tile = halfEdgeOne.Twin.Tile; newHalfEdge.Tile.Edges.AddLast(newHalfEdge); newHalfEdgeTwin.Tile.Edges.AddLast(newHalfEdgeTwin); } else { halfEdgeOne.Next = newHalfEdge; newHalfEdge.Prev = halfEdgeOne; newHalfEdgeTwin.Next = halfEdgeTwo.Twin; halfEdgeTwo.Twin.Prev = newHalfEdgeTwin; halfEdgeTwo.Next = halfEdgeOne.Twin; halfEdgeOne.Twin.Prev = halfEdgeTwo; newHalfEdge.Tile = halfEdgeOne.Tile; newHalfEdgeTwin.Tile = halfEdgeTwo.Twin.Tile; newHalfEdge.Tile.Edges.AddLast(newHalfEdge); newHalfEdgeTwin.Tile.Edges.AddLast(newHalfEdgeTwin); } if (arcs[vEdgeOne.LeftArcIndex].Focus == arcs[vEdgeTwo.LeftArcIndex].Focus || arcs[vEdgeOne.LeftArcIndex].Focus == arcs[vEdgeTwo.RightArcIndex].Focus) { if (arcs[vEdgeOne.LeftArcIndex].Focus == arcs[vEdgeTwo.LeftArcIndex].Focus) { newEdge = new VEdge(vEdgeTwo.RightArcIndex, vEdgeOne.RightArcIndex, newHalfEdge); //newEdge = new VEdge(vEdgeTwo.RightArcIndex, vEdgeOne.RightArcIndex); beachTree[evnt.VEdgeOneIndex].EdgeIndex = edges.Count; beachTree[evnt.VEdgeOneIndex].IsEdge = true; edges.Add(newEdge); //want to delete left arc of edge2 beachTree[getLeftChildIndex(evnt.VEdgeTwoIndex)] = null; copyTree(evnt.VEdgeTwoIndex, getSibling(getLeftChildIndex(evnt.VEdgeTwoIndex)), ref events); } else { newEdge = new VEdge(vEdgeTwo.LeftArcIndex, vEdgeOne.RightArcIndex, newHalfEdge); beachTree[evnt.VEdgeOneIndex].EdgeIndex = edges.Count; beachTree[evnt.VEdgeOneIndex].IsEdge = true; edges.Add(newEdge); //want to delete the right arc of edge2 beachTree[getRightChildIndex(evnt.VEdgeTwoIndex)] = null; copyTree(evnt.VEdgeTwoIndex, getSibling(getRightChildIndex(evnt.VEdgeTwoIndex)), ref events); } } else { //vEdgeOne.RightArcIndex; if (arcs[vEdgeOne.RightArcIndex].Focus == arcs[vEdgeTwo.RightArcIndex].Focus) { newEdge = new VEdge(vEdgeOne.LeftArcIndex, vEdgeTwo.LeftArcIndex, newHalfEdge); beachTree[evnt.VEdgeOneIndex].EdgeIndex = edges.Count; beachTree[evnt.VEdgeOneIndex].IsEdge = true; edges.Add(newEdge); //want to delete right arc of arc2 copyTree(evnt.VEdgeTwoIndex, getSibling(getRightChildIndex(evnt.VEdgeTwoIndex)), ref events); } else { newEdge = new VEdge(vEdgeOne.LeftArcIndex, vEdgeTwo.RightArcIndex, newHalfEdge); beachTree[evnt.VEdgeOneIndex].EdgeIndex = edges.Count; beachTree[evnt.VEdgeOneIndex].IsEdge = true; edges.Add(newEdge); //want to delete left arc of arc2 copyTree(evnt.VEdgeTwoIndex, getSibling(getLeftChildIndex(evnt.VEdgeTwoIndex)), ref events); //copyTree(evnt.VEdgeTwoIndex, getSibling(getRightChildIndex(evnt.VEdgeTwoIndex)), ref events); } } //need to look left and right, events[circleEvent].Deleted = true;//look here... 10-26 //evnt.VEdgeOneIndex int newEdgeIndex = evnt.VEdgeOneIndex; //int parentEdgeOfNewEdgeIndex = getParentIndex(newEdgeIndex); int parentEdgeOfNewEdgeIndex = getClosestLeftAncestor(newEdgeIndex); int closestLeftEdgeIndex = getClosestLeftEdgeIndex(newEdgeIndex); int closestRightEdgeIndex = getClosestRightEdgeIndex(newEdgeIndex); //Check the new triplets for potential circle events if (parentEdgeOfNewEdgeIndex != newEdgeIndex) { newEdge = edges[beachTree[newEdgeIndex].EdgeIndex];//probably not a need line? Vector2 intercept = getRayIntercept(newEdge, edges[beachTree[parentEdgeOfNewEdgeIndex].EdgeIndex], circleEvent.EventLocation); if (intercept.Y != float.NegativeInfinity && intercept != vertex) { VEdge parentEdgeOfNewEdge = edges[beachTree[parentEdgeOfNewEdgeIndex].EdgeIndex]; float radius = Vector2.Distance(arcs[parentEdgeOfNewEdge.LeftArcIndex].Focus, intercept); intercept.Y -= radius; VEvent newCircleEvent = new VEvent(intercept, EventType.CircleEvent); priorityQueue.Enqueue(newCircleEvent); events.Add(newCircleEvent, new VEventInfo() { Radius = radius, VEdgeOneIndex = parentEdgeOfNewEdgeIndex, //pk pl VEdgeTwoIndex = newEdgeIndex, //pl pm }); //add to leafs VArc arc = arcs[parentEdgeOfNewEdge.LeftArcIndex]; arc.CircleEventLocations.Add(newCircleEvent); //beachTree[parentEdgeOfNewEdge.LeftArcIndex] = arc; arc = arcs[parentEdgeOfNewEdge.RightArcIndex]; arc.CircleEventLocations.Add(newCircleEvent); //beachTree[parentEdgeOfNewEdge.LeftArcIndex] = arc; newEdge = edges[beachTree[newEdgeIndex].EdgeIndex]; arc = arcs[newEdge.RightArcIndex]; arc.CircleEventLocations.Add(newCircleEvent); //beachTree[newEdge.RightArcIndex] = arc; } } if (closestLeftEdgeIndex != newEdgeIndex)//here { newEdge = edges[beachTree[newEdgeIndex].EdgeIndex]; Vector2 intercept = getRayIntercept(newEdge, edges[beachTree[closestLeftEdgeIndex].EdgeIndex], circleEvent.EventLocation); if (intercept.Y != float.NegativeInfinity && intercept != vertex) { VEdge closestLeftEdgeOfNewEdge = edges[beachTree[closestLeftEdgeIndex].EdgeIndex]; float radius = Vector2.Distance(arcs[closestLeftEdgeOfNewEdge.LeftArcIndex].Focus, intercept); intercept.Y -= radius; VEvent newCircleEvent = new VEvent(intercept, EventType.CircleEvent); priorityQueue.Enqueue(newCircleEvent); events.Add(newCircleEvent, new VEventInfo() { Radius = radius, VEdgeOneIndex = newEdgeIndex, VEdgeTwoIndex = closestLeftEdgeIndex, }); //add to leafs VArc arc = arcs[closestLeftEdgeOfNewEdge.LeftArcIndex]; arc.CircleEventLocations.Add(newCircleEvent); arc = arcs[closestLeftEdgeOfNewEdge.RightArcIndex]; arc.CircleEventLocations.Add(newCircleEvent); newEdge = edges[beachTree[newEdgeIndex].EdgeIndex]; arc = arcs[newEdge.RightArcIndex]; arc.CircleEventLocations.Add(newCircleEvent); } } if (closestRightEdgeIndex != newEdgeIndex) { newEdge = edges[beachTree[newEdgeIndex].EdgeIndex]; Vector2 intercept = getRayIntercept(newEdge, edges[beachTree[closestRightEdgeIndex].EdgeIndex], circleEvent.EventLocation); if (intercept.Y != float.NegativeInfinity && intercept != vertex) { VEdge closestRightEdgeOfNewEdge = edges[beachTree[closestRightEdgeIndex].EdgeIndex]; float radius = Vector2.Distance(arcs[closestRightEdgeOfNewEdge.LeftArcIndex].Focus, intercept); intercept.Y -= radius; VEvent newCircleEvent = new VEvent(intercept, EventType.CircleEvent); priorityQueue.Enqueue(newCircleEvent); events.Add(newCircleEvent, new VEventInfo() { Radius = radius, VEdgeOneIndex = newEdgeIndex, VEdgeTwoIndex = closestRightEdgeIndex, }); //add to leafs VArc arc = arcs[closestRightEdgeOfNewEdge.LeftArcIndex]; arc.CircleEventLocations.Add(newCircleEvent); arc = arcs[closestRightEdgeOfNewEdge.RightArcIndex]; arc.CircleEventLocations.Add(newCircleEvent); newEdge = edges[beachTree[newEdgeIndex].EdgeIndex]; arc = arcs[newEdge.RightArcIndex]; arc.CircleEventLocations.Add(newCircleEvent); } } }