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

5 ビュー (過去 30 日間)
Alberto Acri
Alberto Acri 2022 年 12 月 23 日
編集済み: Voss 2022 年 12 月 26 日
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 件のコメント
Alberto Acri
Alberto Acri 2022 年 12 月 24 日
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

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

採用された回答

Voss
Voss 2022 年 12 月 24 日
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 件のコメント
Alberto Acri
Alberto Acri 2022 年 12 月 26 日
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 2022 年 12 月 26 日
編集済み: Voss 2022 年 12 月 26 日
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.

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

その他の回答 (3 件)

Karim
Karim 2022 年 12 月 24 日
編集済み: Karim 2022 年 12 月 24 日
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 2022 年 12 月 23 日
編集済み: Image Analyst 2022 年 12 月 23 日
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 件のコメント
Image Analyst
Image Analyst 2022 年 12 月 24 日
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?
Alberto Acri
Alberto Acri 2022 年 12 月 24 日
No, the boundary function does not do that for me.

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


Benjamin Kraus
Benjamin Kraus 2022 年 12 月 23 日
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 件のコメント
Benjamin Kraus
Benjamin Kraus 2022 年 12 月 23 日
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')
Alberto Acri
Alberto Acri 2022 年 12 月 24 日
Read my question which I edited. I hope it is clearer than the previous one.

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

製品


リリース

R2021b

Community Treasure Hunt

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

Start Hunting!

Translated by