Existe-t-il un algorithme pour un jeu de billard?

14

Je recherche un algorithme pour calculer la direction et la vitesse des balles dans un jeu de billard. Je suis sûr qu'il doit y avoir un certain type de code open source pour cela, car les jeux de billard sont parmi les plus anciens jeux informatiques dont je me souvienne.

Je veux dire, quand une balle frappe une autre, j'ai besoin d'un algorithme pour calculer la direction des deux. Cela dépendra de l'angle exact où ils se heurtent et de la vitesse.

Je veux pratiquer le codage Java, donc je recherche du code Java ou un package qui a ce type de code.

Vaillancourt
la source
2
Si vous voulez le résoudre vous-même, vous aurez probablement besoin de quelques connaissances sur les vecteurs. Heureusement, quelqu'un a posté un autre pas à pas sur les mathématiques linéaires ailleurs sur ce site l'autre jour.
doppelgreener

Réponses:

8

Bien que la détection / réponse de collision sphère-sphère de base soit assez simple, il serait plus difficile de le faire avec suffisamment de précision pour une bonne simulation de pool, car vous auriez à faire face à la rotation.

Connaissez-vous l'existence de moteurs physiques? Voici quelques exemples populaires (et ils peuvent faire bien plus que de simples collisions avec des balles de billard). Probablement un bon choix pour faire un jeu de billard, mais pas tant pour apprendre Java ...

En 2D

Box2D: http://www.box2d.org

Chipmunk: http://code.google.com/p/chipmunk-physics/

En 3D

Bullet: http://bulletphysics.org/

ODE: http://www.ode.org

Si vous faisiez un jeu commercial à gros budget:

Havok: http://www.havok.com

bluescrn
la source
1
Parmi ces moteurs, lesquels sont des moteurs physiques Java?
Ricket
Il existe des ports Java ou au moins des liaisons pour Box2D, Chipmunk, Bullet et ODE
bluescrn
2

Pour un jeu de billard simple où le spin n'est pas modélisé, l'algorithme est assez simple.

  1. Pour vérifier si une collision se produit, vérifiez si la distance entre les billes est inférieure à la somme de leur rayon.
  2. Calculez la normale de l'impact
  3. Calculez la force d'impact en fonction de la différence de vitesse, de la normale, du coefficient d'impact et des masses
  4. Appliquer la force d'impact aux deux balles

En pseudo code cela devient:

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

Vous pouvez omettre la masse de l'algorithme si toutes les boules ont la même masse et assumer également un rayon constant pour toutes les boules pour un jeu de billard, mais le code vous sera plus utile sans ces simplifications.

Le code est basé sur ce tutoriel , mais je me souviens que la multiplication d'impulsions y était incorrecte.

msell
la source
Et si le point est inférieur à zéro? J'ai enquêté sur ce pseudocode (et celui que vous avez lié aussi, mais l'autre finit par essayer de prendre le carré d'un nombre négatif - c'est peut-être le problème que vous y avez identifié). Vous voulez sûrement produire un résultat avec chaque ensemble de positions et de vitesses d'entrée?
@Poldie Si le point est négatif, les boules s'éloignent déjà les unes des autres. Pas besoin de gérer la collision dans ce cas.
msell
Je viens de frapper ma version de votre code ici: ideone.com/DhsAoW et j'obtiens -0,707 pour des positions de 110,90 et 100,100, et des vitesses de 0,2 et 0, -3. Il s'agit d'une collision plus ou moins frontale. (Supposons que le contrôle de détection de collision basé sur le rayon initial a déjà eu lieu).