Add vector on sphere generation

This commit is contained in:
Nikita Lisitsa 2020-09-13 11:02:53 +03:00
parent 3705dac55e
commit b1963460c0

View 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;
}
}
};
}