Расчет 2D результирующих сил для транспортных средств в играх - PullRequest
0 голосов
/ 06 марта 2012

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

У меня есть класс агента с членами

vector position // (x,y)
vector velocity // (x,y)
vector forward // (x,y)  
float radius   // radius of the agent (all circles)
float mass     

Так что, если у нас есть A, B: Агент, и на следующем шаге времени скорость изменит положение. Если произойдет столкновение, я хочу выработать силу, которая будет действовать на объекты.

Я знаю, что Line1 = (B.position-A.position) необходим для определения угла результирующей силы, но как рассчитать его, сбивает меня с толку, когда я должен учитывать текущую скорость транспортного средства вместе угол столкновения.

arctan (L1.y, L1.x) - это угол для силы (можно определить направление) sin / cos - высота / ширина компонентов

Также я знаю, чтобы рассчитать повернутую ось мне нужно использовать x = cos (T) * vel.x + sin (T) * vel.y y = cos (T) * vel.y + sin (T) * vel.x

Это то место, где мой мозг больше не может справиться. Любая помощь будет признательна.

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

Добавлен небольшой псевдокод, чтобы показать, где я начинал с ним ..

A,B:Agent 

Agent {
    vector position, velocity, front;
    float radius,mass;
}

vector dist = B.position - A.position;
float distMag = dist.magnitude();

if (distMag < A.radius + B.radius) { // collision 
    float theta = arctan(dist.y,dist.x);
    flost sine = sin(theta);
    float cosine = cos(theta);

    vector newAxis = new vector; 
      newAxis.x  = cosine * dist .x + sine * dist .y;
      newAxis.y  = cosine * dist .y - sine * dist .x;

    // Converted velocities
    vector[] vTemp = { 
         new vector(), new vector()         };
    vTemp[0].x  = cosine * agent.velocity.x + sine * agent.velocity.y;
    vTemp[0].y  = cosine * agent.velocity.y - sine * agent.velocity.x;
    vTemp[1].x  = cosine * current.velocity.x + sine * current.velocity.y;
    vTemp[1].y  = cosine * current.velocity.y - sine * current.velocity.x;        

Здесь можно надеяться, что в стеке есть любопытный математик.

1 Ответ

0 голосов
/ 14 марта 2012

Предположим, без ограничения общности, что мы находимся в системе отсчета второго объекта до столкновения.

Сохранение импульса:

m1*vx1 = m1*vx1' + m2*vx2'
m1*vy1 = m1*vy1' + m2*vy2'

Решение для vx1 ', vy1':

vx1' = vx1 - (m2/m1)*vx2'
vy1' = vy1 - (m2/m1)*vy2'

В тайне я запомню тот факт, что vx1'*vx1' + vy1'*vy1' = v1'*v1'.

Сохранение энергии (одна из вещей, которую дают нам упругие столкновения, это то, что угол падения - это угол отражения):

m1*v1*v1 = m1*v1'*v1' + m2*v2'+v2'

Решение для v1 'в квадрате:

v1'*v1' = v1*v1 - (m2/m1)v2'*v2'

Объединение для устранения v1':

(1-m2/m1)*v2'*v2' = 2*(vx2'*vx1+vy2'*vy1)

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

v2x' = v2'cos(theta)
v2y' = v2'sin(theta)

Следовательно:

v2' = 2/(1-m2/m1)*(vx1*sin(theta)+vy1*cos(theta))

Теперь вы можетерешить для v1 '(либо использовать v1'=sqrt(v1*v1-(m2/m1)*v2'*v2'), либо решить все в терминах входных переменных).

Давайте назовем phi = arctan(vy1/vx1).Угол падения относительно касательной к окружности в точке пересечения составляет 90-phi-theta (pi/2-phi-theta, если вы предпочитаете).Снова добавьте это для отражения, затем преобразуйте обратно в угол относительно горизонтали.Назовем угол падения psi = 180-phi-2*theta (pi-phi-2*theta).Или,

psi = (180 or pi) - (arctan(vy1/vx1))-2*(arctan(dy/dx))

Итак:

vx1' = v1'sin(psi)
vy1' = v1'cos(psi)

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

Следующий момент, который следует учитывать: поскольку компьютер обновляется при дискретных событиях времени, у вас фактически есть перекрывающиеся объекты.Вы должны отказаться от объектов, чтобы они не перекрывались перед вычислением нового местоположения каждого объекта.Для дополнительного кредита определите время, которое они должны были пересечь, затем переместите их в новом направлении на это количество времени.Обратите внимание, что это время - просто перекрытие / старая скорость.Причина, по которой это важно, заключается в том, что вы можете представить себе вычисляемое столкновение, которое заставляет объекты по-прежнему перекрываться (вызывая их повторное столкновение).

Следующий момент, который следует рассмотреть: перевести исходную проблему в эту проблему, просто вычтите скорость объекта 2 из объекта 1 (по компонентам).После вычисления не забудьте добавить его обратно.

Заключительный момент для рассмотрения: я, вероятно, допустил ошибку алгебры где-то вдоль линии.Тебе следует серьезно подумать о проверке моей работы.

...