13

I have a 3d point P and a line segment defined by A and B (A is the start point of the line segment, B the end).

I want to calculate the shortest distance between P and the line AB.

Calculating the distance of a point to an infinite line was easy as their was a solution on Wolfram Mathworld, and I have implemented that, but I need to do this for a line of finite length.

I have not managed to find a reliable solution for this in 3d after a lot of looking around.

I have implemented algorithms to calculate the dot product, cross product, magnitude and so on in C++ with a struct that contains floats x, y and z.

Pseudo code, links, or code in pretty much any language for this would be great.

oggmonster
  • 4,672
  • 10
  • 51
  • 73
  • Here you have a solution in Mathematica for 3D (or 2D) http://stackoverflow.com/questions/849211/shortest-distance-between-a-point-and-a-line-segment/4165840#4165840 – Dr. belisarius Feb 01 '11 at 02:26
  • [softSurfer](http://www.softsurfer.com/index.html) has a nice tutorial showing how to [compute the distance from a point to a line, ray, or segment in 2D and 3D](http://www.softsurfer.com/Archive/algorithm_0102/algorithm_0102.htm). – Reed Copsey Feb 01 '11 at 02:24

3 Answers3

12

Java function

/**
 * Calculates the euclidean distance from a point to a line segment.
 *
 * @param v     the point
 * @param a     start of line segment
 * @param b     end of line segment 
 * @return      distance from v to line segment [a,b]
 *
 * @author      Afonso Santos
 */
 public static
 double
 distanceToSegment( final R3 v, final R3 a, final R3 b )
 {
   final R3 ab  = b.sub( a ) ;
   final R3 av  = v.sub( a ) ;

   if (av.dot(ab) <= 0.0)           // Point is lagging behind start of the segment, so perpendicular distance is not viable.
     return av.modulus( ) ;         // Use distance to start of segment instead.

   final R3 bv  = v.sub( b ) ;

   if (bv.dot(ab) >= 0.0)           // Point is advanced past the end of the segment, so perpendicular distance is not viable.
     return bv.modulus( ) ;         // Use distance to end of the segment instead.

   return (ab.cross( av )).modulus() / ab.modulus() ;       // Perpendicular distance of point to segment.
}

gist of the whole (self contained) R3 3D algebra package: https://gist.github.com/reciprocum/4e3599a9563ec83ba2a63f5a6cdd39eb

part of the open source library https://sourceforge.net/projects/geokarambola/

AlexSp3
  • 2,201
  • 2
  • 7
  • 24
Afonso Santos
  • 179
  • 1
  • 4
6

This is fairly straight forward. First, treat your line segment as if it were an infinite and find the point R on the line where a perpendicular ray off the line at R passes through your point P. If R is between A and B on the line, then the shortest distance is PR. Otherwise, shorestest distance is lessor of PA and PB.

ThomasMcLeod
  • 7,603
  • 4
  • 42
  • 80
0

I know, that question is little old, but to help others:

Here you have link to pseudo code (look under Distance of a Point to a Ray or Segment):

Pseudo code and C++ implementation

Links to multiple language implementations (Look under Contributed implementations):

C, VBA, Java and other implementations

elrado
  • 4,960
  • 1
  • 17
  • 15