sandbox
Loading...
Searching...
No Matches
random.hpp
1#ifndef LIBSBX_MATH_RANDOM_HPP_
2#define LIBSBX_MATH_RANDOM_HPP_
3
4#include <random>
5#include <ranges>
6#include <concepts>
7#include <limits>
8
9#include <libsbx/math/concepts.hpp>
10#include <libsbx/math/vector2.hpp>
11#include <libsbx/math/vector3.hpp>
12#include <libsbx/math/color.hpp>
13#include <libsbx/math/concepts.hpp>
14
15namespace sbx::math {
16
17class random {
18
19public:
20
21 using generator_type = std::mt19937;
22
23 random() = delete;
24
25 template<numeric Type>
26 static auto next(Type min = std::numeric_limits<Type>::min(), Type max = std::numeric_limits<Type>::max()) -> Type {
27 using distribution_type = std::conditional_t<std::floating_point<Type>, std::uniform_real_distribution<Type>, std::uniform_int_distribution<Type>>;
28
29 auto distribution = distribution_type{min, max};
30
31 return distribution(_generator());
32 }
33
34 template<integral Seed>
35 static auto seed(const Seed seed) -> void {
36 _generator().seed(static_cast<generator_type::result_type>(seed));
37 }
38
39private:
40
41 static auto _generator() -> generator_type& {
42 static auto device = std::random_device{};
43 static auto generator = generator_type{device()};
44
45 return generator;
46 }
47
48}; // struct random
49
50template<std::ranges::sized_range Range>
51auto random_element(const Range& range) -> std::ranges::range_value_t<Range> {
52 const auto size = static_cast<std::ranges::range_difference_t<Range>>(std::ranges::size(range));
53 const auto index = random::next<std::ranges::range_difference_t<Range>>(0, size - 1);
54
55 return *std::next(std::begin(range), index);
56}
57
58template<scalar Type>
59auto random_point_in_circle(const basic_vector2<Type>& center, const Type radius) -> basic_vector2<Type> {
60 const auto r = radius * std::sqrt(random::next<Type>(Type{0}, Type{1}));
61 const auto theta = random::next<Type>(Type{0}, Type{2} * std::numbers::pi_v<Type>);
62
63 return center + basic_vector2<Type>{r * std::cos(theta), r * std::sin(theta)};
64}
65
66template<scalar Type>
67auto random_point_on_circle(const basic_vector2<Type>& center, const Type radius) -> basic_vector2<Type> {
68 const auto theta = random::next<Type>(Type{0}, Type{2} * std::numbers::pi_v<Type>);
69
70 return center + basic_vector2<Type>{radius * std::cos(theta), radius * std::sin(theta)};
71}
72
73template<scalar Type>
74auto random_point_in_sphere(const basic_vector3<Type>& center, const Type radius) -> basic_vector3<Type> {
75 const auto r = radius * std::cbrt(random::next<Type>(Type{0}, Type{1}));
76 const auto theta = random::next<Type>(Type{0}, Type{2} * std::numbers::pi_v<Type>);
77 const auto phi = random::next<Type>(Type{0}, std::numbers::pi_v<Type>);
78
79 const auto x = r * std::sin(phi) * std::cos(theta);
80 const auto y = r * std::sin(phi) * std::sin(theta);
81 const auto z = r * std::cos(phi);
82
83 return center + basic_vector3<Type>{x, y, z};
84}
85
86auto random_color(const std::float_t alpha = 1.0f) -> color;
87
88} // namespace sbx::math
89
90#endif // LIBSBX_MATH_RANDOM_HPP_
Definition: random.hpp:17