Perpendicular on a line from a given point

54,775

Solution 1

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

Solution 2

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)

Solution 3

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;

Solution 4

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)

Solution 5

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);
}
Share:
54,775
Zinx
Author by

Zinx

Updated on November 18, 2020

Comments

  • Zinx
    Zinx over 3 years

    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).

  • Mitch Wheat
    Mitch Wheat over 14 years
    you don't know the equation of both lines, until you have worked out the intersection point.
  • Zinx
    Zinx over 14 years
    I just know one line segment (x1,y1)(x2,y2) and a point (x3, y3). I need a way to find (x4,y4).
  • Prasoon Saurav
    Prasoon Saurav over 14 years
    taking the intersection point as x4,y4, we will have two linear equations in x4 and y4 and we can solve that easily.
  • Thanatos
    Thanatos over 14 years
    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.
  • Ray Hidayat
    Ray Hidayat over 14 years
    I hope I haven't made a mistake transferring these from paper to computer!
  • jdbertron
    jdbertron over 11 years
    This is close but wrong. Check out the proof for this answer here: <br/> stackoverflow.com/questions/10301001/…
  • ThomasW
    ThomasW over 9 years
    My brief tests agree with @jdbertron that this is incorrect.
  • Tom De Leu
    Tom De Leu over 9 years
    @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.
  • oddRaven
    oddRaven over 7 years
    I am unfamiliar with Matlab, is this a build-in function?
  • Rajnikant Sharma
    Rajnikant Sharma over 7 years
    No this is not built-in function
  • Amjay
    Amjay over 7 years
    Works like charm!
  • manoos
    manoos almost 7 years
    @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)?
  • Andrey Tyukin
    Andrey Tyukin over 5 years
    Uses square roots. Bad.
  • Andrey Tyukin
    Andrey Tyukin over 5 years
    Also computes unnecessary square roots in getUnitVector(). Also bad.
  • raisa_
    raisa_ over 5 years
    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 ?
  • Davidos
    Davidos about 3 years
    Could you provide explanation how did you calculated it?
  • Joel Teply
    Joel Teply almost 3 years
    If you're using slope be sure to protect against x1=x2 and y1=y2