How can I compare distance (not only between two points, but also a set of points)

I have a set of points (coordinates X, Y). X is matrix 10*100, also Y.
I 've devided these points into 100 collums, 1 collum has 10 points with coordinate (X,Y) and compared distance between one point at one collum and another point at collum, which is next to the previous collum.
For example, I compared these points from collum 1 and collum 2, and chose the distances, which are smaller than distance R
for i = 1:10
X_collum1(i,1) = X(i,1);
X_collum2(i,1) = X(i,2);
end
for i = 1:10
Y_collum1(i,1) = Y(i,1);
Y_collum2(i,1) = Y(i,2);
end
for i = 1:10,
for j = 1:10
X_distance(i,j) = abs(X_collum1(i,1) - X_collum2(j,1));
Y_distance(i,j) = abs(Y_collum1(i,1) - Y_collum2(j,1));
a(i,j) = sqrt(X_distance(i,j)^2+Y_distance(i,j)^2);
if a(i,j) < R
distance = a(i,j);
end
end
end
Next step is comparing between collum 2 and 3, then 3 and 4, then 4 and 5. Finally this will be between collum 99 and 100. But I can't do this 99 times. Therefore, I need someone, who comes up with some ideas to do this task quickly (like making some loop, or so on). Thanks a lot.

 Réponse acceptée

As I understand it, you have 10 by 100 points represented in variables X and Y which are both 10 by 100 matrices. A given point could then for example be defined as pt(i,j) = [X(i,j),Y(i,j)]
My understanding is that you want to calculate all distances between points in adjacent columns and store those which are less than the nominal threshold value R. So when comparing 10 points with 10 points of a given pair of adjacent columns this means looking at 100 distances overall.
For 2016b onwards you one solution would be to do the following:
R = 2000;
D = cell(99,1);
for j = 1:size(X,2)-1
distances = sqrt((X(:,j+1)-X(:,j).').^2 + (Y(:,j+1)-Y(:,j).').^2);
D{j,1} = distances(distances<R); % storing result in cell array D.
end
To understand why I transpose column j, see the following documentation.
For ealier versions you would have to use bsxfun to carry out the same procedure, which would go as follows:
R = 2000;
D = cell(99,1);
for j = 1:size(X,2)-1
distances = sqrt(bsxfun(@minus,X(:,j+1),X(:,j).').^2 ...
+ bsxfun(@minus,Y(:,j+1),Y(:,j).').^2);
D{j,1} = distances(distances<R);
end
EDIT: Changed answer following comments below.

19 commentaires

Sorry, can you explain this code to me, why is diff(X,2)?
Sorry I had the incorrect inputs. I have edited the above answer. diff(X,1,2) returns the differences between adjacent points along a given row and it does that for all rows. So, doing that for both X and Y you can then get the distances from the root sum of squares.
As I understand it, you want the distance from row 1 column 1 to row 1 column 2 and to repeat that for all rows, then you want to move to column 2 and 3 and repeat, then column 4 and 5, and so until you've reached the end. You would get a 10 by 99 array as your output. Something to note is that you don't need loops at all but you especially don't need the first two to assign an array of values to a variable. You could just write
Xcol1 = X(:,1);
Having said that, separating out your columns into different enumerated variables in the first place is something you should never ever do. I suggest you go through the Introductory Onramp course for Matlab.
Hello, I've used your code: Dist = sqrt(diff(X,1,2).^2 +diff(Y,1,2).^2); and added the condition: Dist < R_aim, and I've got 11 results. But the result is different from the result that I've counted by using my previous code. I've slowly tested collum 1 - 2, collum 2 - 3, collum 3 - 4, up to collum 9 - 10, and have already got 11 results. So could you please check it out? Thanks. By the way, I appreciate your code, because it's very brief.
Can you provide the code you used to do that and the X and Y variable?
Also just to confirm, when you are comparing each column are you comparing the first row in column 1 with the first row in column 2 only, or are you comparing row 1 in column 1 with all rows in column 2. If so the answer would be a few more lines.
Anh, you've accepted this answer, so you have a solution, right?
I've agreed with you that I will get the final result (matrix 10*99), but the values I've got aren't exact. So I send you my project in order that you can check it for me please.
The following will compare the distance between all points for each pair of columns and store the distances which are below the threshold R into a cell array D.
D = cell(99,1)
for i = 1:size(X,2)-1
distances = sqrt((X(:,i+1)-X(:,i).').^2 + (Y(:,i+1)-Y(:,i).').^2);
D{i,1} = distances(distances<R);
end
Sorry, but I have error when running this code:
Error using -
Matrix dimensions must agree.
It is said that the line "distances = sqrt(abs(X(:,i+1)-X(:,i).').^2 + abs(Y(:,i+1)-Y(:,i).').^2);" is wrong
Using the code you provided to generate X and Y
clc;
clear all;
close all;
%% display range of radar
alpha = 0:0.1:360;
Rmax = 100000;
for i = 1:length(alpha);
[x(i),y(i)] = fx(Rmax, alpha(i));
end
%% generating trajectory
y0 = 20000;
x0 = -30000;
Ra = x0/cos(atan(y0/x0));
v = 167;
deltat = 4;
t = 0:4:99*4;
xc = x0 + v*t;
yc = zeros(1,length(t));
yc(:) = y0;
for i = 1:length(xc)
rng(0+i,'v5normal');
x_real(i)=xc(i)+100*randn;
rng(1000+i,'v5normal');
y_real(i)=yc(i)+100*randn;
end
%% generating false alarms - uniform distribution
n = 10*length(t); % pocet falesnych detekci
Rf = Rmax*rand(1,n);
alpha2 = 360*rand(1,n);
for i = 1:length(alpha2)
[X_false(i), Y_false(i)] = fx(Rf(i), alpha2(i));
end
X_false_new=reshape(X_false,10,[]);
Y_false_new=reshape(Y_false,10,[]);
%% distinguishing true and false alarm1
for i = 1: length(t)/10
for j = 1 : length(t)
[X(i,j), Y(i,j)] = fx2(X_false_new(i,j), Y_false_new(i,j));
end
end
for i = 1:length(t)
change=randi(11);
if change <= 10
[X(change,i), Y(change,i)] = fx2(x_real(i), y_real(i));
end
end
And then the aforementioned piece I provided works fine for me:
%% Comparing column 1 to column 2, 2 to 3, 3 to 4, ... N-1 to N.
R = 2000;
D = cell(99,1);
for i = 1:size(X,2)-1
distances = sqrt((X(:,i+1)-X(:,i).').^2 + (Y(:,i+1)-Y(:,i).').^2);
D{i,1} = distances(distances<R);
end
D
Still coming up with errors? Let me know.
Sorry, I've still had this error
X(:,i).' doesn't have the same dimension as X(:,i+1), I think my project has this error. But if I remove .', the result will be wrong, right?
Oh what version of Matlab do you have??
I have version MATLAB 2016a
Implicit expansion is a feature in 2016b onwards that I used when subtracting the rows and columns. (There's a nice blog about the change here). For 2016a you can use bsxfun to do the same thing as follows:
R = 2000;
D = cell(99,1);
for i = 1:size(X,2)-1
distances = sqrt(bsxfun(@minus,X(:,i+1),X(:,i).').^2 ...
+ bsxfun(@minus,Y(:,i+1),Y(:,i).').^2);
D{i,1} = distances(distances<R);
end
Can I still have a question: How can I code to show the indices of distances?. For example, D{1,1} = 765.2511 is distance between point(9,1) (from column 1) and point(7,2) (from column 2). I want to have the output is matrix [9 7]. D{2,1} = [1989,071; 598,152] is set of two distances: The first is distance between point(6,2) (from column 2) and point(8,3) (from column 3) and the second is distance between point(7,2) (from column 2) and point(7,3) (from column 3). I want to have the output is [6 8; 7 7] and similarly to D{99,1}. The next step I want to show the coordinate of the points. For example, from D{1,1} I have [9 7], and from the indices I want to find X(9,1), X(7,2), Y(9,1), X(7,2).
Thank you very much
As follows:
R = 2000;
D = cell(99,1);
ind = cell(99,1);
for i = 1:size(X,2)-1
distances = sqrt(bsxfun(@minus,X(:,i+1),X(:,i).').^2 ...
+ bsxfun(@minus,Y(:,i+1),Y(:,i).').^2);
[iNext,iCurr] = find(distances<R); % iNext: index for column i+1, iCurr: index for column i
D{i,1} = distances(iNext,iCurr);
ind{i,1} = [iCurr,iNext];
end
Results
>> ind{1}
ans =
9 7
>> ind{2}
ans =
6 8
7 7
Thank you, and then if I code find(ind{1,1},'row'), will it display 9. I've tried but it's wrong. So can you tell me how to display 9, and 7
You can display the index numbers as I have shown above. If you want to reference the index to the original X and Y arrays you might do something like this for a given i:
x1 = X(ind{i}(:,1),i);
x2 = X(ind{i}(:,2),i+1);
y1 = Y(ind{i}(:,1),1);
y2 = Y(ind{i}(:,2),i+1);

Connectez-vous pour commenter.

Plus de réponses (1)

If you have the Statistics and Machine Learning toolbox, use pdist2(). It will give you the distance of every point to every other point. Split your 10x100 matrices up into some number of N-by-2 lists of (x,y) coordinates and pass them in, like
distances = pdist2(xy, xy);
Let me know if you still can't figure it out.

5 commentaires

Sorry, but i cant combine two coordinates X, Y in one matrix. Could you please give me a hint?
See this:
X = rand(4, 1)
Y = rand(4, 1)
xy = [X, Y]
You'll see something like:
X =
0.42176
0.91574
0.79221
0.95949
Y =
0.65574
0.035712
0.84913
0.93399
xy =
0.42176 0.65574
0.91574 0.035712
0.79221 0.84913
0.95949 0.93399
For your case where X is 10 rows-by-100 columns, and Y is also 10 rows-by-100 columns, please explain what each row and each column represents. Which row(s) or column(s) represent the x and y values?
I am so sorry for not corresponding. For me, X is matrix (10*100), Y is matrix (10*100) represent the coordinates (X,Y). In reality, this is the tracking model. I've devided 1000 points into 100 parts and compared. Each part has 10 points. That's why I have matrix 10*100. In the field of radar system, it means that I have 100 steps. At step 1 when I turn on the radar scanning system, I realize 10 points. At step 2 (t2 = t1 + deltat) when I turn on the radar scanning system, I realize other 10 points, up to step 100. I've known that at each step when I saw 10 points, only 1 point is real, 9 other points are false alarms. Therefore I need to compare the distance between set of point at collum 1 and at collum 2, next will be collum 2 and collum 3, 3 and 4, 4 and 5. Finally 99 and 100. If the distance is smaller than R (a value that I called), I chose these points
This will compute the distances between every point in each column with every point in every column.
X = rand(10, 100);
Y = rand(10, 100);
[rows, columns] = size(X)
distances = zeros(rows, rows, columns);
plane = 1;
% For each pair of columns, get a 10-by-10 matrix that gives
% the distances between one columns and another
for col1 = 1 : columns
xySet1 = [X(:, col1), Y(:, col1)];
for col2 = 1 : columns
xySet2 = [X(:, col2), Y(:, col2)];
distances(:, :, plane) = pdist2(xySet1, xySet2);
plane = plane + 1;
end
end
% Show all 10x10x100 distances in command window
distances
For simplicity in indexing the answers, I did not exclude comparing each column with itself (e.g. there will be comparisons of column 1 with column1, column 2 with column 2, ... column 100 with column 100) but all the distances are in there and if I were to exclude same columns, the indexing would be much more complicated.
To find distances that are less than R, you can create a binary "map" where it's 1 if the distance is less than R
mapOfClosePoints = distances > 0 & distances < R;
Note that by also comparing to non-zero, we will not be selecting columns where the two columns are the same column.

Connectez-vous pour commenter.

Catégories

En savoir plus sur Polar Plots dans Centre d'aide et File Exchange

Produits

Version

R2016a

Community Treasure Hunt

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

Start Hunting!

Translated by