// 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);
}
}
}