How to find the coordinates of a point perpendicular to a line (knowing the distance)?
66 次查看(过去 30 天)
显示 更早的评论
I have a line made of two points A(xA,yA) and B(xB,yB) and I know a point C(xC,yC) belonging to this line (somewhere between A and B).
I want to find the coordinates of point D(xD,yD), knowing that the (CD) is perpendicular to (AB) and knowing also that the part CD is equal to a number (eg 3)
Are you aware of a function already doing it?
0 个评论
采纳的回答
Adam Danz
2019-10-9
编辑:Adam Danz
2019-10-9
Here's a tutorial with comments so you can follow what's going on. The end points of the perpendicular segment ("D" in your photo) are stored in variables x and y. See note at the end of this answer regarding vertical and horizontal lines.
Set the coordinates for points A and B at the top of the code. Then set the 1/2 length of the perpendicular line.
% Enter coordinates of points A and B and
% the 1/2 length of the perpendicular segment
A = [3 3]; %[x,y]
B = [12,8]; %[x,y]
Clen = 3; %length of line CD (1/2 of the full perpendicular line)
%% Do the math
% Get slope and y int of line AB
slope = (B(2)-A(2)) / (B(1)-A(1));
yint = B(2) - slope*B(1);
% Choose a point C along line AB at half distance
C(1) = range([B(1),A(1)])/2+min([A(1),B(1)]);
C(2) = slope * C*(1) + yint;
% Get slope and y int of line perpendicular to AB at point C
perpSlope = -1/slope;
perpYint = C(2) - perpSlope*C(1);
% Find the end points of the perpendicular line with length Clen*2
x = C(1) + (Clen*sqrt(1/(1+perpSlope^2)))*[-1,1];
y = C(2) + (perpSlope*Clen*sqrt(1/(1+perpSlope^2)))*[-1,1];
%% Plot results
figure()
% Draw line AB
p1 = plot([A(1),B(1)], [A(2),B(2)], 'k-o','LineWidth',2,'DisplayName','AB');
hold on
axis equal
grid on
axlim = xlim(gca)+[-1,1]*range(xlim(gca))*1.1;
xlim(axlim)
ylim(axlim)
% Draw a references line parallel to AB
rl = refline(slope,yint);
set(rl, 'LineStyle', '--', 'Color', [.5 .5 .5])
% Draw a references line perpendicular to AB at point C
rl = refline(perpSlope,perpYint);
set(rl, 'LineStyle', '--', 'Color', [.5 .5 .5])
xlim(axlim) %refline() changes limits so we set them again :(
ylim(axlim)
% Add point C
p2 = plot(C(1),C(2), 'r*','DisplayName','C');
% Add the perp segment
p3 = plot(x,y,'b-o','LineWidth',2,'DisplayName','perp AB');
legend([p1,p2,p3])
Note that if line AB is perfectly horizontal, you'll run into +|- inf issues with the perpendicular slope. If AB is perfectly vertical, my calculation of C will fail (it will return a NaN due to the inf slope of AB) but you mentioned that you already have C so that shouldn't be an issue.
8 个评论
Eugenio Alcala
2021-5-20
I think a more reliable answer to this problem is to use the rotation matrix concept.
So, assuming a set of points in a matrix where the first and second columns are X and Y, respectively, we can compute the angle of those points such as:
X1 = points(1,1);
X2 = points(2,1);
Y1 = points(1,2);
Y2 = points(2,2);
angle = atan2( (Y2-Y1), (X2-X1) );
From here we can compute the rotation matrix:
R = [cos(angle) -sin(angle);
sin(angle) cos(angle) ];
And the new othogonal point that we are looking for at a distance "dist" to the left is:
XYnew = [X2; Y2] + R * [0; dist];
If we want another point to the right just recompute the line above with dist negative.
In a for loop it would look like the following:
for i=1:100
X1 = points(i,1);
X2 = points(i+1,1);
Y1 = points(i,2);
Y2 = points(i+1,2);
angle(i) = atan2( (Y2-Y1), (X2-X1) );
R = [cos(angle(i)) -sin(angle(i));
sin(angle(i)) cos(angle(i))];
XYnew = [X2; Y2] + R * [0;dist];
x(i) = XYnew(1);
y(i) = XYnew(2);
end
This method avoids the issues when changing the quadrant avoiding then getting infinite value slopes.
更多回答(0 个)
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Array Geometries and Analysis 的更多信息
产品
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!