Sorting of points (2D) clockwise with respect to the center of gravity

26 ビュー (過去 30 日間)
Alberto Acri
Alberto Acri 2022 年 12 月 24 日
編集済み: Karim 2022 年 12 月 25 日
I am using this code. Can anyone tell me how I can improve it to be able to sort the points (matrix coordinates) clockwise with respect to G?
data = readmatrix('data.txt');
G = mean(data,1);
% Convert to polar coordinates
rad = cart2pol(data(:,1), data(:,2));
radWrapped = mod(rad,2*pi);
radWrapped(radWrapped==0 & rad>0) = 2*pi;
[~, sortIdx] = sort(radWrapped, 'descend');
sortedData = data(sortIdx,:);
% Figure
figure
plot(data(:,1), data(:,2),'k.','Markersize',15)
hold on
plot(G(:,1), G(:,2),'k*','Markersize',15)
a = 14;
plot(data(a,1), data(a,2),'r.','Markersize',15) % display point 14
b = 15;
plot(data(b,1), data(b,2),'g.','Markersize',15) % display point 15
c = 16;
plot(data(c,1), data(c,2),'m.','Markersize',15) % display point 16
d = 17;
plot(data(d,1), data(d,2),'y.','Markersize',15) % display point 17
e = 18;
plot(data(e,1), data(e,2),'b.','Markersize',15) % display point 18
hold off
grid off
axis equal
xlabel('x')
ylabel('y')
  2 件のコメント
Sulaymon Eshkabilov
Sulaymon Eshkabilov 2022 年 12 月 24 日
can you share your data?
Alberto Acri
Alberto Acri 2022 年 12 月 24 日
yes, sorry I forgot to attach the file

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

採用された回答

Karim
Karim 2022 年 12 月 24 日
編集済み: Karim 2022 年 12 月 25 日
Edit: modified the code after the OP added data...
The sort trick with the angle won't work due to the shape of the curve. Below you can find a bit mory tricky method. We look for the closest point and then march on looping over al the points. See below for some coments and a working example.
% read the data
data = readmatrix('data.txt');
% determine the order of the closest points for each point
idx = knnsearch(data,data,'K',size(data,1));
% create a vector to store the order of the points
order = zeros(size(data,1),1);
% we use point 1 as the starting point
order(1) = 1;
% loop over the other points
for i = 2:size(data,1)
% extract the indexes of the points closest to the current point
% these are ordered by distance vie the knnsearch
currPoints = idx(order(i-1),:);
% keep looking for the closest point we havent used so far
for j = 2:size(data,1)
if all(order(1:(i-1)) ~= currPoints(j))
% we found the next point, store in the order and stop the
% internal loop
order(i) = currPoints(j);
break
end
end
end
% sort the points using the order
data = data(order,:);
% add the first point at the end, to close the curve in the figure
data(end+1,:) = data(1,:);
% make a figure
figure
plot(data(:,1),data(:,2),'LineWidth',1.5)
grid on
title('sorted points')
  4 件のコメント
Alberto Acri
Alberto Acri 2022 年 12 月 25 日
Thank you @Karim! Very helpful. Can I just ask you how to connect the first and the last point?
Karim
Karim 2022 年 12 月 25 日
You are welcome, you can add the first point at the end of the array. This will give the appearance of a closed region, i will edit the answer accordingly.

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

その他の回答 (1 件)

John D'Errico
John D'Errico 2022 年 12 月 24 日
編集済み: John D'Errico 2022 年 12 月 24 日
I'm confused. Have you already subtracted off the center of gravity from the columns of data? I don't see that operation. If not, then nothing in what you wrote does it, so your code would be incorrect.
Next, what you wriote is this:
rad = cart2pol(data(:,1), data(:,2));
HUH? The first argument returned from cart2pol is not a radius, in fact it is the SECOND argument returned from cart2pol. Ok, I suppose you wanted it to mean RADIANS. Sigh. Good code is self documenting. So the variables should have meaningful names that will not confuse you when you try to read it.
But all you need to do is a mod, and THEN a sort. You did some other fussing around that makes no sense that I can see.
rad = sort(mod(rad,2*pi),'descend');
For example (Sorry, that I refuse to use rad for an angle. It just hurts my brain to do so.)
data = rand(20,2);
G = mean(data,1);
datashifted = data - G;
theta = cart2pol(datashifted(:,1),datashifted(:,2));
[theta,ind] = sort(mod(theta,2*pi),'descend');
plot(data(ind,1),data(ind,2),'-o',data(ind(1),1),data(ind(1),2),'rs')
I've plotted the first point with a red square here, so you can see the points are now sorted in a clockwise order.
  2 件のコメント
Alberto Acri
Alberto Acri 2022 年 12 月 24 日
編集済み: Alberto Acri 2022 年 12 月 24 日
Thanks for the reply @John D'Errico! I attached you the "date" file I forgot to attach!
The code works fine however there are some issues related to the curve I attached.
John D'Errico
John D'Errico 2022 年 12 月 24 日
編集済み: John D'Errico 2022 年 12 月 24 日
Your points lie along a "polygon", yet sufficiently non-convex that you cannot use the scheme I suggested. I would instead use a traveling salesman solver, so a scheme that finds the shortest route between successive points along the curve. There are a few of them on the file exchange.

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

カテゴリ

Help Center および File ExchangeMultidimensional Arrays についてさらに検索

製品


リリース

R2021b

Community Treasure Hunt

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

Start Hunting!

Translated by