Repository: FlaxEngine/FlaxEngine
File: Source/Engine/Utilities/Extensions.cs (C#)

Code before:

            return Quaternion.Euler(
                NextFloat(random, -180, 180),
                NextFloat(random, -180, 180),
                randomRoll ? NextFloat(random, -180, 180) : 0);
        }

        /// <summary>
        /// Generates a uniformly distributed random unit length vector point on a unit sphere.
        /// </summary>
        /// <param name="random">An instance of <see cref="Random"/>.</param>
        /// <returns>A random <see cref="Vector3"/>.</returns>
        public static Vector3 NextVector3(this Random random)
        {
            Vector3 output;

            do
            {
                // Create random float with a mean of 0 and deviation of ±1
                output.X = NextFloat(random) * 2.0f - 1.0f;
                output.Y = NextFloat(random) * 2.0f - 1.0f;
                output.Z = NextFloat(random) * 2.0f - 1.0f;

            } while (output.LengthSquared > 1 || output.LengthSquared < 1e-6f);

            output *= (1.0f / (float)Math.Sqrt(output.LengthSquared));

            return output;
        }

        /// <summary>
        /// Generates a uniformly distributed random unit length vector point on a unit sphere in 2D.
        /// </summary>
        /// <param name="random">An instance of <see cref="Random"/>.</param>
        /// <returns>A random <see cref="Vector2"/>.</returns>
        public static Vector2 NextVector2(this Random random)
        {
            Vector2 output;

            do
            {
                output.X = NextFloat(random) * 2.0f - 1.0f;
                output.Y = NextFloat(random) * 2.0f - 1.0f;

            } while (output.LengthSquared > 1 || output.LengthSquared < 1e-6f);

            output *= (1.0f / (float)Math.Sqrt(output.LengthSquared));

            return output;
        }


Review comment (suggestion):
This could be replaced with the `Vector3.Normalize()` method.

Code after:
        /// <param name="randomRoll">Should the roll value be randomized.</param>
        /// <returns>A random <see cref="Quaternion"/>.</returns>
        public static Quaternion NextQuaternion(this Random random, bool randomRoll = false)
        {
            return Quaternion.Euler(
                NextFloat(random, -180.0f, 180.0f),
                NextFloat(random, -180.0f, 180.0f),
                randomRoll ? NextFloat(random, -180.0f, 180.0f) : 0.0f);
        }

        /// <summary>
        /// Generates a random <see cref="Vector2"/> point in a circle of a given radius.
        /// </summary>
        /// <param name="random">An instance of <see cref="Random"/>.</param>
        /// <param name="radius">Radius of circle. Default 1.0f./>.</param>
        /// <returns>A random <see cref="Vector2"/>.</returns>
        public static Vector2 NextUnitVector2(this Random random, float radius = 1.0f)
        {
            var randomRadius = (float)random.NextDouble() * radius;

            return new Vector2
            {
                X = (float)Math.Cos(random.NextDouble()) * randomRadius,
                Y = (float)Math.Sin(random.NextDouble()) * randomRadius,
            };
        }

        /// <summary>
        /// Generates a uniformly distributed random unit length vector point on a unit sphere.
        /// </summary>
        /// <param name="random">An instance of <see cref="Random"/>.</param>
        /// <returns>A random <see cref="Vector3"/>.</returns>
        public static Vector3 NextUnitVector3(this Random random)
        {
            Vector3 output;
            float l;

            do
            {
                // Create random float with a mean of 0 and deviation of ±1
                output.X = NextFloat(random) * 2.0f - 1.0f;
                output.Y = NextFloat(random) * 2.0f - 1.0f;
                output.Z = NextFloat(random) * 2.0f - 1.0f;

                l = output.LengthSquared;

            } while (l > 1 || l < Mathf.Epsilon);

            output.Normalize();

            return output;