线(A、V)上与点P最近的点X是该点,线(X、P)与线(@)垂直987654334@, B)。
如果一条线由两个点A 和B 定义,那么给出线方向的Unit vector D 可以计算如下(注意单位向量的长度为1) :
D = normalize(B-A);
对于以下公式,需要在线上的点 O,例如O = A.
现在必须找到最接近直线上的点P(O、D)的点X。
首先计算一个从O到P的向量V:
V = P - O;
d从O到交点(最近点)X的距离可以通过Dot product来计算。
一般来说,2个向量的点积等于2个向量夹角的余弦乘以两个向量的大小(长度)。
dot( A, B ) == | A | * | B | * cos( angle_A_B )
由于D是单位向量,所以V和D的点积等于直线(O、D)与向量V之间夹角的余弦值相乘按V的数量(长度):
d = dot(V, D);
交点X,可以通过将点O沿线(D)移动距离d来计算:
X = O + D * d;
所以交点的公式是:
O ... any point on the line
D ... unit vector which points in the direction of the line
P ... the "Point"
X = O + D * dot(P-O, D);
A、B和P线上的点计算为:
D = normalize(B-A);
X = A + D * dot(P-A, D);
3维笛卡尔坐标的dot积可以表示为:
dot(A, B) = Ax*Bx + Ay*By + Az*Bz
一个normalized向量(单位向量)可以这样计算:
len(A) = sqrt(Ax*Ax + Ay*Ay + Az*Az)
notrmalize(A) = A / len(A)
在纯 Javascript 中,可以这样计算:
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]];
Three.js - Vector3 很容易做到这一点,其中定义了 add、sub、dot 和 normalize 等向量算术运算:
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 ) );