Once we have a good algorithm for generating points on a flat disc, generating points inside the volume of a cylinder should not be a problem. Simply handle the cylinder as a disc oriented parallel to the cylinder's caps and shift the generated point on the cylinder's Z axis by a random value.
/// <summary>Returns a random point within a cylinder</summary>
/// <param name="randomNumberGenerator">Random number generator that will be used</param>
/// <param name="orientation">Orientation of the cylinder</param>
/// <param name="radius">Radius of the cylinder</param>
/// <param name="length">Length of the cylinder</param>
/// <returns>A random point within the cylinder</returns>
public static Vector3 GenerateRandomPointWithin(
System.Random randomNumberGenerator,
Matrix orientation, float radius, float length
) {
Vector2 randomPoint = Areas.PointGenerators.Disc2PointGenerator.GenerateRandomPointWithin(
randomNumberGenerator, radius
);
float z = (float)randomNumberGenerator.NextDouble() * 2.0f - 1.0f;
return Vector3.Transform(
new Vector3(randomPoint.X, randomPoint.Y, z * length),
orientation
);
}
/// <param name="randomNumberGenerator">Random number generator that will be used</param>
/// <param name="orientation">Orientation of the cylinder</param>
/// <param name="radius">Radius of the cylinder</param>
/// <param name="length">Length of the cylinder</param>
/// <returns>A random point within the cylinder</returns>
public static Vector3 GenerateRandomPointWithin(
System.Random randomNumberGenerator,
Matrix orientation, float radius, float length
) {
Vector2 randomPoint = Areas.PointGenerators.Disc2PointGenerator.GenerateRandomPointWithin(
randomNumberGenerator, radius
);
float z = (float)randomNumberGenerator.NextDouble() * 2.0f - 1.0f;
return Vector3.Transform(
new Vector3(randomPoint.X, randomPoint.Y, z * length),
orientation
);
}