Distribute points evenly in rectangle

10 ビュー (過去 30 日間)
victor isarov
victor isarov 2017 年 6 月 10 日
コメント済み: Image Analyst 2017 年 6 月 11 日
Hey guys, I'm trying to tackle the next problem: I have a rectangle with known dimensions and I need to distribute n points inside of it randonmly, but evenly. By evenly I mean that there must be some minimum (or even constant) distance between the points. After some search on the internet I haven't found some algorithm that helps me with this problem. Would appreciate some insights.
Thanks in advance.

回答 (2 件)

Walter Roberson
Walter Roberson 2017 年 6 月 10 日

Image Analyst
Image Analyst 2017 年 6 月 10 日
Did you try to write it yourself? It's not hard. Just get a point and see if it's too close to any prior points. If it's not too close, then place it. This code works.
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
clear; % Erase all existing variables. Or clearvars if you want.
workspace; % Make sure the workspace panel is showing.
format short g;
format compact;
fontSize = 20;
% Define how many points you want to place.
maxPoints = 500;
% Define counter for how many actually get placed.
numPoints = 0;
% Define fail safe, how many iterations you want to keep trying before quitting.
maxIterations = 1000 * maxPoints;
loopCounter = 1;
% Define how close points can come to other points before being rejected.
minClosestDistance = 0.1;
% Declare arrays to hold the x and y coordinate values.
x = nan(1, numPoints);
y = nan(1, numPoints);
while numPoints < maxPoints && loopCounter < maxIterations
% Get a random point.
xPossible = rand();
yPossible = rand();
if numPoints == 0
% First point automatically is valid.
numPoints = numPoints + 1;
x(numPoints) = xPossible;
y(numPoints) = yPossible;
continue;
end
% Find distances between this point and all others.
distances = sqrt((x-xPossible) .^ 2 + (y - yPossible) .^ 2);
if min(distances) >= minClosestDistance
% It's far enough away from all the other points, or it's the first point.
% Include it in our list of acceptable points.
numPoints = numPoints + 1;
x(numPoints) = xPossible;
y(numPoints) = yPossible;
end
% Increment the loop counter.
loopCounter = loopCounter + 1;
end
% Crop away points we were not able to get.
x = x(1:numPoints); % Crop to valid points.
y = y(1:numPoints); % Crop to valid points.
% Plot the points we were able to get.
plot(x, y, 'b.', 'MarkerSize', 15);
grid on;
xlabel('X', 'FontSize', fontSize);
ylabel('Y', 'FontSize', fontSize);
title('Demo by Image Analyst', 'FontSize', fontSize);
% Set up figure properties:
% Enlarge figure to full screen.
set(gcf, 'Units', 'Normalized', 'OuterPosition', [0 0 1 1]);
% Get rid of tool bar and pulldown menus that are along top of figure.
set(gcf, 'Toolbar', 'none', 'Menu', 'none');
% Give a name to the title bar.
set(gcf, 'Name', 'Demo by ImageAnalyst', 'NumberTitle', 'Off')
% Tell user what we were a ble to achieve.
message = sprintf('Found %d points in %d tries', numPoints, loopCounter)
helpdlg(message);
Bonus challenge for you: construct the "Fry plot" of it. Compare its Fry plot to that of a Poisson distribution, and of an aggregated distribution.
  5 件のコメント
Walter Roberson
Walter Roberson 2017 年 6 月 11 日
In a 2D rectangle, the maximum number of points that can be at constant distance from each other is 3.
Image Analyst
Image Analyst 2017 年 6 月 11 日
So just get the location of the first point at random, and use simple trig formulas to get the location of the second point, which can be at a random or specified angle to the first.
If you need a third point, again it's simple trig to find the location of the third point. If the third point is outside the rectangle, flip it on the other side of the line between the first two so that it lands inside the rectangle.
Like Walter said, there will be no solution if your number criteria is anything other than 2 or 3.
If you are going to allow non-uniform spacing, then just how many points were you planning on placing? If it's just a few thousand, perhaps less than a million, the code I gave is pretty fast - the smaller the min spacing the faster it will be since there will be fewer "rejects". A faster way would be to generate the points on a perfectly regular rectangular grid, and then just generate perturbations - delta X's and delta Y's - to slightly move each point. Kind of like Perlin Noise, if you're familiar with that.

サインインしてコメントする。

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by