public void ReplaceWithSingleNode(BeachLineElement newNode) { if (Parent != null) { newNode.SetParent(Parent); if (Parent.LeftChild == this) { Parent.SetLeftChild(newNode); } else { Parent.SetRightChild(newNode); } } else { // This is the root node mBeachLine.SetRoot(newNode); } if (LeftChild != null) { newNode.SetLeftChild(LeftChild); LeftChild.SetParent(newNode); } if (RightChild != null) { newNode.SetRightChild(RightChild); RightChild.SetParent(newNode); } mParent = null; mLeftChild = null; mRightChild = null; }
public List <BeachLineEdge> DoVoronoi(List <VoronoiSite> siteList) { List <BeachLineEdge> outEdges = new List <BeachLineEdge>(); beachLine = new BeachLine(); events = new List <VoronoiEvent>(); // Add site list to event list. foreach (VoronoiSite site in siteList) { events.Add(new SiteEvent(site)); } // Sort site list. events.Sort(); // Test for first two events being very close in y if (events.Count >= 2) { if (events[0].y - events[1].y < 0.01f) { // Add another site events far above them to prevent this from happening events.Insert(0, new SiteEvent(new VoronoiSite(new Vector2(0, -10)))); } } // Start processing events int iterations = 0; while (events.Count != 0) { if (use_max_iterations && iterations == max_iterations) { break; } else { iterations++; } // Pop event off front of list VoronoiEvent thisEvent = events[0]; // Set sweepline sweepLine = thisEvent.y; if (sweepLine >= target_sweepline) { sweepLine = target_sweepline; beachLine.Update(sweepLine); break; } beachLine.Update(sweepLine); if (thisEvent.IsValid()) { // Check event type if (thisEvent is SiteEvent) { SiteEvent siteEvent = (SiteEvent)thisEvent; // Create a new arc for this event. BeachLineArc newArc = new BeachLineArc(siteEvent.Site.Point, sweepLine); // Find arc at this site BeachLineArc arcToSplit = beachLine.SearchX(siteEvent.x); if (arcToSplit == null) { // We could not find an arc, meaning this is the first one. // Lets just add it to the beachline as root. beachLine.SetRoot(newArc); } else { // Split the arc arcToSplit.Split(newArc); // The split will have added newArc to the tree and also created two new edges. // We need to check those for intersections. List <BeachLineArc> arcsToSqueeze = new List <BeachLineArc> { newArc.LeftArc, newArc.RightArc }; foreach (BeachLineArc arc in arcsToSqueeze) { CheckForNewEdgeEvents(arc); } } } else if (thisEvent is EdgeEvent) { EdgeEvent edgeEvent = (EdgeEvent)thisEvent; if (edgeEvent.SqueezedArc != null) { if (edgeEvent.SqueezedArc.LeftEdge != null && edgeEvent.SqueezedArc.RightEdge != null) { BeachLineEdge newEdge; List <BeachLineEdge> outputEdges = edgeEvent.SqueezedArc.Squeeze(out newEdge); // Add edges to output foreach (BeachLineEdge edge in outputEdges) { outEdges.Add(edge); } // Squeeze function will have removed arc and edges from tree and created a new edge. // We need to check that edge for any new intersections. CheckForNewEdgeEvents(newEdge.LeftArc); CheckForNewEdgeEvents(newEdge.RightArc); } } // Otherwise, this must have been pre-empted but not invalidated for some reason } else { Debug.LogError("Wrong event type! Should not happen!"); } } events.RemoveAt(0); } if (iterations != max_iterations) { sweepLine = target_sweepline; beachLine.Update(sweepLine); } if (events.Count == 0) { // We completed the events list. // Add the remaining edges to the output. BeachLineElement node = beachLine.GetRoot(); if (node != null) { // Mode node to start while (node.Prev != null) { node = node.Prev; } // Add all remaining edges while (node.Next != null) { if (node is BeachLineEdge) { outEdges.Add(node as BeachLineEdge); } node = node.Next; } } } return(outEdges); }