// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved. using System; namespace FlaxEngine { /// /// A collection of common random functions which supports various types. /// public static class Randomf { // Single instance for random private static Random _rand = new Random(0); //TODO: Implement some form of generic method for numerics? /// /// Sets the seed of the random number generator. /// Constructs a new instance. /// /// The new seed. public static void SetSeed(int newSeed) => _rand = new Random(newSeed); /// /// Generates a random . /// /// A thats either true or false. public static bool RandomBool() => RandomInt() == 1; /// /// Generates a random with a weight value to adjust preference. /// /// Normalized value that determines the chance to return true. /// A thats either true or false. public static bool RandomBoolWithWeight(float weight = 0) => weight >= RandomFloat(); /// /// Generates a random value between min and max. /// /// The lower boundary. /// The upper boundary. /// A between min and max. public static byte RandomByte(byte min = 0, byte max = 1) { return (byte)_rand.Next(min, max+1); } /// /// Generates a random by using a single value as both upper and lower boundary. /// /// Defines both upper and lower boundary. /// A that is between +value and -value. public static byte RandomUniformByte(byte value = 1) { int max = Math.Abs(value); int min = max * -1; return (byte)_rand.Next(min, max); } /// /// Generates a random value between min and max. /// /// The lower boundary. /// The upper boundary. /// A random between min and max. public static int RandomInt(int min = 0, int max = 1) { return _rand.Next(min, max+1); } /// /// Generates a random by using a single value as both upper and lower boundary. /// /// Defines both upper and lower boundary. /// A random between +value and -value. public static int RandomUniformInt(int value = 1) { int max = Math.Abs(value); int min = max * -1; return _rand.Next(min, max); } /// /// Generates a random value between min and max. /// /// The lower boundary. /// The upper boundary. /// A random between min and max. public static float RandomFloat(float min = 0.0f, float max = 1.0f) { return (float)_rand.NextDouble() * (max - min) + min; } /// /// Generates a random by using a single value as both upper and lower boundary. /// /// Defines both upper and lower boundary. /// A random between +value and -value. public static float RandomUniformFloat(float value = 1.0f) { // Ensure that in case of negative values we still return a value between + value and - value. float max = Math.Abs(value); float min = max * -1; return (float)_rand.NextDouble() * (max - min) + min; } /// /// Generates a random . /// /// A random . public static Quaternion RandomQuaternion() { return Quaternion.Euler( RandomUniformFloat(180), RandomUniformFloat(180), RandomUniformFloat(180)); } /// /// Generates a uniformly distributed random unit length vector point on a unit sphere. /// /// A random . public static Vector3 RandomVector3() { Vector3 output; do { // Create random float with a mean of 0 and deviation of ±1; output.X = RandomFloat() * 2.0f - 1.0f; output.Y = RandomFloat() * 2.0f - 1.0f; output.Z = RandomFloat() * 2.0f - 1.0f; } while (output.LengthSquared > 1 || output.LengthSquared < 1e-6f); output *= (1.0f / (float)Math.Sqrt(output.LengthSquared)); return output; } /// /// Generates a uniformly distributed random unit length vector point on a unit sphere in 2D. /// /// A random public static Vector2 RandomVector2() { Vector2 output; do { output.X = RandomFloat() * 2.0f - 1.0f; output.Y = RandomFloat() * 2.0f - 1.0f; } while (output.LengthSquared > 1 || output.LengthSquared< 1e-6f); output *= (1.0f / (float)Math.Sqrt(output.LengthSquared)); return output; } /// /// Generates a random color. /// /// Should the color be generated from a single random Hue value or separate values for each channel. /// Randomize the alpha value. /// A nice random color. public static Color RandomColor(bool trueRandom, bool randomAlpha) { float alpha = randomAlpha ? RandomFloat() : 1f; if (!trueRandom) return Color.FromHSV(RandomFloat(0f, 360f), 1f, 1f, alpha); return new Color( RandomFloat(0f, 255f), RandomFloat(0f, 255f), RandomFloat(0f, 255f), alpha); } } }