/// <summary> /// Perform a circular query on this index. This will return all entries in the index that are in the specified range /// of the specified point, using the euclidean distance function (i.e. <c>sqrt(x*x+y*y)</c>). /// </summary> /// <param name="center">The query point near which to get entries.</param> /// <param name="radius">The maximum distance an entry may be away from the query point to be returned.</param> /// <param name="callback">The method to call for each found hit.</param> /// <returns></returns> /// <remarks> /// This checks for intersections of the query circle and the bounds of the entries in the index. Intersections /// (i.e. bounds not fully contained in the circle) will be returned, too. /// </remarks> public bool Find(TPoint center, float radius, SimpleQueryCallback <T> callback) { // Getting the full list and then iterating it seems to actually be faster // than injecting a delegate... /* * * // HashSet we might use for filtering duplicate results. We initialize it lazily. * HashSet<T> filter = null; * * // Compute the area bounds for that query to get the involved trees. * var queryBounds = IntersectionExtensions.BoundsFor(ref center, radius); * foreach (var cell in ComputeCells(queryBounds)) * { * // Only if the cell exists. * if (_entries.ContainsKey(cell.Item1)) * { * // Convert the query to the tree's local coordinate space. * var relativePoint = (Vector2)(center + cell.Item2); * * // And do the query. * if (!_entries[cell.Item1].Find(relativePoint, radius, * value => !Filter(value, ref filter) || callback(value))) * { * return false; * } * } * } * * /*/ ISet <T> results = new HashSet <T>(); Find(center, radius, results); foreach (var result in results) { if (!callback(result)) { return(false); } } //*/ return(true); }
/// <summary> /// Perform an area query on this index. This will return all entries in the tree that are contained in or /// intersecting with the specified query rectangle. /// </summary> /// <param name="rectangle">The query rectangle.</param> /// <param name="callback">The method to call for each found hit.</param> /// <returns></returns> public bool Find(TRectangle rectangle, SimpleQueryCallback <T> callback) { // Getting the full list and then iterating it seems to actually be faster // than injecting a delegate... /* * * // HashSet we might use for filtering duplicate results. We initialize it lazily. * HashSet<T> filter = null; * * foreach (var cell in ComputeCells(rectangle)) * { * if (_entries.ContainsKey(cell.Item1)) * { * // Convert the query bounds to the tree's local coordinate space. * var relativeFarBounds = rectangle; * relativeFarBounds.Offset(cell.Item2); * * // And do the query. * var relativeBounds = (Math.RectangleF)relativeFarBounds; * if (!_entries[cell.Item1].Find(relativeBounds, * value => !Filter(value, ref filter) || callback(value))) * { * return false; * } * } * } * * /*/ ISet <T> results = new HashSet <T>(); Find(rectangle, results); foreach (var result in results) { if (!callback(result)) { return(false); } } //*/ return(true); }