Javascript - Circle-Circle Collision Issue

Javascript - Circle-Circle Collision Issue

本文关键字:Issue Collision Circle-Circle Javascript      更新时间:2023-09-26

我正在用HTML5,Canvas制作一个游戏,这是我解决两个移动圆圈之间冲突的代码:

function resCCCol(a, b) {
    var dx = a.x - b.x;
    var dy = a.y - b.y;
    var dist = dx * dx + dy * dy;
    var vx = b.vx - a.vx;
    var vy = b.vy - a.vy;
    var dot = dx * vx + dy * vy;
    if (dot > 0) {
        var scale = dot / dist;
        var cx = dx * scale;
        var cy = dy * scale;
        var mass = a.r + b.r;
        var cw1 = 2 * b.r / mass;
        var cw2 = 2 * a.r / mass;
        a.vx += cw1 * cx
        a.vy += cw1 * cy
        b.vx -= cw2 * cx
        b.vy -= cw2 * cy
    }
}

如果我设置坐标,使圆重叠但仍然具有 0 的速度,则圆不会相互推出,这就是问题所在。我该如何解决这个问题?

编辑:小提琴:http://jsfiddle.net/yP7xf/2/,单击"故障!"以查看故障,因为您会看到它们不会分开。

我不确定dot的目的是什么(也许我在这里缺少一些数学知识),但是如果dist < sum(radii),就会发生两个圆圈碰撞。如果发生这种情况,您应该偏转圆圈,但要确保它们至少有一些小速度以确保它们分开。

当两个圆圈以无速度重叠时,您的resCCCol()方法将不起作用,因为dot0。即使您将if语句更改为在dot >= 0上执行,您仍然只剩下 0 速度。

if (dot > 0) { //dot === 0
    var scale = dot / dist; //scale === 0
    var cx = dx * scale; //cx === 0
    var cy = dy * scale; //cy === 0
    var mass = a.r + b.r;
    var cw1 = 2 * b.r / mass;
    var cw2 = 2 * a.r / mass;
    a.vx += cw1 * cx // 0
    a.vy += cw1 * cy // 0
    b.vx -= cw2 * cx // 0
    b.vy -= cw2 * cy // 0
}

您应该在dot === 0时处理情况。最简单的方法是在速度0时简单地给它们一个设定的速度:

if (dot > 0) { 
    ... 
} else {
    a.vx = 1;
    a.vy = 1;
    b.vx = -1;
    b.vy = -1;
}

当然,这只会将它们彼此推到屏幕的相对角落,但你可以很容易地实现一些更好地遵守物理定律的东西(忽略两个物体不能占用相同空间的事实)。

目前还不完全清楚处理此问题的最佳方法是什么,我认为最好确保您不会首先陷入这种情况(通过确保它们永远不会与零速度重叠),但一个快速而肮脏的解决方法是检查dot === 0如果是这样, 给他们一些速度。例如:

if (dot === 0) {
    // numbers pulled completely out of thin air...
    a.vx = 0.5;
    a.vy = 0.5;
    b.vx = -0.5;
    b.vy = -0.5;
}

http://jsfiddle.net/yP7xf/5/

现在你应该给他们什么速度?这是你需要解决的问题。可能您希望它们分开,这样您就可以根据从一条线的中心到另一条线的中心计算一些向量,并以您认为合适的速度沿该向量的一个方向发送一个向量,另一个向量在另一个方向上发送。但是,如果它们完全放在彼此之上(中心在同一点),那么您也需要考虑这种情况。