2D弹性碰撞 - '粘贴'行为?

时间:2014-11-18 05:08:12

标签: java physics sfml

我使用此方法处理弹性碰撞(使用this作为来源):

public static void handleElasticCollisions(Entity a, Entity b) {
    // make a few variables to make equations easier to read
    Vector2f aPos = a.getPos();
    Vector2f bPos = b.getPos();

    Vector2f aV = a.getVelocity();
    Vector2f bV = b.getVelocity();

    float aMass = a.getSize();
    float bMass = b.getSize();

    // find unit normal vector
    Vector2f uN = normalize(Vector2f.sub(bPos, aPos));

    // find unit tanget vector
    Vector2f uT = new Vector2f(-uN.y, uN.x);

    // get normal and tangential components of both velocity vectors 
    // before the collision
    float aVn = dot(uN, aV);
    float aVt = dot(uT, aV);

    float bVn = dot(uN, bV);
    float bVt = dot(uT, bV);

    // get normal and tangential components of both velocity vectors 
    // after the collision
    float aVN = (aVn*(aMass - bMass) + 2*bMass*bVn)/(aMass + bMass);
    float aVT = aVt;

    float bVN = (bVn*(bMass - aMass) + 2*aMass*aVn)/(aMass + bMass);
    float bVT = bVt;

    // convert normal and tangential components into vectors
    Vector2f avn = Vector2f.mul(uN, aVN);
    Vector2f avt = Vector2f.mul(uT, aVT);

    Vector2f bvn = Vector2f.mul(uN, bVN);
    Vector2f bvt = Vector2f.mul(uT, bVT);

    a.setVelocity(Vector2f.add(avn, avt));
    b.setVelocity(Vector2f.add(bvn, bvt));
}

然而,有时候,实体彼此进入/彼此粘在一起而不是彼此反弹。 这是我的更新方法,仅包含相关代码:

public void show() {

    // set delta time
    float currentTime = clock.getElapsedTime().asSeconds();
    float dt = currentTime - lastTime;


    // update entities and check for removal
    for (Entity e : entities) {
        e.update(dt);
    }

    // draw entities
    for (Entity e : entities) {
        e.draw();
    }


    Window.getWindow().draw(pointerSprite);
    Window.getWindow().display();

    lastTime = currentTime;

}

在我的碰撞实体的update中,我检查了一下:

public boolean intersectsWithAsteroid() {
    for (Entity e : GameScreen.getEntities()) {
        if (e instanceof AsteroidEntity &&
                asteroidSprite.getGlobalBounds().intersection(e.getBounds()) != null &&
                !this.equals(e)) {
            collidingAsteroid = (AsteroidEntity)e;
            return true;
        }
    }
    return false;
}

public void handleAsteroidIntersection() {
    CMath.handleElasticCollisions(this, collidingAsteroid);
}

Hereintersection的文档。

我不明白为什么会发生这种情况,有人能告诉我我是如何实施这种算法的吗?

1 个答案:

答案 0 :(得分:0)

所以,我最后修改了它,将这3行代码添加到我的响应函数中:

    Vector2f rv = Vector2f.sub(bV, aV);
    Vector2f norm = Vector2f.sub(bPos, aPos);
    float velAlongNormal = CMath.dot(rv, norm);

    // Do not resolve if velocities are separating
    if(velAlongNormal > 0) {
        return;
    }

如果物体的速度没有直接碰撞,那么就不应该有碰撞响应。这解决了所有问题。