You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JS物理模拟中移动球体被固定球体卡住无法弹开的问题排查

移动球体被固定球体卡住的碰撞检测问题分析与修复

问题场景

基于Matthias Müller《10分钟物理》第3课修改的台球碰撞模拟,采用SVG实现,支持添加球体、设置固定障碍物及暂停功能,但存在移动球被固定球卡住无法逃脱的问题,例如启动后红球会立即被黑球卡住。

问题代码

碰撞处理核心逻辑:

function handleBallCollision(ball1, ball2, restitution) {
    const   pushVel = 2.0;
    const   dir = new Vector2();
    dir.subtractVectors(ball2.pos, ball1.pos);
    const   d = dir.length();
    const   rsum = ball1.radius + ball2.radius;
    if (d == 0.0 || d > rsum) return;

    dir.scale(1.0 / d);
    let     corr = (ball1.radius + ball2.radius - d) / 2.0;

    if (ball1.isMoving == 0 || ball2.isMoving == 0) {
        const ball = ball1.isMoving == 0 ? ball2 : ball1;

        ball.pos.add(dir, corr);
        var v = ball.vel.dot(dir);
        ball.vel.add(dir, pushVel - v);
        }
    // else handle case of two balls moving...
}

问题原因

  1. 位移修正量错误:
    代码中corr = (rsum - d)/2是两个移动球碰撞时的修正逻辑(两球各移动一半距离分离),但当其中一个球固定时,固定球不会移动,移动球需要移动全部的分离距离(rsum - d)才能脱离重叠状态。仅移动一半距离会导致两球始终重叠,下一帧再次触发碰撞检测,形成循环卡顿。

  2. 速度调整逻辑不符合物理规律:
    强制将移动球的法线方向速度设置为固定值pushVel,而非基于弹性碰撞的反弹逻辑,可能导致速度方向或大小异常,加剧卡顿现象。

修复方案

修改固定球碰撞分支的逻辑,修正位移量并替换为正确的弹性碰撞速度处理:

function handleBallCollision(ball1, ball2, restitution) {
    const dir = new Vector2();
    dir.subtractVectors(ball2.pos, ball1.pos);
    const d = dir.length();
    const rsum = ball1.radius + ball2.radius;
    if (d == 0.0 || d > rsum) return;

    dir.scale(1.0 / d);

    if (ball1.isMoving === 0 || ball2.isMoving === 0) {
        // 区分固定球和移动球
        const fixedBall = ball1.isMoving === 0 ? ball1 : ball2;
        const movingBall = ball1.isMoving === 0 ? ball2 : ball1;

        // 修正位移:移动球移动全部分离距离远离固定球
        const corr = rsum - d;
        movingBall.pos.add(dir, corr);

        // 修正速度:法线方向弹性反弹
        const v = movingBall.vel.dot(dir);
        // 仅当移动球朝向固定球时触发反弹
        if (v < 0) {
            // 移除原法线方向速度分量,添加反弹后的分量
            movingBall.vel.add(dir, -2 * v * restitution);
        }
    } else {
        // 处理两移动球碰撞的原有逻辑...
    }
}

关键改动说明

  • 位移修正:将corr从(rsum - d)/2改为rsum - d,确保移动球一次性完全脱离与固定球的重叠区域。
  • 速度修正:使用弹性碰撞公式,将移动球在法线方向的速度分量反向并乘以恢复系数,仅当移动球朝向固定球时触发,符合真实物理反弹效果。
  • 逻辑清晰化:明确区分固定球与移动球,避免混淆碰撞双方的角色。

内容的提问来源于stack exchange,提问作者Ken

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 21:50:20