Add hemispherical random distributions

This commit is contained in:
Nikita Lisitsa 2020-12-10 10:39:04 +03:00
parent 3ce7f05adf
commit 077a95e78b
2 changed files with 121 additions and 0 deletions

View file

@ -0,0 +1,60 @@
#pragma once
#include <psemek/random/uniform_hemisphere.hpp>
namespace psemek::random
{
template <typename T, std::size_t N>
struct uniform_hemiball_vector_distribution
{
using result_type = geom::vector<T, N>;
uniform_hemiball_vector_distribution(geom::vector<T, N> const & n, T r = T{1})
: sphere_d_{n, r}
{}
uniform_hemiball_vector_distribution(uniform_hemiball_vector_distribution const &) = default;
template <typename RNG>
auto operator()(RNG && rng)
{
result_type v = sphere_d_(rng);
auto r = uniform_real_distribution<T>{}(rng);
return v * std::pow(r, T{1} / N);
}
T radius() const { return sphere_d_.radius(); }
private:
uniform_hemisphere_vector_distribution<T, N> sphere_d_;
};
template <typename T, std::size_t N>
struct uniform_hemiball_point_distribution
{
using result_type = geom::point<T, N>;
uniform_hemiball_point_distribution(result_type origin, geom::vector<T, N> const & n, T r = T{1})
: origin_{origin}
, vector_d_{n, r}
{}
uniform_hemiball_point_distribution(uniform_hemiball_point_distribution const &) = default;
template <typename RNG>
auto operator()(RNG && rng)
{
return origin_ + vector_d_(rng);
}
result_type origin() const { return origin_; }
T radius() const { return vector_d_.radius(); }
private:
result_type origin_;
uniform_hemiball_vector_distribution<T, N> vector_d_;
};
}

View file

@ -0,0 +1,61 @@
#pragma once
#include <psemek/random/uniform_sphere.hpp>
namespace psemek::random
{
template <typename T, std::size_t N>
struct uniform_hemisphere_vector_distribution
{
using result_type = geom::vector<T, N>;
uniform_hemisphere_vector_distribution(geom::vector<T, N> const & n, T r = T{1})
: d_{r}
, n_{n}
{}
uniform_hemisphere_vector_distribution(uniform_hemisphere_vector_distribution const &) = default;
template <typename RNG>
auto operator()(RNG && rng)
{
result_type v = d_(rng);
if (dot(v, n_) < 0)
v = -v;
return v;
}
T radius() const { return d_.radius(); }
private:
uniform_sphere_vector_distribution<T, N> d_;
geom::vector<T, N> n_;
};
template <typename T, std::size_t N>
struct uniform_hemisphere_point_distribution
{
using result_type = geom::point<T, N>;
uniform_hemisphere_point_distribution(result_type origin, geom::vector<T, N> const & n, T r = T{1})
: origin_{origin}
, vector_d_{n, r}
{}
template <typename RNG>
auto operator()(RNG && rng)
{
return origin_ + vector_d_(rng);
}
result_type origin() const { return origin_; }
T radius() const { return vector_d_.radius(); }
private:
result_type origin_;
uniform_hemisphere_vector_distribution<T, N> vector_d_;
};
}