Generate N random uniformly distributed points in a specific area
70 views (last 30 days)
Here's a simple way (edited)
N=100; %number of points
x_range=[-1 1]; %Range of width
mid_point=[mean(x_range),mean(x_range)]; %Center of box
radius=1; %Radius of circle
point_arr=zeros(N,2); %This will hold the point
temp_xy = (x_range(2)-x_range(1)).*rand(1,2) + x_range(1); %Generate 2 random numbers x and y
d = pdist([temp_xy;mid_point],'euclidean'); %Find distance between the point generated and the middle
if d>radius %If the distance is smaller than the radius, discard it, else accept it
More Answers (2)
Edited: ytzhak goussha on 4 May 2019
Here's a different solution:
This one is evenly distributed and spaced. however it created 108 points or 92 point
[X,Y] = meshgrid(x_p,x_p);
John D'Errico on 4 May 2019
Edited: John D'Errico on 4 May 2019
+1 to ytzhak goussha for the correct solution of course. A rejection method is really the logical way to solve it. What I'll point out are some issues that you can consider, and some alternative methods.
The rejection fraction here is moderately large.
(4 - pi)/4*100
So 78.5% of the points will be rejected. That is not massively bad. You might want to do it all in one large, essentially unlooped approach. So instead generate more points than you need, but do it all at once.
nreq = 1000;
% an extra 20% in case we reject too many.
rejectfrac = (4 - pi)/4;
oversample = 0.2;
xy = ;
nxy = 0;
center = [0, 0];
rad = 1;
while nxy < nreq
% assume we have a circle incribed in a square. So the square has edge length of 2*rad.
nsample = ceil((1 + oversample)*(nreq - nxy)/rejectfrac);
% this mext line uses a feature found in R2016b or later.
xypoints = (rand(nsample,2)*2 - 1)*rad + center;
% delete points inside the circle.
xypoints(sum((xypoints - center).^2,2) <= rad^2,:) = ;
% were there enough points
xy = [xy;xypoints];
nxy = size(xy,1);
if nxy > nreq
xy = xy(1:nreq,:);
But, still we rejected 78.5% of the points. Could I have done better? Perhaps. One idea is to generate points initially that are less likely to have been rejected. So don't bother to generate points that are known to be fully inside the circle. I can think of several such ways off the top of my head. I might choose a smaller polygonal region that describes the region(s) of interest, then generate points randomly and uniformly inside the indicated polygon.
However, the extra work might be more effort to code than the cost of the CPU cycles to reject too many points. Computers are fast, and programmer time is costly. Code that is more complex to write is also more complex to debug and to maintain.