Logik hinter aufeinander stoßenden kugeln

  • GM 8

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Logik hinter aufeinander stoßenden kugeln

    Hallo,
    ich programmiere zwar in VB.Net aber das düfte ja
    kein Problem sein für euch.

    Ich habe mehrere Kreise (Wir nehmen jetzt dennoch einfahc erstmal zwei)
    Die stoßen irgedwann zusammen und ich möchte die daraus Resultierende
    X und Y Beweungsrichtung ermitten.
    Speedx ist die Geschwindigkeit in X richtung
    Speedy ist die Geschwindigikeit in Y richtung





    u1 und u2 sind ja die Geschwindigkeiten NACH dem Stoß.
    v1 und v2 sind die Geschwindigkeiten VOR dem Stoß.
    Als Masse habe ich jeweils einfach '1' genommen.

    Das ganze habe ich einmal für die X und einmal für die Y-Richtung
    berechnen lassen:



    V1x = speedX(i)
    V1y = speedY(i)
    V2x = speedX(x)
    V2y = speedY(x)
    M1 = 1
    M2 = 1

    U1x = (M1 * V1x + M2 * (2 * V2x - V1x)) / (M1 + M2)
    U1y = (M1 * V1y + M2 * (2 * V2y - V1y)) / (M1 + M2)

    U2x = (M2 * V2x + M1 * (2 * V1x - V2x)) / (M2 + M1)
    U2y = (M2 * V2y + M1 * (2 * V1y - V2y)) / (M2 + M1)

    speedX(i) = U1x
    speedY(i) = U1y

    speedX(x) = U2x
    speedY(x) = U2y


    Jetzt habe ich aber folgendes Problem:
    Stößt eine Kugel eine andere NICHT Zentral an, sondern versetzt vom Mittelpunkt her
    dann rollt die eine Kugel einfach weiter in X richtung und nicht der Physik entsprechend,
    sagen wir mal Schräg nach oben, so wie man es erwarten würde!

    Warum?

    Meine Vermutung ist: Ich brauche wohl dennoch Vektoren, weil es ein Zweidimensionaler Elastischer Stoß ist-
    Dummerweise leuchtet mir grad nicht ein wie ich das nun realisieren soll, sprich mir fehlt grad ein Ansatz, ich
    vergewaltige gerade schon wikipedia :D, könntet ihr mir da bitte helfen?
  • boxxar hat ja schon erwähnt, wie es von der Theorie her funktioniert: Reduktion auf das eindimensionale Problem. Ich erweitere einfach mal deinen Code so wie es funktionieren sollte.

    Quellcode

    1. V1x = speedX(i)
    2. V1y = speedY(i)
    3. V2x = speedX(x)
    4. V2y = speedY(x)
    5. M1 = 1
    6. M2 = 1
    7. // Vektor von einem Mittelpunkt zum anderen. (posX/Y stehen also für die Koordinaten)
    8. Rx = posX(i)-posX(x)
    9. Ry = posY(i)-posY(x)
    10. // Normieren.
    11. len = sqrt(Rx*Rx+Ry*Ry)
    12. Rx /= len
    13. Ry /= len
    14. // Projektion der Geschwindigkeiten auf die Gerade durch die Mittelpunkte.
    15. // Ist einfach das Skalarprodukt unter der Voraussetzung, dass (Rx,Ry) normiert ist.
    16. V1 = Rx*V1x+Ry*V1y
    17. V2 = Rx*V2x+Ry*V2y
    18. // Prüfen, ob sich die Kreise aufeinander zu bewegen.
    19. if (V1-V2 < 0) {
    20. // Nun die gewohnte Berechnung der neuen Geschwindigkeiten.
    21. // Hier mal die allgemeinste Formel. Die für den realen Stoß. (siehe Wikipedia)
    22. U1 = (M1*V1+M2*V2-M2*(V1-V2)*k)/(M1+M2)
    23. U2 = (M1*V1+M2*V2-M1*(V2-V1)*k)/(M1+M2)
    24. // Rückrechnung.
    25. speedX(i) += (U1-V1)*Rx
    26. speedY(i) += (U1-V1)*Ry
    27. speedX(x) += (U2-V2)*Rx
    28. speedY(x) += (U2-V2)*Ry
    29. }
    Alles anzeigen

    Habe den Code jetzt nicht getestet, aber so in etwa sollte es funktionieren.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Bl@ckSp@rk ()

  • Ich danke euch,
    das hat mir sehr geholfen und dein Code BlackSpark
    hat auch funktioniert. Ich hab aber den k-faktor entfernt
    da ich nicht wusste was du damit gemeint hast.

    Funktioniert aufjedenfall super, verstanden hab ich es auch! Danke :)

    Jetzt muss ich nur noch zusehn dass die Bälle auf garkeinenfall
    in einander rutschen, das passiert wenn ein ball in ruhe ist
    und ein anderer drauf fällt, dann schieben sie sich ineinander
    oder wenn man einen ball in den anderen mit gewalt reinschiebt
  • MindCode schrieb:

    Ich hab aber den k-faktor entfernt
    da ich nicht wusste was du damit gemeint hast.

    Schau mal hier: de.wikipedia.org/wiki/Sto%C3%9…hysik%29#Realer_Sto.C3.9F

    Beim realen Stoß werden elastischer und plastischer Stoß gemischt, wobei das k den Anteil des elastischen Stoßes angibt. Ist also k = 0, handelt es sich um einen rein plastischen Stoß, bei k = 1 um einen rein elastischen Stoß.
  • okay danke, ich hab mittlerweile
    jetzt die option eingebaut die kreise in unterschiedlicher größe erstellen zu können
    natürlich ändert sich die masse je nach größe des kreises, sau geil :)

    aber ich komm immer noch nicht drauf wie man verhindert
    dass die kreise sich überlagern in gewissen fällen, das kann wie gesagt
    passieren wenn:

    - eine kugel zu schnell ist
    - man eine kugel mti gewalt gegen eine andere drückt
    - eine kugel steht und die andere fällt drauf
    - die kollisions reaktion und erkennung zu träge abläuft

    bei vierecken ist das ja einfach, sollte x1 > x2 sein dann
    sagt man einfach x1 = x2 und führt dannach den abstoß algorhytmus aus
    aber entweder hab ich grad ne denkblockade oder es ist weitaus komplizierter
    bei kreisen... hast du oder jemand anders da vielleicht ne idee?
  • Du meinst wie man zwei sich überlappende Kreise auseinander bewegt?

    Ist eigentlich auch nicht so schwer.

    Quellcode

    1. // Summe der Radien beider Kreise.
    2. R = r(i)+r(x)
    3. // Wieder der Vektor von einem Mittelpunkt zum anderen.
    4. Rx = posX(i)-posX(x)
    5. Ry = posY(i)-posY(x)
    6. // Abstand der Mittelpunkte.
    7. d = sqrt(Rx*Rx+Ry*Ry)
    8. // Prüfen, ob sich die Kreise überschneiden.
    9. if (d < R) {
    10. // Falls die Mittelpunkte genau aufeinander liegen, ist es egal in welcher Richtung die Kreise auseinander bewegt werden.
    11. if (d == 0) {
    12. Rx = 1
    13. Ry = 0
    14. } else {
    15. Rx /= d
    16. Ry /= d
    17. }
    18. // Entfernung, um die beide Kreise bewegt werden.
    19. Rd = (R-d)/2
    20. // Kreise auseinander bewegen.
    21. posX(i) += Rd*Rx
    22. posY(i) += Rd*Ry
    23. posX(x) -= Rd*Rx
    24. posY(x) -= Rd*Ry
    25. }
    Alles anzeigen

    Es ist sinnvoll den Code für den Abprall dann einfach am Ende des äußeren if-Blocks auszuführen.
  • Klappt soweit gut, nur musste ich den
    gesamtradius bissl anders berechnen
    der reagiert zu früh wenn die radius summe aus r1 + r2
    besteht. daher habe ich die hälfte der radien addiert


    allerdings kleben abundzu mal die kreise aneinander...
    ich hab jetzt versucht da ne lösung zu finden, kann mir das allerdings nicht erklären
    ich vermute dass irgendwas mit den richtungsvektoren nicht stimmt, in die sich
    der kreis verschieben soll:
    schau mal hier:

    youtube.com/watch?v=RcBNjGEsWiI

    sie tendieren übrigends auch immer richtung Links oben oder Rechts unten!
    Das habe ich dadurch überprüft in dem ich die collisionreaktion umgekehrt habe
    und zwar so dass sich die kreise gegenseitig anziehen....
    dann sieht man dass eine perlenkette ensteht die schräg verläuft


    EDIT: PAssiert aber nur bei unterschiedlich großen bällen

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von MindCode ()

  • Klappt soweit gut, nur musste ich den
    gesamtradius bissl anders berechnen
    der reagiert zu früh wenn die radius summe aus r1 + r2
    besteht. daher habe ich die hälfte der radien addiert

    Das sollte eigentlich nicht sein, dass der da zu früh reagiert. Da es funktioniert hat, wenn du jeweils die Hälfte nimmst, kann ich mir nur vorstellen, dass du versehentlich den Durchmesser verwendet hast.

    Wenn ich mir so das Video anschaue, scheint da aber auch noch was anderes nicht zu stimmen. Bei 0:39 macht der eine kleine Kreis einen ungewöhnlich großen Sprung, was eigentlich nicht sein sollte. Prüfe nochmal deinen Code oder poste ihn hier.

    Was das aneinander Hängenbleiben der Kreise betrifft hast du recht. Ich hatte es erst weggelassen, weil ich noch nicht wusste für was du den Code brauchst. Habe es jetzt aber eingebaut in meinem ersten Post. Ist nur eine simple Abfrage hinzugekommen.
  • So, das Thema ist also vorerst mal erledigt.
    Ich werde jetzt demnächst noch dinge
    einbauen wie Anziehungskraft beeinflusst durch Masse.
    Und evtl die kollision bei Ball Gravity noch etwas
    verfeinern....

    hier mal ein video + source
    was aus dem projekt bisher geworden ist:

    [url]http://www.youtube.com/watch?v=GJN8DFhTEeE
    [/url]

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von MindCode ()

  • Habe mir deinen Code mal angeschaut. Was das erwähnte "Perlenkettenproblem" betrifft: Da hast du meinen Code falsch übernommen.

    Quellcode

    1. ...
    2. rc = (BallSize(i) / 4) + (BallSize(x) / 4)
    3. ry = (bCenterY(i) - bCenterY(x)) / 2
    4. rx = (bCenterX(i) - bCenterX(x)) / 2
    5. d = Sqrt(rx * rx + ry * ry)
    6. If d < rc Then
    7. If d = 0 Then
    8. rx = 0
    9. ry = 0
    10. Else
    11. rx /= d
    12. ry /= d
    13. End If
    14. rd = ((rc - d) / 2)
    15. 'Perlenkettenproblem liegt hier:
    16. If i <> x Then
    17. ball_loc_x(i) += (rd) * rx
    18. ball_loc_y(i) += (rd) * ry
    19. ball_loc_x(x) -= (rd) * rx
    20. ball_loc_y(x) -= (rd) * ry
    21. End If
    22. End If
    23. ...
    Alles anzeigen

    In Zeile 2 solltest du nur jeweils durch 2 teilen, in Zeilen 3 und 4 soll gerade nicht durch 2 geteilt werden. Dann sollte das funktionieren.

    Warum hast du eigentlich in Zeile 9 die 1 zu einer 0 gemacht? Wenn die Mittelpunkte aufeinander lägen, würden die Kreise ja dann gar nicht auseinander bewegt. Prinzipiell kann man an dieser Stelle einen beliebigen Einheitsvektor angeben. Ich habe der Einfachheit halber (1,0) gewählt.

    Noch einen Hinweis zur Doppelschleife: Du willst ja sicherlich jeden Kreis mit jedem anderen prüfen. In diesem Fall bietet sich folgendes Schema an:

    Quellcode

    1. For i = 0 To Ball_IndX
    2. For x = i+1 To Ball_IndX
    3. ...
    4. Next
    5. Next

    Damit ersparst du dir einerseits die Abfrage i <> x, und andererseits hast du auch nur halb so viele Durchläufe.
  • Zu Zeile 9:
    Da wollte ich was probiern, habe es aber vergessen wieder zu 1 zu machen.
    Allerdings tritt der fall so selten auf, dass er eigentlich garnicht auftritt :)

    Zu der For Next schleife, da hast du recht, das hatte ich mir auch schon
    überlegt aber dann nicht mehr dran gedacht, danke :)

    Zu Zeile 2:
    Sobald ich da durch 2 Teile, stoppen die schon vorher,
    das perlenkettenproblem ist zwar schon gelöst, allerdings nicht
    direkt elegant. Allerdings sagtest du gerade
    dass ich in Z. 3 und 4 nicht teilen soll, das erklärt
    natürlich einiges :)

    Danke