/// <summary> /// Checks wether some part of the rectangle is inside of the quadrant. /// </summary> /// <param name="searchArea">The rectangle that will be checked.</param> /// <param name="aQuad">The quad to check against.</param> /// <returns>True if some part of the rectangle is in the quad, false otherwise.</returns> private bool IsPartiallyInRectangle(SimpleRect searchArea, QuadTreeNode aQuad) { if (IsInXInterval(searchArea.leftX, aQuad) || IsInXInterval(searchArea.rightX, aQuad) || IsInYInterval(searchArea.upperY, aQuad) || IsInYInterval(searchArea.lowerY, aQuad)) { return(true); } return(false); }
/// <summary> /// Calculates which quadrants are in the search area. /// </summary> /// <param name="searchArea">Objects withing this rectangle is returned.</param> /// <returns>A list of quadrants that are in the area /// and a bool that is true if they are entirely within it.</returns> private List <Tuple <QuadTreeNode, bool> > GetIncludedQuads(SimpleRect searchArea) { List <Tuple <QuadTreeNode, bool> > includedQuadrants = new List <Tuple <QuadTreeNode, bool> >(); List <QuadTreeNode> allQuads = new List <QuadTreeNode> { NE, NW, SE, SW }; foreach (QuadTreeNode aQuad in allQuads) { if (aQuad == null) { continue; } /* If the searchArea is entirely withing a quad, it can not be in other quads, * so break out of the loop.*/ if (IsInRectangle(searchArea.leftX, searchArea.upperY, aQuad) && IsInRectangle(searchArea.rightX, searchArea.lowerY, aQuad)) { includedQuadrants.Add(new Tuple <QuadTreeNode, bool>(aQuad, false)); break; } /* If a quad is entirely within the search area, no further searching needs to be done * below it, so the bool to get all the objects from the subtree is set to true. */ if (IsInRectangle(aQuad.nodeX, aQuad.nodeY, searchArea) && IsInRectangle(aQuad.nodeX + aQuad.nodeWidth, aQuad.nodeY + aQuad.nodeHeight, searchArea)) { includedQuadrants.Add(new Tuple <QuadTreeNode, bool>(aQuad, true)); continue; } /* If any part of the search area is withing the quad it's included in the list */ if (IsPartiallyInRectangle(searchArea, aQuad)) { includedQuadrants.Add(new Tuple <QuadTreeNode, bool>(aQuad, false)); } } return(includedQuadrants); }
/// <summary> /// Gets all the objects that lies within the inputed rectangle. /// </summary> /// <param name="searchArea">Objects withing this rectangle is returned.</param> /// <param name="theWholeThing">If the whole node is in the area set this to true.</param> /// <returns>A list of the objects sort of close to the inputed rectangle.</returns> internal List <T> GetNeighbourhood(SimpleRect searchArea, bool theWholeThing) { List <T> neighbourhood = new List <T>(); /* If the entire node is inside the search area no further searching * need be done, and all the objects stored in or under are returned. */ if (theWholeThing) { neighbourhood.AddRange(GetAllObjectsUnder()); } /* If the node is a leaf, all the objects within are checked to see if they * are inside of the search area. */ else if (isLeaf) { for (int i = 0; i < count; i++) { if (IsInRectangle(nodeBucket[i], searchArea)) { neighbourhood.Add(nodeBucket[i]); } } } /* If the node isn't a leaf or entirely withing the search area, the search needs * to be pushed down to all the quadrants that are in the search area. * The returned results from that must then be combined before they are returned. */ else { List <Tuple <QuadTreeNode, bool> > includedQuadrants = GetIncludedQuads(searchArea); foreach (Tuple <QuadTreeNode, bool> quadrant in includedQuadrants) { neighbourhood.AddRange(quadrant.Item1.GetNeighbourhood(searchArea, quadrant.Item2)); } } return(neighbourhood); }
/// <summary> /// Gets all the objects that lies within nodes that are partially covered by the inputed /// rectangular area. /// A better distance measure than GetObjectsInCell. /// </summary> /// <param name="searchArea">A reactangular area to search for objects.</param> /// <returns>A list of objects that lies "close to" the inputted area.</returns> public List <T> GetNeighbourhood(SimpleRect searchArea) { return(Root.GetNeighbourhood(searchArea, false)); }
private bool IsInRectangle(float x, float y, SimpleRect searchArea) { return(IsInRectangle(x, y, searchArea.leftX, searchArea.rightX, searchArea.upperY, searchArea.lowerY)); }
/// <summary> /// Checks if input object is within a rectangular area. /// </summary> /// <param name="aObject">Object one is looking for to see if it is inside of the area.</param> /// <param name="searchArea">The are one is looking at to see if the object is inside of.</param> /// <returns>True if the object is in the area, false if it's outside.</returns> private bool IsInRectangle(T aObject, SimpleRect searchArea) { return(IsInRectangle(aObject.Coords.X, aObject.Coords.Y, searchArea.leftX, searchArea.rightX, searchArea.upperY, searchArea.lowerY)); }