Czy istnieje algorytm gry w bilard?

14

Szukam algorytmu do obliczania kierunku i prędkości piłek w grze bilardowej. Jestem pewien, że musi istnieć jakiś rodzaj kodu typu open source, ponieważ gry w basenie są jednymi z najstarszych gier komputerowych, jakie pamiętam.

Mam na myśli, że kiedy jedna piłka uderza drugą, potrzebuję algorytmu, aby obliczyć kierunek obu z nich. Będzie to zależeć od dokładnego kąta ich uderzenia i prędkości.

Chcę poćwiczyć kodowanie Java, więc szukam kodu Java lub pakietu zawierającego ten typ kodu.

Vaillancourt
źródło
2
Jeśli jednak chcesz to rozwiązać samodzielnie, prawdopodobnie będziesz potrzebować wiedzy na temat wektorów. Na szczęście ktoś opublikował świetny przewodnik na temat matematyki liniowej gdzie indziej na tej stronie jeszcze innego dnia.
doppelgreener 30.01.11

Odpowiedzi:

8

Podczas gdy podstawowe wykrywanie / reakcja na kolizję sfera-kula jest dość prosta, wykonanie jej wystarczająco dokładnie dla dobrej symulacji puli byłoby trudniejsze, ponieważ musiałbyś poradzić sobie ze spinem.

Czy zdajesz sobie sprawę z istnienia silników fizyki? Oto niektóre popularne przykłady (i mogą one zrobić znacznie więcej niż tylko kolizje z piłką bilardową). Prawdopodobnie dobry wybór do tworzenia gier bilardowych, ale nie tyle do nauki Java ...

W 2D

Box2D: http://www.box2d.org

Wiewiórka: http://code.google.com/p/chipmunk-physics/

W 3D

Bullet: http://bulletphysics.org/

ODE: http://www.ode.org

Jeśli tworzysz komercyjną grę o dużym budżecie:

Havok: http://www.havok.com

bluescrn
źródło
1
Które z nich to jednak silniki fizyki Java?
Ricket 30.01.11
Istnieją porty Java, a przynajmniej powiązania dla Box2D, Chipmunk, Bullet i ODE
bluescrn 30.01.11
2

W przypadku prostej gry w bilard, w której spin nie jest modelowany, algorytm jest dość prosty.

  1. Aby sprawdzić, czy nastąpi kolizja, sprawdź, czy odległość między kulkami jest mniejsza niż suma ich promienia.
  2. Oblicz normalną siłę uderzenia
  3. Oblicz siłę uderzenia na podstawie różnicy prędkości, normalnej, współczynnika uderzenia i mas
  4. Przyłóż siłę uderzenia do obu kul

W pseudo-kodzie staje się to:

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

Możesz pominąć masę z algorytmu, jeśli wszystkie piłki mają tę samą masę, a także przyjąć stały promień dla wszystkich piłek w grze bilardowej, ale kod będzie bardziej przydatny bez tych uproszczeń.

Kod oparty jest na tym samouczku , ale pamiętam, że mnożenie impulsów było tam nieprawidłowe.

sprzedać
źródło
Co jeśli kropka jest mniejsza niż zero? Badałem ten pseudokod (i ten, który również podłączyłeś, ale drugi kończy się moją próbą zmierzenia kwadratu liczby ujemnej - być może jest to problem, który z nim zidentyfikowałeś). Czy na pewno chcesz uzyskać wynik z każdym zestawem pozycji wejściowych i prędkości?
@Poldie Jeśli kropka jest ujemna, kule już się od siebie oddalają. W takim przypadku nie ma potrzeby radzenia sobie z kolizją.
sprzedaje
Właśnie podrzuciłem tutaj moją wersję twojego kodu: ideone.com/DhsAoW i otrzymuję -0,707 za pozycje 110,90 i 100,100 oraz prędkości 0,2 i 0, -3. To mniej więcej zderzenie czołowe. (Załóżmy, że sprawdzanie kolizji oparte na początkowym promieniu już nastąpiło).