g/s/surface: add an 'accept' query for poisson sampling
This commit is contained in:
parent
94d3f676c6
commit
3fffacc19c
@ -30,16 +30,29 @@ namespace cruft::geom::sample {
|
||||
/// best of a set of candidates. The 'best' is the point that is
|
||||
/// furthest from all selected points.
|
||||
///
|
||||
/// \tparam SamplerT A surface sampler
|
||||
/// \tparam DistanceT The type of point-to-point distances
|
||||
/// \tparam GeneratorT The random generator passed to the sampler
|
||||
/// \tparam AcceptT A unary bool function that returns true if a sampled
|
||||
/// point is permissible. The point is counted in the candidate set
|
||||
/// regardless.
|
||||
///
|
||||
/// \return A vector of the computed points
|
||||
template <typename SamplerT, typename DistanceT, typename GeneratorT>
|
||||
template <
|
||||
typename SamplerT,
|
||||
typename DistanceT,
|
||||
typename GeneratorT,
|
||||
typename AcceptT
|
||||
>
|
||||
auto
|
||||
poisson (SamplerT const &target,
|
||||
GeneratorT &&gen,
|
||||
DistanceT &&minimum_distance,
|
||||
size_t candidates_count)
|
||||
|
||||
{
|
||||
using point_type = decltype (target.eval (gen));
|
||||
poisson (
|
||||
SamplerT const &sampler,
|
||||
GeneratorT &&gen,
|
||||
AcceptT &&accept,
|
||||
DistanceT &&minimum_distance,
|
||||
std::size_t candidates_count
|
||||
) {
|
||||
using point_type = decltype (sampler.eval (gen));
|
||||
using value_type = typename point_type::value_type;
|
||||
|
||||
std::vector<point_type> selected;
|
||||
@ -47,7 +60,7 @@ namespace cruft::geom::sample {
|
||||
|
||||
// prime the found elements list with an initial point we can
|
||||
// perform distance calculations on
|
||||
selected.push_back (target.eval (gen));
|
||||
selected.push_back (sampler.eval (gen));
|
||||
|
||||
// keep trying to add one more new point
|
||||
while (1) {
|
||||
@ -57,10 +70,16 @@ namespace cruft::geom::sample {
|
||||
std::back_inserter (candidates),
|
||||
candidates_count,
|
||||
[&] (void) {
|
||||
return target.eval (gen);
|
||||
return sampler.eval (gen);
|
||||
}
|
||||
);
|
||||
|
||||
// Remove points that aren't acceptable
|
||||
std::erase_if (
|
||||
candidates,
|
||||
[&] (auto const &p) { return !accept (p); }
|
||||
);
|
||||
|
||||
// find the point whose minimum distance to the existing
|
||||
// points is the greatest (while also being greater than the
|
||||
// required minimum distance);
|
||||
@ -95,6 +114,30 @@ namespace cruft::geom::sample {
|
||||
}
|
||||
|
||||
|
||||
/// A convenience function that forwards to poisson with unconditional
|
||||
/// point acceptance.
|
||||
template <
|
||||
typename SamplerT,
|
||||
typename DistanceT,
|
||||
typename GeneratorT
|
||||
>
|
||||
auto
|
||||
poisson (
|
||||
SamplerT &&sampler,
|
||||
GeneratorT &&gen,
|
||||
DistanceT &&minimum_distance,
|
||||
std::size_t candidates_count
|
||||
) {
|
||||
return poisson (
|
||||
std::forward<SamplerT> (sampler),
|
||||
std::forward<GeneratorT> (gen),
|
||||
[] (auto&&...) { return true; },
|
||||
std::forward<DistanceT> (minimum_distance),
|
||||
candidates_count
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/// A surface sampler specialisation for 2d extents.
|
||||
///
|
||||
/// The actual work is handed off to the volume sampler, as it's
|
||||
|
Loading…
Reference in New Issue
Block a user