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
14namespace sbx::math {
15
16struct random {
17
18 random() = delete;
19
20 template<numeric Type>
21 static auto next(Type min = std::numeric_limits<Type>::min(), Type max = std::numeric_limits<Type>::max()) -> Type {
22 using distribution_type = std::conditional_t<std::floating_point<Type>, std::uniform_real_distribution<Type>, std::uniform_int_distribution<Type>>;
23
24 static auto device = std::random_device{};
25 static auto generator = std::mt19937{device()};
26
27 auto distribution = distribution_type{min, max};
28
29 return distribution(generator);
30 }
31
32}; // struct random
33
34template<std::ranges::sized_range Range>
35auto random_element(const Range& range) -> std::ranges::range_value_t<Range> {
36 const auto size = static_cast<std::ranges::range_difference_t<Range>>(std::ranges::size(range));
37 const auto index = random::next<std::ranges::range_difference_t<Range>>(0, size - 1);
38
39 return *std::next(std::begin(range), index);
40}
41
42template<scalar Type>
43auto random_point_in_circle(const basic_vector2<Type>& center, const Type radius) -> basic_vector2<Type> {
44 const auto r = radius * std::sqrt(random::next<Type>(Type{0}, Type{1}));
45 const auto theta = random::next<Type>(Type{0}, Type{2} * std::numbers::pi_v<Type>);
46
47 return center + basic_vector2<Type>{r * std::cos(theta), r * std::sin(theta)};
48}
49
50template<scalar Type>
51auto random_point_on_circle(const basic_vector2<Type>& center, const Type radius) -> basic_vector2<Type> {
52 const auto theta = random::next<Type>(Type{0}, Type{2} * std::numbers::pi_v<Type>);
53
54 return center + basic_vector2<Type>{radius * std::cos(theta), radius * std::sin(theta)};
55}
56
57template<scalar Type>
58auto random_point_in_sphere(const basic_vector3<Type>& center, const Type radius) -> basic_vector3<Type> {
59 const auto r = radius * std::cbrt(random::next<Type>(Type{0}, Type{1}));
60 const auto theta = random::next<Type>(Type{0}, Type{2} * std::numbers::pi_v<Type>);
61 const auto phi = random::next<Type>(Type{0}, std::numbers::pi_v<Type>);
62
63 const auto x = r * std::sin(phi) * std::cos(theta);
64 const auto y = r * std::sin(phi) * std::sin(theta);
65 const auto z = r * std::cos(phi);
66
67 return center + basic_vector3<Type>{x, y, z};
68}
69
70auto random_color() -> color;
71
72} // namespace sbx::math
73
74#endif // LIBSBX_MATH_RANDOM_HPP_
Definition: random.hpp:16