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

10 views (last 30 days)

Show older comments

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 Comments

### Accepted Answer

Karim
on 24 Dec 2022

Edited: Karim
on 25 Dec 2022

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 Comments

Karim
on 25 Dec 2022

### More Answers (1)

John D'Errico
on 24 Dec 2022

Edited: John D'Errico
on 24 Dec 2022

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 Comments

John D'Errico
on 24 Dec 2022

Edited: John D'Errico
on 24 Dec 2022

### See Also

### Categories

### Community Treasure Hunt

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

Start Hunting!