1
0
Fork 0

Codechange: Enhance KD-Tree functionality and documentation

- Modified `FindNearestRecursive` to handle an optional parameter to exclude a specific element from the search.
- Added `FindNearestExcept` function to find the nearest element excluding a specified element.
- Improved Doxygen comments for `FindNearest`, `FindNearestExcept`, and `FindContained` functions.
- Ensured that Doxygen comments now include parameter descriptions and return values for better documentation and clarity.
pull/13116/head
SamuXarick 2024-11-19 21:14:22 +00:00
parent a284913578
commit 72f685c5f6
1 changed files with 31 additions and 4 deletions

View File

@ -237,7 +237,7 @@ class Kdtree {
NOT_REACHED(); // a.first == b.first: same element must not be inserted twice NOT_REACHED(); // a.first == b.first: same element must not be inserted twice
} }
/** Search a sub-tree for the element nearest to a given point */ /** Search a sub-tree for the element nearest to a given point */
node_distance FindNearestRecursive(CoordT xy[2], size_t node_idx, int level, DistT limit = std::numeric_limits<DistT>::max()) const node_distance FindNearestRecursive(CoordT xy[2], size_t node_idx, int level, std::optional<T> e = std::nullopt, DistT limit = std::numeric_limits<DistT>::max()) const
{ {
/* Dimension index of current level */ /* Dimension index of current level */
int dim = level % 2; int dim = level % 2;
@ -247,7 +247,7 @@ class Kdtree {
/* Coordinate of element splitting at this node */ /* Coordinate of element splitting at this node */
CoordT c = TxyFunc()(n.element, dim); CoordT c = TxyFunc()(n.element, dim);
/* This node's distance to target */ /* This node's distance to target */
DistT thisdist = ManhattanDistance(n.element, xy[0], xy[1]); DistT thisdist = !e.has_value() || n.element != e.value() ? ManhattanDistance(n.element, xy[0], xy[1]) : std::numeric_limits<DistT>::max();
/* Assume this node is the best choice for now */ /* Assume this node is the best choice for now */
node_distance best = std::make_pair(n.element, thisdist); node_distance best = std::make_pair(n.element, thisdist);
@ -255,7 +255,8 @@ class Kdtree {
size_t next = (xy[dim] < c) ? n.left : n.right; size_t next = (xy[dim] < c) ? n.left : n.right;
if (next != INVALID_NODE) { if (next != INVALID_NODE) {
/* Check if there is a better node down the tree */ /* Check if there is a better node down the tree */
best = SelectNearestNodeDistance(best, this->FindNearestRecursive(xy, next, level + 1)); node_distance candidate = this->FindNearestRecursive(xy, next, level + 1, e);
best = SelectNearestNodeDistance(best, candidate);
} }
limit = std::min(best.second, limit); limit = std::min(best.second, limit);
@ -264,7 +265,7 @@ class Kdtree {
* if it is we also need to check the other side of the split. */ * if it is we also need to check the other side of the split. */
size_t opposite = (xy[dim] >= c) ? n.left : n.right; // reverse of above size_t opposite = (xy[dim] >= c) ? n.left : n.right; // reverse of above
if (opposite != INVALID_NODE && limit >= abs((int)xy[dim] - (int)c)) { if (opposite != INVALID_NODE && limit >= abs((int)xy[dim] - (int)c)) {
node_distance other_candidate = this->FindNearestRecursive(xy, opposite, level + 1, limit); node_distance other_candidate = this->FindNearestRecursive(xy, opposite, level + 1, e, limit);
best = SelectNearestNodeDistance(best, other_candidate); best = SelectNearestNodeDistance(best, other_candidate);
} }
@ -437,6 +438,9 @@ public:
* Find the element closest to given coordinate, in Manhattan distance. * Find the element closest to given coordinate, in Manhattan distance.
* For multiple elements with the same distance, the one comparing smaller with * For multiple elements with the same distance, the one comparing smaller with
* a less-than comparison is chosen. * a less-than comparison is chosen.
* @param x First coordinate.
* @param y Second coordinate.
* @return T The element closest to the given coordinate.
*/ */
T FindNearest(CoordT x, CoordT y) const T FindNearest(CoordT x, CoordT y) const
{ {
@ -446,6 +450,24 @@ public:
return this->FindNearestRecursive(xy, this->root, 0).first; return this->FindNearestRecursive(xy, this->root, 0).first;
} }
/**
* Find the element closest to the given coordinate, excluding a specified element.
* For multiple elements with the same distance, the one comparing smaller with
* a less-than comparison is chosen.
* @note If the tree has only one element and it is the excluded one, this function will return that element.
* @param x First coordinate.
* @param y Second coordinate.
* @param e The element to be excluded from the search.
* @return The element closest to the given coordinate.
*/
T FindNearestExcept(CoordT x, CoordT y, T e) const
{
assert(this->Count() > 0);
CoordT xy[2] = { x, y };
return this->FindNearestRecursive(xy, this->root, 0, e).first;
}
/** /**
* Find all items contained within the given rectangle. * Find all items contained within the given rectangle.
* @note Start coordinates are inclusive, end coordinates are exclusive. x1<x2 && y1<y2 is a precondition. * @note Start coordinates are inclusive, end coordinates are exclusive. x1<x2 && y1<y2 is a precondition.
@ -471,6 +493,11 @@ public:
/** /**
* Find all items contained within the given rectangle. * Find all items contained within the given rectangle.
* @note End coordinates are exclusive, x1<x2 && y1<y2 is a precondition. * @note End coordinates are exclusive, x1<x2 && y1<y2 is a precondition.
* @param x1 Start first coordinate, points found are greater or equals to this.
* @param y1 Start second coordinate, points found are greater or equals to this.
* @param x2 End first coordinate, points found are less than this.
* @param y2 End second coordinate, points found are less than this.
* @return std::vector<T> A vector of items contained within the given rectangle.
*/ */
std::vector<T> FindContained(CoordT x1, CoordT y1, CoordT x2, CoordT y2) const std::vector<T> FindContained(CoordT x1, CoordT y1, CoordT x2, CoordT y2) const
{ {