Perpendicular on a line segment from a given point

I want to calculate a point on a given line that is perpendicular from a given point.

I have a line segment AB and have a point C outside line segment. I want to calculate a point D on AB such that CD is perpendicular to AB.

Find point D

I have to find point D.

It quite similar to this, but I want to consider to Z coordinate also as it does not show up correctly in 3D space.


Solution 1:

Proof: Point D is on a line CD perpendicular to AB, and of course D belongs to AB. Write down the Dot product of the two vectors CD.AB = 0, and express the fact D belongs to AB as D=A+t(B-A).

We end up with 3 equations:

 Dx=Ax+t(Bx-Ax)
 Dy=Ay+t(By-Ay)
(Dx-Cx)(Bx-Ax)+(Dy-Cy)(By-Ay)=0

Subtitute the first two equations in the third one gives:

(Ax+t(Bx-Ax)-Cx)(Bx-Ax)+(Ay+t(By-Ay)-Cy)(By-Ay)=0

Distributing to solve for t gives:

(Ax-Cx)(Bx-Ax)+t(Bx-Ax)(Bx-Ax)+(Ay-Cy)(By-Ay)+t(By-Ay)(By-Ay)=0

which gives:

t= -[(Ax-Cx)(Bx-Ax)+(Ay-Cy)(By-Ay)]/[(Bx-Ax)^2+(By-Ay)^2]

getting rid of the negative signs:

t=[(Cx-Ax)(Bx-Ax)+(Cy-Ay)(By-Ay)]/[(Bx-Ax)^2+(By-Ay)^2]

Once you have t, you can figure out the coordinates for D from the first two equations.

 Dx=Ax+t(Bx-Ax)
 Dy=Ay+t(By-Ay)

Solution 2:

function getSpPoint(A,B,C){
    var x1=A.x, y1=A.y, x2=B.x, y2=B.y, x3=C.x, y3=C.y;
    var px = x2-x1, py = y2-y1, dAB = px*px + py*py;
    var u = ((x3 - x1) * px + (y3 - y1) * py) / dAB;
    var x = x1 + u * px, y = y1 + u * py;
    return {x:x, y:y}; //this is D
}

question

Solution 3:

There is a simple closed form solution for this (requiring no loops or approximations) using the vector dot product.

Imagine your points as vectors where point A is at the origin (0,0) and all other points are referenced from it (you can easily transform your points to this reference frame by subtracting point A from every point).

In this reference frame point D is simply the vector projection of point C on the vector B which is expressed as:

// Per wikipedia this is more efficient than the standard (A . Bhat) * Bhat
Vector projection = Vector.DotProduct(A, B) / Vector.DotProduct(B, B) * B

The result vector can be transformed back to the original coordinate system by adding point A to it.

Solution 4:

A point on line AB can be parametrized by:

M(x)=A+x*(B-A), for x real.

You want D=M(x) such that DC and AB are orthogonal:

dot(B-A,C-M(x))=0.

That is: dot(B-A,C-A-x*(B-A))=0, or dot(B-A,C-A)=x*dot(B-A,B-A), giving:

x=dot(B-A,C-A)/dot(B-A,B-A) which is defined unless A=B.

Solution 5:

What you are trying to do is called vector projection