Go around matrices/vectors columns

1 visualización (últimos 30 días)
LH
LH el 8 de Nov. de 2023
Comentada: LH el 10 de Nov. de 2023
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.

Respuesta aceptada

Voss
Voss el 8 de Nov. de 2023
Editada: Voss el 8 de Nov. de 2023
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 comentarios
Jon
Jon el 8 de Nov. de 2023
@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 el 10 de Nov. de 2023
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.

Iniciar sesión para comentar.

Más respuestas (0)

Categorías

Más información sobre Computational Geometry en Help Center y File Exchange.

Community Treasure Hunt

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

Start Hunting!

Translated by