Generating a uniform random distribution of points in a circle

In case anyone wants this simple code snippet. Plenty of examples on the web in python, mathematica etc. none in Igor. It generates points within a circle of radius 1, about the origin. It doesn't work by exclusion (generate random point and then delete those that fall outside the circle), which is a method that apparently saves some computation time.
////    @param  num number of points to be generated
Function UniformCircle(num)
    Variable num
   
    Make/O/N=(num) xw,yw
    Variable tt,uu,rr
   
    Variable i
   
    for(i = 0; i < num; i += 1)
        tt = 2 * pi * (0.5 + enoise(0.5))
        uu = (0.5 + enoise(0.5)) + (0.5 + enoise(0.5))
        if(uu > 1)
            rr = 2 - uu
        else
            rr = uu
        endif
        xw[i] = rr * cos(tt)
        yw[i] = rr * sin(tt)
    endfor
    DoWindow/K resultPlot
    Display/N=resultPlot yw vs xw
    ModifyGraph/W=resultPlot mode=3,marker=8
    ModifyGraph/W=resultPlot width={Plan,1,bottom,left}
End
This snippet works because of a subtlety in the code that is not immediately apparent. At first glance, it might appear that 'rr' has a uniformly distributed probability density function (pdf). If this were the case, then the 2D randomly distributed points would not have a uniform areal density. However, the random part of 'rr' is composed of the sum of two uniform independent 'enoise' pdfs. The sum for the total variable with mean offset 1 has a convolved pdf with a linear increase from rr =0 to 1, and gives the correct areal density. I point this out to those interested in extending or understanding the snippet, and are as lazy as I am to search out references.
Take a closer look at that radial component. Compare a straightforward enoise() assignment and the code in the OP.
Function test(num)
Variable num

    make/o/n=(num) r1,r2

    Variable i,uu
    for(i=0;i<num;i+=1)
    r1[i]=0.5+enoise(0.5)
    uu = (0.5 + enoise(0.5)) + (0.5 + enoise(0.5))
    if(uu > 1)
            r2[i] = 2 - uu
    else
        r2[i] = uu
    endif
    endfor
End


Run the this code with e.g., 1e6 samples and execute the following commands:
wavestats/w r1
duplicate/o M_wavestats rs1
wavestats/w r2
duplicate/o M_wavestats rs2
Edit/K=0 root:rs1.ld,root:rs2.ld


Now compare the avg, sdev, rms, adev and skew between the two...

The OP did not state explicitly what is meant by "uniform". My own guess would be: density that is independent of location inside the circle. One can verify angular uniformity using StatsCircularMoments with the /KUPR, but clearly if the radial distribution was also strictly uniform then the density of points per unit area would be higher closer to the origin. A joint histogram for xw and yw can help display the results:
JointHistogram xw,yw
NewImage M_JointHistogram



Forum

Support

Gallery

Igor Pro 8

Learn More

Igor XOP Toolkit

Learn More

Igor NIDAQ Tools MX

Learn More