From 077a95e78b835dbdd39c37efb13533200d64143d Mon Sep 17 00:00:00 2001 From: lisyarus Date: Thu, 10 Dec 2020 10:39:04 +0300 Subject: [PATCH] Add hemispherical random distributions --- .../psemek/random/uniform_hemiball.hpp | 60 ++++++++++++++++++ .../psemek/random/uniform_hemisphere.hpp | 61 +++++++++++++++++++ 2 files changed, 121 insertions(+) create mode 100644 libs/random/include/psemek/random/uniform_hemiball.hpp create mode 100644 libs/random/include/psemek/random/uniform_hemisphere.hpp diff --git a/libs/random/include/psemek/random/uniform_hemiball.hpp b/libs/random/include/psemek/random/uniform_hemiball.hpp new file mode 100644 index 00000000..25baadd7 --- /dev/null +++ b/libs/random/include/psemek/random/uniform_hemiball.hpp @@ -0,0 +1,60 @@ +#pragma once + +#include + +namespace psemek::random +{ + + template + struct uniform_hemiball_vector_distribution + { + using result_type = geom::vector; + + uniform_hemiball_vector_distribution(geom::vector const & n, T r = T{1}) + : sphere_d_{n, r} + {} + + uniform_hemiball_vector_distribution(uniform_hemiball_vector_distribution const &) = default; + + template + auto operator()(RNG && rng) + { + result_type v = sphere_d_(rng); + auto r = uniform_real_distribution{}(rng); + return v * std::pow(r, T{1} / N); + } + + T radius() const { return sphere_d_.radius(); } + + private: + uniform_hemisphere_vector_distribution sphere_d_; + }; + + template + struct uniform_hemiball_point_distribution + { + using result_type = geom::point; + + uniform_hemiball_point_distribution(result_type origin, geom::vector const & n, T r = T{1}) + : origin_{origin} + , vector_d_{n, r} + {} + + uniform_hemiball_point_distribution(uniform_hemiball_point_distribution const &) = default; + + template + 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 vector_d_; + }; + +} diff --git a/libs/random/include/psemek/random/uniform_hemisphere.hpp b/libs/random/include/psemek/random/uniform_hemisphere.hpp new file mode 100644 index 00000000..83963917 --- /dev/null +++ b/libs/random/include/psemek/random/uniform_hemisphere.hpp @@ -0,0 +1,61 @@ +#pragma once + +#include + +namespace psemek::random +{ + + template + struct uniform_hemisphere_vector_distribution + { + using result_type = geom::vector; + + uniform_hemisphere_vector_distribution(geom::vector const & n, T r = T{1}) + : d_{r} + , n_{n} + {} + + uniform_hemisphere_vector_distribution(uniform_hemisphere_vector_distribution const &) = default; + + template + 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 d_; + geom::vector n_; + }; + + template + struct uniform_hemisphere_point_distribution + { + using result_type = geom::point; + + uniform_hemisphere_point_distribution(result_type origin, geom::vector const & n, T r = T{1}) + : origin_{origin} + , vector_d_{n, r} + {} + + template + 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 vector_d_; + }; + +}