mal-math
C++20 mathematics library.
All Classes Namespaces Files Functions Variables Typedefs Concepts
random.hpp
Go to the documentation of this file.
1#pragma once
2#include "../math.hpp"
3#include <random>
12{
13 namespace _detail
14 {
21 template <AnyVec T>
23 {
24 std::uniform_real_distribution<float> dis(-1.0f, 1.0f);
26 for (size_t i = 0; i < T::size; i++)
27 p[i] = dis(gen);
28 return normalize(p);
29 }
39 template<AnyVec T, AnyVec U>
40 inline vec<T::size, std::remove_const_t<typename T::type>> RandomVector(std::mt19937 &gen, U const &from, U const &to) noexcept requires(T::size == U::size)
41 {
42 std::uniform_real_distribution<float> dis(0.0f, 1.0f);
44 for (size_t i = 0; i < T::size; i++)
45 p[i] = static_cast<typename T::type>(from[i] + dis(gen) * (to[i] - from[i]));
46 return p;
47 }
48
58 template<AnyVec T, Primitive U>
59 inline vec<T::size, std::remove_const_t<typename T::type>> RandomVector(std::mt19937 &gen, U const &from, U const to) noexcept
60 {
61 std::uniform_real_distribution<float> dis(0.0f, 1.0f);
63 for (size_t i = 0; i < T::size; i++)
64 p[i] = static_cast<typename T::type>(from + dis(gen) * (to - from));
65 return p;
66 }
67 } // namespace _detail
73 inline vec2 RandomDirection2(std::mt19937 &gen) noexcept { return _detail::UnitRandom<vec2>(gen); }
79 inline vec3 RandomDirection3(std::mt19937 &gen) noexcept { return _detail::UnitRandom<vec3>(gen); }
85 inline vec4 RandomDirection4(std::mt19937 &gen) noexcept { return _detail::UnitRandom<vec4>(gen); }
86
87 template<AnyVec U>
88 vec2 RandomVector2(std::mt19937 &gen, U const &from, U const &to) noexcept { return _detail::RandomVector<vec2>(gen, from, to); }
89 template<AnyVec U>
90 vec3 RandomVector3(std::mt19937 &gen, U const &from, U const &to) noexcept { return _detail::RandomVector<vec3>(gen, from, to); }
91 template<AnyVec U>
92 vec4 RandomVector4(std::mt19937 &gen, U const &from, U const &to) noexcept { return _detail::RandomVector<vec4>(gen, from, to); }
93 template<Primitive U>
94 vec2 RandomVector2(std::mt19937 &gen, U const &from, U const &to) noexcept { return _detail::RandomVector<vec2>(gen, from, to); }
95 template<Primitive U>
96 vec3 RandomVector3(std::mt19937 &gen, U const &from, U const &to) noexcept { return _detail::RandomVector<vec3>(gen, from, to); }
97 template<Primitive U>
98 vec4 RandomVector4(std::mt19937 &gen, U const &from, U const &to) noexcept { return _detail::RandomVector<vec4>(gen, from, to); }
99
100 template<AnyVec U>
101 dvec2 RandomDVector2(std::mt19937 &gen, U const &from, U const &to) noexcept { return _detail::RandomVector<dvec2>(gen, from, to); }
102 template<AnyVec U>
103 dvec3 RandomDVector3(std::mt19937 &gen, U const &from, U const &to) noexcept { return _detail::RandomVector<dvec3>(gen, from, to); }
104 template<AnyVec U>
105 dvec4 RandomDVector4(std::mt19937 &gen, U const &from, U const &to) noexcept { return _detail::RandomVector<dvec4>(gen, from, to); }
106 template<Primitive U>
107 dvec2 RandomDVector2(std::mt19937 &gen, U const &from, U const &to) noexcept { return _detail::RandomVector<dvec2>(gen, from, to); }
108 template<Primitive U>
109 dvec3 RandomDVector3(std::mt19937 &gen, U const &from, U const &to) noexcept { return _detail::RandomVector<dvec3>(gen, from, to); }
110 template<Primitive U>
111 dvec4 RandomDVector4(std::mt19937 &gen, U const &from, U const &to) noexcept { return _detail::RandomVector<dvec4>(gen, from, to); }
112
113 template<AnyVec U>
114 ivec2 RandomIVector2(std::mt19937 &gen, U const &from, U const &to) noexcept { return _detail::RandomVector<ivec2>(gen, from, to); }
115 template<AnyVec U>
116 ivec3 RandomIVector3(std::mt19937 &gen, U const &from, U const &to) noexcept { return _detail::RandomVector<ivec3>(gen, from, to); }
117 template<AnyVec U>
118 ivec4 RandomIVector4(std::mt19937 &gen, U const &from, U const &to) noexcept { return _detail::RandomVector<ivec4>(gen, from, to); }
119 template<Primitive U>
120 ivec2 RandomIVector2(std::mt19937 &gen, U const &from, U const &to) noexcept { return _detail::RandomVector<ivec2>(gen, from, to); }
121 template<Primitive U>
122 ivec3 RandomIVector3(std::mt19937 &gen, U const &from, U const &to) noexcept { return _detail::RandomVector<ivec3>(gen, from, to); }
123 template<Primitive U>
124 ivec4 RandomIVector4(std::mt19937 &gen, U const &from, U const &to) noexcept { return _detail::RandomVector<ivec4>(gen, from, to); }
125
126 template<AnyVec U>
127 uivec2 RandomUVector2(std::mt19937 &gen, U const &from, U const &to) noexcept { return _detail::RandomVector<uivec2>(gen, from, to); }
128 template<AnyVec U>
129 uivec3 RandomUVector3(std::mt19937 &gen, U const &from, U const &to) noexcept { return _detail::RandomVector<uivec3>(gen, from, to); }
130 template<AnyVec U>
131 uivec4 RandomUVector4(std::mt19937 &gen, U const &from, U const &to) noexcept { return _detail::RandomVector<uivec4>(gen, from, to); }
132 template<Primitive U>
133 uivec2 RandomUVector2(std::mt19937 &gen, U const &from, U const &to) noexcept { return _detail::RandomVector<uivec2>(gen, from, to); }
134 template<Primitive U>
135 uivec3 RandomUVector3(std::mt19937 &gen, U const &from, U const &to) noexcept { return _detail::RandomVector<uivec3>(gen, from, to); }
136 template<Primitive U>
137 uivec4 RandomUVector4(std::mt19937 &gen, U const &from, U const &to) noexcept { return _detail::RandomVector<uivec4>(gen, from, to); }
138
139 namespace poisson_disc
140 {
141 namespace _detail
142 {
153 template<AnyVec U>
154 inline std::vector<U> PoissonDisc(std::mt19937 &gen, U const &from, U const &to, float min_distance, size_t max_attempts = 30) noexcept
155 {
156 std::vector<U> result;
157 std::uniform_real_distribution<float> dist(0.0f, 1.0f);
158 std::vector<U> active;
159 result.push_back(random::_detail::RandomVector<U>(gen, from, to));
160 active.push_back(result.back());
161 while (!active.empty())
162 {
163 std::uniform_int_distribution<size_t> dist2(0, active.size() - 1);
164 size_t index = dist2(gen);
165 U point = active[index];
166 bool found = false;
167 for (size_t i = 0; i < max_attempts; ++i)
168 {
169 U new_point = point + random::_detail::RandomVector<U>(gen, -min_distance, min_distance);
170 if (new_point.x < from.x || new_point.x > to.x || new_point.y < from.y || new_point.y > to.y)
171 continue;
172 bool ok = true;
173 for (auto const &p : result)
174 {
175 if (distance(p, new_point) < min_distance)
176 {
177 ok = false;
178 break;
179 }
180 }
181 if (ok)
182 {
183 found = true;
184 result.push_back(new_point);
185 active.push_back(new_point);
186 break;
187 }
188 }
189 if (!found)
190 {
191 active.erase(active.begin() + index);
192 }
193 }
194 return result;
195 }
196 } // namespace _detail
206 inline std::vector<vec2> Generate(std::mt19937 &gen, vec2 const &from, vec2 const &to, float min_distance, size_t max_attempts = 30) noexcept
207 {
208 return _detail::PoissonDisc<vec2>(gen, from, to, min_distance, max_attempts);
209 }
210 } // namespace poisson_disc
211} // namespace mal_math::random
Provides various mathematical utilities, vector operations, and custom hash specializations.
vec< T::size, std::remove_const_t< typename T::type > > UnitRandom(std::mt19937 &gen) noexcept
Generates a unit vector with random direction.
Definition random.hpp:22
vec< T::size, std::remove_const_t< typename T::type > > RandomVector(std::mt19937 &gen, U const &from, U const &to) noexcept
Generates a random vector between two other vectors.
Definition random.hpp:40
std::vector< U > PoissonDisc(std::mt19937 &gen, U const &from, U const &to, float min_distance, size_t max_attempts=30) noexcept
Generates a set of points distributed according to Poisson Disk Sampling.
Definition random.hpp:154
std::vector< vec2 > Generate(std::mt19937 &gen, vec2 const &from, vec2 const &to, float min_distance, size_t max_attempts=30) noexcept
Wrapper function for generating Poisson Disk sampled 2D points.
Definition random.hpp:206
vec4 RandomVector4(std::mt19937 &gen, U const &from, U const &to) noexcept
Definition random.hpp:92
ivec4 RandomIVector4(std::mt19937 &gen, U const &from, U const &to) noexcept
Definition random.hpp:118
uivec3 RandomUVector3(std::mt19937 &gen, U const &from, U const &to) noexcept
Definition random.hpp:129
vec2 RandomDirection2(std::mt19937 &gen) noexcept
Generates a random 2D float direction.
Definition random.hpp:73
vec3 RandomVector3(std::mt19937 &gen, U const &from, U const &to) noexcept
Definition random.hpp:90
ivec3 RandomIVector3(std::mt19937 &gen, U const &from, U const &to) noexcept
Definition random.hpp:116
vec2 RandomVector2(std::mt19937 &gen, U const &from, U const &to) noexcept
Definition random.hpp:88
vec4 RandomDirection4(std::mt19937 &gen) noexcept
Generates a random 4D float direction.
Definition random.hpp:85
uivec2 RandomUVector2(std::mt19937 &gen, U const &from, U const &to) noexcept
Definition random.hpp:127
dvec3 RandomDVector3(std::mt19937 &gen, U const &from, U const &to) noexcept
Definition random.hpp:103
dvec4 RandomDVector4(std::mt19937 &gen, U const &from, U const &to) noexcept
Definition random.hpp:105
dvec2 RandomDVector2(std::mt19937 &gen, U const &from, U const &to) noexcept
Definition random.hpp:101
uivec4 RandomUVector4(std::mt19937 &gen, U const &from, U const &to) noexcept
Definition random.hpp:131
ivec2 RandomIVector2(std::mt19937 &gen, U const &from, U const &to) noexcept
Definition random.hpp:114
vec3 RandomDirection3(std::mt19937 &gen) noexcept
Generates a random 3D float direction.
Definition random.hpp:79
vec< 3, int > ivec3
Definition vec.hpp:20
vec< 3, float > vec3
Definition vec.hpp:18
vec< 4, int > ivec4
Definition vec.hpp:25
constexpr std::remove_const_t< typename T::type > distance(T const &left, T const &right) noexcept
Compute the distance between two vectors.
Definition vec_math.inl:877
vec< 4, unsigned int > uivec4
Definition vec.hpp:26
vec< 4, float > vec4
Definition vec.hpp:23
constexpr qua< T > normalize(qua< T > const &q) noexcept
Normalizes a quaternion.
vec< 4, double > dvec4
Definition vec.hpp:24
vec< 3, unsigned int > uivec3
Definition vec.hpp:21
vec< 3, double > dvec3
Definition vec.hpp:19
Definition of the mathematical vector with fixed size L and type T
Definition vecn.hpp:22