Go around matrices/vectors columns

조회 수: 1 (최근 30일)
LH
LH 2023년 11월 8일
댓글: LH 2023년 11월 10일
Hi all,
If I have a point on one of a pentagon edges, say , and I want to calculate the vectors coorindates between this point and each vertex of the polygon, i.e., , except the neighbouring ones as shown below:
In this case, I should have three vectors that correspond to three vertices. My question is, how to construct these vectors by looping over the vertices coordinates columns? If I'm in the first edge, then I need the second, third and fourth column of the vertices coordinates. What if the point is in the third edge? This time, I need to take the fourth, fifth, and first cooridnates. Also, what if I have a hexagon instead? I'd like to have a generalisable code that goes through the next vertices coordinates (n here is then umber of the polygon sides) no matter where the point is in the polygon.
Here is my attempt:
%polygon vertices coordinates
Cox = [0.4540 0.9877 0.1564 -0.8910 -0.7071] ;
Coy = [-0.8910 0.1564 0.9877 0.4540 -0.7071] ;
%point coodinates
x0 = -0.4649;
y0 = -0.7455;
%the first vector
vecx1 = Cox(2) - x0;
vecy1 = Coy(2) - y0;
vec1 = [vecx1 ; vecy1]
%the second vector
vecx2 = Cox(3) - x0;
vecy2 = Coy(3) - y0;
vec2 = [vecx2 ; vecy2]
%the third vector
vecx3 = Cox(4) - x0;
vecy3 = Coy(4) - y0;
vec3 = [vecx3 ; vecy3]
Any help would be appreicted.

채택된 답변

Voss
Voss 2023년 11월 8일
편집: Voss 2023년 11월 8일
Here's one way, which is generalized in that it will work for other polygons besides pentagon, but it assumes the vertices are given in counter-clockwise order, as yours are.
%polygon vertices coordinates
Cox = [0.4540 0.9877 0.1564 -0.8910 -0.7071] ;
Coy = [-0.8910 0.1564 0.9877 0.4540 -0.7071] ;
% number of edges (and vertices):
Nedges = numel(Cox);
%point coodinates
x0 = -0.4649;
y0 = -0.7455;
% plot:
plot(Cox([1:end 1]),Coy([1:end 1]))
hold on
plot(x0,y0,'o')
% label vertices:
text(Cox,Coy,"V"+string(1:Nedges),'BackgroundColor','w','HorizontalAlignment','center')
% calculate edge centers, and label edges:
xm = (Cox+Cox([2:end 1]))/2;
ym = (Coy+Coy([2:end 1]))/2;
text(xm,ym,"E"+string(1:Nedges),'BackgroundColor','w','HorizontalAlignment','center')
% this is just to get the figure to show up here; you don't need this line:
copyobj(gca(),figure())
% define which vertex starts and ends each edge:
start_idx = 1:Nedges;
end_idx = mod(start_idx,Nedges)+1;
% calculate the distance from the point to each edge, along a line
% perpendicular to the edge (this will tell us which edge is closest to the
% point):
d = zeros(1,Nedges);
for ii = 1:Nedges
P1 = [Cox(start_idx(ii)),Coy(start_idx(ii))];
P2 = [Cox(end_idx(ii)),Coy(end_idx(ii))];
d(ii) = distanceFromPointToLine(P1,P2,[x0,y0]);
end
% the closest edge is the one with miniumum distance to the point:
[~,on_edge] = min(d)
on_edge = 5
% the vertices the point is between are the start and end points of the
% closest edge:
between_vertices = [start_idx(on_edge) end_idx(on_edge)]
between_vertices = 1×2
5 1
% the "other" vertices:
idx = 1:Nedges;
idx(between_vertices) = []
idx = 1×3
2 3 4
% calculate the vector from the point to each "other" vertex:
v = [Cox(idx)-x0; Coy(idx)-y0] % [vec1, vec2, vec3] all together
v = 2×3
1.4526 0.6213 -0.4261 0.9019 1.7332 1.1995
% plot:
v_z = zeros(1,Nedges-2);
v_n = NaN(1,Nedges-2);
x_plot = reshape(x0+[v_z; v(1,:); v_n],[],1);
y_plot = reshape(y0+[v_z; v(2,:); v_n],[],1);
plot(x_plot,y_plot)
If your points are not given in counter-clockwise order (i.e., they are clockwise or are unordered), then you can sort them by angle first, something along these lines:
xy = [Cox(:) Coy(:)];
xy = xy(randperm(Nedges),:) % random order, for demonstration
xy = 5×2
0.9877 0.1564 -0.8910 0.4540 0.1564 0.9877 -0.7071 -0.7071 0.4540 -0.8910
xy_c = mean(xy,1);
th = atan2(xy(:,2)-xy_c(:,2),xy(:,1)-xy_c(:,1));
th(th<0) = th(th<0)+2*pi;
[~,idx] = sort(th);
xy_sorted = xy(idx,:) % counter-clockwise order
xy_sorted = 5×2
0.9877 0.1564 0.1564 0.9877 -0.8910 0.4540 -0.7071 -0.7071 0.4540 -0.8910
function Dist = distanceFromPointToLine(P1, P2, Q)
% Is point Q=[x3,y3] on line through P1=[x1,y1] and P2=[x2,y2]
% Normal along the line:
P12 = P2 - P1;
L12 = sqrt(P12 * P12');
N = P12 / L12;
% Line from P1 to Q:
PQ = Q - P1;
% Norm of distance vector: LPQ = N x PQ
Dist = abs(N(1) * PQ(2) - N(2) * PQ(1));
end
The distanceFromPointToLine function is adapted from this answer:
  댓글 수: 4
Jon
Jon 2023년 11월 8일
@Lama Hamadeh Interesting problem you posed. Glad you got such a great approach from @Voss
Just for future reference, it would be good to try to come up with a more descriptive titles for your questions. "Go around matrice/vectors", doesn't suggest anything about plotting lines connecting points on edges of a polygon to its vertices.
Having better titles increases the chance that you attract the attention of someone who has some specific interest/skills related to your problem. Also, for people who have similar problems in the future, having a good title will make it easier for them to find that there is already a solution.
LH
LH 2023년 11월 10일
Thank you both @Jon and @Voss for your help in this problem.
@Jon THe reason I chose this title is becasue I was focused on how to deal with the vector elements of the coodinators and how to loop over them. But I do agree that the titel could be better formulated.
Thanks again.

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Computational Geometry에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by