点到线的距离 3d 公式

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)

Rab*_*d76 7

的最近点X至点P就行(AV)是点,其中,所述线(XP)是垂直于线(AB)。

如果一条直线由两个点A和定义B,那么给出直线方向的单位向量 D可以计算如下(注意单位向量的长度为 1):

D = normalize(B-A);
Run Code Online (Sandbox Code Playgroud)

对于以下公式,O需要在线上的一个点,例如O = A

现在必须找到与直线 ( , )上X的点最近的点。POD

首先计算VO到的向量P

V = P - O;
Run Code Online (Sandbox Code Playgroud)

的距离dO到交叉点(最近点)X可以通过计算标量积
一般来说,2个向量的点积等于2个向量之间夹角的余弦乘以两个向量的幅度(长度)。

dot( A, B ) == | A | * | B | * cos( angle_A_B ) 
Run Code Online (Sandbox Code Playgroud)

点AB

由于D是一个单位矢量,的点积VD等于所述线之间的角度的余弦(OD)和向量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)

交线点

就行了计算由点AB并且点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,其中用于向量运算一样的操作addsubdotnormalize定义如下:

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)