Given the line segment AB, how do I find the point Pn where the normal to AB passes through the point P? I also need to know if there is no normal that passes through the point (e.g. the point Q).
2 Answers
If R
is any point on the normal line passing through P
(different from P
), then Pn
is the point where AB
and PR
intersect.
One way to generate point R
is to rotate segment AB
by 90 degrees and then translate it so that A
coincides with P
. The the translated B
is your R
:
Rx = Px + (By - Ay)
Ry = Py - (Bx - Ax)
Once you have your point R
, it becomes a simple line-line intersection problem, which will give you your Pn
(the formulas can be simplified for a specific case of perpendicular lines).
Then you can easily check whether Pn
lies between A
and B
or not.
P.S. Note that solution provided in @MBo's answer is a more direct and efficient one (and if you combine and simplify/optimize the formulas required for my answer you will eventually arrive at the same thing). What I describe above might make good sense if you already have a primitive function that calculates the intersection of two lines, say,
find_intersection(Ax, Ay, Bx, By, Cx, Cy, Dx, Dy)
// Intersect AB and CD
In that case finding Pn
becomes a simple one-liner
Pn = find_intersection(Ax, Ay, Bx, By, Px, Py, Px + (By - Ay), Py - (Bx - Ax))
But if you don't have such primitive function at your disposal and/or care for making your code more efficient, then you might want to opt for a more direct dedicated sequence of calculations like the one in @MBo's answer.

- 312,472
- 42
- 525
- 765
Find vectors
AB = (B.X-A.X, B.Y-A.Y)
AP = (P.X-A.X, P.Y-A.Y)
Projection of P to AB is:
APn = AB * (AB.dot.AP) / (AB.dot.AB);
where .dot. is scalar product
In coordinates:
cf = ((B.X-A.X)*(P.X-A.X)+(B.Y-A.Y)*(P.Y-A.Y))/((B.X-A.X)^2+(B.Y-A.Y)^2)
if cf < 0 or cf > 1 then projection lies outside AB segment
Pn.X = A.X + (B.X-A.X) * cf
Pn.Y = A.Y + (B.Y-A.Y) * cf

- 77,366
- 5
- 53
- 86