THREEJS:如何计算 THREE.ray 到另一个 THREE.ray 上的最近点

THREEJS: How to calculate the closest point on a THREE.ray to another THREE.ray

我正在使用 THREE.js 并且我有两个 THREE.Ray 对象。每条光线都有一个起点 (Vector3) 和一个方向 (Vector3)。

我想弄清楚如何在每条射线上找到距离另一条射线最近的点。

求解的关键,就是要知道由距离最近的2个点连成的线,是垂直于2条射线的。

第一步是找到由最近的2个点形成的直线的方向向量。由于矢量垂直于两条射线,这可以通过 Cross product.
rayArayBTHREE.Ray:

类型的 2 个对象
let Nv = rayA.direction.clone().cross(rayB.direction);

下一步是为每条射线找到一个平面,其中包括这条射线和另一条射线上的最近点。平面图由 2 个向量组成,在本例中为平面的方向向量和 nv。但是我们需要平面的另一种表示,通过一个点和一个法向量。点是射线的原点。法向量又可以通过Cross product得到。为了进一步计算,这个向量必须是单位向量(长度为1),所以它们被归一化:

let Na = rayA.direction.clone().cross(Nv).normalize();
let Nb = rayB.direction.clone().cross(Nv).normalize();

现在的问题是射线与平面的交集。 ptAptBTHREE.Vector3 个对象,射线上的最近点:

let Da = rayA.direction.clone().normalize();
let Db = rayB.direction.clone().normalize();

let da = rayB.origin.clone().sub(rayA.origin).dot(Nb) / Da.dot(Nb);
let db = rayA.origin.clone().sub(rayB.origin).dot(Na) / Db.dot(Na);

let ptA = rayA.origin.clone().add(Da.multiplyScalar(da));
let ptB = rayB.origin.clone().add(Db.multiplyScalar(db));

射线与平面相交的解释:

光线由点 Ra 和方向 Da 定义。
该平面由点 Rb 和法向量 Nb.

定义

Ra到平面的法向距离n为(见Dot product):

n  =  | Rb - Ra | * cos(alpha)  =  dot(Rb - Ra, Nb)

由此得到交点ptA到射线Ra原点的距离da为:

da  =  n / cos(beta)  =  n / dot(Da, Nb)

交点ptA是:

ptA  =  Ra + Da * da  =  Ra + Da * dot(Rb - Ra, Nb) / dot(Da, Nb)