Esiste un algoritmo per un gioco di biliardo?


14

Sto cercando un algoritmo per calcolare la direzione e la velocità delle palle in un gioco di biliardo. Sono sicuro che ci deve essere un qualche tipo di codice open source per questo dato che i giochi di biliardo sono alcuni dei più vecchi giochi per computer che io possa ricordare.

Voglio dire, quando una palla colpisce un'altra, ho bisogno di un algoritmo per calcolare la direzione di entrambe. Dipenderà dall'angolo esatto di dove si urtano e dalla velocità.

Voglio esercitarmi nella codifica Java, quindi sto cercando codice java o pacchetto con questo tipo di codice.


2
Se vuoi risolverlo da solo, probabilmente avrai bisogno di una certa conoscenza dei vettori. Fortunatamente, qualcuno ha pubblicato un grande walkthrough sulla matematica lineare altrove su questo sito proprio l'altro giorno.
doppelgreener,

Risposte:


8

Mentre il rilevamento / risposta di base delle collisioni sfera-sfera è abbastanza semplice, farlo in modo sufficientemente accurato per una buona simulazione del pool sarebbe più complicato, dato che dovresti affrontare gli effetti.

Sei a conoscenza dell'esistenza di motori fisici? Alcuni esempi popolari sono questi (e possono fare molto di più di una semplice collisione con una palla da biliardo). Probabilmente una buona scelta per creare un gioco di biliardo, ma non tanto per imparare Java ...

In 2D

Box2D: http://www.box2d.org

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

In 3D

Bullet: http://bulletphysics.org/

ODE: http://www.ode.org

Se stavi realizzando un gioco commerciale di grande budget:

Havok: http://www.havok.com


1
Quali di questi sono motori fisici Java però?
Ricket,

Esistono porte Java o almeno collegamenti per Box2D, Chipmunk, Bullet e ODE
bluescrn


2

Per un semplice gioco di biliardo in cui lo spin non è modellato l'algoritmo è abbastanza semplice.

  1. Per verificare se si verifica una collisione, verificare se la distanza tra le sfere è inferiore alla somma del loro raggio.
  2. Calcola la normale dell'impatto
  3. Calcola la forza di impatto in base alla differenza di velocità, normale, coefficiente di impatto e masse
  4. Applicare la forza d'impatto su entrambe le sfere

In pseudo codice questo diventa:

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

Puoi omettere la massa dall'algoritmo se tutte le palline hanno la stessa massa e anche assumere un raggio costante per tutte le palline per un gioco di biliardo, ma il codice ti sarà più utile senza quelle semplificazioni.

Il codice si basa su questo tutorial , ma ricordo che la moltiplicazione dell'impulso non era corretta lì.


Che dire se il punto è inferiore a zero? Ho studiato questo pseudocodice (e anche quello che hai collegato, ma l'altro finisce con il mio tentativo di prendere il quadrato di un numero negativo - forse questo è il problema che hai identificato con esso). Sicuramente vuoi produrre un risultato con ogni set di posizioni e velocità di input?

@Poldie Se il punto è negativo, le palle si stanno già allontanando l'una dall'altra. Non è necessario gestire la collisione in quel caso.
msell,

Ho appena rovinato la mia versione del tuo codice qui: ideone.com/DhsAoW e sto ottenendo -0.707 per posizioni di 110,90 e 100,100 e velocità di 0,2 e 0, -3. Questa è una collisione più o meno frontale. (Si supponga che il controllo iniziale del rilevamento delle collisioni basato sul raggio sia già avvenuto).
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.