Обнаружение столкновений с использованием теоремы Пифагора ненадежно?

Объекты часто могут проходить сквозь друг друга? Кроме того, при расчете импульса иногда при столкновении спрайты будут образовывать капли, двигаясь вместе, а не отскакивая.

Код работает для большинства коллизий, но часто терпит неудачу. Есть идеи?

xV = X Скорость. yV = Y Скорость. В каждом кадре значения этой скорости добавляются к координатам X и Y квадратора.

bool Quad::IsTouching(Quad &q)
{
float distance = 0;
float combinedRadius = (size/2) + (q.GetSize()/2);

distance = sqrt(pow(q.GetX() - GetX(), 2) + pow(q.GetY() - GetY(), 2));

if(distance < combinedRadius)
{
return true;
}

return false;
}

void Quad::Collide(Quad &q)
{
float mX, mY, mX2, mY2, mXTmp, mYTmp;

mX = mass * xV;
mY = mass * yV;
mXTmp = mX;
mYTmp = mY;

mX2 = q.GetMass() * q.GetxV();
mY2 = q.GetMass() * q.GetyV();

mX = mX2;
mY = mY2;

mX2 = mXTmp;
mY2 = mYTmp;

xV = mX/mass;
yV = mY/mass;

q.SetxV(mX2/q.GetMass());
q.SetyV(mY2/q.GetMass());
}

1

Решение

У меня был та же проблема а также Вот быстрое видео, которое я сделал, чтобы продемонстрировать проблему.

Чтобы решить эту проблему, нужно рассчитать точное время столкновения, чтобы частицы переместили оставшееся время итерации / временного шага с новой скоростью. Для этого вам необходимо проверить, будет ли столкновение перед обновлением позиции, поэтому: sqrt((x1 - x2 + dt * (vx1 - vx2))^2 + (y1 - y2 + dt * (vy1 - vy2))^2) <= distance,

Вы также можете выбрать более простое решение, в котором вы слегка перемещаете оба объекта, чтобы они больше не сталкивались. Это приведет к неточности создателя, но требует меньше вычислений:

dx = x1 - x2;
dy = y1 - y2;
d = sqrt(dx^2 + dy^2);
D = r1 + r2;
if(d < D)
{
s = (d - D) / (2 * d);
x1 = x1 + s * dx;
x2 = x2 - s * dx;
y1 = y1 + s * dy;
y2 = y2 - s * dy;
}
0

Другие решения

Какой тип столкновений вы имеете в виду? Эластичный или неэластичный? Для упругого столкновения код потерпит неудачу, и вам придется создать дополнительное свойство, чтобы предотвратить слипание двух объектов при контакте. Вы также должны были бы убедиться с помощью цикла или оператора if, что если один объект пересекает положение другого объекта в то же время, что и другой объект, эти два элемента будут разделяться с углом, пропорциональным скорости столкновения. Используйте соответствующие физические формулы.

0

Как выведенный, потенциальный вопрос (нет значений для скоростей, размеров и т. Д., Поэтому я не могу сказать наверняка), вы не учитываете, что квад именно так трогательный. То есть, distance == combinedRadius, Поэтому, когда это правда, проверка не проходит, тогда объекты продолжают двигаться на следующем тике … прямо через друг друга.

Измените свой чек на distance <= combinedRadius, Кроме того, вы можете просто получать эффект туннелирования, потому что объекты достаточно малы и движутся достаточно быстро, чтобы на каждом тике они проходили друг через друга. Есть несколько способов исправить это, некоторые из которых: навязать максимальную скорость и минимальный размер; увеличить частоту кадров для проверок физики; использовать непрерывные проверки столкновений по сравнению с дискретными проверками: см статью википедии на тему

0
По вопросам рекламы [email protected]