三个JS |检测一个对象何时离开另一个对象

ThreeJS | Detect when an object leaves another object

我正在制作一个 ThreeJS 项目,其中我有 平面(Object3D) 球体(网格) 内飞行。

我正在尝试检测平面与球体边界之间的碰撞,以便我可以删除该平面并使其重新出现在球体内的另一个位置。

我的问题是如何检测一个对象何时离开另一个对象?

我现在的代码:

detectCollision(plane, sphere) {

  var boxPlane = new THREE.Box3().setFromObject(plane);
  boxPlane.applyMatrix4(plane.matrixWorld);

  var boxSphere = new THREE.Box3().setFromObject(sphere);
  boxSphere.applyMatrix4(sphere.matrixWorld);

  return boxPlane.intersectsBox(boxSphere);

}

在我的渲染函数中:

var collision = this.detectCollision(plane, this.radar)
  if (collision == true) {
    console.log("the plane is inside the sphere")
  }
  else {
    console.log("the plane is outside the sphere")
  }
})

问题是,当平面在球体内时,我得到 true false 基本上一直到所有平面都离开球体为止。那时我有一个 false 而没有更多 true.

Box3 不是您想用来计算球体和平面碰撞的东西,因为盒子不会遵循球体的曲率,也不会跟随平面的旋转。

Three.js 有一个 class THREE.Sphere that is closer to what you need. Keep in mind that this class is not the same as a Mesh with a SphereGeometry, this is more of a math helper that doesn't render to the canvas. You can use its .containsPoint() 方法可以满足您的需要:

var sphereCalc = new THREE.Sphere( center, radius );
var point = new THREE.Vector3(10, 4, -6);

detectCollision() {
    var collided = sphereCalc.containsPoint(point);

    if (collided) {
        console.log("Point is in sphere");
    } else {
        console.log("No collision");
    }

    return collided;
}

您必须应用变换并循环检查每个平面的所有 4 个点。请注意,有一种 Sphere.intersectsPlane() 方法听起来像是可以为您执行此操作,但它并不相同,因为它使用 infinite 平面来计算交点,而不是具有定义的交点宽度和高度,所以不要使用它。

编辑:

澄清一下,每个平面通常有 4 个顶点,因此您必须检查每个顶点 in a for() loop 以查看球体是否包含 4 个点中的每一个。

此外,平面可能已经移动和旋转,因此其原始顶点位置将应用变换矩阵。我想你已经在你的例子中考虑到了这一点,但它会是这样的:

point.copy(vertex1);
point.applyMatrix4(plane.matrixWorld)
sphereCalc.containsPoint(point);

point.copy(vertex2);
point.applyMatrix4(plane.matrixWorld)
sphereCalc.containsPoint(point);

// ... and so on