diff --git a/libs/pcg/include/psemek/pcg/random/vector_sphere.hpp b/libs/pcg/include/psemek/pcg/random/vector_sphere.hpp new file mode 100644 index 00000000..927a68ed --- /dev/null +++ b/libs/pcg/include/psemek/pcg/random/vector_sphere.hpp @@ -0,0 +1,101 @@ +#pragma once + +#include +#include + +#include + +namespace psemek::pcg +{ + + template + struct uniform_sphere_vector_distribution + { + std::normal_distribution d; + T r; + + uniform_sphere_vector_distribution(T r = T{1}) + : r{r} + {} + + template + auto operator()(RNG && rng) + { + geom::vector v; + while (true) + { + for (std::size_t i = 0; i < N; ++i) + v[i] = d(rng); + + T l = length(v); + if (l != T{}) + return v / l * r; + } + } + }; + + template + struct uniform_sphere_vector_distribution + { + std::uniform_int_distribution d{0, 1}; + T r; + + uniform_sphere_vector_distribution(T r = T{1}) + : r{r} + {} + + template + geom::vector operator()(RNG && rng) + { + if (d(rng) == 0) + return {r}; + return {-r}; + } + }; + + template + struct uniform_sphere_vector_distribution + { + std::uniform_real_distribution d{0, 2 * geom::pi}; + T r; + + uniform_sphere_vector_distribution(T r = T{1}) + : r{r} + {} + + template + geom::vector operator()(RNG && rng) + { + T a = d(rng); + return {r * std::cos(a), r * std::sin(a)}; + } + }; + + template + struct uniform_sphere_vector_distribution + { + std::uniform_real_distribution d{-1, 1}; + T r; + + uniform_sphere_vector_distribution(T r = T{1}) + : r{r} + {} + + template + auto operator()(RNG && rng) + { + geom::vector v; + while (true) + { + for (std::size_t i = 0; i < 3; ++i) + v[i] = d(rng); + + T l = length(v); + + if (l <= T{1}) + return v / l * r; + } + } + }; + +}