0

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

Line's normal through point

SSteve
  • 10,550
  • 5
  • 46
  • 72

2 Answers2

1

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.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
1

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
MBo
  • 77,366
  • 5
  • 53
  • 86