/// <summary> /// Returns a uniformly distributed vector (corresponds to a /// uniformly distributed point on the unit sphere) by using /// 2 random values from the series with the supplied indices. /// Note, that the returned vector will never be equal to [0, 0, -1]. /// </summary> public static V3d UniformV3dDirection(this IRandomSeries rnd, int si0, int si1) { double phi = rnd.UniformDouble(si0) * Constant.PiTimesTwo; double z = 1.0 - rnd.UniformDouble(si1) * 2.0; double s = System.Math.Sqrt(1.0 - z * z); return(new V3d(System.Math.Cos(phi) * s, System.Math.Sin(phi) * s, z)); }
/// <summary> /// Uses the 2 random series (seriesIndex, seriesIndex+1) /// </summary> public static V3d Spherical( IRandomSeries rnds, int seriesIndex) { double phi = Constant.PiTimesTwo * rnds.UniformDouble(seriesIndex); double z = 1.0 - 2.0 * rnds.UniformDouble(seriesIndex + 1); double r = Fun.Max(1.0 - z * z, 0.0).Sqrt(); return(new V3d(r * phi.Cos(), r * phi.Sin(), z)); }
/// <summary> /// Supplied normal MUST be normalized, uses the 2 random series /// (seriesIndex, seriesIndex+1). /// </summary> public static V3d Lambertian( V3d normal, IRandomSeries rnds, int seriesIndex) { V3d vec; double squareLen; do { double phi = Constant.PiTimesTwo * rnds.UniformDouble(seriesIndex); double z = 1.0 - 2.0 * rnds.UniformDouble(seriesIndex + 1); double r = Fun.Max(1.0 - z * z, 0.0).Sqrt(); vec = new V3d(r * phi.Cos(), r * phi.Sin(), z) + normal; squareLen = vec.LengthSquared; }while (squareLen < 0.000001); vec *= 1.0 / squareLen.Sqrt(); return(vec); }
/// <summary> /// Generates a uniform distributed random sample on the given triangle using /// two random series (seriesIndex, seriesIndex + 1). /// </summary> public static V2d Triangle(Triangle2d t, IRandomSeries rnd, int seriesIndex) { return(Triangle(t.P0, t.P1, t.P2, rnd.UniformDouble(seriesIndex), rnd.UniformDouble(seriesIndex + 1))); }
/// <summary> /// Uses the 2 random series (seriesIndex, seriesIndex+1) to generate a random point on a sphere. /// </summary> public static V3d Spherical(IRandomSeries rnds, int seriesIndex) { return(Spherical(rnds.UniformDouble(seriesIndex), rnds.UniformDouble(seriesIndex + 1))); }
/// <summary> /// Generates a uniform distributed 2d random sample on a disk with radius 1. /// It uses two random series (seriesIndex, seriesIndex+1). /// </summary> public static V2d Disk(IRandomSeries rnd, int seriesIndex) { return(Disk(rnd.UniformDouble(seriesIndex), rnd.UniformDouble(seriesIndex + 1))); }
/// <summary> /// Supplied normal MUST be normalized, uses the 2 random series /// (seriesIndex, seriesIndex+1). /// </summary> public static V3d Lambertian(V3d normal, IRandomSeries rnds, int seriesIndex) { return(Lambertian(normal, rnds.UniformDouble(seriesIndex), rnds.UniformDouble(seriesIndex + 1))); }
/// <summary> /// Generates a uniform distributed random sample on the given triangle using /// two random series (seriesIndex, seriesIndex + 1). /// </summary> public static V3d Triangle(V3d p0, V3d p1, V3d p2, IRandomSeries rnd, int seriesIndex) { return(Triangle(p0, p1, p2, rnd.UniformDouble(seriesIndex), rnd.UniformDouble(seriesIndex + 1))); }