Пример #1
0
        /// <summary>
        /// Subdivide this QuadTree and move it's children into the appropriate Quads where applicable.
        /// </summary>
        private void Subdivide()
        {
            // We've reached capacity, subdivide...
            PrecisePoint size = new PrecisePoint(rect.Width / 2.0d, rect.Height / 2.0d);
            PrecisePoint mid  = new PrecisePoint(rect.X + size.X, rect.Y + size.Y);

            childTL = new QuadTreeNode <T>(this, new PreciseRectangle(rect.Left, rect.Top, size.X, size.Y));
            childTR = new QuadTreeNode <T>(this, new PreciseRectangle(mid.X, rect.Top, size.X, size.Y));
            childBL = new QuadTreeNode <T>(this, new PreciseRectangle(rect.Left, mid.Y, size.X, size.Y));
            childBR = new QuadTreeNode <T>(this, new PreciseRectangle(mid.X, mid.Y, size.X, size.Y));

            // If they're completely contained by the quad, bump objects down
            for (int i = 0; i < objects.Count; i++)
            {
                QuadTreeNode <T> destTree = GetDestinationTree(objects[i]);

                if (destTree != this)
                {
                    // Insert to the appropriate tree, remove the object, and back up one in the loop
                    destTree.Insert(objects[i]);
                    Remove(objects[i]);
                    i--;
                }
            }
        }
Пример #2
0
        private void Relocate(QuadTreeObject <T> item)
        {
            // Are we still inside our parent?
            if (QuadRect.Contains(item.Data.QuadBounds))
            {
                // Good, have we moved inside any of our children?
                if (childTL != null)
                {
                    QuadTreeNode <T> dest = GetDestinationTree(item);
                    if (item.Owner != dest)
                    {
                        // Delete the item from this quad and add it to our child
                        // Note: Do NOT clean during this call, it can potentially delete our destination quad
                        QuadTreeNode <T> formerOwner = item.Owner;
                        Delete(item, false);
                        dest.Insert(item);

                        // Clean up ourselves
                        formerOwner.CleanUpwards();
                    }
                }
            }
            else
            {
                // We don't fit here anymore, move up, if we can
                if (parent != null)
                {
                    parent.Relocate(item);
                }
            }
        }
Пример #3
0
 ///<summary>
 ///Adds an item to the <see cref="T:System.Collections.Generic.ICollection`1" />.
 ///</summary>
 ///
 ///<param name="item">The object to add to the <see cref="T:System.Collections.Generic.ICollection`1" />.</param>
 ///<exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.Generic.ICollection`1" /> is read-only.</exception>
 public void Add(T item)
 {
     lock (objLock) {
         QuadTreeObject <T> wrappedObject = new QuadTreeObject <T>(item);
         wrappedDictionary.Add(item, wrappedObject);
         quadTreeRoot.Insert(wrappedObject);
     }
 }
Пример #4
0
        /// <summary>
        /// Insert an item into this QuadTree object.
        /// </summary>
        /// <param name="item">The item to insert.</param>
        internal void Insert(QuadTreeObject <T> item)
        {
            // If this quad doesn't contain the items rectangle, do nothing, unless we are the root
            if (!rect.Contains(item.Data.QuadBounds))
            {
                //System.Diagnostics.Debug.Assert(parent == null, "We are not the root, and this object doesn't fit here. How did we get here?");
                if (parent == null)
                {
                    // This object is outside of the QuadTree bounds, we should add it at the root level
                    Add(item);
                }
                else
                {
                    parent.Insert(item);
                    return;
                }
            }

            if (objects == null ||
                (childTL == null && objects.Count + 1 <= maxObjectsPerNode))
            {
                // If there's room to add the object, just add it
                Add(item);
            }
            else
            {
                // No quads, create them and bump objects down where appropriate
                if (childTL == null)
                {
                    Subdivide();
                }

                // Find out which tree this object should go in and add it there
                QuadTreeNode <T> destTree = GetDestinationTree(item);
                if (destTree == this)
                {
                    Add(item);
                }
                else
                {
                    destTree.Insert(item);
                }
            }
        }