From ea6e267d983a34978606b2cedde383a1bd1fb53d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20M=C3=BCller?= Date: Mon, 13 Mar 2023 00:15:39 +0100 Subject: [PATCH] Add `random_angle` function To generate a random angle in the range `[0.0f;2.0f * pi[`. This ensures that the random angle cannot be `2.0f * pi`, which would be identical to the angle `0.0f` and therefore cause the random angle to be less uniformly selected. Note that this first casts `RAND_MAX` to a `float` and then uses `std::nextafter` to get the next larger `float`. Using `RAND_MAX + 1` would cause an integer overflow on systems where `RAND_MAX == INT_MAX` (e.g. Ubuntu and macOS). --- src/base/math.h | 9 +++++++-- src/game/client/components/damageind.cpp | 2 +- src/game/client/components/effects.cpp | 14 +++++++------- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/base/math.h b/src/base/math.h index 91a19c80c..5c9bb7b50 100644 --- a/src/base/math.h +++ b/src/base/math.h @@ -9,6 +9,8 @@ using std::clamp; +constexpr float pi = 3.1415926535897932384626433f; + constexpr inline int round_to_int(float f) { return f > 0 ? (int)(f + 0.5f) : (int)(f - 0.5f); @@ -30,6 +32,11 @@ inline float random_float() return rand() / (float)(RAND_MAX); } +inline float random_angle() +{ + return 2.0f * pi * (rand() / std::nextafter((float)RAND_MAX, std::numeric_limits::max())); +} + constexpr int fxpscale = 1 << 10; // float to fixed @@ -85,8 +92,6 @@ public: } }; -constexpr float pi = 3.1415926535897932384626433f; - template constexpr inline T minimum(T a, T b) { diff --git a/src/game/client/components/damageind.cpp b/src/game/client/components/damageind.cpp index 35001568d..07ddf80a7 100644 --- a/src/game/client/components/damageind.cpp +++ b/src/game/client/components/damageind.cpp @@ -41,7 +41,7 @@ void CDamageInd::Create(vec2 Pos, vec2 Dir) pItem->m_Pos = Pos; pItem->m_StartTime = LocalTime(); pItem->m_Dir = Dir * -1; - pItem->m_StartAngle = (random_float() - 1.0f) * 2.0f * pi; + pItem->m_StartAngle = -random_angle(); } } diff --git a/src/game/client/components/effects.cpp b/src/game/client/components/effects.cpp index 6cd94a9cd..06f5b125f 100644 --- a/src/game/client/components/effects.cpp +++ b/src/game/client/components/effects.cpp @@ -34,7 +34,7 @@ void CEffects::AirJump(vec2 Pos) p.m_LifeSpan = 0.5f; p.m_StartSize = 48.0f; p.m_EndSize = 0; - p.m_Rot = random_float() * pi * 2; + p.m_Rot = random_angle(); p.m_Rotspeed = pi * 2; p.m_Gravity = 500; p.m_Friction = 0.7f; @@ -71,7 +71,7 @@ void CEffects::PowerupShine(vec2 Pos, vec2 Size) p.m_LifeSpan = 0.5f; p.m_StartSize = 16.0f; p.m_EndSize = 0; - p.m_Rot = random_float() * pi * 2; + p.m_Rot = random_angle(); p.m_Rotspeed = pi * 2; p.m_Gravity = 500; p.m_Friction = 0.9f; @@ -95,7 +95,7 @@ void CEffects::FreezingFlakes(vec2 Pos, vec2 Size) p.m_UseAlphaFading = true; p.m_StartAlpha = 1.0f; p.m_EndAlpha = 0.0f; - p.m_Rot = random_float() * pi * 2; + p.m_Rot = random_angle(); p.m_Rotspeed = pi; p.m_Gravity = random_float() * 250.0f; p.m_Friction = 0.9f; @@ -171,7 +171,7 @@ void CEffects::PlayerSpawn(vec2 Pos) p.m_LifeSpan = 0.3f + random_float() * 0.3f; p.m_StartSize = 64.0f + random_float() * 32; p.m_EndSize = 0; - p.m_Rot = random_float() * pi * 2; + p.m_Rot = random_angle(); p.m_Rotspeed = random_float(); p.m_Gravity = random_float() * -400.0f; p.m_Friction = 0.7f; @@ -212,7 +212,7 @@ void CEffects::PlayerDeath(vec2 Pos, int ClientID) p.m_LifeSpan = 0.3f + random_float() * 0.3f; p.m_StartSize = 24.0f + random_float() * 16; p.m_EndSize = 0; - p.m_Rot = random_float() * pi * 2; + p.m_Rot = random_angle(); p.m_Rotspeed = (random_float() - 0.5f) * pi; p.m_Gravity = 800.0f; p.m_Friction = 0.8f; @@ -243,7 +243,7 @@ void CEffects::Explosion(vec2 Pos) p.m_LifeSpan = 0.4f; p.m_StartSize = 150.0f; p.m_EndSize = 0; - p.m_Rot = random_float() * pi * 2; + p.m_Rot = random_angle(); m_pClient->m_Particles.Add(CParticles::GROUP_EXPLOSIONS, &p); // add the smoke @@ -273,7 +273,7 @@ void CEffects::HammerHit(vec2 Pos) p.m_LifeSpan = 0.3f; p.m_StartSize = 120.0f; p.m_EndSize = 0; - p.m_Rot = random_float() * pi * 2; + p.m_Rot = random_angle(); m_pClient->m_Particles.Add(CParticles::GROUP_EXPLOSIONS, &p); if(g_Config.m_SndGame) m_pClient->m_Sounds.PlayAt(CSounds::CHN_WORLD, SOUND_HAMMER_HIT, 1.0f, Pos);