114 lines
4.4 KiB
C#
114 lines
4.4 KiB
C#
using System;
|
|
using UnityEngine;
|
|
using UnityEngine.TestTools;
|
|
using Random = System.Random;
|
|
using Vector2 = System.Numerics.Vector2;
|
|
using Vector3 = System.Numerics.Vector3;
|
|
|
|
namespace BracerLib.Utility
|
|
{
|
|
[ExcludeFromCoverage]
|
|
public static class RandomUtility
|
|
{
|
|
public static readonly string CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
|
|
[ThreadStatic]
|
|
private static Random unrepeatedRandomThreadInstance;
|
|
|
|
private static Random unrepeatedRandom => unrepeatedRandomThreadInstance ??= new Random(DateTime.Now.Millisecond);
|
|
|
|
private static int prevSeed = -1;
|
|
|
|
public static float NextFloat(this Random prng) => (float)prng.NextDouble();
|
|
|
|
public static float Range(this Random prng, float minInclusive, float maxExclusive)
|
|
=> minInclusive + (maxExclusive - minInclusive) * prng.NextFloat();
|
|
|
|
public static void RandomizeUnityRandom()
|
|
{
|
|
var seed = (int)DateTime.Now.Ticks;
|
|
if (seed != prevSeed)
|
|
return;
|
|
|
|
prevSeed = seed;
|
|
UnityEngine.Random.InitState(seed);
|
|
}
|
|
|
|
/// <summary> Random between 0.0 inclusive and 1.0 exclusive. </summary>
|
|
public static double NextDouble() => unrepeatedRandom.NextDouble();
|
|
|
|
/// <summary> Random between 0f inclusive and 1f exclusive. </summary>
|
|
public static float NextFloat() => unrepeatedRandom.NextFloat();
|
|
|
|
/// <summary>
|
|
/// Given a value, return a random number between the negative and positive of the input value.
|
|
/// </summary>
|
|
/// <param name="bookendRangeValue">Non-negative value.</param>
|
|
public static float Range(float bookendRangeValue) => unrepeatedRandom.Range(-bookendRangeValue, bookendRangeValue);
|
|
|
|
public static float Range(float minInclusive, float maxExclusive) => unrepeatedRandom.Range(minInclusive, maxExclusive);
|
|
|
|
public static int Range(int minInclusive, int maxExclusive) => unrepeatedRandom.Next(minInclusive, maxExclusive);
|
|
|
|
/// <summary> Random point uniformly distributed on the surface of a sphere of radius 1. </summary>
|
|
public static Vector3 RandomOnUnitSphere() {
|
|
var theta = MathUtility.TWO_PI * NextDouble();
|
|
var phi = Math.Acos(2.0 * NextDouble() - 1.0);
|
|
var sinPhi = Math.Sin(phi);
|
|
return new Vector3(
|
|
(float)(sinPhi * Math.Cos(theta)),
|
|
(float)(sinPhi * Math.Sin(theta)),
|
|
(float)Math.Cos(phi)
|
|
);
|
|
}
|
|
|
|
/// <summary> Random point uniformly distributed inside a sphere of radius 1. </summary>
|
|
public static Vector3 RandomInUnitSphere() => RandomOnUnitSphere() * (float)Math.Pow(NextDouble(), 1.0 / 3.0);
|
|
|
|
/// <summary> Random point uniformly distributed on the perimeter of a circle of radius 1. </summary>
|
|
public static Vector2 RandomOnUnitCircle() {
|
|
var angle = MathUtility.TWO_PI * NextDouble();
|
|
return new Vector2((float)Math.Cos(angle), (float)Math.Sin(angle));
|
|
}
|
|
|
|
/// <summary> Random point uniformly distributed in a circle of radius 1. </summary>
|
|
public static Vector2 RandomInUnitCircle() => RandomOnUnitCircle() * (float)Math.Sqrt(NextDouble());
|
|
|
|
/// <summary> Random point uniformly distributed in a ring starting at radius1 and ending at radius2. </summary>
|
|
public static Vector2 RandomInRing(float r1, float r2) {
|
|
var r2sq = r2 * r2;
|
|
return RandomOnUnitCircle() * (float)Math.Sqrt(NextDouble() * (r1 * r1 - r2sq) + r2sq);
|
|
}
|
|
|
|
public static Color RandomColorRGB()
|
|
{
|
|
return new Color(
|
|
unrepeatedRandom.NextFloat(),
|
|
unrepeatedRandom.NextFloat(),
|
|
unrepeatedRandom.NextFloat(),
|
|
1f
|
|
);
|
|
}
|
|
|
|
public static Color RandomColorRGBA()
|
|
{
|
|
return new Color(
|
|
unrepeatedRandom.NextFloat(),
|
|
unrepeatedRandom.NextFloat(),
|
|
unrepeatedRandom.NextFloat(),
|
|
unrepeatedRandom.NextFloat()
|
|
);
|
|
}
|
|
public static string GetRandomString(int length)
|
|
{
|
|
var stringChars = new char[length];
|
|
var random = new Random();
|
|
|
|
for (var i = 0; i < stringChars.Length; i++)
|
|
stringChars[i] = CHARS[random.Next(CHARS.Length)];
|
|
|
|
return new string(stringChars);
|
|
}
|
|
}
|
|
}
|