【问题标题】:How to avoid particles glitching together in an elastic particle collision simulator?如何避免粒子在弹性粒子碰撞模拟器中一起出现故障?
【发布时间】:2013-04-05 14:53:05
【问题描述】:

这是一个short video,其中可以看到两个(可能更多)粒子的组相互干扰。

源代码可以在here找到。

这是我用来计算碰撞的代码:

function collisionPhysics()
{
    for (var i = 0; i < N - 1; ++i)
    {
        for (var j = i + 1; j < N; ++j)
        {
            var Dx = objects[j].x - objects[i].x;    // Difference in X direction between objects[i] and objects[j].
            var Dy = objects[j].y - objects[i].y;    // Difference in Y direction between objects[i] and objects[j].
            var D2 = Dx * Dx + Dy * Dy;              // Distance between objects[i] and objects[j] squared.

            if (D2 <= (objects[i].rad + objects[j].rad) * (objects[i].rad + objects[j].rad))    // Colision check could be inserted here, reusing D2.
            {
                var delta = 2 * (Dx * (objects[i].Vx - objects[j].Vx) + Dy * (objects[i].Vy - objects[j].Vy)) / (D2 * (objects[i].m + objects[j].m));
                objects[i].Vx += -objects[i].m * delta * Dx;
                objects[i].Vy += -objects[i].m * delta * Dy;
                objects[j].Vx +=  objects[j].m * delta * Dx;
                objects[j].Vy +=  objects[j].m * delta * Dy;
            }
        }
    }
}

编辑 2013/04/06: nwellcome 提到的问题导致了奇怪的行为。这个调整后的功能应该可以解决这个问题,不确定它是否可以提高性能,但它确实有效:

function collisionPhysics()
{
    for (var i = 0; i < N - 1; ++i)
    {
        for (var j = i + 1; j < N; ++j)
        {
            var Dx = objects[j].x - objects[i].x + timeStep * (objects[j].u - objects[i].u);
            var Dy = objects[j].y - objects[i].y + timeStep * (objects[j].v - objects[i].v);
            var D2 = Dx * Dx + Dy * Dy;              // Distance between objects[i] and objects[j] squared.

            if (D2 <= (objects[i].r + objects[j].r) * (objects[i].r + objects[j].r))    // Colision check could be inserted here, reusing D2.
            {
                objects[i].col = true;
                objects[j].col = true;
                var dx = objects[j].x - objects[i].x;
                var dy = objects[j].y - objects[i].y;
                var du = objects[j].u - objects[i].u;
                var dv = objects[j].v - objects[i].v;
                var dr = objects[j].r + objects[i].r;
                var dt = (-Math.sqrt(2 * dx * du * dy * dv - du * du * (dy * dy - dr * dr) - dv * dv * (dx * dx - dr * dr)) - dx * du - dy * dv) / (du * du + dv * dv);
                Dx = objects[j].x - objects[i].x + dt * (objects[j].u - objects[i].u);
                Dy = objects[j].y - objects[i].y + dt * (objects[j].v - objects[i].v);
                D2 = Dx * Dx + Dy * Dy;
                var delta = 2 * (Dx * (objects[i].u - objects[j].u) + Dy * (objects[i].v - objects[j].v)) / (D2 * (objects[i].m + objects[j].m));
                objects[i].u += -objects[i].m * delta * Dx;
                objects[i].v += -objects[i].m * delta * Dy;
                objects[j].u +=  objects[j].m * delta * Dx;
                objects[j].v +=  objects[j].m * delta * Dy;
                objects[i].x += (timeStep - dt) * objects[i].u;
                objects[i].y += (timeStep - dt) * objects[i].v; 
                objects[j].x += (timeStep - dt) * objects[j].u;
                objects[j].y += (timeStep - dt) * objects[j].v;
            }
        }
    }
}

【问题讨论】:

    标签: javascript simulation collision


    【解决方案1】:

    问题是您的碰撞解决方法不能确保粒子在下一帧开始时仍不会相交。

    当你发现碰撞时,你需要回溯到粒子边界发生碰撞的时间点,并从那里解决碰撞。有关执行此操作的方法,请参阅 this game development answer 的类似问题。

    【讨论】:

    • 这确实是导致问题的原因,在做了一些数学运算后,我得到了一个工作对撞机。当一个粒子同时与两个粒子碰撞时,它似乎也能正常工作。谢谢,这实际上是一个非常合乎逻辑的方法,不知道为什么我之前没有想到这个。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-21
    • 1970-01-01
    • 2014-01-20
    • 1970-01-01
    • 2014-12-28
    • 2018-04-24
    相关资源
    最近更新 更多