Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
0
        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));
        }
Ejemplo n.º 4
0
        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;
                }
            }
        }
Ejemplo n.º 5
0
        //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));
                    }
                }
            }
        }
Ejemplo n.º 6
0
        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);
                }
            }
        }
Ejemplo n.º 7
0
        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;
                    }
                }
            }
        }
Ejemplo n.º 8
0
        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));
            }
        }