Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Fr Jul 18, 2025 07:58

Foren-Übersicht » Programmierung » OpenGL
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 9 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Kollision: Sphere-Sphere + Abprall
BeitragVerfasst: Di Dez 13, 2005 16:31 
Offline
DGL Member
Benutzeravatar

Registriert: Di Sep 06, 2005 18:34
Beiträge: 362
Wohnort: Hamburg
Hi ...

Ich hänge jetzt schon eine ganze Weile an einem Problem fest...
Vorab nochmal kurz zu meinem Projekt:
In einem Terrain fliegen Bälle durch die Gegend.
Problem:
Die Bälle sollen sich untereinander auch treffen und von einander abprallen (der Realismus muss dabei nicht sehr hoch sein, aber es muss gut funktionieren)

Ich habe mit schon viele Tutorials zu Sphere-Sphere Kollisionen durchgelesen und auch zum Abprallen von einander, aber irgendwie bin ich nie richtig schlau draus geworden oder es hat nicht richtig funktioniert...

Also habe ich mir mal meine eigenen Gedanken gemacht:
Da ich für Schüsse bereits eine funktionierende Strahl-Sphere Kollision habe, dachte ich damit ließe sich was Anfangen.
Meine Überlegung: den Radius der Sphere B um den Radius der Sphere A erhöhen und dann mit dem Richtungsvektor und dem Mittelpunkt von A eine Strahl-Sphere Kollision mit der Sphere B mit erhöhtem Radius berechnen.
Die Berechnung funktioniert auch ganz gut glaube ich.
Damit lässt sich auch ziemlich genau der Kollisionspunkt bestimmen ...
Allerdings bin ich mir nicht 100%ig sicher, dass dies der richtige Weg ist ...

Hier mal der Code (zwar C++, aber ich denke die meisten werden damit klar kommen ;) )
Code:
  1.  
  2. bool Ball::SphereCollision(Ball *pBall,float time,CVector3 *norm)
  3. {
  4.     // pos = Mittelpunkt von B
  5.     CVector3 pos = pBall->GetPos();
  6.     // rad = erhöhter Radius von B
  7.     float rad = m_fRadius + pBall->GetRadius();
  8.     float r2 = rad * rad;
  9.  
  10.     // dir = normalisierter Richtungsvektor des Strahls
  11.     CVector3 dir = m_vVelocity;
  12.     float length = dir.GetLength();
  13.     dir.Normalize();
  14.  
  15.     CVector3 vL = pos - m_vPos;
  16.     float l2 = vL * vL;
  17.     if(l2 <= r2)
  18.     {
  19.         norm->Set(vL);
  20.         return true;
  21.     }
  22.  
  23.     float tca = dir * vL;
  24.     if(tca < 0.0f)
  25.         return false;
  26.  
  27.     float d2 = l2 - tca * tca;
  28.     if(d2 > r2)
  29.         return false;
  30.  
  31.     // t = Kollisionszeitpunkt
  32.     float t = tca - sqrt(r2 - d2);
  33.     if(t > length * time)
  34.         return false;
  35.  
  36.     // gibt den Vektor vom Kollisionspunkt zum Mittelpunkt von P zurück
  37.     norm->Set(pos - (m_vPos + dir * t));
  38.     return true;
  39. }
  40.  


Nun zum zweiten Problem, dem Abprallen von einander.
Da habe ich bis jetzt 2 Möglichkeiten ausprobiert.
1. Den Vektor zwischen Kollisionspunkt und Mittelpunkt von B als Normalenvektor der Kollisionsebene nehmen und für beide Kugeln den Richtungsvektor entsprechend des Normalenvektors verändern
2. Die mehr physikalische Möglichkeit die im NeHe Tut 30 vorgestellt wird. Dort wird auch auf die Masse der Kugeln eingegangen, was besser ist, da eine Kugel eine andere, die ruhig liegt damit auch anstoßen kann. (was mir lieber ist)

Allerdings bringen beide Möglichkeiten keine zufriedenstellenden Ergebnisse.
Bei beiden tritt das Problem auf, dass wenn die Kugeln mit einer sehr geringen Geschwindigkeit auf einander treffen sie sich sozusagen in einander verhaken und nur schwer wieder zu lösen sind (durch Schüsse) oder eine um die andere herumfliegt und dann leicht weggeschleudert wird ...

Wenn die Geschwindigkeiten groß genug sind, dass sie auch anständig Abprallen, d.h. der Weg während eines Frames groß genug ist, klappt die Kollision sehr gut und sieht auch relativ gut aus ...

Hier der Code: (zwar unoptimiert, aber wenn er nicht funktioniert muss ich ihn auch nicht optimieren *g*)
Code:
  1.  
  2. // jeden Ball durchgehen
  3. for(i=0;i<balls->iNumber;i++)
  4. {
  5.     // auf Kollision mit anderen Bällen prüfen
  6.     for(int j=i+1;j<balls->iNumber;j++)
  7.     {
  8.         if(m_pBalls[j].SphereCollision(&m_pBalls[i],time,&norm))
  9.         {
  10.             CVector3 xaxis = m_pBalls[j].GetPos() - m_pBalls[i].GetPos();
  11.             xaxis.Normalize();
  12.  
  13.             CVector3 U1x = xaxis * (xaxis * m_pBalls[i].GetVelocity());
  14.             CVector3 U1y = m_pBalls[i].GetVelocity() - U1x;
  15.  
  16.             CVector3 U2x = (xaxis * -1) * ((xaxis * -1) * m_pBalls[j].GetVelocity());
  17.             CVector3 U2y = m_pBalls[j].GetVelocity() - U2x;
  18.  
  19.             CVector3 tmp = (U1x * m_pBalls[i].GetWeight()) + (U2x * m_pBalls[j].GetWeight());
  20.             CVector3 V1x = (tmp - (U1x - U2x) * m_pBalls[j].GetWeight()) * (1 / (m_pBalls[i].GetWeight() + m_pBalls[j].GetWeight()));
  21.             CVector3 V2x = (tmp - (U2x - U1x) * m_pBalls[i].GetWeight()) * (1 / (m_pBalls[i].GetWeight() + m_pBalls[j].GetWeight()));
  22.  
  23.             m_pBalls[i].SetVelocity(V1x + U1y);
  24.             m_pBalls[j].SetVelocity(V2x + U2y);
  25.         }
  26.     }
  27.  
  28.     // andere Kollisionsabfragen ... Ball bewegen
  29. }
  30.  


Hoffe mir kann da jemand helfen ...

Gruß
Shai

_________________
Der Mensch hat neben dem Trieb der Fortpflanzung und dem zu essen und zu trinken zwei Leidenschaften: Krach zu machen und nicht zuzuhören. (Kurt Tucholsky)
Schwabbeldiwapp, hier kommt die Grütze. (Der Quästor)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Dez 13, 2005 16:42 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jul 17, 2002 12:07
Beiträge: 976
Wohnort: Tübingen
Also ich habe so etwas ähnliches schonmal gemacht (also Kollision von zwei Bällen) und das Ganze auch noch ein bisschen weitergedacht. Da du ja (wahrscheinlich) die Massen der Kugeln und ihre Geschwwindigkeit kennst, würde ich folgende Formel aus meiner Formalsammlung für den elastischen Stoß verwenden:
Zitat:
v1= (m1*v1 + m2*(2*v2-v1)) / (m1 + m2);
v2= (m2*v2 + m1*(2*v1-v2)) / (m1 + m2);

Wenn ich richtig liege, kannst du ja v jeweils in drei Teilvektoren zerlegen, und dann dürfte das eigentlich physikalisch optimal funktionieren.

PS: Warum nutzt du eigentlich nicht Newton? (Das musste einfach kommen)

_________________
"Du musst ein Schwein sein in dieser Welt, sangen die Prinzen, das ist so 1.0. Du musst auf YouTube zeigen, dass dir dein Schweinsein gefällt, das ist leuchtendes, echtes Web 2.0."
- Hal Faber

Meine Homepage: http://laboda.delphigl.com


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Dez 13, 2005 18:49 
Offline
DGL Member
Benutzeravatar

Registriert: Di Sep 06, 2005 18:34
Beiträge: 362
Wohnort: Hamburg
Hi ...

erstmal danke für die Antwort ...
Ich werde deinen Tip mal ausprobieren ...

Warum benutze ich nicht Newton?
Naja, ich schätze ich will nicht so viel vorgegeben bekommen, ich möchte lieber meine eigenen Erfahrungen machen und selber ein bischen tiefer in die Materie einsteigen, d.h. solche Sachen auch selber verstehen ...

Gruß
Shai

_________________
Der Mensch hat neben dem Trieb der Fortpflanzung und dem zu essen und zu trinken zwei Leidenschaften: Krach zu machen und nicht zuzuhören. (Kurt Tucholsky)
Schwabbeldiwapp, hier kommt die Grütze. (Der Quästor)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Dez 13, 2005 19:26 
Offline
DGL Member
Benutzeravatar

Registriert: Di Sep 06, 2005 18:34
Beiträge: 362
Wohnort: Hamburg
Hi...

Ich glaube ich habe dich nicht ganz verstanden ...

V1 / V2 ... sind dass die Geschwindigkeitsvektoren oder die Geschwindigkeiten (also die Längen der Vektoren) ???
Und was meinst du genau mit zerlegen in Teilvektoren ???

Gruß
Shai

_________________
Der Mensch hat neben dem Trieb der Fortpflanzung und dem zu essen und zu trinken zwei Leidenschaften: Krach zu machen und nicht zuzuhören. (Kurt Tucholsky)
Schwabbeldiwapp, hier kommt die Grütze. (Der Quästor)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Dez 13, 2005 19:49 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jul 17, 2002 12:07
Beiträge: 976
Wohnort: Tübingen
Also Kugel 1 hat v1, Kugel 2 v2.
Die Geschwindigkeit muss man ja für drei Richtungen angeben. v1 und v2 sind also Vektoren
v1: (v1x, v1y, v1z)
v2 analog

Du rechnest also mit der Formal sechsmal, für jede Kugel dreimal.
also zB:

v1x= (m1*v1x + m2*(2*v2x-v1x)) / (m1 + m2);

_________________
"Du musst ein Schwein sein in dieser Welt, sangen die Prinzen, das ist so 1.0. Du musst auf YouTube zeigen, dass dir dein Schweinsein gefällt, das ist leuchtendes, echtes Web 2.0."
- Hal Faber

Meine Homepage: http://laboda.delphigl.com


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Dez 13, 2005 20:07 
Offline
DGL Member
Benutzeravatar

Registriert: Di Sep 06, 2005 18:34
Beiträge: 362
Wohnort: Hamburg
Ok, hab ich mir fast schon gedacht ...
Jetzt denken die Bälle aber garnicht mehr daran sich von einander zu lösen und verfransen sich bei jedem Kontakt in einander ... ich glaub ich gebs langsam auf, hab da keinen bock mehr drauf ... *grmpf*

naja, auf jeden fall danke für die Hilfe ... und fals jemand noch irgend welche Vorschläge hat, was ich falsch gemacht habe, bzw. was ich besser machen könnte ... immer her damit ...

ich bin total fertig und brauch jetzt erstmal ne kippe ;)

_________________
Der Mensch hat neben dem Trieb der Fortpflanzung und dem zu essen und zu trinken zwei Leidenschaften: Krach zu machen und nicht zuzuhören. (Kurt Tucholsky)
Schwabbeldiwapp, hier kommt die Grütze. (Der Quästor)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Dez 13, 2005 21:32 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jul 17, 2002 12:07
Beiträge: 976
Wohnort: Tübingen
Da du nicht unendlich genau arbeiten kannst, kann es sein, dass in einem Frame die Kugeln schon ineinanderrutschen, bevor du den Kollisionstest machst. Nach diesem Test sollten die Kugeln dann auseinanderstreben, aber wenn sie sich dann noch nicht so weit bewegt haben, dass sie sich immer noch überschneiden, dann wird wieder die Kollision durchgeführt und das geht das immer so weiter.
Du solltest also nach der Kollisionsprüfung und der Berechnung der neuen Geschwindigkeitsvektoren auch die Positionen der Kugeln so setzen, dass sie sich garantiert nicht überscheiden.

_________________
"Du musst ein Schwein sein in dieser Welt, sangen die Prinzen, das ist so 1.0. Du musst auf YouTube zeigen, dass dir dein Schweinsein gefällt, das ist leuchtendes, echtes Web 2.0."
- Hal Faber

Meine Homepage: http://laboda.delphigl.com


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Dez 13, 2005 22:26 
Offline
DGL Member
Benutzeravatar

Registriert: Di Sep 06, 2005 18:34
Beiträge: 362
Wohnort: Hamburg
Ok ... da, alles andere nicht funktioniert hat habe ich noch einmal an der Möglichkeit mit der einfachen Abprall-Normalen gearbeitet und sie stabil bekommen ...
Dazu habe ich noch einen gefakten Stoß angefügt, der schon relativ realistisch erscheint, aber noch etwas verbessert wird ...

Will damit sagen, das Problem ist vorerst abgehakt ...

Sollte trotzdem jemand weitere Vorschläge haben würde ich mich trotzdem freuen

danke für die Hilfe

Gruß
Shai

_________________
Der Mensch hat neben dem Trieb der Fortpflanzung und dem zu essen und zu trinken zwei Leidenschaften: Krach zu machen und nicht zuzuhören. (Kurt Tucholsky)
Schwabbeldiwapp, hier kommt die Grütze. (Der Quästor)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Dez 13, 2005 22:30 
Offline
DGL Member
Benutzeravatar

Registriert: Di Dez 02, 2003 12:47
Beiträge: 300
Wohnort: Marburg
Wahrscheinlich ist ein Vorzeichen bei der Geschwindigkeit falsch!

und:

du musst dir merken für welche kugel-paare du eine Kollision berechnet hast,
bei diesen Kugel-Kombinationen darf dann solange keine Kollision mehr berechnet werden,
bis sie einen Frame lang nicht in berührjung waren.

und:

deine Methode wird automatisch versagen, wenn 3 kugeln kollidieren!

wenn du dass verhindern willst, kann man mit recht guter Performance Kollisionen elastisch berechnen.

oder: man muss die Position von kugeln nachkorrigieren, wenn sie länger als einen Rehchenschritt ineinander eingedrungen bleiben, damit würde auch ermöglicht, dass kugeln aufeinander liegen können (theoretisch jedenfalls).

ich arbeite aber mit elastischer Kollision, kommt auf den Verwendungszweck an (ich will auch Reibung und so haben, da ist das einfacher).

übrigens: bei solchen Sachen macht man zu beginn viele flüchtigkeits- fehler (meiner Erfahrung nach). dann glaubt man es funktioniert nicht, aber in Wirklichkeit sind’s nur blöde Fehler...

_________________
Nothing, oh sweet nothing,
today we are doing nothing at all...
http://www.geo-progs.de


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 9 Beiträge ] 
Foren-Übersicht » Programmierung » OpenGL


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 2 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
cron
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.009s | 14 Queries | GZIP : On ]