find closest Coordinates to a point

118 visualizzazioni (ultimi 30 giorni)
I need to find closest point to A=[6,8] among B=[1,2 ; 5,7 ; 3,10 ; ...], and i need to return those coordinates: for example in this case: [5,7]

Risposta accettata

W. Owen Brimijoin
W. Owen Brimijoin il 21 Nov 2013
In your example, you are returning A, rather than the closest point in B... assuming that the answer you are looking for was actually [5,7], then the following should get the job done:
%make some example random values:
A = rand(1,2);
B = rand(10,2);
%compute Euclidean distances:
distances = sqrt(sum(bsxfun(@minus, B, A).^2,2));
%find the smallest distance and use that as an index into B:
closest = B(find(distances==min(distances)),:);
Should work fine!
  13 Commenti
Walter Roberson
Walter Roberson il 5 Mar 2021
A = [1 2 ;
5 6];
B = [2 3;
4 7];
dist2 = reshape(sqrt(sum(((A - permute(B, [3 2 1])).^2),2)),size(A,1),[])
dist2 = 2×2
1.4142 5.8310 4.2426 1.4142
Read this as the first column of the result is comparing each row of A to the first row of B, then the second column of the result is comparing each row of A to the second row of B, and so on. You would take the minimum across the second dimension to find which row of B that each row of A is closest to.
Dora de Jong
Dora de Jong il 8 Mar 2021
Thank you all!!
In the end I used pdist2! Is works really nice.
But every one thank you for the help

Accedi per commentare.

Più risposte (5)

Azzi Abdelmalek
Azzi Abdelmalek il 21 Nov 2013
A = rand(1,2);
B = rand(10,2);
dist=bsxfun(@hypot,B(:,1)-A(1),B(:,2)-A(2));
out = B(dist==min(dist),:)
  6 Commenti
Walter Roberson
Walter Roberson il 29 Mar 2019
A1 A3
AC A2
B1B2B3
BCB4
Here, A1 and A2 are part of a cluster with centroid AC. B1, B2, B3, B4 are part of a cluster with centroid BC. The two closest points to AC over all of the points are A1 and B1. The two closest points to AC within the cluster are A1 and A2.
Would the answer you would be looking for, for 2 closest points, be A1, A2, or would it be A1, B1 ?
MA-Winlab
MA-Winlab il 29 Mar 2019
Modificato: MA-Winlab il 29 Mar 2019
I see. I undestarnd from the example that B1 in a diffrent cluster than that if A1 after doing the clustering.
If my assumption is correct, then I want A1 & A2, i.e. the points that belong to the cluster of that given centroid, after doing the clustering.

Accedi per commentare.


Peter Barsznica
Peter Barsznica il 4 Feb 2016
dsearchn: N-D nearest point search.
[k, d] = dsearchn(A,B) "returns the distances, d, to the closest points. d is a column vector of length p."

Peyman Obeidy
Peyman Obeidy il 7 Mar 2017
This is very helpful, thank you for sharing.
A question, how do I get the indexes for B (I want the index of the value which are in B list and have been selected as the closest to A values)?
Many thanks for your help
  1 Commento
Jan
Jan il 7 Mar 2017
In the suggested codes this is done by:
distances==min(distances) % logical indexing
find(distances==min(distances)) % With FIND
This considers multiple occurrences of the minimal value. If only one occurrence is required, use:
[distances, index] = min(distances);

Accedi per commentare.


Peyman Obeidy
Peyman Obeidy il 7 Mar 2017
I have multiple values for A, so what I did is as follows;
PointinCh1 =
20 482
19 359
45 438
61 248
90 403
104 95
149 335
148 392
161 73
186 29
188 236
189 319
200 162
208 70
204 198
203 343
214 250
225 307
233 171
238 205
237 245
253 148
264 362
281 34
300 341
306 88
305 203
328 234
326 164
330 20
364 199
424 241
433 314
491 187
PointinCh2 =
99 399
104 95
149 335
148 392
158 82
184 238
190 320
202 343
236 246
263 361
299 342
330 20
493 193
%compute Euclidean distances:
for idis=1: length(PointinCh1)
distances = sqrt(sum(bsxfun(@minus, PointinCh2, PointinCh1(idis,:)).^2,2));
%find the smallest distance and use that as an index into B:
closestForPin2toPin1(idis,:)= PointinCh2(find(distances==min(distances)),:);
end
  2 Commenti
Jan
Jan il 7 Mar 2017
You can use the 2nd output of the min command:
[value, index] = min(distances);
closestForPin2toPin1(idis,:)= PointinCh2(index,:);
This uses the first occurence, while your code fails, if the minimal distance exists multiple times.
Johannes Stoerkle
Johannes Stoerkle il 25 Mar 2020
Modificato: Johannes Stoerkle il 30 Mar 2020
If A has multiple points which should be found nearby a grid named B, one can first crop the grid to the points. Second, one can do a coase search by means of a square and finally, the closest points to the grid can be computed:
% find points in A next to grid B, where size(A)>>size(B)
A = rand(2000,2); % point positions
[X, Y] = meshgrid(linspace(0,1,5),linspace(0,1,5));
B = [X(:), Y(:)]; % grid positions
% crop B to area A
dxA = max(A(:,1))-min(A(:,1));
dyA = max(A(:,2))-min(A(:,2));
scaleWind = 0.1;
xRangeA = [min(A(:,1))-dxA*scaleWind max(A(:,1))+dxA*scaleWind];
yRangeA = [min(A(:,2))-dyA*scaleWind max(A(:,2))+dyA*scaleWind];
idxB_inA = xRangeA(1)<=B(:,1) & B(:,1)<=xRangeA(2) & ...
yRangeA(1)<=B(:,2) & B(:,2)<=yRangeA(2);
B = B(idxB_inA,:);
% coase search: find points in squares centered at grid points
Npoints = size(A,1); % number of points
Ngrid = size(B,1); % number of points on grid
dX = max(B(:,1))-min(B(:,1));
dY = max(B(:,2))-min(B(:,2));
% charactersitic length for the square (empirical determined)
dL = max(abs([dX;dY]))/sqrt((Npoints+Ngrid)/20);
idxPreSearch = A(:,1)>B(:,1).'-dL & A(:,1)<B(:,1).'+dL & ...
A(:,2)>B(:,2).'-dL & A(:,2)<B(:,2).'+dL;
% find index-number of closest point for each grid-item
nIdxPointMinAll = nan(Ngrid,1);
for iGrid=1:Ngrid
idxTemp = idxPreSearch(:,iGrid);
nIdxTemp = find(idxTemp);
% compute Euclidean distances
dist2 = sum((B(iGrid,:) - A(idxTemp,:)).^ 2, 2);
nIdexPointMin = dist2 == min(dist2);
if ~isempty(nIdexPointMin)
nIdxPointMinAll(iGrid) = nIdxTemp(nIdexPointMin);
end
end
nIdxPointMinAll(isnan(nIdxPointMinAll)) = [];
nIdxPointMinAll = unique(nIdxPointMinAll);
figure; hold on; plot(A(:,1),A(:,2),'.g');
plot(B(:,1),B(:,2),'*r')
plot(A(idxPreSearch(:,floor(Ngrid/3)),1),A(idxPreSearch(:,floor(Ngrid/3)),2),'.k')
plot(A(nIdxPointMinAll,1),A(nIdxPointMinAll,2),'+b')

Accedi per commentare.


alberto bodoque
alberto bodoque il 7 Apr 2019
So the problem that I need to solve is that I have 6 landfills and I have to place 2 treatment plants but I have to do this considering the minimum total distance between the landfills and the plants. For example: lets say that 1 plant supports landfill 1 and 2 and that the other supports 3,4,5 and 6. That was one possibility but I need to explore all the possibilities and then see which one gives me the less total distance that it has to be cover between the landfills and the plants that is translated in transportation cost.
Let me know if you have more doubts about the statement of this problem and I hope you can help me!
  1 Commento
Jan
Jan il 6 Giu 2019
Please do not attach a new question to an existing thread, even if the topics are similar. Open your own question. If it seems to be useful, add a link to this thread. Then please delete this message here, because it is not an answer.

Accedi per commentare.

Categorie

Scopri di più su Creating and Concatenating Matrices in Help Center e File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by