Commit 36c49b6d authored by Philip Trettner's avatar Philip Trettner
Browse files

added arbitrary random for smart ranges

parent 66ef0550
......@@ -328,6 +328,25 @@ auto smart_range<this_t, ElementT>::aabb(FuncT&& f) const -> polymesh::minmax_t<
return r;
}
template <class this_t, class ElementT>
template <class Generator, class FuncT>
auto smart_range<this_t, ElementT>::random(Generator& g, FuncT&& f) const -> tmp::decayed_result_type_of<FuncT, ElementT>
{
auto it = static_cast<this_t const*>(this)->begin();
POLYMESH_ASSERT(it.is_valid() && "requires non-empty range");
auto v = f(*it);
double cnt = 2;
++it;
while (it.is_valid())
{
if (double(g()) * cnt < double(g.max()))
v = f(*it);
++it;
cnt += 1;
}
return v;
}
template <class this_t, class ElementT>
template <class FuncT>
auto smart_range<this_t, ElementT>::minmax(FuncT&& f) const -> polymesh::minmax_t<tmp::decayed_result_type_of<FuncT, ElementT>>
......
......@@ -161,6 +161,11 @@ struct smart_range
template <class PredT>
auto filter(PredT&& p) -> filtered_range<ElementT, this_t&, PredT>;
/// returns a uniformly random sampled element from this range
/// complexity is O(n) (but does not allocate)
template <class Generator, class FuncT = tmp::identity>
auto random(Generator& g, FuncT&& f = {}) const -> tmp::decayed_result_type_of<FuncT, ElementT>;
// TODO: (requires new ranges)
// - filter (or where?)
// - map
......@@ -233,6 +238,7 @@ struct smart_collection : smart_range<smart_collection<mesh_ptr, tag, iterator>,
end_iterator end() const { return {}; }
/// returns a handle chosen uniformly at random
/// Complexity is usually O(1)
/// NOTE: when only valid handles are allowed, this will use rejection sampling
/// and thus get very slow if a lot of data is invalid
template <class Generator>
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment