From e832407ea0dd8d5bd0b137c13b822be611636a10 Mon Sep 17 00:00:00 2001 From: karl Date: Mon, 7 Dec 2020 00:17:20 +0100 Subject: [PATCH] Mostly revert ef01f37 That commit message was a lie, it did not improve performance but actually reduce it significantly... I had accidentally added a lot of complexity due to the std::list data structure. this approach might seem more redundant, but it's much faster with rectangles (like 100x faster) and doesn't seem to make a difference in the other cases. --- Quickhull.h | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/Quickhull.h b/Quickhull.h index f953ce9..99a486f 100644 --- a/Quickhull.h +++ b/Quickhull.h @@ -149,38 +149,38 @@ private: // If the input vector is empty, we're done if (input.empty()) return; - // Find the points which are furthest away from the line + // Find the point which is furthest away from the line, add it to the output + Point furthest_point; float furthest_distance = -1.0; - std::list furthest_points; - for (const Point &point : input) { float this_distance = line.distance_squared_to(point); - // It's possible for there to be multiple closests points (e.g. in the case) - // of a rectangle). We need to handle all these properly, so we make a list - // of all points at the furthest distance. if (this_distance > furthest_distance) { furthest_distance = this_distance; - furthest_points.clear(); - furthest_points.emplace_back(point); - } - else if (this_distance == furthest_distance) - { - furthest_points.emplace_back(point); + furthest_point = point; } } - for (const Point &point : furthest_points) + // This seems unnecessarily complicated, but it actually yielded the best results, + // especially when the rectangle edge case is taken into account. + for (const Point &point : input) { - // All furthest points we found are part of the hull, so add them to the output - // and remove them from the input. - output.emplace_back(point); - input.remove(point); + float this_distance = line.distance_squared_to(point); + if (this_distance == furthest_distance) + { + output.emplace_back(point); + } } + // Remove the previously checked points from the input -- we can't do that in + // the previous loop because we can't delete from the list we're iterating over + input.remove_if([furthest_distance, line](Point point) + { + return furthest_distance == line.distance_squared_to(point); + }); - Point furthest_point = furthest_points.front(); + output.emplace_back(furthest_point); // Build a triangle with these 3 points