connect nodes (coordinates of a matrix rx3) with a line

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')

1 comentario

I have thought of something like this but at the moment it does not bring the desired result:
data = readmatrix('data.txt');
count_rows = height(data);
for i = 1:2:count_rows
odd_row = data(i,:);
for j = 2:2:count_rows
row_even = data(j,:);
line(odd_row, row_even)
end
end

Iniciar sesión para comentar.

 Respuesta aceptada

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 comentarios

Thank you for your response @Voss. In the case where I have two similar curves (see example.m) I don't understand why the line joining the final coordinate with the initial one is not created. I thank you if you can take a look at the code.
Voss
Voss el 26 de Dic. de 2022
Editada: Voss el 26 de Dic. de 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.

Iniciar sesión para comentar.

Más respuestas (3)

Karim
Karim el 24 de Dic. de 2022
Editada: Karim el 24 de Dic. de 2022
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')
Image Analyst
Image Analyst el 23 de Dic. de 2022
Editada: Image Analyst el 23 de Dic. de 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 comentarios

Thank you for your reply. I don't understand your solution. I needed to connect the coordinates present in "data.txt" via a line.
data = readmatrix('data.txt');
figure
plot(data(:,1), data(:,2),'k*','Markersize',5)
axis equal
grid off
xlabel('x')
ylabel('y')
By line thickness I am referring to the use of "LineWidth".
Image Analyst
Image Analyst el 24 de Dic. de 2022
Editada: Image Analyst el 24 de Dic. de 2022
I know you think you need to do that to measure the thickness or width of the shape but I don't think you do need to do that. I was able to make the thickness measurement of the shape without connecting any boundary points with a line. Why do you think it's necessary?
Read my question which I edited. I hope it is clearer than the previous one.
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?
No, the boundary function does not do that for me.

Iniciar sesión para comentar.

You can specify the LineWidth when you call the plot command.
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 comentarios

If you want a different line width for the line versus the markers, you need to use hold like this:
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')
Read my question which I edited. I hope it is clearer than the previous one.

Iniciar sesión para comentar.

Categorías

Productos

Versión

R2021b

Preguntada:

el 23 de Dic. de 2022

Editada:

el 26 de Dic. de 2022

Community Treasure Hunt

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

Start Hunting!

Translated by