//$ Copyright 2015-22, Code Respawn Technologies Pvt Ltd - All Rights Reserved $// using System; namespace DungeonArchitect.Utils { /// /// A random stream based on normal distribution. Also support uniform distsribution /// public class PMRandom { const int A = 16807; const int M = 2147483647; uint seed = 0; Random random = new Random(); public Random UniformRandom { get { return random; } } /// /// Creates a new random stream with seed 0 /// public PMRandom() { Initialize(0); } /// /// Creates a new random stream with the specified seed /// /// The seed to initialize the random stream public PMRandom(uint seed) { Initialize(seed); } /// /// Initializes the stream with the given seed /// /// public void Initialize(uint seed) { this.seed = seed; random = new Random((int)this.seed); } // http://stackoverflow.com/a/218600 /// /// Gets the next random number from a uniform distribution /// /// Random number from a uniform stream public float NextGaussianFloat() { double u1 = random.NextDouble(); //these are uniform(0,1) random doubles double u2 = random.NextDouble(); double randStdNormal = Math.Sqrt(-2.0 * Math.Log(u1)) * Math.Sin(2.0 * Math.PI * u2); //random normal(0,1) return (float)randStdNormal; } /// /// Gets the next random number from a uniform distribution /// /// The mean used for the normal distribution /// The standard deviation used for the normal distribution /// The resulting random number from the normal distributed random stream public float NextGaussianFloat(float mean, float stdDev) { return mean + stdDev * NextGaussianFloat(); } public UnityEngine.Vector2 RandomPointOnCircle() { float angle = GetNextUniformFloat() * UnityEngine.Mathf.PI * 2; return new UnityEngine.Vector2(UnityEngine.Mathf.Cos(angle), UnityEngine.Mathf.Sin(angle)); } /// /// Gets a random number from the uniformly distributed stream /// /// public float GetNextUniformFloat() { return (float)random.NextDouble(); } } }