diff --git a/glm/gtc/random.hpp b/glm/gtc/random.hpp index 79d66bfd..5d5ceeec 100644 --- a/glm/gtc/random.hpp +++ b/glm/gtc/random.hpp @@ -65,21 +65,46 @@ namespace glm genType const & Max); /// Generate random numbers in the interval [Min, Max], according a gaussian distribution - /// (From GLM_GTX_random extension) - template class vecType> - vecType gaussRand( - vecType const & Mean, - vecType const & Deviation); + /// + /// @param Mean + /// @param Deviation + /// @see gtc_random + template + genType gaussRand( + genType const & Mean, + genType const & Deviation); /// Generate a random 2D vector which coordinates are regulary distributed on a circle of a given radius - /// (From GLM_GTX_random extension) + /// + /// @param Radius + /// @see gtc_random template - detail::tvec2 circularRand(T const & Radius); + detail::tvec2 circularRand( + T const & Radius); /// Generate a random 3D vector which coordinates are regulary distributed on a sphere of a given radius - /// (From GLM_GTX_random extension) + /// + /// @param Radius + /// @see gtc_random template - detail::tvec3 sphericalRand(T const & Radius); + detail::tvec3 sphericalRand( + T const & Radius); + + /// Generate a random 2D vector which coordinates are regulary distributed within the area of a disk of a given radius + /// + /// @param Radius + /// @see gtc_random + template + detail::tvec2 diskRand( + T const & Radius); + + /// Generate a random 3D vector which coordinates are regulary distributed within the volume of a ball of a given radius + /// + /// @param Radius + /// @see gtc_random + template + GLM_FUNC_QUALIFIER detail::tvec3 ballRand( + T const & Radius); /// @} }//namespace glm diff --git a/glm/gtc/random.inl b/glm/gtc/random.inl index 68df87cc..6491a53c 100644 --- a/glm/gtc/random.inl +++ b/glm/gtc/random.inl @@ -12,5 +12,197 @@ namespace glm{ +template <> +GLM_FUNC_QUALIFIER glm::half linearRand +( + glm::half const & Min, + glm::half const & Max +) +{ + return glm::half(float(std::rand()) / float(RAND_MAX) * (float(Max) - float(Min)) + float(Min)); +} + +template <> +GLM_FUNC_QUALIFIER float linearRand +( + float const & Min, + float const & Max +) +{ + return float(std::rand()) / float(RAND_MAX) * (Max - Min) + Min; +} + +template <> +GLM_FUNC_QUALIFIER double linearRand +( + double const & Min, + double const & Max +) +{ + return double(std::rand()) / double(RAND_MAX) * (Max - Min) + Min; +} + +template +GLM_FUNC_QUALIFIER detail::tvec2 linearRand +( + detail::tvec2 const & Min, + detail::tvec2 const & Max +) +{ + return detail::tvec2( + linearRand(Min.x, Max.x), + linearRand(Min.y, Max.y)); +} + +template +GLM_FUNC_QUALIFIER detail::tvec3 linearRand +( + detail::tvec3 const & Min, + detail::tvec3 const & Max +) +{ + return detail::tvec3( + linearRand(Min.x, Max.x), + linearRand(Min.y, Max.y), + linearRand(Min.z, Max.z)); +} + +template +GLM_FUNC_QUALIFIER detail::tvec4 linearRand +( + detail::tvec4 const & Min, + detail::tvec4 const & Max +) +{ + return detail::tvec4( + linearRand(Min.x, Max.x), + linearRand(Min.y, Max.y), + linearRand(Min.z, Max.z), + linearRand(Min.w, Max.w)); +} + +template +GLM_FUNC_QUALIFIER genType gaussRand +( + genType const & Mean, + genType const & Deviation +) +{ + genType w, x1, x2; + + do + { + x1 = compRand1(genType(-1), genType(1)); + x2 = compRand1(genType(-1), genType(1)); + + w = x1 * x1 + x2 * x2; + } while(w > genType(1)); + + return x2 * std_deviation * std_deviation * sqrt((genType(-2) * log(w)) / w) + mean; +} + +template +GLM_FUNC_QUALIFIER detail::tvec2 gaussRand +( + detail::tvec2 const & Min, + detail::tvec2 const & Max +) +{ + return detail::tvec2( + gaussRand(Min.x, Max.x), + gaussRand(Min.y, Max.y)); +} + +template +GLM_FUNC_QUALIFIER detail::tvec3 gaussRand +( + detail::tvec3 const & Min, + detail::tvec3 const & Max +) +{ + return detail::tvec3( + gaussRand(Min.x, Max.x), + gaussRand(Min.y, Max.y), + gaussRand(Min.z, Max.z)); +} + +template +GLM_FUNC_QUALIFIER detail::tvec4 gaussRand +( + detail::tvec4 const & Min, + detail::tvec4 const & Max +) +{ + return detail::tvec4( + gaussRand(Min.x, Max.x), + gaussRand(Min.y, Max.y), + gaussRand(Min.z, Max.z), + gaussRand(Min.w, Max.w)); +} + +template +GLM_FUNC_QUALIFIER detail::tvec3 diskRand +( + T const & Radius +) +{ + detail::tvec2 Result(T(0)); + T LenRadius(T(0)); + + do + { + Result = compRand2(-Radius, Radius); + LenRadius = length(Result); + } + while(LenRadius > Radius); + + return Result; +} + +template +GLM_FUNC_QUALIFIER detail::tvec3 ballRand +( + T const & Radius +) +{ + detail::tvec3 Result(T(0)); + T LenRadius(T(0)); + + do + { + Result = compRand3(-Radius, Radius); + LenRadius = length(Result); + } + while(LenRadius > Radius); + + return Result; +} + +template +GLM_FUNC_QUALIFIER detail::tvec2 circularRand +( + T const & Radius +) +{ + T a = compRand1(T(0), T(6.283185307179586476925286766559f)); + return detail::tvec2(cos(a), sin(a)) * Radius; +} + +template +GLM_FUNC_QUALIFIER detail::tvec3 sphericalRand +( + T const & Radius +) +{ + T z = compRand1(T(-1), T(1)); + T a = compRand1(T(0), T(6.283185307179586476925286766559f)); + + T r = sqrt(T(1) - z * z); + + T x = r * cos(a); + T y = r * sin(a); + + return detail::tvec3(x, y, z) * Radius; +} }//namespace glm diff --git a/test/gtc/gtc_random.cpp b/test/gtc/gtc_random.cpp index bf4a5e94..ff5999c4 100644 --- a/test/gtc/gtc_random.cpp +++ b/test/gtc/gtc_random.cpp @@ -8,11 +8,11 @@ /////////////////////////////////////////////////////////////////////////////////////////////////// #include -#include +#include #include #include -int test_signedRand1() +int test_linearRand() { int Error = 0; @@ -21,8 +21,8 @@ int test_signedRand1() double ResultDouble = 0.0f; for(std::size_t i = 0; i < 100000; ++i) { - ResultFloat += glm::signedRand1(/*-1.0f, 1.0f*/); - ResultDouble += glm::signedRand1(/*-1.0, 1.0*/); + ResultFloat += glm::linearRand(-1.0f, 1.0f); + ResultDouble += glm::linearRand(-1.0, 1.0); } Error += glm::equalEpsilon(ResultFloat, 0.0f, 0.0001f); @@ -93,7 +93,7 @@ int main() { int Error = 0; - Error += test_signedRand1(); + Error += test_linearRand(); Error += test_normalizedRand2(); Error += test_normalizedRand3();