Для простої гри в пул, де віджимання не моделюється, алгоритм досить простий.
- Щоб перевірити, чи відбувається зіткнення, перевірте, чи відстань між кулями менша від суми їх радіуса.
- Обчисліть норму удару
- Обчисліть силу удару на основі різниці швидкостей, норми, коефіцієнта удару та маси
- Нанесіть ударну силу на обидва кулі
У псевдокоді це стає:
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
}
}
Ви можете опустити масу з алгоритму, якщо всі кулі мають однакову масу, а також припустити постійний радіус для всіх кульок для гри в більярд, але код буде кориснішим для вас без цих спрощень.
Код заснований на цьому підручнику , але я пам’ятаю, що множення імпульсів там було неправильним.