Note that there are some explanatory texts on larger screens.

plurals
  1. POFast uniformly distributed random points on the surface of a unit hemisphere
    text
    copied!<p>I am trying to generate uniform random points on the surface of a unit sphere for a Monte Carlo ray tracing program. When I say uniform I mean the points are uniformly distributed with respect to surface area. My current methodology is to calculate uniform random points on a hemisphere pointing in the positive z axis and base in the x-y plane.</p> <p>The random point on the hemisphere represents the direction of emission of thermal radiation for a diffuse grey emitter.</p> <p><strong>I achieve the correct result when I use the following calculation :</strong></p> <p><strong>Note : dsfmt* is will return a random number between 0 and 1.</strong></p> <pre><code>azimuthal = 2*PI*dsfmt_genrand_close_open(&amp;dsfmtt); zenith = asin(sqrt(dsfmt_genrand_close_open(&amp;dsfmtt))); // Calculate the cartesian point osRay.c._x = sin(zenith)*cos(azimuthal); osRay.c._y = sin(zenith)*sin(azimuthal); osRay.c._z = cos(zenith); </code></pre> <p>However this is quite slow and profiling suggests that it takes up a large proportion of run time. Therefore I sought out some alternative methods:</p> <p><strong>The Marsaglia 1972 rejection method</strong></p> <pre><code>do { x1 = 2.0*dsfmt_genrand_open_open(&amp;dsfmtt)-1.0; x2 = 2.0*dsfmt_genrand_open_open(&amp;dsfmtt)-1.0; S = x1*x1 + x2*x2; } while(S &gt; 1.0f); osRay.c._x = 2.0*x1*sqrt(1.0-S); osRay.c._y = 2.0*x2*sqrt(1.0-S); osRay.c._z = abs(1.0-2.0*S); </code></pre> <p><strong>Analytical cartesian coordinate calculation</strong></p> <pre><code>azimuthal = 2*PI*dsfmt_genrand_close_open(&amp;dsfmtt); u = 2*dsfmt_genrand_close_open(&amp;dsfmtt) -1; w = sqrt(1-u*u); osRay.c._x = w*cos(azimuthal); osRay.c._y = w*sin(azimuthal); osRay.c._z = abs(u); </code></pre> <p>While these last two methods run serval times faster than the first, when I use them I get results which indicate that they are not generating uniform random points on the surface of a sphere but rather are giving a distribution which favours the equator.</p> <p>Additionally the last two methods give identical final results however I am certain that they are incorrect as I am comparing against an analytical solution.</p> <p>Every reference I have found indicates that these methods do produce uniform distributions however I do not achieve the correct result.</p> <p>Is there an error in my implementation or have I missed a fundamental idea in the second and third methods?</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload