Пример #1
0
        /// <summary>
        /// Inserts an object into index.
        /// </summary>
        /// <param name="obj">An object to insert</param>
        public void Insert <T>(T obj)
            where T : IIndexable
        {
            if (!IndexedSpace.ContainsRectangle(obj.BoundingRectangle))
            {
                throw new ArgumentException("Bounding rectangle of the object is outside of the indexed space. Need to rebuild index.", "obj");
            }

            _root.Insert(obj, 1);
        }
            internal int Insert(T ins, MultidimensionalComparator <T> comparator, int level)
            {
                Load();
                CompareResult diff = comparator.Compare(ins, obj, level % comparator.NumberOfDimensions);

                if (diff == CompareResult.EQ && deleted)
                {
                    Storage.Deallocate(obj);
                    Modify();
                    obj     = ins;
                    deleted = false;
                    return(level);
                }
                else if (diff != CompareResult.GT)
                {
                    if (left == null)
                    {
                        Modify();
                        left = new KDTreeNode(Storage, ins);
                        return(level + 1);
                    }
                    else
                    {
                        return(left.Insert(ins, comparator, level + 1));
                    }
                }
                else
                {
                    if (right == null)
                    {
                        Modify();
                        right = new KDTreeNode(Storage, ins);
                        return(level + 1);
                    }
                    else
                    {
                        return(right.Insert(ins, comparator, level + 1));
                    }
                }
            }
Пример #3
0
            /// <summary>
            /// Adds an object to this node
            /// or one of its childs.
            /// </summary>
            internal void Insert(IIndexable obj, int branchDepth)
            {
                // возможно глубина текущей ветки
                // уже больше глубины индекса
                if (branchDepth > _parent.Depth)
                {
                    _parent._depth++;
                }

                // возможно мы достигли:
                // 1. максимально допустимой глубины индекса
                // 2. порогового значения площади ячейки узла
                // при этом создавать дочерние узлы уже нельзя
                if (_parent.Depth >= _parent.MaxDepth ||
                    _parent._boxSquareThreshold > _boundingBox.Width * _boundingBox.Height)
                {
                    _objects.Add(obj);
                    return;
                }

                BoundingRectangle box0, box1;
                bool hasChilds = _child0 != null && _child1 != null;

                // усли у узла еще нет дочерних узлов, вычисляем их ограничивающие прямоугольники,
                // иначе берем их из дочерних узлов
                if (!hasChilds)
                {
                    splitMaxAxis(_boundingBox, out box0, out box1);
                }
                else
                {
                    box0 = _child0._boundingBox;
                    box1 = _child1._boundingBox;
                }

                bool f0 = box0.Intersects(obj.BoundingRectangle);
                bool f1 = box1.Intersects(obj.BoundingRectangle);

                if (f0 && f1)
                {
                    // дочерние узлы уже были созданы,
                    // вариантов разбиения больше нет
                    if (hasChilds)
                    {
                        _objects.Add(obj);
                        return;
                    }

                    // возможно при разбиении вдоль другой оси ситуация не столь плачевна
                    splitMinAxis(_boundingBox, out box0, out box1);

                    f0 = box0.Intersects(obj.BoundingRectangle);
                    f1 = box1.Intersects(obj.BoundingRectangle);
                    if (f0 && f1)
                    {
                        // добавляемый объект пересекает оба ограничивающих прямоугольника в обоих
                        // вариантах разбиения, значит мы не можем добавить его в дочерние узлы,
                        // добавляем в текущий узел
                        _objects.Add(obj);
                        return;
                    }
                }

                // если дочерние узлы еще не были созданы, создаем их
                if (_child0 == null && _child1 == null)
                {
                    _child0 = new KDTreeNode(box0, _parent);
                    _child1 = new KDTreeNode(box1, _parent);
                }

                if (f0)
                {
                    _child0.Insert(obj, branchDepth + 1);
                    return;
                }

                if (f1)
                {
                    _child1.Insert(obj, branchDepth + 1);
                    return;
                }

#if DEBUG
                Debug.Assert(false, "This statement should never be executed");
#endif
            }