示例#1
0
        static bool NumberOfIntersectedIsLessThanBoundOnNode(RectangleNode <T, P> node, IRectangle <P> rect, ref int bound, Func <T, bool> conditionFunc)
        {
            Debug.Assert(bound > 0);
            if (!node.Rectangle.Intersects(rect))
            {
                return(true);
            }
            if (node.IsLeaf)
            {
                if (conditionFunc(node.UserData))
                {
                    return((--bound) != 0);
                }
                return(true);
            }

            return(NumberOfIntersectedIsLessThanBoundOnNode(node.Left, rect, ref bound, conditionFunc) &&
                   NumberOfIntersectedIsLessThanBoundOnNode(node.Right, rect, ref bound, conditionFunc));
        }
        static public RectangleNode <T, P> CreateRectangleNodeOnListOfNodes(IList <RectangleNode <T, P> > nodes)
        {
            ValidateArg.IsNotNull(nodes, "nodes");
            if (nodes.Count == 0)
            {
                return(null);
            }

            if (nodes.Count == 1)
            {
                return(nodes[0]);
            }

            //Finding the seeds
            var b0 = nodes[0].Rectangle;

            //the first seed
            int seed0 = 1;

            int seed1 = ChooseSeeds(nodes, ref b0, ref seed0);

            //We have two seeds at hand. Build two groups.
            var gr0 = new List <RectangleNode <T, P> >();
            var gr1 = new List <RectangleNode <T, P> >();

            gr0.Add(nodes[seed0]);
            gr1.Add(nodes[seed1]);

            var box0 = nodes[seed0].Rectangle;
            var box1 = nodes[seed1].Rectangle;

            //divide nodes on two groups
            DivideNodes(nodes, seed0, seed1, gr0, gr1, ref box0, ref box1, GroupSplitThreshold);

            var ret = new RectangleNode <T, P>(nodes.Count)
            {
                Rectangle = box0.Add(box1),
                Left      = CreateRectangleNodeOnListOfNodes(gr0),
                Right     = CreateRectangleNodeOnListOfNodes(gr1)
            };

            return(ret);
        }
示例#3
0
        public IEnumerable <RectangleNode <TData> > GetLeafRectangleNodesIntersectingRectangle(Rectangle rectanglePar)
        {
            var stack = new Stack <RectangleNode <TData> >();

            stack.Push(this);
            while (stack.Count > 0)
            {
                RectangleNode <TData> node = stack.Pop();
                if (node.Rectangle.Intersects(rectanglePar))
                {
                    if (node.IsLeaf)
                    {
                        yield return(node);
                    }
                    else
                    {
                        stack.Push(node.left);
                        stack.Push(node.right);
                    }
                }
            }
        }
示例#4
0
 static HitTestBehavior VisitTreeStatic(RectangleNode <TData> rectangleNode, Func <TData, HitTestBehavior> hitTest, Rectangle hitRectangle)
 {
     if (rectangleNode.Rectangle.Intersects(hitRectangle))
     {
         if (hitTest(rectangleNode.UserData) == HitTestBehavior.Continue)
         {
             if (rectangleNode.Left != null)
             {
                 // If rectangleNode.Left is not null, rectangleNode.Right won't be either.
                 if (VisitTreeStatic(rectangleNode.Left, hitTest, hitRectangle) == HitTestBehavior.Continue &&
                     VisitTreeStatic(rectangleNode.Right, hitTest, hitRectangle) == HitTestBehavior.Continue)
                 {
                     return(HitTestBehavior.Continue);
                 }
                 return(HitTestBehavior.Stop);
             }
             return(HitTestBehavior.Continue);
         }
         return(HitTestBehavior.Stop);
     }
     return(HitTestBehavior.Continue);
 }
 internal static void CrossRectangleNodes <TA>(RectangleNode <TA> a, RectangleNode <TA> b, Action <TA, TA> action)
 {
     if (!a.rectangle.Intersects(b.rectangle))
     {
         return;
     }
     if (Equals(a, b))
     {
         HandleEquality(a, action);
     }
     else if (a.Left == null)
     {
         if (b.Left == null)
         {
             action(a.UserData, b.UserData);
         }
         else
         {
             CrossRectangleNodes <TA>(a, b.Left, action);
             CrossRectangleNodes <TA>(a, b.Right, action);
         }
     }
     else
     {
         if (b.Left != null)
         {
             CrossRectangleNodes <TA>(a.Left, b.Left, action);
             CrossRectangleNodes <TA>(a.Left, b.Right, action);
             CrossRectangleNodes <TA>(a.Right, b.Left, action);
             CrossRectangleNodes <TA>(a.Right, b.Right, action);
         }
         else
         {
             CrossRectangleNodes <TA>(a.Left, b, action);
             CrossRectangleNodes <TA>(a.Right, b, action);
         }
     }
 }
示例#6
0
        static internal bool TreeIsCorrect(RectangleNode <T, P> node)
        {
            if (node == null)
            {
                return(true);
            }
            bool ret = node.Left != null && node.Right != null ||
                       node.Left == null && node.Right == null;

            if (!ret)
            {
                return(false);
            }
            if (node.Left != null && node.Left.Parent != node)
            {
                return(false);
            }
            if (node.Right != null && node.Right.Parent != node)
            {
                return(false);
            }

            return(TreeIsCorrect(node.Left) && TreeIsCorrect(node.Right));
        }
 /// <summary>
 /// rebuild the whole tree
 /// </summary>
 public void Rebuild()
 {
     _rootNode = RectangleNode <TData> .CreateRectangleNodeOnEnumeration(_rootNode.GetAllLeafNodes());
 }
 /// <summary>
 /// Create a query tree for a given root node
 /// </summary>
 /// <param name="rootNode"></param>
 public RTree(RectangleNode <TData> rootNode)
 {
     this._rootNode = rootNode;
 }
 static bool Balanced(RectangleNode <TData> rectangleNode)
 {
     return(2 * rectangleNode.Left.Count >= rectangleNode.Right.Count &&
            2 * rectangleNode.Right.Count >= rectangleNode.Left.Count);
 }
        static void RebuildUnderNodeWithoutLeaf(RectangleNode <TData> nodeForRebuild, RectangleNode <TData> leaf)
        {
            Debug.Assert(leaf.IsLeaf);
            Debug.Assert(!nodeForRebuild.IsLeaf);
            var newNode =
                RectangleNode <TData> .CreateRectangleNodeOnEnumeration(
                    nodeForRebuild.GetAllLeafNodes().Where(n => !(n.Equals(leaf))));

            nodeForRebuild.Count     = newNode.Count;
            nodeForRebuild.Left      = newNode.Left;
            nodeForRebuild.Right     = newNode.Right;
            nodeForRebuild.Rectangle = new Rectangle(newNode.Left.rectangle, newNode.Right.rectangle);
        }
 public RTree(IEnumerable <KeyValuePair <Rectangle, TData> > rectsAndData)
 {
     _rootNode = RectangleNode <TData> .CreateRectangleNodeOnEnumeration(GetNodeRects(rectsAndData));
 }
        /// <summary>
        /// returns true if "property" holds for some pair
        /// </summary>
        /// <typeparam name="TA"></typeparam>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <param name="property"></param>
        /// <returns></returns>
        internal static bool FindIntersectionWithProperty <TA>(RectangleNode <TA> a, RectangleNode <TA> b, Func <TA, TA, bool> property)
        {
            if (!a.rectangle.Intersects(b.rectangle))
            {
                return(false);
            }
            if (Equals(a, b))
            {
                return(HandleEqualityCheck(a, property));
            }

            if (a.Left == null)
            {
                if (b.Left == null)
                {
                    return(property(a.UserData, b.UserData));
                }

                if (FindIntersectionWithProperty(a, b.Left, property))
                {
                    return(true);
                }
                if (FindIntersectionWithProperty(a, b.Right, property))
                {
                    return(true);
                }
            }
            else
            {
                if (b.Left != null)
                {
                    if (FindIntersectionWithProperty(a.Left, b.Left, property))
                    {
                        return(true);
                    }
                    if (FindIntersectionWithProperty(a.Left, b.Right, property))
                    {
                        return(true);
                    }
                    if (FindIntersectionWithProperty(a.Right, b.Left, property))
                    {
                        return(true);
                    }
                    if (FindIntersectionWithProperty(a.Right, b.Right, property))
                    {
                        return(true);
                    }
                }
                else
                {
                    if (FindIntersectionWithProperty(a.Left, b, property))
                    {
                        return(true);
                    }
                    if (FindIntersectionWithProperty(a.Right, b, property))
                    {
                        return(true);
                    }
                }
            }
            return(false);
        }
示例#13
0
 internal static void CrossRectangleNodes <TA, TB, P>(RectangleNode <TA, P> a, RectangleNode <TB, P> b, Action <TA, TB> action)
 {
     if (!a.rectangle.Intersects(b.rectangle))
     {
         return;
     }
     if (a.Left == null)     //a is a leat
     {
         if (b.Left == null) //b is a leaf
         {
             action(a.UserData, b.UserData);
         }
         else
         {
             CrossRectangleNodes(a, b.Left, action);
             CrossRectangleNodes(a, b.Right, action);
         }
     }
     else     //a is not a leaf
     {
         if (b.Left != null)
         {
             CrossRectangleNodes(a.Left, b.Left, action);
             CrossRectangleNodes(a.Left, b.Right, action);
             CrossRectangleNodes(a.Right, b.Left, action);
             CrossRectangleNodes(a.Right, b.Right, action);
         }
         else     // b is a leaf
         {
             CrossRectangleNodes(a.Left, b, action);
             CrossRectangleNodes(a.Right, b, action);
         }
     }
 }