如何在THREE.js中利用抛物线(曲线)实现抛射物碰撞检测?
抛物线与场景物体交点检测方案(Three.js)
核心思路
Three.js的Raycaster确实只支持直线射线检测,但可以通过离散采样轨迹点或数学精确求解两种方式实现抛物线与物体的交点检测,进而控制轨迹绘制的停止时机。
方法一:离散采样轨迹点(简单易实现)
这是最适合大多数场景的快速方案:
- 按固定时间步长计算抛物线上的连续点
- 用
Raycaster检测相邻两点间的线段与场景物体的交点 - 一旦检测到交点,立即终止轨迹绘制
示例代码:
function checkParabolaIntersection(startPos, velocity, gravity, sceneObjects) { const raycaster = new THREE.Raycaster(); let prevPoint = startPos.clone(); let t = 0; const timeStep = 0.05; // 步长越小精度越高,按需调整 const maxTime = 10; // 最大模拟时长,避免无限循环 while (t < maxTime) { t += timeStep; // 抛物线位置公式:s = 初始位置 + 初速度*t + 0.5*重力*t² const currentPoint = startPos.clone() .add(velocity.clone().multiplyScalar(t)) .add(gravity.clone().multiplyScalar(0.5 * t * t)); // 用射线检测当前线段与物体的交点 raycaster.set(prevPoint, currentPoint.clone().sub(prevPoint).normalize()); const intersects = raycaster.intersectObjects(sceneObjects); if (intersects.length > 0) { // 返回最近的交点 return intersects[0]; } prevPoint = currentPoint; } return null; // 未检测到交点 }
方法二:数学精确求解(高性能、高精度)
如果追求极致精度和性能,可直接联立抛物线与物体的几何方程求解:
- 针对平面类物体(地面、墙面):直接解一元二次方程得到交点时间,再计算具体位置
- 针对复杂几何体:遍历几何体的三角面,逐个计算抛物线与三角面的交点(需具备基础几何知识)
示例:检测抛物线与地面(y=0平面)的交点
function getParabolaGroundIntersection(startPos, velocity, gravity) { // 抛物线y分量方程:y = y0 + vy*t + 0.5*gy*t² const y0 = startPos.y; const vy = velocity.y; const gy = gravity.y; // 求解y=0时的t值(一元二次方程:0.5*gy*t² + vy*t + y0 = 0) const a = 0.5 * gy; const b = vy; const c = y0; const discriminant = b*b - 4*a*c; if (discriminant >= 0) { const t1 = (-b + Math.sqrt(discriminant)) / (2*a); const t2 = (-b - Math.sqrt(discriminant)) / (2*a); // 取正的有效时间值 const validT = t1 > 0 ? t1 : t2; if (validT > 0) { return startPos.clone() .add(velocity.clone().multiplyScalar(validT)) .add(gravity.clone().multiplyScalar(0.5 * validT * validT)); } } return null; }
轨迹停止绘制逻辑
无论采用哪种方法,一旦获取到交点:
- 停止后续轨迹点的生成
- 仅绘制从起点到交点的线段即可
内容的提问来源于stack exchange,提问作者z3db0y
相关产品推荐
相关产品推荐

