19
\$\begingroup\$

Let's say I have a line defined by two points, A and B, both in the form (x, y, z). These points represent a line in 3D space.

I also have a point P, defined in the same format, that isn't on the line.

How would I calculate the projection of that point on to the line? I'm aware of how to do this in 2D but 3D seems to have bugger all resources on it.

\$\endgroup\$
29
\$\begingroup\$

You simply need to project vector AP onto vector AB, then add the resulting vector to point A.

Here is one way to compute it:

A + dot(AP,AB) / dot(AB,AB) * AB

This formula will work in 2D and in 3D. In fact it works in all dimensions.

\$\endgroup\$
  • \$\begingroup\$ thank you mr Sam - how did you derive the above formula? \$\endgroup\$ – BKSpurgeon May 4 '17 at 5:31
  • 2
    \$\begingroup\$ I did not derive it, it is a well known formula you can find in many handbooks. \$\endgroup\$ – sam hocevar May 4 '17 at 12:13
  • \$\begingroup\$ Is there a sample on how to write that in a programming language like C++? \$\endgroup\$ – Vinicius de Melo Rocha Jul 5 at 14:47
  • 1
    \$\begingroup\$ @ViniciusdeMeloRocha dot would be a.x*b.x+a.y*b.y+a.z*b.z ... everything else is as straightforward as per-coordinate operation between vectors. \$\endgroup\$ – Ocelot Aug 12 at 1:26
4
\$\begingroup\$

Here's a fast and easy way to do it in python:

from numpy import *
def ClosestPointOnLine(a, b, p):
    ap = p-a
    ab = b-a
    result = a + dot(ap,ab)/dot(ab,ab) * ab
    return result

Use floats; If your vectors contain integers the division will be an integer division, and the results will be incorrect.

\$\endgroup\$
  • 1
    \$\begingroup\$ /dot(ab,ab) is redundant \$\endgroup\$ – Waldo Bronchart Jul 4 '17 at 23:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.