mirror of https://github.com/mosra/magnum.git
2 changed files with 126 additions and 0 deletions
@ -0,0 +1,125 @@ |
|||||||
|
#ifndef Magnum_Math_Random_h |
||||||
|
#define Magnum_Math_Random_h |
||||||
|
|
||||||
|
// TO DO Licence things.
|
||||||
|
|
||||||
|
#include <random> |
||||||
|
#include <chrono> |
||||||
|
#include "Magnum/Types.h" |
||||||
|
#include "Magnum/Math/Constants.h" |
||||||
|
#include "Magnum/Math/Vector2.h" |
||||||
|
#include "Magnum/Math/Vector3.h" |
||||||
|
#include "Magnum/Math/Quaternion.h" |
||||||
|
#include "Magnum/Math/Functions.h" |
||||||
|
|
||||||
|
namespace Magnum |
||||||
|
{ |
||||||
|
namespace Math |
||||||
|
{ |
||||||
|
|
||||||
|
namespace Implementation |
||||||
|
{ |
||||||
|
static std::seed_seq seeds{{ |
||||||
|
static_cast<std::uintmax_t>(std::random_device{}()), |
||||||
|
static_cast<std::uintmax_t>(std::chrono::steady_clock::now() |
||||||
|
.time_since_epoch() |
||||||
|
.count()), |
||||||
|
}}; |
||||||
|
|
||||||
|
class RandomGenerator |
||||||
|
{ |
||||||
|
public: |
||||||
|
RandomGenerator() = delete; |
||||||
|
|
||||||
|
template <typename T> |
||||||
|
static typename std::enable_if<std::is_same<Int, T>::value, T>::type |
||||||
|
generate(T start = -Magnum::Math::Constants<T>::inf(), |
||||||
|
T end = Magnum::Math::Constants<T>::inf()) |
||||||
|
{ |
||||||
|
return std::uniform_int_distribution<T>{start, end}(generator()); |
||||||
|
} |
||||||
|
|
||||||
|
template <typename T> |
||||||
|
static typename std::enable_if<std::is_same<Float, T>::value, T>::type |
||||||
|
generate(T start = -Magnum::Math::Constants<T>::inf(), |
||||||
|
T end = Magnum::Math::Constants<T>::inf()) |
||||||
|
{ |
||||||
|
return std::uniform_real_distribution<T>{start, end}(generator()); |
||||||
|
} |
||||||
|
|
||||||
|
public: |
||||||
|
static std::mt19937 &generator() |
||||||
|
{ |
||||||
|
static std::mt19937 g{seeds}; |
||||||
|
return g; |
||||||
|
} |
||||||
|
}; |
||||||
|
} // namespace Implementation
|
||||||
|
namespace Random |
||||||
|
{ |
||||||
|
template <class T = Float> |
||||||
|
T randomUnsignedScalar() // range [0, 1]
|
||||||
|
{ |
||||||
|
return Implementation::RandomGenerator::generate<T>(static_cast<T>(0.0f), |
||||||
|
static_cast<T>(1.0f)); |
||||||
|
} |
||||||
|
template <class T = Float> |
||||||
|
T randomSignedScalar() // range [-1, 1]
|
||||||
|
{ |
||||||
|
return Implementation::RandomGenerator::generate(static_cast<T>(-1.0f), static_cast<T>(1.0f)); |
||||||
|
} |
||||||
|
|
||||||
|
template <class T = Float> |
||||||
|
Vector3<T> randomUnitVector2() |
||||||
|
{ |
||||||
|
auto a = Implementation::RandomGenerator::generate(0.0f, 2 * Math::Constants<T>::pi()); |
||||||
|
return {std::cos(a), std::sin(a)}; |
||||||
|
} |
||||||
|
|
||||||
|
template <class T = Float> |
||||||
|
Vector3<T> randomUnitVector3() |
||||||
|
{ |
||||||
|
auto a = Implementation::RandomGenerator::generate(0.0f, 2 * Math::Constants<T>::pi()); |
||||||
|
auto z = randomSignedScalar(); |
||||||
|
auto r = sqrt<T>(1 - z * z); |
||||||
|
return {r * std::cos(a), r * std::sin(a), z}; |
||||||
|
} |
||||||
|
template <class T = Float> |
||||||
|
Vector2<T> randomPointInACircle() // always length < 1
|
||||||
|
{ |
||||||
|
while (true) |
||||||
|
{ |
||||||
|
auto p = Vector2<T>( |
||||||
|
randomSignedScalar(), randomSignedScalar()); |
||||||
|
if (p.length() >= 1) |
||||||
|
continue; |
||||||
|
return p; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
template <class T = Float> |
||||||
|
Vector3<T> randomPointInASphere() // always length < 1
|
||||||
|
{ |
||||||
|
auto x = randomSignedScalar(); |
||||||
|
auto y = randomSignedScalar(); |
||||||
|
while (true) |
||||||
|
{ |
||||||
|
auto p = Vector3<T>(x, y, randomSignedScalar()); |
||||||
|
if (p.length() >= 1) |
||||||
|
continue; |
||||||
|
return p; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
template <class T = Float> |
||||||
|
Quaternion<T> randomRotation() |
||||||
|
{ |
||||||
|
return Quaternion<T>({randomSignedScalar<T>(), randomSignedScalar<T>(), randomSignedScalar<T>()}, randomSignedScalar<T>()).normalized(); |
||||||
|
} |
||||||
|
|
||||||
|
} // namespace Random
|
||||||
|
|
||||||
|
} // namespace Math
|
||||||
|
} // namespace Magnum
|
||||||
|
|
||||||
|
#endif |
||||||
Loading…
Reference in new issue