Heuristics used for tree generation
예제 #1
0
        /// <summary>
        /// Creates a node and either splits the objects recursively into sub-nodes, or stores them at the node depending on the heuristics.
        /// Tree is built top->down
        /// </summary>
        /// <param name="objList">Geometries to index</param>
        /// <param name="depth">Current depth of tree</param>
        /// <param name="heurdata">Heuristics data</param>
        public QuadTree(List<BoxObjects> objList, uint depth, Heuristic heurdata)
        {
            _Depth = depth;

            _box = objList[0].box;
            for (int i = 0; i < objList.Count; i++)
                _box = _box.Join(objList[i].box);

            // test our build heuristic - if passes, make children
            if (depth < heurdata.maxdepth && objList.Count > heurdata.mintricnt &&
                (objList.Count > heurdata.tartricnt || ErrorMetric(_box) > heurdata.minerror))
            {
                List<BoxObjects>[] objBuckets = new List<BoxObjects>[2]; // buckets of geometries
                objBuckets[0] = new List<BoxObjects>();
                objBuckets[1] = new List<BoxObjects>();

                uint longaxis = _box.LongestAxis; // longest axis
                double geoavg = 0; // geometric average - midpoint of ALL the objects

                // go through all bbox and calculate the average of the midpoints
                double frac = 1.0f/objList.Count;
                for (int i = 0; i < objList.Count; i++)
                    geoavg += objList[i].box.GetCentroid()[longaxis]*frac;

                // bucket bbox based on their midpoint's side of the geo average in the longest axis
                for (int i = 0; i < objList.Count; i++)
                    objBuckets[geoavg > objList[i].box.GetCentroid()[longaxis] ? 1 : 0].Add(objList[i]);

                //If objects couldn't be splitted, just store them at the leaf
                //TODO: Try splitting on another axis
                if (objBuckets[0].Count == 0 || objBuckets[1].Count == 0)
                {
                    _child0 = null;
                    _child1 = null;
                    // copy object list
                    _objList = objList;
                }
                else
                {
                    // create new children using the buckets
                    _child0 = new QuadTree(objBuckets[0], depth + 1, heurdata);
                    _child1 = new QuadTree(objBuckets[1], depth + 1, heurdata);
                }
            }
            else
            {
                // otherwise the build heuristic failed, this is 
                // set the first child to null (identifies a leaf)
                _child0 = null;
                _child1 = null;
                // copy object list
                _objList = objList;
            }
        }
예제 #2
0
        /// <summary>
        /// Adds a new <see cref="BoxObjects"/> to this node.
        /// </summary>
        /// <param name="o">The boxed object</param>
        /// <param name="h">The child node creation heuristic</param>
        public void AddNode(BoxObjects o, Heuristic h)
        {
          /* -------------------------------------------------------------------- */
          /*      If there are subnodes, then consider whether this object        */
          /*      will fit in them.                                               */
          /* -------------------------------------------------------------------- */
            if (_child0 != null && _depth < h.maxdepth)
            {
                if (_child0.Box.Contains(o.Box.Centre))
                    _child0.AddNode(o, h);
                else if (_child1.Box.Contains(o.Box.Centre))
                    _child1.AddNode(o, h);
                return;
            }
        
            /* -------------------------------------------------------------------- */
            /*      Otherwise, consider creating two subnodes if could fit into     */
            /*      them, and adding to the appropriate subnode.                    */
            /* -------------------------------------------------------------------- */
            if( h.maxdepth > _depth && !IsLeaf )
            {
                Envelope half1, half2;
                SplitBoundingBox(Box, out half1, out half2);
            

                if( half1.Contains(o.Box.Centre)) 
                {
                    _child0 = new QuadTree(half1, _depth + 1);
                    _child1 = new QuadTree(half2, _depth + 1);
                    _child0.AddNode(o, h);
                    return;
                }    
	            if(half2.Contains(o.Box.Centre))
	            {
                    _child0 = new QuadTree(half1, _depth + 1);
                    _child1 = new QuadTree(half2, _depth + 1);
	                _child1.AddNode(o, h);
	                return;
	            }
            }
        
            /* -------------------------------------------------------------------- */
            /*      If none of that worked, just add it to this nodes list.         */
            /* -------------------------------------------------------------------- */
            //Debug.Assert(_child0 == null);
            
            if (_objList == null)
                _objList = new List<BoxObjects>();

            Box.ExpandToInclude(o.Box); 
            
            _objList.Add(o);

        }