三个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
我正在制作一个 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