Пример #1
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>	Insert a new polygon arising from a site event. </summary>
        /// <remarks>	Darrellp, 2/19/2011. </remarks>
        /// <param name="evt">	Site event causing the new polygon. </param>
        /// <param name="evq">	Event queue. </param>
        ////////////////////////////////////////////////////////////////////////////////////////////////////
        internal void PolyInsertNode(SiteEvent evt, EventQueue evq)
        {
            // If there's no tree yet
            if (NdRoot == null)
            {
                // Create a leaf node and make it the tree root
                NdRoot = new LeafNode(evt.Poly);

                return;
            }

            // Get the parabola above this site and the parabolas to its left and right
            var lfn      = LfnSearchNode(evt.Pt.X, evt.Pt.Y);
            var lfnLeft  = lfn.LeftAdjacentLeaf;
            var lfnRight = lfn.RightAdjacentLeaf;

            // Remove the circle event associated with the parabola we intersect
            //
            // We are inserting ourselves into this parabola which means it's old circle event is defunct
            // so toss it.
            lfn.DeleteAssociatedCircleEvent(evq);

            // Create a new subtree to hold the new leaf node
            var innSubRoot = NdCreateInsertionSubtree(lfn, evt);

            // If the root node is a leaf
            if (NdRoot.IsLeaf)
            {
                // Replace it with the new inner node we just created
                NdRoot = innSubRoot;
            }

            // TODO: Rebalancing the tree
            //Rebalance(innSubRoot);

            // For every circle event
            //
            // Remove any circle events that this generator is inside since it will be closer to the center
            // of the circle than any of the three points which lie on the circle
            // TODO: Is there a good way to optimize this?
            var lln = evq.CircleEvents.First;

            while (lln != null)
            {
                var cevt    = lln.Value;
                var llnNext = lln.Next;
                if (cevt.Contains(evt.Pt))
                {
                    // Delete the circle event
                    evq.CircleEvents.Remove(lln);
                    cevt.LinkedListNode = null;
                }

                lln = llnNext;
            }

            // Create any circle events which this site causes
            CreateCircleEventsFromSiteEvent(lfnLeft, lfnRight, evt.Pt.Y, evq);
        }
Пример #2
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>	Insert a new LeafNode into the tree. </summary>
        /// <remarks>	Darrellp, 2/19/2011. </remarks>
        /// <param name="lfn">	Place to put the new leaf node. </param>
        /// <param name="evt">	The event to insert. </param>
        /// <returns>	. </returns>
        ////////////////////////////////////////////////////////////////////////////////////////////////////
        private static InternalNode NdCreateInsertionSubtree(LeafNode lfn, SiteEvent evt)
        {
            // Initialize locals
            var innParent      = lfn.NdParent;
            var lfnNewParabola = new LeafNode(evt.Poly);
            var innSubRoot     = new InternalNode(evt.Poly, lfn.Poly);
            var fLeftChild     = true;

            // If this isn't on the root node, shuffle things around a bit
            if (innParent != null)
            {
                fLeftChild = lfn.IsLeftChild;

                lfn.SnipFromParent();
                if (fLeftChild)
                {
                    innParent.LeftChild = innSubRoot;
                }
                else
                {
                    innParent.RightChild = innSubRoot;
                }
            }

            // Watch for the odd corner case of the top n generators having the same y coordinate.  See comments
            // on NdInsertAtSameY().
            if (Geometry2D.FCloseEnough(evt.Pt.Y, lfn.Poly.VoronoiPoint.Y))
            {
                NdInsertAtSameY(lfn, lfnNewParabola, innParent, innSubRoot, fLeftChild);
            }
            else
            {
                InsertAtDifferentY(lfn, lfnNewParabola, innSubRoot);
            }

            return(innSubRoot);
        }