Есть ли алгоритм для игры в бильярд?

14

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

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

Я хочу попрактиковаться в Java-кодировании, поэтому я ищу Java-код или пакет с таким типом кода.

Vaillancourt
источник
2
Если вы хотите решить это самостоятельно, вам, вероятно, понадобится знание векторов. К счастью, кто-то недавно опубликовал большое руководство по линейной математике в другом месте на этом сайте.
двойник
может быть , этот сайт может помочь вам archive.ncsa.illinois.edu/Classes/MATH198/townsend/...

Ответы:

8

Хотя базовое обнаружение / реакция столкновения сфера-сфера довольно простое, сделать это достаточно точно для хорошей симуляции пула будет сложнее, так как вам придется иметь дело с вращением.

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

В 2D

Box2D: http://www.box2d.org

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

В 3D

Bullet: http://bulletphysics.org/

ODE: http://www.ode.org

Если вы делали большую бюджетную коммерческую игру:

Havok: http://www.havok.com

bluescrn
источник
1
Какие из них являются физическими движками Java?
Рикет
Существуют Java-порты или, по крайней мере, привязки для Box2D, Бурундука, Bullet и ODE
bluescrn,
6

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

Leander
источник
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
    }
}

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

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

msell
источник
А что если точка меньше нуля? Я исследовал этот псевдокод (и тот, который вы тоже связали, но другой заканчивает тем, что я пытался взять квадрат отрицательного числа - возможно, это проблема, которую вы с ним идентифицировали). Конечно, вы хотите получить результат с каждым набором входных позиций и скоростей?
@Poldie Если точка отрицательная, шары уже удаляются друг от друга. Не нужно обрабатывать столкновения в этом случае.
msell
Я только что выбил свою версию вашего кода здесь: ideone.com/DhsAoW, и я получаю -0,707 за позиции 110,90 и 100,100 и скорости 0,2 и 0, -3. Это более или менее лобовое столкновение. (Предположим, что начальная проверка обнаружения столкновений по радиусу уже произошла).