Go around matrices/vectors columns
1 Ansicht (letzte 30 Tage)
Ältere Kommentare anzeigen
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.
0 Kommentare
Akzeptierte Antwort
Voss
am 8 Nov. 2023
Bearbeitet: Voss
am 8 Nov. 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)
% 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)]
% the "other" vertices:
idx = 1:Nedges;
idx(between_vertices) = []
% calculate the vector from the point to each "other" vertex:
v = [Cox(idx)-x0; Coy(idx)-y0] % [vec1, vec2, vec3] all together
% 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_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
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 Kommentare
Jon
am 8 Nov. 2023
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.
Weitere Antworten (0)
Siehe auch
Kategorien
Mehr zu Computational Geometry finden Sie in Help Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!