joh*_*per 3 javascript 3d geometry three.js
我正在寻找一个 javascript 3D 公式来获取从点到线的距离。公式也可以是另一种编程语言。P是一个点,A&B是直线上的点。
P=(4,2,1);
A=(1,0,1);
B=(1,2,0);
Run Code Online (Sandbox Code Playgroud)
的最近点X至点P就行(A,V)是点,其中,所述线(X,P)是垂直于线(A,B)。
如果一条直线由两个点A和定义B,那么给出直线方向的单位向量 D可以计算如下(注意单位向量的长度为 1):
D = normalize(B-A);
Run Code Online (Sandbox Code Playgroud)
对于以下公式,O需要在线上的一个点,例如O = A。
现在必须找到与直线 ( , )上X的点最近的点。POD
首先计算V从O到的向量P:
V = P - O;
Run Code Online (Sandbox Code Playgroud)
的距离d从O到交叉点(最近点)X可以通过计算标量积。
一般来说,2个向量的点积等于2个向量之间夹角的余弦乘以两个向量的幅度(长度)。
dot( A, B ) == | A | * | B | * cos( angle_A_B )
Run Code Online (Sandbox Code Playgroud)
由于D是一个单位矢量,的点积V和D等于所述线之间的角度的余弦(O,D)和向量V,乘以的量(长度)V:
d = dot(V, D);
Run Code Online (Sandbox Code Playgroud)
交点X,可以通过将点O沿线 ( D) 移动距离来计算d:
X = O + D * d;
Run Code Online (Sandbox Code Playgroud)
所以交点的公式是:
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);
Run Code Online (Sandbox Code Playgroud)
就行了计算由点A,B并且点P是:
D = normalize(B-A);
X = A + D * dot(P-A, D);
Run Code Online (Sandbox Code Playgroud)
dot3 维笛卡尔坐标的乘积可以表示为:
dot(A, B) = Ax*Bx + Ay*By + Az*Bz
Run Code Online (Sandbox Code Playgroud)
一个normalized向量(单位向量)可以通过以下方式计算:
len(A) = sqrt(Ax*Ax + Ay*Ay + Az*Az)
notrmalize(A) = A / len(A)
Run Code Online (Sandbox Code Playgroud)
在纯 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]];
Run Code Online (Sandbox Code Playgroud)
这是很容易通过这个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 ) );
Run Code Online (Sandbox Code Playgroud)