geom/sample: don't rely on float distances in poisson sampling

This commit is contained in:
Danny Robson 2018-05-01 16:02:23 +10:00
parent d72485307a
commit 8b47a2e350

View File

@ -103,6 +103,8 @@ namespace util::geom {
{ {
using point_type = decltype (target (gen)); using point_type = decltype (target (gen));
using value_type = typename point_type::value_type;
std::vector<point_type> selected; std::vector<point_type> selected;
std::vector<point_type> candidates; std::vector<point_type> candidates;
@ -125,28 +127,28 @@ namespace util::geom {
// find the point whose minimum distance to the existing // find the point whose minimum distance to the existing
// points is the greatest (while also being greater than the // points is the greatest (while also being greater than the
// required minimum distance); // required minimum distance);
float best_distance = -INFINITY; auto best_distance2 = std::numeric_limits<value_type>::lowest ();
size_t best_index; size_t best_index;
for (size_t i = 0; i < candidates.size (); ++i) { for (size_t i = 0; i < candidates.size (); ++i) {
auto const p = candidates[i]; auto const p = candidates[i];
float d = INFINITY; auto d2 = std::numeric_limits<value_type>::max ();
// find the minimum distance from this candidate to the // find the minimum distance from this candidate to the
// selected points // selected points
for (auto q: selected) for (auto q: selected)
d = util::min (d, distance (p, q)); d2 = util::min (d2, util::distance2 (p, q));
// record if it's the furthest away // record if it's the furthest away
if (d > best_distance && d > minimum_distance (p)) { if (d2 > best_distance2 && d2 > util::pow (minimum_distance (p), 2)) {
best_distance = d; best_distance2 = d2;
best_index = i; best_index = i;
} }
} }
// if we didn't find a suitable point then we give up and // if we didn't find a suitable point then we give up and
// return the points we found, otherwise record the best point // return the points we found, otherwise record the best point
if (best_distance <= 0) if (best_distance2 <= 0)
break; break;
selected.push_back (candidates[best_index]); selected.push_back (candidates[best_index]);