С помощью сообщества Stack Overflow я написал довольно простой, но увлекательный симулятор физики.
Вы щелкаете мышью и запускаете шар. Он будет подпрыгивать и в конце концов остановится на «полу».
Моя следующая большая особенность, которую я хочу добавить, это столкновение мяча с мячом. Движение мяча разбито на вектор скорости x и y. У меня есть сила тяжести (небольшое уменьшение вектора y на каждом шаге), у меня есть трение (небольшое уменьшение обоих векторов при каждом столкновении со стеной). Шары честно перемещаются удивительно реалистичным способом.
Полагаю, мой вопрос состоит из двух частей:
- Каков наилучший метод обнаружения столкновения шара с шаром?
У меня просто есть петля O (n ^ 2), которая перебирает каждый шар и проверяет каждый другой шар, чтобы увидеть, перекрывается ли его радиус?
- Какие уравнения я использую, чтобы справиться с столкновениями шара с шаром? Физика 101
Как это влияет на скорость вращения двух шаров по векторам x / y? В каком направлении движутся два мяча? Как применить это к каждому шару?
Обработка обнаружения столкновений «стенок» и результирующих изменений вектора была легкой, но я вижу больше сложностей с столкновениями шара и шара. Со стенами мне просто нужно было взять отрицательное значение соответствующего вектора x или y, и оно пошло бы в правильном направлении. С шарами я не думаю, что это так.
Несколько быстрых пояснений: для простоты я в данный момент в порядке с совершенно упругим столкновением, также все мои шары имеют одинаковую массу прямо сейчас, но я могу изменить это в будущем.
Редактировать: ресурсы, которые я нашел полезными
2d Физика шаров с векторами: 2-мерные столкновения без тригонометрии.pdf
Пример обнаружения столкновения 2d Ball: Добавление обнаружения столкновения
Успех!
У меня отлично работает обнаружение и реакция на столкновение мячей!
Соответствующий код:
Обнаружение столкновения:
for (int i = 0; i < ballCount; i++)
{
for (int j = i + 1; j < ballCount; j++)
{
if (balls[i].colliding(balls[j]))
{
balls[i].resolveCollision(balls[j]);
}
}
}
Это проверит наличие столкновений между каждым мячом, но пропустит лишние проверки (если вам нужно проверить, сталкивается ли шар 1 с шаром 2, вам не нужно проверять, сталкивается ли шар 2 с шаром 1. Кроме того, он пропускает проверку столкновения с собой).
Затем в моем классе с мячом у меня есть методы colliding () и resolCollision ():
public boolean colliding(Ball ball)
{
float xd = position.getX() - ball.position.getX();
float yd = position.getY() - ball.position.getY();
float sumRadius = getRadius() + ball.getRadius();
float sqrRadius = sumRadius * sumRadius;
float distSqr = (xd * xd) + (yd * yd);
if (distSqr <= sqrRadius)
{
return true;
}
return false;
}
public void resolveCollision(Ball ball)
{
// get the mtd
Vector2d delta = (position.subtract(ball.position));
float d = delta.getLength();
// minimum translation distance to push balls apart after intersecting
Vector2d mtd = delta.multiply(((getRadius() + ball.getRadius())-d)/d);
// resolve intersection --
// inverse mass quantities
float im1 = 1 / getMass();
float im2 = 1 / ball.getMass();
// push-pull them apart based off their mass
position = position.add(mtd.multiply(im1 / (im1 + im2)));
ball.position = ball.position.subtract(mtd.multiply(im2 / (im1 + im2)));
// impact speed
Vector2d v = (this.velocity.subtract(ball.velocity));
float vn = v.dot(mtd.normalize());
// sphere intersecting but moving away from each other already
if (vn > 0.0f) return;
// collision impulse
float i = (-(1.0f + Constants.restitution) * vn) / (im1 + im2);
Vector2d impulse = mtd.normalize().multiply(i);
// change in momentum
this.velocity = this.velocity.add(impulse.multiply(im1));
ball.velocity = ball.velocity.subtract(impulse.multiply(im2));
}
Исходный код: Полный исходный код для шарового коллайдера.
Если у кого-то есть предложения по улучшению этого базового симулятора физики, дайте мне знать! Одна вещь, которую я еще должен добавить, это угловой момент, чтобы шары катились более реалистично. Любые другие предложения? Оставить комментарий!