points too close XY space

15 ビュー (過去 30 日間)
DF
DF 2017 年 6 月 15 日
コメント済み: Image Analyst 2017 年 6 月 19 日
Hello,
I have a set of N points with coordinates (x1,y1)...(xN, yN). I would like to find the pairs that are closer than DX in X and closer than DY in Y, avoiding for-loops. Thanks in advance for any help!
  1 件のコメント
James Tursa
James Tursa 2017 年 6 月 15 日
How large is N? How is the data currently stored? What do you want for output? (e.g., a logical NxN matrix, or ...?)

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

採用された回答

Image Analyst
Image Analyst 2017 年 6 月 17 日
Here is a solution that shows you all pairs of points where delta x is less than 0.2:
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 long g;
format compact;
fontSize = 20;
% Define number of points.
N = 50;
% Get random x,y coordinates for those points.
x = rand(N, 1);
y = rand(N, 1);
subplot(2, 2, 1);
plot(x, y, 'b.', 'MarkerSize', 18);
grid on;
% Get distance of every point to every other point.
distances = pdist2(x, x);
% Find points closer than some specified distance to each other.
closestAllowableDistance = 0.02;
closePairs = distances < closestAllowableDistance;
subplot(2, 2, 2);
imshow(closePairs, []);
axis on;
xlabel('Column Index');
ylabel('Row Index');
% Show circles around pairs that are close
subplot(2, 2, 3);
plot(x, y, 'b.', 'MarkerSize', 18);
grid on;
hold on;
% 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')
drawnow;
% Show circles around pairs that are close
hPair = plot(0, 0); % Initialize so we have something to delete the first time though the loop.
for col = 1 : N
for row = 1 : col-1
% Plot this point
if closePairs(row, col)
% The pair is close, so plot it.
x1 = x(row);
y1 = y(row);
x2 = x(col);
y2 = y(col);
% Delete old point
delete(hPair);
% Plot next point.
hPair = plot([x1, x2], [y1, y2], 'ro', 'MarkerSize', 13, 'LineWidth', 2);
% Tell them how far apart they are, and ask them if they want to continue.
promptMessage = sprintf('This pair is separated by %f\n\nDo you want to Continue processing,\nor Quit processing?',...
distances(row, col));
titleBarCaption = 'Continue?';
buttonText = questdlg(promptMessage, titleBarCaption, 'Continue', 'Quit', 'Continue');
if strcmpi(buttonText, 'Quit')
return;
end
end
end
end
  2 件のコメント
DF
DF 2017 年 6 月 19 日
Thank you very much! This answers my question. I was not expecting a full working script, but just some indications. Thanks again!
Image Analyst
Image Analyst 2017 年 6 月 19 日
You're welcome. Thanks for accepting. It's not a full solution. It's just for delta X. You have to basically repeat most of it for delta Y.

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

その他の回答 (3 件)

Julian Hapke
Julian Hapke 2017 年 6 月 15 日
assuming only neighboring points are of interest:
% find close points, add first index because diff is one shorter than x
idxx = [false;diff(x(:))<dx];
% for close points also mark the previous one, so you get both an not only the latter
idxx = idxx | circshift(idxx,[-1,0]);
same goes for y

Image Analyst
Image Analyst 2017 年 6 月 16 日
編集済み: Image Analyst 2017 年 6 月 16 日
Use pdist2() from the Statistics and Machine Learning Toolbox to get all distances from every point to every other point without loops, all in one function call. Try this demo. (My loops are only to display the close pairs with red circles around them, not to compute the separation distances).
clearvars;
clc;
close all;
% Define number of points.
N = 50;
% Get random x,y coordinates for those points.
xy = rand(N, 2);
subplot(2, 2, 1);
plot(xy(:, 1), xy(:, 2), 'b.', 'MarkerSize', 18);
grid on;
% Get distance of every point to every other point.
distances = pdist2(xy, xy);
% Find points closer than some specified distance to each other.
closestAllowableDistance = 0.05;
closePairs = distances < closestAllowableDistance;
subplot(2, 2, 2);
imshow(closePairs, []);
axis on;
xlabel('Column Index');
ylabel('Row Index');
% Show circles around pairs that are close
subplot(2, 2, 3);
plot(xy(:, 1), xy(:, 2), 'b.', 'MarkerSize', 18);
grid on;
hold on;
% 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')
drawnow;
% Show circles around pairs that are close
hPair = plot(0, 0); % Initialize so we have something to delete the first time though the loop.
for col = 1 : N
for row = 1 : col-1
% Plot this point
if closePairs(row, col)
% The pair is close, so plot it.
x1 = xy(row, 1);
y1 = xy(row, 2);
x2 = xy(col, 1);
y2 = xy(col, 2);
% Delete old point
delete(hPair);
% Plot next point.
hPair = plot([x1, x2], [y1, y2], 'ro', 'MarkerSize', 13, 'LineWidth', 2);
% Tell them how far apart they are, and ask them if they want to continue.
promptMessage = sprintf('This pair is separated by %f\n\nDo you want to Continue processing,\nor Quit processing?',...
distances(row, col));
titleBarCaption = 'Continue?';
buttonText = questdlg(promptMessage, titleBarCaption, 'Continue', 'Quit', 'Continue');
if strcmpi(buttonText, 'Quit')
return;
end
end
end
end
  1 件のコメント
Julian Hapke
Julian Hapke 2017 年 6 月 16 日
編集済み: Julian Hapke 2017 年 6 月 16 日
I understood that DF asked for close DX and close DY, the distance for points close in x-direction but far apart in y direction is still big, so no match. also: inside if pdist2 there are several for loops. One could use the good ol' bsxfun to calculate the distances between all the points:
distx = bsxfun(@minus,x,x')
disty = bsxfun(@minus,y,y')
dist = x.^2+y.^2; % no need for sqrt if you check against the squared threshold
Edit: really nice visualization of your answer!

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


DF
DF 2017 年 6 月 17 日
Thank you all for your answers! However, I think my request was not very clear: I'm not interested in the (Euclidean) distance between the points, but I need to know which pairs of points are closer than DX in X AND DY in Y. The output can be either a NxN logical matrix or the first pair found that is too close in DX and DY.
  1 件のコメント
Image Analyst
Image Analyst 2017 年 6 月 17 日
編集済み: Image Analyst 2017 年 6 月 17 日
Simply call pdist2() on the X and Y separately, then threshold the distances matrix at DX and DY. It's easy. If you don't think so, then give me the range of x and y and the values for DX and DY and the number of points. I'm not sure why you're not sharing any diagram with me to help me visualize your situation. Why leave me guessing???
See my second answer.

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

カテゴリ

Help Center および File ExchangeIntroduction to Installation and Licensing についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by