3D Kugelkollision mit anderen Kugeln
-
Danke schonmal, die Kollisionserkennung hab ich schon ganz gut gelöst, ähnlich wie deine Idee. Aber es ging mir grad nur um die Berechnuung der neuen Geschwindigkeitsvektoren. Sprich bei einem Hit in einer 3D-Umgebung ihre neuen Richtungen.
Danke.
Gruß Chris
EDIT: Die Lösung für die Erkennung ist wie folgt:
Jede Kugel bekommt eine lineare Gleichung, die dann gleichgesetzt werden, jedoch enthält diese megagleichung dann noch ein b, das Werte >= 0 <= 1 annehmen kann, und im Prinzip die den Faktor repräsentiert, womit die Geschwindigkeit multipliziert werden muss, damit man GENAU vor die andere Kugel gesetzt wird...
-
Abend.
Für die Neuberechnung der Geschwindigkeiten wendest du einen Kraftstoß an.
- Kugeln a und b bestehen aus Mittelpunkt p, Radius r und Masse m
- n = a.p - b.p- |n| bestimmen
- wenn (|n| > a.r + b.r), dann Abbruch, sonst n = n / |n| (Normierung)- vrel = n * (a.v - b.v) (Skalarprodukt)
- wenn (vrel < 0), dann ist ein Kraftsroß von Nöten, damit keine Durchdringung
stattfindet, sonst Abbruch- j = -(1 + eps) * vrel / (1 / a.m + 1 / b.m)
- J = j * n (Vektor mit Skalar multiplizieren)- a.v = a.v + J / a.m
- b.v = b.v - J / b.mDie Längenbestimmung |n| nur 1 Mal, wegen der ineffizienten Wurzelbestimmung.
4 Divisionen (auch zeitfressende Operationen) kannst du dir auch sparen, indem
du die inversen Massen speicherst, anstatt der bzw. zusätzlich zu den normalen
Massen./edit:
Die Kollisionserkennung kannst du auch verbessern, indem du statt
|n| = sqrt(n.x² + n.y² + n.z²) mit der Summe der Radien, die quadratische Länge |n|² = n.x² + n.y² + n.z² mit der quadratischen Summe der beiden Radien (a.r + b.r)², vergleichst.So und nun wirklich gute Nacht.
-
Erstmal wieder vielen DANK!!
So, die Kollisionserkennung klappt hervorragend die ich bereits hab. Grade was Speed > Durchmesser einer anderen Kugel angeht, und das daurch unausweichliche "Durchfliegen". So aber es ging mir jetzt speziell um die berechnung der neuen Richtungsvektoren, oder ist in deinem Beitrag bereits drin und ich bin nur zu doof um das zu erkennen zu dieser späten Stunde. Was meisnt du mit "eps" ??
Und genau enthält j bzw J hinterher ?Danke für deinen ausführlichen Tipp
Gruß Chris
-
Morgen.
Ja, das ist eigentlich ein Rundum-Programm: Kollisionserkennung und -behandlung
Ich sehe ich hab, vergessen zu erwähnen, dass v die Richtungsvektoren sein
sollen. Naja war spät.
Und wie du siehst wird ganz am Ende a.v und b.v neu berechnet.Das eps ist eine Stoßkonstante mit 0 <= eps <= 1.
0 bedeutet maximaler Energieverlust
1 bedeutet kein Energieverlustj ist eine positive reelle Zahl, die die Stärke des Kraftstoßes angibt.
n ist die Richtung des KraftstoßesJ ist der Vektor des Kraftstoßes (also j * n)
Und am Ende wird eben dann der Kraftstoß auf die Kugeln übertragen. Einmal
+ auf Kugel a und einmal - auf die Kugel b.
Damit bleibt die relative tangentielle Geschwindigkeit erhalten. Nur die
Geschwindigkeit parallel zu n muss verändert werden, da nur sie eine
Durchdringung hervorruft.Du hast Recht. Da hab ich gar nicht mehr dran gedacht, dass sich diese beiden Kugeln durchfliegen können ohne Durchdringung. Aber der naive Ansatz geht auch bei normalen Simulationen, wie Snooker oder ähnliches.
-
Alles klar... Ich drehe die Impulsvektoren im moment mit der Y bzw Z Rotationsmatrix, damit ich die Komponenten haben, die wirklich zur Richtungsänderung beitragen, mein Problem war, dass bei 3D (Nicht bei 2D, da klappte alles wunderbar) anscheined iwie die MAtrixrotation falsch läuft was natürlcih eine Fehlberechnung der Impulsvektoren zur Folge hat. Ich werde es iwie schon hinkriegen, danke aber für die Ansätze!!
Gruß Chris
-
Ganz schön kompliziert und ineffizient, wenn du mit Matrizen arbeitest in
diesen Bereich.
Mein Ansatz kickt viele von diesen Redundanzen raus. Aber das musst du selbst
entscheiden.Übung macht den Meister
-
Ehrlich gesagt bin ich etwas deprimiert, dass du das ohne kannst
Ich dachte immer man bräuchte für die berechnet des Impulses ne Matrize !!
-
Naja, siehst du in meinem Vorschlag eine Matrix, die kein Vektor ist?
-
Also deine Idee klappt hervorragend, nur eine Sache is mir aufgefallen war (Ich will nicht sagen falsch, aber wenn ich sie aßer Acht lassen, klappt alles)
Du hast diese gepostet:
- vrel = n * (a.v - b.v) (Skalarprodukt)
- wenn (vrel < 0), dann ist ein Kraftsroß von Nöten, damit keine Durchdringung
stattfindet, sonst AbbruchIch habe den Betrag von vrel geprüft, (Ich hoffe das Meintest du damit), und dann klappte es nicht , wenn ich bei >= 0 aus meiner Funktion sprang.
Hier der Code
public static void betweenBalls(Ball tori, Ball uke) { if(tori == null || uke == null) return; //Wir berechnen zuerst die Entfernung der beiden Bälle Vector dist = tori.getPosition().sub(uke.getPosition()).unitVector(); Vector vrel = dist.mul( tori.getSpeed().sub(uke.getSpeed()) ); //if(!(vrel.track() < 0)) //return; double j = vrel.mul(-(1 + 1)).div( 1 / tori.getMass() + 1 / uke.getMass() ).track(); Vector J = dist.mul(j); tori.setSpeed( tori.getSpeed().add(J.div(tori.getMass()) ) ); uke.setSpeed( uke.getSpeed().sub(J.div(uke.getMass())) ); }
Damit scheint es zu funktionieren. Einfach genial, und ich hantiere da mit MAtrizen rum, was auch geklappt hat, aber deines ist genialer
Naja danke !!
Gruß Chris
-
Zeile 9 : vrel ist kein Vektor sondern eine reelle Zahl(deswegen Skalarprodukt)
Und diese vielleicht negative Zahl zeigt an, ob sich die beiden Kugeln im
nächsten Zeitschritt durchdringen.
-
Sry, habs übersehen, aber als Vektor klappts auch :D^^ Ok, danke für alles! Dank dir hab ich ne neue Sicht der Dinge
Gruß Chris
-
Klar klappt's damit^^ du brauchst ja bloß den Betrag. Das Vorzeichen soll aber
noch andere Informationen liefern. Aber wenn's geht, kann ich ja beruhigt
Einkaufen fahren.