/// <summary> /// Display the Voronoi Diagram /// </summary> private void DisplayVoronoiDiagram() { Tools.current = Tool.None; //Check if the cells array in the Voronoi class is not null if (sc.Voronoi.Cells != null) { //Set the Handles color Handles.color = Color.grey; //Loop for (int i = 0; i < sc.Voronoi.CellCount; i++) { //Check if the current cell is not null if (sc.Voronoi.Cells[i] != null) { //Get the first edge in the current cell vEdge fE = sc.Voronoi.FirstEdge(sc.Voronoi.Cells[i]); //Set e to the first edge vEdge e = fE; do { //Draw a line Handles.DrawLine(e.v0.Site.Vector3(), e.v1.Site.Vector3()); //Set e to the next ege e = e.Next; //While e is not the first edge contuine //This will allow us to go around though each //edge unitll we reach the first edge again } while (e != fE); } } } }
/// <summary> /// Add a new arc into the beachline. This will split the /// beachline arc. The arc which is split is the arc above the /// new site /// </summary> /// <param name="a_newCell"></param> public void ProcessSiteEvent(Cell a_newCell) { //Find arc to split Arc splitArc = Search(a_newCell.Site); //If there is a circle event with the split arc, delete it if (splitArc.circleNode != null) { circleQueue.Delete(splitArc.circleNode); } //Create new edges between the new arcs vEdge edge0 = new vEdge(); vEdge edge1 = new vEdge(); //set the edges cells edge0.Cell = splitArc.cell; edge1.Cell = a_newCell; //set the twin edges edge0.Twin = edge1; edge1.Twin = edge0; //check if the arc to be split cell has an edge //if it does not set it's edge to edge0 if (splitArc.cell.Edge == null) { splitArc.cell.Edge = edge0; } //check if newCell has an edge. If not set it's //edge to edge1 if (a_newCell.Edge == null) { a_newCell.Edge = edge1; } //Make a new arc Arc newLeftArc; //if there are any previous arc reuse then if (!recycledArcs.IsEmpty()) { newLeftArc = recycledArcs.Pop(); } else { newLeftArc = new Arc(); } //set all the values for the new left arc newLeftArc.parentArc = splitArc; newLeftArc.leftArc = splitArc.leftArc; newLeftArc.rightArc = null; newLeftArc.previousArc = splitArc.previousArc; newLeftArc.nextArc = splitArc; newLeftArc.cell = splitArc.cell; newLeftArc.leftEdge = splitArc.leftEdge; newLeftArc.rightEdge = edge0; newLeftArc.circleNode = null; //check if there is a leftArc. If there is then //we need to set it parentArc to the newLeftArc //this links the arc together if (newLeftArc.leftArc != null) { newLeftArc.leftArc.parentArc = newLeftArc; } //Make a new arc Arc newRightArc; //if there are any previous arc reuse then if (!recycledArcs.IsEmpty()) { newRightArc = recycledArcs.Pop(); } else { newRightArc = new Arc(); } //set all the values for the new left arc newRightArc.parentArc = splitArc; newRightArc.leftArc = null; newRightArc.rightArc = splitArc.rightArc; newRightArc.previousArc = splitArc; newRightArc.nextArc = splitArc.nextArc; newRightArc.cell = splitArc.cell; newRightArc.leftEdge = edge0; newRightArc.rightEdge = splitArc.rightEdge; newRightArc.circleNode = null; //check if there is a rightArc. If there is then //we need to set it parentArc to the newRightArc //this links the arc together if (newRightArc.rightArc != null) { newRightArc.rightArc.parentArc = newRightArc; } //Set split arc variables to the two new created arcs splitArc.leftArc = newLeftArc; splitArc.rightArc = newRightArc; splitArc.previousArc = newLeftArc; splitArc.nextArc = newRightArc; splitArc.cell = a_newCell; splitArc.leftEdge = edge1; splitArc.rightEdge = edge1; splitArc.circleNode = null; // Have next and previous arcs point to the new arcs. This maintains the linked list // through the beachline. if (newLeftArc.previousArc != null) { newLeftArc.previousArc.nextArc = newLeftArc; } if (newRightArc.nextArc != null) { newRightArc.nextArc.previousArc = newRightArc; } // Find new circle events for new left and right arcs. The new middle arc is always // diverging when it is created so we don't need to check for it. newLeftArc.circleNode = AddCircleEvent(a_newCell.Site.y, newLeftArc); newRightArc.circleNode = AddCircleEvent(a_newCell.Site.y, newRightArc); }
/// <summary> /// Deletes an existing arc and adds a new vertex to the diagram. Each new vertex /// also creates a new edge between the neighboring arcs. /// </summary> /// <param name="a_cEvent"></param> public void ProcessCircleEvent(CircleQueue.Event a_cEvent) { Arc deleteArc = a_cEvent.arc; Arc previousArc = deleteArc.previousArc; Arc nextArc = deleteArc.nextArc; vEdge leftEdge = deleteArc.leftEdge; vEdge rightEdge = deleteArc.rightEdge; //Create a new vertex at the location of the circle event vVertex v = new vVertex(a_cEvent.vertex); //Create a new edge that emerges from the event vEdge edge0 = new vEdge(); vEdge edge1 = new vEdge(); //setup the new edges edge0.Cell = leftEdge.Twin.Cell; edge1.Cell = rightEdge.Twin.Cell; edge0.Twin = edge1; edge1.Twin = edge0; //Set all edges to point to the new vertex leftEdge.v0 = v; leftEdge.Twin.v1 = v; rightEdge.v1 = v; rightEdge.Twin.v0 = v; edge0.v0 = v; edge1.v1 = v; //Stich the edge together leftEdge.Previous = rightEdge; rightEdge.Next = leftEdge; edge0.Previous = leftEdge.Twin; edge0.Previous.Next = edge0; edge1.Next = rightEdge.Twin; edge1.Next.Previous = edge1; // If there's a circle event associated with a neighboring arc, delete it if (previousArc.circleNode != null) { circleQueue.Delete(previousArc.circleNode); } if (nextArc.circleNode != null) { circleQueue.Delete(nextArc.circleNode); } //Set the neighboring arcs to point to the new edge previousArc.rightEdge = edge0; nextArc.leftEdge = edge1; //Delete the completed arc Delete(deleteArc); //Calculate new circle events for the site arcs previousArc.circleNode = AddCircleEvent(a_cEvent.yLock, previousArc); nextArc.circleNode = AddCircleEvent(a_cEvent.yLock, nextArc); }