From 46a026e117a5d2a682c8ebfba3d68d3f52c8318d Mon Sep 17 00:00:00 2001 From: sariug Date: Sun, 5 Apr 2020 22:04:46 +0200 Subject: [PATCH] Initial Random.h --- src/Magnum/Math/CMakeLists.txt | 1 + src/Magnum/Math/Random.h | 125 +++++++++++++++++++++++++++++++++ 2 files changed, 126 insertions(+) create mode 100644 src/Magnum/Math/Random.h diff --git a/src/Magnum/Math/CMakeLists.txt b/src/Magnum/Math/CMakeLists.txt index 749d824d7..663c2ae86 100644 --- a/src/Magnum/Math/CMakeLists.txt +++ b/src/Magnum/Math/CMakeLists.txt @@ -49,6 +49,7 @@ set(MagnumMath_HEADERS Quaternion.h Packing.h PackingBatch.h + Random.h Range.h RectangularMatrix.h StrictWeakOrdering.h diff --git a/src/Magnum/Math/Random.h b/src/Magnum/Math/Random.h new file mode 100644 index 000000000..6cd1a2c5a --- /dev/null +++ b/src/Magnum/Math/Random.h @@ -0,0 +1,125 @@ +#ifndef Magnum_Math_Random_h +#define Magnum_Math_Random_h + +// TO DO Licence things. + +#include +#include +#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::random_device{}()), + static_cast(std::chrono::steady_clock::now() + .time_since_epoch() + .count()), +}}; + +class RandomGenerator +{ +public: + RandomGenerator() = delete; + + template + static typename std::enable_if::value, T>::type + generate(T start = -Magnum::Math::Constants::inf(), + T end = Magnum::Math::Constants::inf()) + { + return std::uniform_int_distribution{start, end}(generator()); + } + + template + static typename std::enable_if::value, T>::type + generate(T start = -Magnum::Math::Constants::inf(), + T end = Magnum::Math::Constants::inf()) + { + return std::uniform_real_distribution{start, end}(generator()); + } + +public: + static std::mt19937 &generator() + { + static std::mt19937 g{seeds}; + return g; + } +}; +} // namespace Implementation +namespace Random +{ +template +T randomUnsignedScalar() // range [0, 1] +{ + return Implementation::RandomGenerator::generate(static_cast(0.0f), + static_cast(1.0f)); +} +template +T randomSignedScalar() // range [-1, 1] +{ + return Implementation::RandomGenerator::generate(static_cast(-1.0f), static_cast(1.0f)); +} + +template +Vector3 randomUnitVector2() +{ + auto a = Implementation::RandomGenerator::generate(0.0f, 2 * Math::Constants::pi()); + return {std::cos(a), std::sin(a)}; +} + +template +Vector3 randomUnitVector3() +{ + auto a = Implementation::RandomGenerator::generate(0.0f, 2 * Math::Constants::pi()); + auto z = randomSignedScalar(); + auto r = sqrt(1 - z * z); + return {r * std::cos(a), r * std::sin(a), z}; +} +template +Vector2 randomPointInACircle() // always length < 1 +{ + while (true) + { + auto p = Vector2( + randomSignedScalar(), randomSignedScalar()); + if (p.length() >= 1) + continue; + return p; + } +} + +template +Vector3 randomPointInASphere() // always length < 1 +{ + auto x = randomSignedScalar(); + auto y = randomSignedScalar(); + while (true) + { + auto p = Vector3(x, y, randomSignedScalar()); + if (p.length() >= 1) + continue; + return p; + } +} + +template +Quaternion randomRotation() +{ + return Quaternion({randomSignedScalar(), randomSignedScalar(), randomSignedScalar()}, randomSignedScalar()).normalized(); +} + +} // namespace Random + +} // namespace Math +} // namespace Magnum + +#endif