Gibt es einen Algorithmus für ein Poolspiel?

14

Ich suche einen Algorithmus, um die Richtung und Geschwindigkeit von Bällen in einem Poolspiel zu berechnen. Ich bin mir sicher, dass es dafür eine Art Open-Source-Code geben muss, da Pool-Spiele zu den ältesten Computerspielen gehören, an die ich mich erinnern kann.

Ich meine, wenn ein Ball auf einen anderen trifft, brauche ich einen Algorithmus, um die Richtung beider zu berechnen. Es hängt vom genauen Winkel des Aufeinandertreffens und von der Geschwindigkeit ab.

Ich möchte Java-Codierung üben, daher suche ich nach Java-Code oder einem Paket mit diesem Codetyp.

Vaillancourt
quelle
2
Wenn Sie es jedoch selbst lösen möchten, benötigen Sie wahrscheinlich einige Vektorkenntnisse. Glücklicherweise hat neulich jemand anderswo auf dieser Website eine großartige Anleitung zur linearen Mathematik veröffentlicht .
Doppelgreener
Vielleicht kann Ihnen diese Seite helfen, archive.ncsa.illinois.edu/Classes/MATH198/townsend/…

Antworten:

8

Während die grundlegende Erkennung / Reaktion von Kugel-Kugel-Kollisionen recht einfach ist, wäre es schwieriger, sie genau genug für eine gute Pool-Simulation durchzuführen, da Sie sich mit dem Spin befassen müssten.

Kennen Sie die Existenz von Physik-Motoren? Einige beliebte Beispiele sind diese (und sie können viel mehr als nur Poolballkollisionen). Wahrscheinlich eine gute Wahl, um ein Poolspiel zu machen, aber nicht so sehr, um Java zu lernen ...

In 2D

Box2D: http://www.box2d.org

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

In 3D

Aufzählungszeichen: http://bulletphysics.org/

ODE: http://www.ode.org

Wenn Sie ein kommerzielles Spiel mit großem Budget erstellt haben:

Havok: http://www.havok.com

Bluescrn
quelle
1
Welche davon sind Java Physics Engines?
Ricket
Es gibt Java - Ports oder zumindest Bindungen für Box2D, Chipmunk, Geschoss, und ODE
bluescrn
2

Für ein einfaches Poolspiel, bei dem der Spin nicht modelliert ist, ist der Algorithmus recht einfach.

  1. Um zu überprüfen, ob eine Kollision auftritt, prüfen Sie, ob der Abstand zwischen den Kugeln kleiner ist als die Summe ihrer Radien.
  2. Berechnen Sie die Normalen des Aufpralls
  3. Berechnen Sie die Aufprallkraft anhand der Geschwindigkeitsdifferenz, der Normalen, des Aufprallkoeffizienten und der Massen
  4. Wenden Sie die Schlagkraft auf beide Kugeln an

Im Pseudocode wird dies:

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

Sie können die Masse aus dem Algorithmus auslassen, wenn alle Bälle die gleiche Masse haben und für alle Bälle für ein Poolspiel einen konstanten Radius annehmen. Ohne diese Vereinfachungen ist der Code jedoch für Sie nützlicher.

Der Code basiert auf diesem Tutorial , aber ich erinnere mich, dass die Impulsmultiplikation dort falsch war.

msell
quelle
Was ist, wenn der Punkt kleiner als Null ist? Ich habe diesen Pseudocode untersucht (und den, den Sie auch verlinkt haben, aber der andere führt dazu, dass ich versuche, das Quadrat einer negativen Zahl zu nehmen - vielleicht ist das das Problem, das Sie damit identifiziert haben). Sicherlich möchten Sie mit jedem Satz von Eingabepositionen und -geschwindigkeiten ein Ergebnis erzielen?
@Poldie Wenn der Punkt negativ ist, bewegen sich die Kugeln bereits voneinander weg. In diesem Fall ist keine Kollision erforderlich.
msell
Ich habe gerade meine Version Ihres Codes hier geknockt : ideone.com/DhsAoW und ich erhalte -0.707 für Positionen von 110,90 und 100.100 und Geschwindigkeiten von 0,2 und 0, -3. Dies ist eine mehr oder weniger direkte Kollision. (Angenommen, die anfängliche radiusbasierte Kollisionserkennungsprüfung ist bereits erfolgt.)