From 72f685c5f6e0e45f49bfac9ecdfa1a5df31354ea Mon Sep 17 00:00:00 2001 From: SamuXarick <43006711+SamuXarick@users.noreply.github.com> Date: Tue, 19 Nov 2024 21:14:22 +0000 Subject: [PATCH] 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. --- src/core/kdtree.hpp | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/src/core/kdtree.hpp b/src/core/kdtree.hpp index 993c36a87c..eda5e5e8fd 100644 --- a/src/core/kdtree.hpp +++ b/src/core/kdtree.hpp @@ -237,7 +237,7 @@ class Kdtree { 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 */ - node_distance FindNearestRecursive(CoordT xy[2], size_t node_idx, int level, DistT limit = std::numeric_limits::max()) const + node_distance FindNearestRecursive(CoordT xy[2], size_t node_idx, int level, std::optional e = std::nullopt, DistT limit = std::numeric_limits::max()) const { /* Dimension index of current level */ int dim = level % 2; @@ -247,7 +247,7 @@ class Kdtree { /* Coordinate of element splitting at this node */ CoordT c = TxyFunc()(n.element, dim); /* 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::max(); /* Assume this node is the best choice for now */ 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; if (next != INVALID_NODE) { /* 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); @@ -264,7 +265,7 @@ class Kdtree { * 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 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); } @@ -437,6 +438,9 @@ public: * Find the element closest to given coordinate, in Manhattan distance. * For multiple elements with the same distance, the one comparing smaller with * 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 { @@ -446,6 +450,24 @@ public: 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. * @note Start coordinates are inclusive, end coordinates are exclusive. x1 A vector of items contained within the given rectangle. */ std::vector FindContained(CoordT x1, CoordT y1, CoordT x2, CoordT y2) const {