Чи існує алгоритм гри в більярд?


14

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

Я маю на увазі, коли одна куля потрапляє в іншу, мені потрібен алгоритм, щоб обчислити напрямок обох. Це буде залежати від точного кута, де вони б’ють одне одного і від швидкості.

Я хочу практикувати кодування Java, тому я шукаю java-код або пакет, у якому є такий тип коду.


2
Якщо ви хочете вирішити це самостійно, вам, ймовірно, знадобляться певні знання про вектори. На щастя, хтось опублікував чудовий посібник з лінійної математики в інших місцях на цьому сайті лише днями.
doppelgreener

можливо, цей сайт може допомогти вам archive.ncsa.illinois.edu/Classes/MATH198/townsend/…

Відповіді:


8

Хоча базове виявлення / реагування на зіткнення сфери-сфери є досить простим, зробити це досить точно для хорошого моделювання пулу було б більш складно, оскільки вам доведеться мати справу зі спіном.

Вам відомо про існування двигунів фізики? Деякі популярні приклади є такими (і вони можуть зробити набагато більше, ніж просто зіткнення кульових куль). Можливо, вдалий вибір для гри в більярд, але не стільки для вивчення Java ...

У 2D

Box2D: http://www.box2d.org

Бурундук: http://code.google.com/p/chipmunk-physics/

У 3D

Куля: http://bulletphysics.org/

ODE: http://www.ode.org

Якщо ви робили велику бюджетну комерційну гру:

Хавок: http://www.havok.com


1
Які з них є двигунами фізики Java?
Ricket

Є порти Java або принаймні прив’язки для Box2D, Бурундука, Кулі та ODE
bluescrn

6

Вас може зацікавити стаття « Уроки залу в басейні: Швидке, точне виявлення зіткнень між колами чи сферами », якщо ви вирішите піти по маршруту «прокатати свій». Це не специфічно для Java, але обговорює деякі алгоритми, що використовуються для простого моделювання.


2

Для простої гри в пул, де віджимання не моделюється, алгоритм досить простий.

  1. Щоб перевірити, чи відбувається зіткнення, перевірте, чи відстань між кулями менша від суми їх радіуса.
  2. Обчисліть норму удару
  3. Обчисліть силу удару на основі різниці швидкостей, норми, коефіцієнта удару та маси
  4. Нанесіть ударну силу на обидва кулі

У псевдокоді це стає:

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
    }
}

Ви можете опустити масу з алгоритму, якщо всі кулі мають однакову масу, а також припустити постійний радіус для всіх кульок для гри в більярд, але код буде кориснішим для вас без цих спрощень.

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


А як бути, якщо крапка менше нуля? Я досліджував цей псевдокод (і той, з яким ви також пов’язали, але другий закінчується моєю спробою взяти квадрат від'ємного числа - можливо, це проблема, яку ви з ним визначили). Ви впевнені, що хочете отримати результат при кожному наборі позицій та швидкостей введення?

@Poldie Якщо точка негативна, кульки вже віддаляються одна від одної. У цьому випадку не потрібно впоратися зіткненням.
msell

Я щойно збив тут свою версію коду: ideone.com/DhsAoW, і я отримую -0.707 на позиції 110,90 та 100,100, а також швидкості 0,2 та 0, -3. Це більш-менш лобове зіткнення. (Припустимо, початкова перевірка виявлення зіткнень на радіусі вже відбулася).
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.