private void copyTree(int target, int treeStart, ref Dictionary <VEvent, VEventInfo> events) { if (beachTree[treeStart] == null) { return; } beachTree[target] = beachTree[treeStart]; if (beachTree[treeStart].IsEdge) { //update related circle events to edge VEdge edge = edges[beachTree[treeStart].EdgeIndex]; VArc arc = arcs[edge.LeftArcIndex]; foreach (VEvent circleEventLocation in arc.CircleEventLocations) { if (events[circleEventLocation].VEdgeTwoIndex == treeStart) { events[circleEventLocation].VEdgeTwoIndex = target; } else if (events[circleEventLocation].VEdgeOneIndex == treeStart) { events[circleEventLocation].VEdgeOneIndex = target; } } } beachTree[treeStart] = null; copyTree(getLeftChildIndex(target), getLeftChildIndex(treeStart), ref events); copyTree(getRightChildIndex(target), getRightChildIndex(treeStart), ref events); }
public static (List <VPlace>, List <VTransition>, List <VArc>) FromOriginalModel(PetriNet net) { Dictionary <string, VPlace> places = new Dictionary <string, VPlace>(); foreach (var netPlace in net.Places) { var vplace = new VPlace(netPlace.Position.x, netPlace.Position.y, netPlace.Tokens, netPlace.Id) { Label = netPlace.Label, }; places[netPlace.Id] = vplace; vplace.BindSyncPlace(netPlace); } VPlace.Counter = places.Count + 1; Dictionary <string, VTransition> transitions = new Dictionary <string, VTransition>(); foreach (var netTransition in net.Transitions) { var vtransition = new VTransition(netTransition.Position.x, netTransition.Position.y, netTransition.Id) { Label = netTransition.Label, Priority = netTransition.Priority }; transitions[netTransition.Id] = vtransition; vtransition.BindSyncTransition(netTransition); } VTransition.Counter = transitions.Count + 1; Dictionary <string, PetriNetNode> nodes = new Dictionary <string, PetriNetNode>(); foreach (var kv in places) { nodes[kv.Key] = kv.Value; } foreach (var kv in transitions) { nodes[kv.Key] = kv.Value; } List <VArc> arcs = new List <VArc>(); foreach (var netArc in net.Arcs) { var varc = new VArc(); varc.IsDirected = true; varc.Id = netArc.Id; varc.Weight = netArc.Weight.ToString(); varc.From = nodes[netArc.NodeFrom.Id]; varc.To = nodes[netArc.NodeTo.Id]; varc.From.ThisArcs.Add(varc); varc.To.ThisArcs.Add(varc); arcs.Add(varc); varc.BindSyncArc(netArc); } return(places.Select(t => t.Value).ToList(), transitions.Select(t => t.Value).ToList(), arcs); }
private float solveForY(VArc arc, float x, Vector2 eventLocation) { double xFocus = arc.Focus.X; double yFocus = arc.Focus.Y; double directrix = eventLocation.Y; double K = Math.Pow(xFocus, 2) + Math.Pow(yFocus, 2) - Math.Pow(directrix, 2); double L = 2 * xFocus; double M = 2 * (yFocus - directrix); double N = 1 / M; double O = (L / M) * -1; double P = K / M; //NX ^ 2 + OX + P return((float)(N * Math.Pow(x, 2) + O * x + P)); }
public static void SetCoordinatesOfLine(Line lineVisible, VArc arc) { var from = arc.From; var to = arc.To; var tempX1 = @from.CoordX; var tempX2 = to.CoordX; var tempY1 = @from.CoordY; var tempY2 = to.CoordY; if (tempX2 > tempX1) { if (to is VPlace) { lineVisible.X1 = tempX1 + 20; lineVisible.Y1 = tempY1 + 25; lineVisible.Y2 = tempY2 + 15; } else { lineVisible.X1 = tempX1 + 30; lineVisible.Y1 = tempY1 + 15; lineVisible.Y2 = tempY2 + 25; } lineVisible.X2 = tempX2; } else { lineVisible.X1 = tempX1; if (to is VPlace) { lineVisible.Y1 = tempY1 + 25; lineVisible.X2 = tempX2 + 30; lineVisible.Y2 = tempY2 + 15; } else { lineVisible.Y1 = tempY1 + 15; lineVisible.X2 = tempX2 + 20; lineVisible.Y2 = tempY2 + 25; } } }
//going from left to right on the curve of the left Arc, return the first intersection with the right Arc private float getPorabolaRightIntercept(VArc leftArc, VArc rightArc, Vector2 eventLocation) { if (leftArc.Focus.Y == eventLocation.Y) { return(leftArc.Focus.X); } else if (rightArc.Focus.Y == eventLocation.Y) { return(rightArc.Focus.X); } //y = ((x - a)^2 + b^2 - c^2)/(2(b - c)) double ANot = leftArc.Focus.X; double BNot = leftArc.Focus.Y; double APrime = rightArc.Focus.X; double BPrime = rightArc.Focus.Y; double C = eventLocation.Y; double E = Math.Pow(ANot, 2) + Math.Pow(BNot, 2) - Math.Pow(C, 2); double F = 2 * ANot; double G = 2 * (BNot - C); double H = 1 / G; double I = (F / G) * -1; double J = E / G; double K = Math.Pow(APrime, 2) + Math.Pow(BPrime, 2) - Math.Pow(C, 2); double L = 2 * APrime; double M = 2 * (BPrime - C); double N = 1 / M; double O = (L / M) * -1; double P = K / M; //HX^2 + IX + J = NX^2 + OX + P //(H - N)X^2 + (I - O)X + (J - P) //QX^2 + RX + S = 0 double Q = N - H; double R = O - I; double S = P - J; if (Q == 0) { //RX + S = 0 //X = -S / R; if ((-S / R) < leftArc.Focus.X) { return(float.NaN); } else { return((float)(-S / R)); } } double x1; double x2; QuadraticEquation(out x1, out x2, Q, R, S); if (Double.IsNaN(x1) || Double.IsInfinity(x1)) { //There is less than two solutions if (Double.IsNaN(x2) || Double.IsInfinity(x2)) { //There is no solution return(float.NaN); } else { //There is one solution //return (float)x2; if (leftArc.Focus.Y > rightArc.Focus.Y) { return(float.NaN); } else if (leftArc.Focus.Y == rightArc.Focus.Y) { if (leftArc.Focus.X < rightArc.Focus.X) { return(float.NaN); } else { return((float)x2); } } else { return((float)x2); } } } else { //There might be two solutions if (Double.IsNaN(x2) || Double.IsInfinity(x2)) { //There is one solution //return (float)x1; if (leftArc.Focus.Y > rightArc.Focus.Y) { return((float)x1); } else if (leftArc.Focus.Y == rightArc.Focus.Y) { if (leftArc.Focus.X < rightArc.Focus.X) { return((float)x1); } else { return(float.NaN); } } else { return((float)x1); } } else { //There are two solutions if (leftArc.Focus.Y > rightArc.Focus.Y) { return((float)Math.Min(x1, x2)); } else { return((float)Math.Max(x1, x2)); } } } }
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); } } }
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; } } } }
private Vector2 getRayIntercept(VEdge edgeOne, VEdge edgeTwo, Vector2 eventLocation) { //VectorEquation vecEQ = midPointOne + vectorSlopeOne * t where t >= 0 VArc LeftArc = arcs[edgeOne.LeftArcIndex]; VArc RightArc = arcs[edgeOne.RightArcIndex]; float x1 = LeftArc.Focus.X; float y1 = LeftArc.Focus.Y; float x2 = RightArc.Focus.X; float y2 = RightArc.Focus.Y; Vector2 vectorSlopeOne = new Vector2(y2 - y1, x1 - x2); // instead of midpoint, it should be at the relavant intersection of the two arcs. //Vector2 midPointOne = new Vector2((x1 + x2) / 2, (y1 + y2) / 2); float startingPointOneX = getPorabolaRightIntercept(LeftArc, RightArc, eventLocation); float startingPointOneY = solveForY(LeftArc, startingPointOneX, eventLocation); if (float.IsNaN(startingPointOneY) || float.IsInfinity(startingPointOneY)) { startingPointOneY = solveForY(RightArc, startingPointOneX, eventLocation); } Vector2 startPointOne = new Vector2(startingPointOneX, startingPointOneY); LeftArc = arcs[edgeTwo.LeftArcIndex]; RightArc = arcs[edgeTwo.RightArcIndex]; x1 = LeftArc.Focus.X; y1 = LeftArc.Focus.Y; x2 = RightArc.Focus.X; y2 = RightArc.Focus.Y; Vector2 vectorSlopeTwo = new Vector2(y2 - y1, x1 - x2); // instead of midpoint, it should be at the relavant intersection of the two arcs. //Vector2 midPointTwo = new Vector2((x1 + x2) / 2, (y1 + y2) / 2); float startingPointTwoX = getPorabolaRightIntercept(LeftArc, RightArc, eventLocation); float startingPointTwoY = solveForY(LeftArc, startingPointTwoX, eventLocation); if (float.IsNaN(startingPointTwoY) || float.IsInfinity(startingPointTwoY)) { startingPointTwoY = solveForY(RightArc, startingPointOneX, eventLocation); } Vector2 startPointTwo = new Vector2(startingPointTwoX, startingPointTwoY); float[,] GMatrix = { { vectorSlopeOne.X, -vectorSlopeTwo.X, (startPointTwo.X - startPointOne.X) }, { vectorSlopeOne.Y, -vectorSlopeTwo.Y, (startPointTwo.Y - startPointOne.Y) } }; GaussianElim.SolutionResult result = GaussianElim.Solve(GMatrix, GMatrix.GetLength(0)); if (result == GaussianElim.SolutionResult.OneSolution) { float parameterResultOne = GMatrix[0, 2] / GMatrix[0, 0]; float parameterResultTwo = GMatrix[1, 2] / GMatrix[1, 1]; if (parameterResultOne >= 0 && parameterResultTwo >= 0) { Vector2 foo = new Vector2(startPointOne.X + vectorSlopeOne.X * parameterResultOne, startPointOne.Y + vectorSlopeOne.Y * parameterResultOne); Vector2 bar = new Vector2(startPointTwo.X + vectorSlopeTwo.X * parameterResultTwo, startPointTwo.Y + vectorSlopeTwo.Y * parameterResultTwo); return(bar); //return new Vector3(midPointOne.x + vectorSlopeOne.x * parameterResultOne, midPointOne.y + vectorSlopeOne.y * parameterResultOne); } else { return(new Vector2(float.NegativeInfinity, float.NegativeInfinity)); } } else { return(new Vector2(float.NegativeInfinity, float.NegativeInfinity)); } }