Очень простое разрешение коллизий с интеграцией verlet

Я учусь делать некоторые очень простые физические вещи для собственного развлечения, но я сталкиваюсь со странной проблемой.

Я использую метод интеграции Verlet с поправкой на время, как описано на http://www.lonesock.net/article/verlet.html , и до сих пор это работало довольно хорошо. Движения и прочее выглядят довольно хорошо.

Моя проблема возникает в отношении разрешения коллизий. Я могу решить (кажется, довольно хорошо) против местности, так как местность не движется. Я просто установил текущую позицию игрока в безопасное место, и все вроде бы хорошо. Однако, когда я пытаюсь решить против другого спрайта (физического актера и т. д.), все, кажется, стреляет повсюду.

Мой код разрешения выглядит следующим образом:

void ResolveCollision(Sprite* entity1, Sprite* entity2)
{
    Vec2D depth = GetCollisionDepth(entity1, entity2);
    if (GetSpritePhysical(entity1) && GetSpritePhysical(entity2))
    {
        /* Two physical objects. Move them apart both by half the collision depth. */
        SetPosition(entity1, PointFromVector(AddVectors(
            VectorFromPoint(GetPosition(entity1)), ScalarMultiply(0.5f, depth))));
        SetPosition(entity2, PointFromVector(AddVectors(
            VectorFromPoint(GetPosition(entity2)), ScalarMultiply(-0.5f, depth))));
    }
    else if (GetSpritePhysical(entity1) && !GetSpritePhysical(entity2))
    {
        SetPosition(entity1, PointFromVector(AddVectors(
            VectorFromPoint(GetPosition(entity1)), ScalarMultiply(-1.0f, depth))));
    }
    else if (!GetSpritePhysical(entity1) && GetSpritePhysical(entity2))
    {
        SetPosition(entity2, PointFromVector(AddVectors(
            VectorFromPoint(GetPosition(entity2)), depth)));
    }
    else
    {
        /* Do nothing, why do we have two collidable but nonphysical objects... */
    }
}

Как видите, есть три случая, определяемые тем, является ли спрайт физическим или нет.

Вполне вероятно, что это первый случай, в котором возникла проблема; и я использую ту же функцию, чтобы получить глубину проникновения здесь, что и в моих (кажущихся работающими) столкновениях с ландшафтом.

Почему столкнувшиеся спрайты разлетаются повсюду? Я совсем запутался в этой проблеме. Любая помощь будет здорово.


person Kozaki    schedule 17.04.2011    source источник


Ответы (1)


Как только вы разделите их, вы определите их скорости/импульсы. Как ты это делаешь?

Скорее всего, чтобы определить направление разделения, вы используете вектор, идущий от центра каждого. Чем глубже проникновение, тем менее точным может быть этот вектор (нормаль столкновения). Это может привести к неожиданным результатам.

Что работает лучше, так это не разделять их, а скорее рассчитать, где будет точка столкновения, прежде чем перемещать их, а затем переместить их только на это расстояние... затем определить скорости... затем переместить их в новом направлении для остальную часть временного отрезка. Конечно, это немного сложнее, но результаты более точны.

person Steve H    schedule 17.04.2011