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

조회 수: 3 (최근 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