# Perpendicular on a line from a given point

How can I draw a perpendicular on a line segment from a given point? My line segment is defined as (x1, y1), (x2, y2), If I draw a perpendicular from a point (x3,y3) and it meets to line on point (x4,y4). I want to find out this (x4,y4).

• Mar 3, 2013 at 15:55

I solved the equations for you:

``````k = ((y2-y1) * (x3-x1) - (x2-x1) * (y3-y1)) / ((y2-y1)^2 + (x2-x1)^2)
x4 = x3 - k * (y2-y1)
y4 = y3 + k * (x2-x1)
``````

Where ^2 means squared

• I hope I haven't made a mistake transferring these from paper to computer! Nov 28, 2009 at 5:08
• This is close but wrong. Check out the proof for this answer here: <br/> stackoverflow.com/questions/10301001/… Mar 3, 2013 at 20:09
• My brief tests agree with @jdbertron that this is incorrect. Sep 30, 2014 at 8:16
• @jbertron: the answer is correct, but make sure that when running this code you use longs or doubles as the type for all vars, as with large numbers the calculation can easily overflow and you get a wrong answer. Oct 17, 2014 at 13:50
• @RayHidayat: How can we do it, if the points are in 3D space, means, points are (x1,y1,z1),(x2,y2,z2),(x3,y3,z3),(x4,y4,z4). How can we find perpendicular lines end point (x4,y4,z4) to line between (x1,y1,z1) and (x2,y2,z2) and starts from (x3,y3,z3)? Sep 19, 2017 at 0:25

From wiki:

In algebra, for any linear equation y=mx + b, the perpendiculars will all have a slope of (-1/m), the opposite reciprocal of the original slope. It is helpful to memorize the slogan "to find the slope of the perpendicular line, flip the fraction and change the sign." Recall that any whole number a is itself over one, and can be written as (a/1)

To find the perpendicular of a given line which also passes through a particular point (x, y), solve the equation y = (-1/m)x + b, substituting in the known values of m, x, and y to solve for b.

The slope of the line, m, through (x1, y1) and (x2, y2) is m = (y1 - y2) / (x1 - x2)

I agree with peter.murray.rust, vectors make the solution clearer:

``````// first convert line to normalized unit vector
double dx = x2 - x1;
double dy = y2 - y1;
double mag = sqrt(dx*dx + dy*dy);
dx /= mag;
dy /= mag;

// translate the point and get the dot product
double lambda = (dx * (x3 - x1)) + (dy * (y3 - y1));
x4 = (dx * lambda) + x1;
y4 = (dy * lambda) + y1;
``````
• Works like charm! Feb 25, 2017 at 13:54
• Uses square roots. Bad. Jan 2, 2019 at 17:54
• I know the question was 9 years ago, and now I'm on the same boat. How do I computer (x3, y3) instead ? if I already know the line, perpendicular line and the intersection point ? Mar 3, 2019 at 23:32

You know both the point and the slope, so the equation for the new line is:

``````y-y3=m*(x-x3)
``````

Since the line is perpendicular, the slope is the negative reciprocal. You now have two equations and can solve for their intersection.

``````y-y3=-(1/m)*(x-x3)
y-y1=m*(x-x1)
``````
• I just know one line segment (x1,y1)(x2,y2) and a point (x3, y3). I need a way to find (x4,y4).
– Zinx
Nov 28, 2009 at 4:34
• So, find the slope between point 1 and point 2, and take the negative reciprocal. Remember that a line is `y=mx+b` -- `m` here is the slope you just found, b you can solve for using p3. You now have all that's needed for a line. Nov 28, 2009 at 4:49
• If you're using slope be sure to protect against x1=x2 and y1=y2 Aug 6, 2021 at 21:38

You will often find that using vectors makes the solution clearer...

Here is a routine from my own library:

``````public class Line2  {

Real2 from;
Real2 to;
Vector2 vector;
Vector2 unitVector = null;

public Real2 getNearestPointOnLine(Real2 point) {
unitVector = to.subtract(from).getUnitVector();
Vector2 lp = new Vector2(point.subtract(this.from));
double lambda = unitVector.dotProduct(lp);
Real2 vv = unitVector.multiplyBy(lambda);
return from.plus(vv);
}
``````

}

You will have to implement Real2 (a point) and Vector2 and dotProduct() but these should be simple:

The code then looks something like:

``````Point2 p1 = new Point2(x1, y1);
Point2 p2 = new Point2(x2, y2);
Point2 p3 = new Point2(x3, y3);
Line2 line = new Line2(p1, p2);
Point2 p4 = getNearestPointOnLine(p3);
``````

The library (org.xmlcml.euclid) is at: http://sourceforge.net/projects/cml/

and there are unit tests which will exercise this method and show you how to use it.

``````@Test
public final void testGetNearestPointOnLine() {
Real2 p = l1112.getNearestPointOnLine(new Real2(0., 0.));
Real2Test.assertEquals("point", new Real2(0.4, -0.2), p, 0.0000001);
}
``````
• Also computes unnecessary square roots in `getUnitVector()`. Also bad. Jan 2, 2019 at 17:55

Compute the slope of the line joining points (x1,y1) and (x2,y2) as `m=(y2-y1)/(x2-x1)`

Equation of the line joining (x1,y1) and (x2,y2) using point-slope form of line equation, would be `y-y2 = m(x-x2)`

Slope of the line joining (x3,y3) and (x4,y4) would be `-(1/m)`

Again, equation of the line joining (x3,y3) and (x4,y4) using point-slope form of line equation, would be `y-y3 = -(1/m)(x-x3)`

Solve these two line equations as you solve a linear equation in two variables and the values of x and y you get would be your (x4,y4)

I hope this helps.

cheers

Find out the slopes for both the lines, say slopes are m1 and m2 then m1*m2=-1 is the condition for perpendicularity.

• you don't know the equation of both lines, until you have worked out the intersection point. Nov 28, 2009 at 4:31
• taking the intersection point as x4,y4, we will have two linear equations in x4 and y4 and we can solve that easily. Nov 28, 2009 at 4:34

Matlab function code for the following problem

``````function Pr=getSpPoint(Line,Point)
% getSpPoint(): find Perpendicular on a line segment from a given point
x1=Line(1,1);
y1=Line(1,2);
x2=Line(2,1);
y2=Line(2,1);
x3=Point(1,1);
y3=Point(1,2);

px = x2-x1;
py = y2-y1;
dAB = px*px + py*py;

u = ((x3 - x1) * px + (y3 - y1) * py) / dAB;
x = x1 + u * px;
y = y1 + u * py;

Pr=[x,y];

end
``````
• I am unfamiliar with Matlab, is this a build-in function? Nov 26, 2016 at 14:27
• No this is not built-in function Nov 28, 2016 at 6:58

Mathematica introduced the function `RegionNearest[]` in version 10, 2014. This function could be used to return an answer to this question:

``````{x4,y4} = RegionNearest[Line[{{x1,y1},{x2,y2}}],{x3,y3}]
``````

This is mostly a duplicate of Arnkrishn's answer. I just wanted to complete his section with a complete Mathematica code snippet:

``````m = (y2 - y1)/(x2 - x1)
eqn1 = y - y3 == -(1/m)*(x - x3)
eqn2 = y - y1 == m*(x - x1)
Solve[eqn1 && eqn2, {x, y}]
``````

This is a C# implementation of the accepted answer. It's also using ArcGis to return a MapPoint as that's what we're using for this project.

``````        private MapPoint GenerateLinePoint(double startPointX, double startPointY, double endPointX, double endPointY, double pointX, double pointY)
{
double k = ((endPointY - startPointY) * (pointX - startPointX) - (endPointX - startPointX) * (pointY - startPointY)) / (Math.Pow(endPointY - startPointY, 2)
+ Math.Pow(endPointX - startPointX, 2));
double resultX = pointX - k * (endPointY - startPointY);
double resultY = pointY + k * (endPointX - startPointX);

return new MapPoint(resultX, resultY, 0, SpatialReferences.Wgs84);
}
``````

Thanks to Ray as this worked perfectly for me.

Just for the sake of completeness, here is a solution using homogeneous coordinates.

1. The homogeneous points are:

p1 = (x1,y1,1), p2 = (x2,y2,1), p3 = (x3,y3,1)

2. a line through two points is their cross-product

l_12 := p1 x p2 = (y1-y2, x2-x1, x1*y2 - x2*y1)

3. The (signed) distance of a point to a line is their dot product.

d := l_12 * p3 = x3*(y1-y2) + y3*(x2-x1) + x1*y2 - x2*y1

4. The vector from p4 to p3 is d times the normal vector of l_12 divided by the squared length of the normal vector.

n2 := (y1-y2)^2 + (x2-x1)^2

p4 := p3 + d/n2*(y1-y2, x2-x1, 0)

Note: if you divide l_12 by the length of the normal vector

l_12 := l_12 / sqrt((y1-y2)^2 + (x2-x1)^2)

the distance d will be the euclidean distance.

First, calculate the linear function determined by the points `(x1,y2),(x2,y2)`.

We get:

``````y1 = mx+b1 where m and b1 are constants.
``````

This step is easy to calculate by the formula of linear function between two points.

Then, calculate the linear function y that goes through (x3,y3).

The function slope is -m, where m is the slope of y1.

Then calculate the const b2 by the coordinates of the point (x3,y3).

We get y2 = -mx+b2 where m and b2 are constants.

The last thing to do is to find the intersection of y1, y2. You can find x by solving the equation: `-mx+b2 = mx+b1`, then place x in one of the equations to find y.

This is a vectorized Matlab function for finding pairwise projections of `m` points onto `n` line segments. Here `xp` and `yp` are `m by 1` vectors holding coordinates of `m` different points, and `x1`, `y1`, `x2` and `y2` are `n by 1` vectors holding coordinates of start and end points of `n` different line segments. It returns `m by n` matrices, `x` and `y`, where `x(i, j)` and `y(i, j)` are coordinates of projection of `i`-th point onto `j`-th line.

The actual work is done in first few lines and the rest of the function runs a self-test demo, just in case where it is called with no parameters. It's relatively fast, I managed to find projections of 2k points onto 2k line segments in less than 0.05s.

``````function [x, y] = projectPointLine(xp, yp, x1, y1, x2, y2)
if nargin > 0
xd = (x2-x1)';
yd = (y2-y1)';
dAB = xd.*xd + yd.*yd;
u = bsxfun(@rdivide, bsxfun(@times, bsxfun(@minus, xp, x1'), xd) + ...
bsxfun(@times, bsxfun(@minus, yp, y1'), yd), dAB);
x = bsxfun(@plus, x1', bsxfun(@times, u, xd));
y = bsxfun(@plus, y1', bsxfun(@times, u, yd));
else
nLine = 3;
nPoint = 2;
xp = rand(nPoint, 1) * 2 -1;
yp = rand(nPoint, 1) * 2 -1;
x1 = rand(nLine, 1) * 2 -1;
y1 = rand(nLine, 1) * 2 -1;
x2 = rand(nLine, 1) * 2 -1;
y2 = rand(nLine, 1) * 2 -1;
tic;
[x, y] = projectPointLine(xp, yp, x1, y1, x2, y2);
toc
close all;
plot([x1'; x2'], [y1'; y2'], '.-', 'linewidth', 2, 'markersize', 20);
axis equal;
hold on
C = lines(nPoint + nLine);
for i=1:nPoint
scatter(x(i, :), y(i, :), 100, C(i+nLine, :), 'x', 'linewidth', 2);
scatter(xp(i), yp(i), 100, C(i+nLine, :), 'x', 'linewidth', 2);
end
for i=1:nLine
scatter(x(:, i)', y(:, i)', 100, C(i, :), 'o', 'linewidth', 2);
end
end
end
``````
{"found_math": false, "script_math_tex": 0, "script_math_asciimath": 0, "math_annotations": 0, "math_alttext": 0, "mathml": 0, "mathjax_tag": 0, "mathjax_inline_tex": 0, "mathjax_display_tex": 0, "mathjax_asciimath": 0, "img_math": 0, "codecogs_latex": 0, "wp_latex": 0, "mimetex.cgi": 0, "/images/math/codecogs": 0, "mathtex.cgi": 0, "katex": 0, "math-container": 0, "wp-katex-eq": 0, "align": 0, "equation": 0, "x-ck12": 0, "texerror": 0}