MATLAB: Scatter random points on a circle with a minimum distance

circlerandom generator

Hi Matlab users,
I am trying to write a code to randomly scatter points on a cirlce which these points should have a minimum distant on this circle.
R=1;
for i=1:100
theta(i) = 2*pi*rand();
r(i) = R*sqrt(rand());
x = r.*cos(theta);
y = r.*sin(theta);
end
plot(x,y,'*')
axis equal
This code just creates the points. I want to add a condition that not two points can be closer than (0.005*R) to eachother.
Best,
Argu

Best Answer

Try this accept/reject method similar to what you've tried:
fontSize = 20;
R=1;
minAllowableDistance = 0.005 * R;
requiredNumberOfPoints = 100;
pointCount = 0;
for k = 1 : 100 * requiredNumberOfPoints
thisTheta = 2*pi*rand();
thisRadius = R * rand();
% Compute distances to other points.
thisx = thisRadius .* cos(thisTheta);
thisy = thisRadius .* sin(thisTheta);
if k == 1
% We can ALWAYS place/accept the first point.

pointCount = pointCount + 1; % Increment count.

x(pointCount) = thisx;
y(pointCount) = thisy;
else
% Compute distances to other points
theseDistances = sqrt((x-thisx) .^ 2 + (y - thisy) .^ 2);
if min(theseDistances) >= minAllowableDistance
pointCount = pointCount + 1; % Increment count.
% We can ALWAYS place/accept the first point.
x(pointCount) = thisx;
y(pointCount) = thisy;
distances(pointCount) = min(theseDistances);
% Bail out if we have enough points.
if pointCount >= requiredNumberOfPoints
break;
end
end
end
end
fprintf('Placed %d points after %d attempts.\n', pointCount, k);
% Plot points.
subplot(2, 1, 1);
plot(x, y, 'b*')
xlim([-R, R]);
ylim([-R, R]);
axis('equal', 'square');
grid on;
hold on;
% Plot circle
pos = [-R, -R, 2*R, 2*R];
rectangle('Position',pos,'Curvature',[1 1])
xlabel('X', 'fontSize', fontSize);
ylabel('Y', 'fontSize', fontSize);
caption = sprintf(' %d Random points in a circle.', requiredNumberOfPoints);
title(caption, 'fontSize', fontSize);
% Plot histogram of distances.
subplot(2, 1, 2);
histogram(distances, 15);
grid on;
title('Histogram of Closest Distances', 'fontSize', fontSize);
You can also do this without a for loop and do it vectorized.
Note the histogram is the histogram as the points were being placed, and is not going to be the same as the histogram of the final set of points. To do that, you can use pdist2() and pass the result into histogram().