When looking for the point X
that is closest to the point P
on the line (A
, V
), it is important to find the point where the line (X
, P
) is normal to the line (A
, B
).
For a line defined by two points A
and B
, a Unit vector D
that gives the direction of the line can be calculated as follows (Note that the length of a unit vector is 1):
D = normalize(B-A);
To use the following formula, a point O
on the line is required, such as O = A
.
Now, the closest point X
to the point P
on the line (O
, D
) needs to be determined.
First, calculate a vector V
from O
to P
:
V = P - O;
The distance d
from O
to the intersection point (closest point) X
can be calculated using the Dot product.
In general, the dot product of two vectors is equal to the cosine of the angle between the two vectors multiplied by the magnitude (length) of both vectors.
dot( A, B ) == | A | * | B | * cos( angle_A_B )
https://i.sstatic.net/IoXGA.png
Since D
is a unit vector, the dot product of V
and D
is equal to the cosine of the angle between the line (O
, D
) and the vector V
, multiplied by the magnitude (length) of V
:
d = dot(V, D);
The intersection point X
can be calculated by moving the point O
along the line (D
) by the distance d
:
X = O + D * d;
Therefore, the formula for the intersection point is:
O ... any point on the line
D ... unit vector pointing in the direction of the line
P ... the "Point"
X = O + D * dot(P-O, D);
https://i.sstatic.net/3s0V5.png
The calculation involving points on the line A
, B
, and the point P
is as follows:
D = normalize(B-A);
X = A + D * dot(P-A, D);
The dot
Product for 3-dimensional cartesian coordinates can be expressed as:
dot(A, B) = Ax*Bx + Ay*By + Az*Bz
A normalized
vector (unit vector) can be calculated by:
len(A) = sqrt(Ax*Ax + Ay*Ay + Az*Az)
normalize(A) = A / len(A)
In pure Javascript, this can be calculated as follows:
var P=[4,2,1];
var A=[1,0,1];
var B=[1,2,0];
var AB = [B[0]-A[0], B[1]-A[1], B[2]-A[2]];
var lenAB = Math.sqrt(AB[0]*AB[0] + AB[1]*AB[1] + AB[2]*AB[2]);
var D = [AB[0]/lenAB, AB[1]/lenAB, AB[2]/lenAB];
var AP = [P[0]-A[0], P[1]-A[1], P[2]-A[2]];
var d = D[0]*AP[0] + D[1]*AP[1] + D[2]*AP[2];
var X = [A[0] + d * D[0], A[1] + d * D[1], A[2] + d * D[2]];
This can also be achieved using Three.js - Vector3
, where vector arithmetic operations like add
, sub
, dot
, and normalize
are provided:
var P = new THREE.Vector3(4, 2, 1);
var A = new THREE.Vector3(1, 0, 1);
var B = new THREE.Vector3(1, 2, 0);
var D = B.clone().sub(A).normalize();
var d = P.clone().sub(A).dot(D);
var X = A.clone().add(D.clone().multiplyScalar(d));