Add vector on sphere generation
This commit is contained in:
parent
3705dac55e
commit
b1963460c0
1 changed files with 101 additions and 0 deletions
101
libs/pcg/include/psemek/pcg/random/vector_sphere.hpp
Normal file
101
libs/pcg/include/psemek/pcg/random/vector_sphere.hpp
Normal file
|
|
@ -0,0 +1,101 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <psemek/geom/vector.hpp>
|
||||||
|
#include <psemek/geom/constants.hpp>
|
||||||
|
|
||||||
|
#include <random>
|
||||||
|
|
||||||
|
namespace psemek::pcg
|
||||||
|
{
|
||||||
|
|
||||||
|
template <typename T, std::size_t N>
|
||||||
|
struct uniform_sphere_vector_distribution
|
||||||
|
{
|
||||||
|
std::normal_distribution<T> d;
|
||||||
|
T r;
|
||||||
|
|
||||||
|
uniform_sphere_vector_distribution(T r = T{1})
|
||||||
|
: r{r}
|
||||||
|
{}
|
||||||
|
|
||||||
|
template <typename RNG>
|
||||||
|
auto operator()(RNG && rng)
|
||||||
|
{
|
||||||
|
geom::vector<T, N> 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 <typename T>
|
||||||
|
struct uniform_sphere_vector_distribution<T, 1>
|
||||||
|
{
|
||||||
|
std::uniform_int_distribution<int> d{0, 1};
|
||||||
|
T r;
|
||||||
|
|
||||||
|
uniform_sphere_vector_distribution(T r = T{1})
|
||||||
|
: r{r}
|
||||||
|
{}
|
||||||
|
|
||||||
|
template <typename RNG>
|
||||||
|
geom::vector<T, 1> operator()(RNG && rng)
|
||||||
|
{
|
||||||
|
if (d(rng) == 0)
|
||||||
|
return {r};
|
||||||
|
return {-r};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct uniform_sphere_vector_distribution<T, 2>
|
||||||
|
{
|
||||||
|
std::uniform_real_distribution<T> d{0, 2 * geom::pi};
|
||||||
|
T r;
|
||||||
|
|
||||||
|
uniform_sphere_vector_distribution(T r = T{1})
|
||||||
|
: r{r}
|
||||||
|
{}
|
||||||
|
|
||||||
|
template <typename RNG>
|
||||||
|
geom::vector<T, 2> operator()(RNG && rng)
|
||||||
|
{
|
||||||
|
T a = d(rng);
|
||||||
|
return {r * std::cos(a), r * std::sin(a)};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct uniform_sphere_vector_distribution<T, 3>
|
||||||
|
{
|
||||||
|
std::uniform_real_distribution<T> d{-1, 1};
|
||||||
|
T r;
|
||||||
|
|
||||||
|
uniform_sphere_vector_distribution(T r = T{1})
|
||||||
|
: r{r}
|
||||||
|
{}
|
||||||
|
|
||||||
|
template <typename RNG>
|
||||||
|
auto operator()(RNG && rng)
|
||||||
|
{
|
||||||
|
geom::vector<T, 3> 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue