2010-10-29 8 views
0

это математическая проблема для 2-й игры.Алгоритм столкновений для 2 движущихся объектов

Given 2 object (2 car, 2 tank, 2...), for each object i know: 
1. X, Y 
2. Actual Speed 
3. Degree of movement (or radiant) 

Как рассчитать «эффект» столкновения для 2 объекта

Ps:

I «движение» объект с этой простой формуле каждый тик моей «игры цикла»:

ychange = Math.Sin(radiant) * ((carspeed/xVar)); 
xchange = Math.Cos(radiant) * ((carspeed/xVar)); 

(где xVar является "мультипликатор", чтобы сделать более замедлить мой автомобиль на экране)

И для «первого» объекта, который сталкивается, если я добавлю «минус» (-) перед этой формулой, я смогу имитировать хороший «отскок» первого объекта .. но не для второго.

Так что мой вопрос касается способа вычисления хорошего (не идеального!) И более реалистичного «эффекта удара» для второго объекта.

Спасибо за вашу помощь

+1

Вы хотите упругое или неупругое столкновение? – Niki

+0

Потому что «твердый» объект, я думаю .. неупругий! – stighy

+1

Здесь «эластичный» не означает мягкость. Это означает, что они сталкиваются, не теряя энергии, они выходят так же быстро, как и они. Бильярдные шары тяжелы, но они сталкиваются упруго. Две машины сталкиваются неупруго, когда они разбиваются вместе и становятся двумя медленными кусками смятого металла (или, может быть, одного!). – Beta

ответ

1

Вот объяснение физики:

У вас есть четыре unknows: хна скорости каждого шара после столкновения.

Итак, вам нужны четыре уравнения.

Сохранение импульса по х и у дает два. Mom = mv
Сохранение кинетической энергии дает третье; Ke = 1/2 * мв^2 (до & после)

В дополнение к этому, принцип относительности можно считать один шар вначале неподвижен, скажем uB.x = uB.y = 0

И импульс должен происходить по линии, которая соединяется между центрами каждого шара во время удара. Поэтому, если вы предположили, что мяч B первоначально находится в состоянии покоя, теперь он будет двигаться в направлении этой линии, поэтому вы можете выразить vB.y = f + g * vB.x, тем самым уменьшив количество неизвестных до 3.

Три неизвестных, три уравнения. Ура!

Если столкновение не является упругим, это зависит от того, насколько точно вы хотите имитировать. Что-то вроде Ke_after = 0.99 * Ke_before, а затем бросьте это в математику.

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

+0

Если вы хотите сделать физику правильно, гораздо проще использовать рамку центра масс. – Beta

0

Ммм ... это было давно, так как я сделал коллизии развития игры, так возьмите мой совет легкомысленно. Вы пробовали «переворачивать» степень перемещения или просто добавляли один Pi в radiant?

2

Простейший способ состоит в том, чтобы иметь их скорости обмена. Это имеет смысл, если они идентичны.

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

+0

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

+0

@ Ohmu: Это правда, что скорости обмена реалистичны только для идеального столкновения мертвых центров с идентичными объектами, но это хороший (не идеальный!) И * простой * трюк для использования в игре. И обратите внимание, что я упомянул о более реалистичных методах лечения, включая «оглядывающиеся столкновения». – Beta

3

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

Этот метод вычисляет результирующую скорость и углы в зависимости от массы, скорости и угла каждого объекта.

Это работало как шарм в моей игре.

float dx = b1->x - b2->x, dy = b1->y - b2->y; 
    float d = sqrt(sqr(dx) + sqr(dy)); 
    float vp1, vp2, vx1, vx2, vy1, vy2; 
    vx1 = ballSpeedX(b1); 
    vx2 = ballSpeedX(b2); 
    vy1 = ballSpeedY(b1); 
    vy2 = ballSpeedY(b2); 
    vp1 = vx1 * dx/d + vy1 * dy/d; 
    vp2 = vx2 * dx/d + vy2 * dy/d; 

    float distance = sqrt(sqr(dx) + sqr(dy)); 

// Unit vector in the direction of the collision. 
    float ax = dx/distance, ay = dy/distance; 

// Projection of the velocities in these axes. 
    float va1 = vx1 * ax + vy1 * ay, vb1 = -vx1 * ay + vy1 * ax; 
    float va2 = vx2 * ax + vy2 * ay, vb2 = -vx2 * ay + vy2 * ax; 

// New velocities in these axes (after collision): edmass/b2->mass); 
    float vaP2 = va2 + (1.0 + D_BALL_ELASTIC_COEFFICIENT) * (va1 - va2)/(1.0 + b2->mass/b1->mass); 

// Undo the projections. 
    vx1 = vaP1 * ax - vb1 * ay; vy1 = vaP1 * ay + vb1 * ax; // new vx,vy for ball 1 after collision. 
    vx2 = vaP2 * ax - vb2 * ay; vy2 = vaP2 * ay + vb2 * ax; // new vx,vy for ball 2 after collision. 

    b1->speed = sqrt(sqr(vx1) + sqr(vy1)); 
    b1->angle = acos(fabs(vx1/b1->speed)); 

    b2->speed = sqrt(sqr(vx2) + sqr(vy2)); 
    b2->angle = acos(fabs(vx2/b2->speed));

Этот код был написан на чистом C. То, как хранить данные движения точно так же, как ваши. Переменные b1 и b2 являются шарами.

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

Надеюсь, это поможет!

+0

vaP1 используется, но не инициализируется. может быть похож на vaP2. Было бы полезно знать наверняка. Также имена переменных могут быть более наглядными. – dStulle

Смежные вопросы