public static VoronoiDiagram MakeVoronoiSF(List <Vector2> seeds, Vector2 boundry)
        {
            tiles            = new VTile[seeds.Count];
            currentTileIndex = 0;
            vertices         = new List <Vector2>();
            halfEdges        = new List <VHalfEdge>();

            priorityQueue = new PriorityQueue();
            events        = new Dictionary <VEvent, VEventInfo>();

            foreach (Vector2 seed in seeds)
            {
                VEvent newEvent = new VEvent(seed, EventType.VertexEvent);
                priorityQueue.Enqueue(newEvent);
                events.Add(newEvent, null);
            }

            beachLine = new BeachLine();

            while (priorityQueue.NotEmpty)
            {
                VEvent     nextEvent = priorityQueue.Dequeue();
                VEventInfo evtInfo   = events[nextEvent];
                if (evtInfo == null || evtInfo.Deleted != true)
                {
                    handleEvent(nextEvent, nextEvent.EventType, halfEdges);
                }
            }
            VoronoiDiagram retVal = new VoronoiDiagram()
            {
                Verticies = vertices.ToArray(),
                Tiles     = tiles,
                HalfEdges = halfEdges
            };

            tiles         = null;
            vertices      = null;
            halfEdges     = null;
            priorityQueue = null;
            events        = null;
            beachLine     = null;

            return(retVal);
        }
Beispiel #2
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);
                }
            }
        }