connect nodes (coordinates of a matrix rx3) with a line
3 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
I am modifying the question because it was completely misunderstood.
I want to connect the coordinates in data.txt (representing the black * in the figure) with a line (red) in the following way:
I tried this code but it does not give the desired result.
data = readmatrix('data.txt');
figure
plot(data(:,1), data(:,2),'k*','Markersize',15)
hold on
plot(data(:,1), data(:,2),'-r','LineWidth',1)
hold off
grid off
xlabel('x')
ylabel('y')
Réponse acceptée
Voss
le 24 Déc 2022
data = readmatrix('data.txt');
N = size(data,1);
% d: distance (squared) from each point to each other point
% (with the distance from a point to itself set to Inf,
% so that it won't be the minimum)
x = data(:,1);
y = data(:,2);
d = (x-x.').^2+(y-y.').^2;
d(1:N+1:end) = Inf;
% used_idx: indices of points used so far
% unused_idx: indices of points not used so far
% start with point 1
used_idx = 1;
unused_idx = 2:N;
% as long as there are some points not yet used
while ~isempty(unused_idx)
% find the unused point nearest to the last used one
[~,idx] = min(d(used_idx(end),unused_idx),[],2);
% add that index to the used_idx vector
used_idx(end+1) = unused_idx(idx);
% and remove it from the unused_idx vector
unused_idx(idx) = [];
end
% plot
plot(x,y,'*k')
hold on
% include the first point at the beginning and end ([1:end 1]),
% in order to close the loop
plot(x(used_idx([1:end 1])),y(used_idx([1:end 1])), ...
'LineWidth',3)
2 commentaires
Voss
le 26 Déc 2022
Modifié(e) : Voss
le 26 Déc 2022
That happens because of the NaNs you put into x_sx and x_dx in an attempt to partition the dataset into the two separate curves. Basically, in between the last point and the first point of each curve, the entire other curve exists but its x-coordinates are all NaN's so you don't see it, but you also don't get the line connecting the last point back to the first.
You could modify the code to handle NaNs, but what makes more sense to me is, instead of using NaNs, separate the two curves completely:
data = readmatrix('te_300.txt');
x = data(:,1);
y = data(:,2);
threshold = 255;
idx = x > threshold;
x_sx = x(idx);
y_sx = y(idx);
coord_left = [x_sx, y_sx];
x_dx = x(~idx);
y_dx = y(~idx);
coord_right = [x_dx, y_dx];
And then, of course, the calculations of d_sx and d_dx have to use y_sx and y_dx, respectively, instead of y:
% ...
d_sx = (x_sx - x_sx.').^2 + (y_sx - y_sx.').^2;
% ...
d_dx = (x_dx-x_dx.').^2+(y_dx-y_dx.').^2;
% ...
And the rest stays the same.
Plus de réponses (3)
Karim
le 24 Déc 2022
Modifié(e) : Karim
le 24 Déc 2022
i guess this is related to Sorting of points (2D) clockwise with respect to the center of gravity - MATLAB Answers - MATLAB Central (mathworks.com) :) however here you have the answer again.
Note that the typical sorting trick using the angle won't work due to the shape of your curve. Hence the method below uses a loop over the points, looking for the closest neighbour until the order is found.
See below for a demonstration of the principle using your data points. Hope it helps.
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,:);
% make a figure
figure
plot(data(:,1),data(:,2),'LineWidth',1.5)
grid on
title('sorted points')
0 commentaires
Image Analyst
le 23 Déc 2022
Modifié(e) : Image Analyst
le 23 Déc 2022
Not sure how you define thickness but if it's the distance between the two points that are fartest away from each other, you can use pdist2 or bwferet
data = readmatrix('data.txt');
% FIGURE 1
figure
plot(data(:,1), data(:,2),'k*','Markersize',5)
hold on
plot(data(:,1), data(:,2),'-r','LineWidth',1)
hold off
grid off
xlabel('x')
ylabel('y')
% FIGURE 2
x = data(:,1);
y = data(:,2);
s = 1;
k = boundary(x,y,s);
figure
plot(x,y, 'k*', x(k), y(k), '-r')
grid off
xlabel('x')
ylabel('y')
% Get boundary points.
xb = x(k);
yb = y(k);
rows = max(y)
columns = max(x)
mask = poly2mask(xb, yb, rows, columns);
figure
imshow(mask)
axis('on', 'xy')
feretInfo = bwferet(mask)
% Use pdist2 to find out which points are farthest from each other.
distances = pdist2([xb, yb], [xb, yb]);
maxDistance = max(distances(:))
feretInfo =
1×3 table
MaxDiameter MaxAngle MaxCoordinates
________________ ________________ ______________
113.600176056202 170.371843871513 {2×2 double}
maxDistance =
113.282831885507
5 commentaires
Image Analyst
le 24 Déc 2022
You're going to need to sort your data in a clockwise manner instead of by x value. We talked about this in your prior question. Doesn't boundary do that for you?
Benjamin Kraus
le 23 Déc 2022
data = readmatrix('data.txt');
x = data(:,1);
y = data(:,2);
s = 1;
k = boundary(x,y,s);
plot(x,y, 'k*', x(k), y(k), '-r','LineWidth',3) % Specify Line Width here
grid off
xlabel('x')
ylabel('y')
2 commentaires
Benjamin Kraus
le 23 Déc 2022
data = readmatrix('data.txt');
x = data(:,1);
y = data(:,2);
s = 1;
k = boundary(x,y,s);
plot(x,y, 'k*', 'MarkerSize',5)
hold on
plot(x(k), y(k), '-r','LineWidth',3) % Specify Line Width here
grid off
xlabel('x')
ylabel('y')
Voir également
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!