Для простой игры в пул, где спин не моделируется, алгоритм довольно прост.
- Чтобы проверить, не произошло ли столкновения, проверьте, меньше ли расстояние между шариками, чем сумма их радиуса.
- Рассчитать нормаль воздействия
- Рассчитать силу удара на основе разности скоростей, нормы, коэффициента удара и масс
- Приложите силу удара к обоим шарам
В псевдокоде это становится:
vector difference = ball2.position - ball1.position
float distance = sqrt(difference)
if (distance < ball1.radius + ball2.radius) {
vector normal = difference / distance
//vector velocityDelta = ball2.velocity - ball1.velocity
vector velocityDelta = ball1.velocity - ball2.velocity
float dot = dotProduct(velocityDelta, normal)
if (dot > 0) {
float coefficient = 0.5
float impulseStrength = (1 + coefficient) * dot * (1 / ball1.mass + 1 / ball2.mass)
vector impulse = impulseStrength * normal
ball1.velocity -= impulse / ball1.mass
ball2.velocity += impulse / ball2.mass
}
}
Вы можете опустить массу из алгоритма, если все шары имеют одинаковую массу, а также принять постоянный радиус для всех шаров для игры в пул, но код будет более полезным для вас без этих упрощений.
Код основан на этом уроке , но я помню, что умножение импульсов там было неверным.