How to find the coordinates of a point perpendicular to a line (knowing the distance)?

54 views (last 30 days)
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?

Accepted Answer

Adam Danz
Adam Danz on 9 Oct 2019
Edited: Adam Danz on 9 Oct 2019
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 Comments
Eugenio Alcala
Eugenio Alcala on 20 May 2021
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.

Sign in to comment.

More Answers (0)

Products

Community Treasure Hunt

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

Start Hunting!