private void ensureExtraCapacity(int index) { //2 * parentIndex + 2 if (2 * index + 2 >= capacity) { BeachLineItem[] newArray = new BeachLineItem[2 * index + 3]; Array.Copy(beachTree, newArray, beachTree.Length); beachTree = newArray; capacity = beachTree.Length; } }
internal void HandleVertexEvent(Vector2 eventLocation, List <VHalfEdge> halfEdges, ref Dictionary <VEvent, VEventInfo> events, ref VTile[] tiles, int curTileIndex, ref PriorityQueue priorityQueue) { //locate the existing arc (if any) that is above the new site int arcIndex = getExistingArc(beachTree, eventLocation); //break the arc by replacing the leaf node with a sub tree representing //the new arc and its break points tiles[curTileIndex] = new VTile(eventLocation); if (arcIndex == -1) { //beachTree[0] = new VArc(eventLocation); beachTree[0] = new BeachLineItem() { IsEdge = false, ArcIndex = arcs.Count, }; arcs.Add(new VArc(eventLocation, tiles[curTileIndex])); } else { //Corresponding leaf replaced by a new sub-tree removeRelatedCircleEvent(arcIndex, eventLocation, ref events); VArc newArc = new VArc(eventLocation, tiles[curTileIndex]); VArc arc = arcs[beachTree[arcIndex].ArcIndex]; //Add two half-edge records in the doubly linked list VHalfEdge halfEdge = new VHalfEdge()//pm pl { Tile = newArc.Tile, }; halfEdges.Add(halfEdge); VHalfEdge twinHalfEdge = new VHalfEdge()//pl pm { Tile = arc.Tile, }; //edges[edges.Count - 1].HalfEdge = halfEdge; //edges[edges.Count - 2].HalfEdge = twinHalfEdge; halfEdges.Add(twinHalfEdge); halfEdge.Twin = twinHalfEdge; twinHalfEdge.Twin = halfEdge; newArc.Tile.Neighbors.AddLast(arc.Tile); arc.Tile.Neighbors.AddLast(newArc.Tile); newArc.Tile.Edges.AddLast(halfEdge); //halfedge belongs to the newArc created arc.Tile.Edges.AddLast(twinHalfEdge); //created twinedge belongs to the split collided arc int leftChildIndex = getLeftChildIndex(arcIndex); beachTree[leftChildIndex] = new BeachLineItem() { IsEdge = false, ArcIndex = beachTree[arcIndex].ArcIndex, }; //arc; int rChild = getRightChildIndex(arcIndex); ensureExtraCapacity(getLeftChildIndex(rChild)); beachTree[getLeftChildIndex(rChild)] = new BeachLineItem() { IsEdge = false, ArcIndex = arcs.Count, }; //newArc; arcs.Add(newArc); ensureExtraCapacity(getRightChildIndex(rChild)); beachTree[getRightChildIndex(rChild)] = new BeachLineItem() { IsEdge = false, ArcIndex = arcs.Count, }; //arc; arcs.Add(new VArc(arc.Focus, arc.Tile)); beachTree[rChild] = new BeachLineItem() { IsEdge = true, EdgeIndex = edges.Count, }; edges.Add(new VEdge(beachTree[getLeftChildIndex(rChild)].ArcIndex, beachTree[getRightChildIndex(rChild)].ArcIndex, twinHalfEdge)); //edges[edges.Count - 1].HalfEdge = halfEdges.Count; beachTree[arcIndex] = new BeachLineItem() { IsEdge = true, EdgeIndex = edges.Count, }; edges.Add(new VEdge(beachTree[leftChildIndex].ArcIndex, beachTree[getLeftChildIndex(rChild)].ArcIndex, halfEdge)); //edges[edges.Count - 1].HalfEdge = halfEdges.Count + 1; //Check for potential circle events, add them to event queue if they exist if (!hasParent(arcIndex)) { //there is no possible circle event, return; } //int parentIndex = getParentIndex(arcIndex);//<-- get first right parent index //int rightParentIndex = getRightParentIndex(arcIndex); VEdge leftCreatedHalfEdge = edges[beachTree[arcIndex].EdgeIndex]; int leftParentIndex = getFirstLeftParentIndex(arcIndex); //if(leftParentIndex == -1) -> then there is no need to check for edges on the left if (leftParentIndex >= 0) { VEdge leftParentEdge = edges[beachTree[leftParentIndex].EdgeIndex]; Vector2 intercept = getRayIntercept(leftCreatedHalfEdge, leftParentEdge, eventLocation); if (intercept.Y != float.NegativeInfinity)//probably don't need this check? { //we want circle event location to be droped lower by radius to x val //we want to calculate radius and store it with the event //we add starting point to the halfedge that belongs to the newArc //halfEdge.Start = intercept; float radius = Vector2.Distance((arcs[leftCreatedHalfEdge.LeftArcIndex]).Focus, intercept); intercept.Y -= radius; VEvent newCircleEvent = new VEvent(intercept, EventType.CircleEvent); priorityQueue.Enqueue(newCircleEvent); events.Add(newCircleEvent, new VEventInfo() { Radius = radius, VEdgeOneIndex = leftParentIndex, //pk pl VEdgeTwoIndex = arcIndex, //pl pm //rChild? }); //add to leafs arc = arcs[leftCreatedHalfEdge.LeftArcIndex]; arc.CircleEventLocations.Add(newCircleEvent); //beachTree[edgeOne.LeftArcIndex] = arc; arc = arcs[leftCreatedHalfEdge.RightArcIndex]; arc.CircleEventLocations.Add(newCircleEvent); //beachTree[edgeOne.LeftArcIndex] = arc; arc = arcs[leftParentEdge.LeftArcIndex]; arc.CircleEventLocations.Add(newCircleEvent); //beachTree[edgeTwo.RightArcIndex] = arc; } } VEdge rightCreatedHalfEdge = edges[beachTree[rChild].EdgeIndex]; int rightParentIndex = getFirstRightParentIndex(arcIndex); //if(rightParentIndex == -1) -> then there is no need to check for edges on the right if (rightParentIndex >= 0) { VEdge rightParentEdge = edges[beachTree[rightParentIndex].EdgeIndex];//(VEdge)beachTree[parentIndex]; Vector2 intercept = getRayIntercept(rightCreatedHalfEdge, rightParentEdge, eventLocation); if (intercept.Y != float.NegativeInfinity) { //we want circle event location to be droped lower by radius to x val //we want to calculate radius and store it with the event //we add starting point to the halfedge that belongs to the newArc //twinHalfEdge.Start = intercept; float radius = Vector2.Distance((arcs[rightCreatedHalfEdge.LeftArcIndex]).Focus, intercept); intercept.Y -= radius; VEvent newCircleEvent = new VEvent(intercept, EventType.CircleEvent); priorityQueue.Enqueue(newCircleEvent); events.Add(newCircleEvent, new VEventInfo() { Radius = radius, VEdgeOneIndex = rightParentIndex, //pk pl VEdgeTwoIndex = rChild, //pl pm }); //add to leafs arc = arcs[rightCreatedHalfEdge.LeftArcIndex]; arc.CircleEventLocations.Add(newCircleEvent); //beachTree[edgeOne.LeftArcIndex] = arc; arc = arcs[rightCreatedHalfEdge.RightArcIndex]; arc.CircleEventLocations.Add(newCircleEvent); //beachTree[edgeOne.LeftArcIndex] = arc; arc = arcs[rightParentEdge.RightArcIndex]; arc.CircleEventLocations.Add(newCircleEvent); //beachTree[edgeTwo.RightArcIndex] = arc; } } } }