Kollision und Reflexion - Elastischer Stoß

    • C#

    Es gibt 5 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

      Kollision und Reflexion - Elastischer Stoß

      Um diesen Thread den wesentlichen Inhalten vorzubehalten und weil er der Moderation unterliegt, postet bitte Meinungen, Fehlermeldungen und solstiges hier:
      Diskussion zum Thema Kollision und Reflexion - Elastischer Stoß


      Der Bitte vom @ErfinderDesRades folgend hab ich mich mal hingesetzt und das ganze in WinForm als Billiard-Spiel umgesetzt.
      Hilfe bei Erstellung einer Kollisionserkennung
      Kein Pong - Erstaunliches mit ItemsControl.Itemspanel
      Hier war der bisher beste Ansatz: 2D Physic Engine (Kreise mit Kollision) [NEUE FRAGE]

      Letztenendes sind zwei Prozeduren interessant: Die Behandlung der Reflexion an der Wand und die der Reflexion zweier Bälle.
      Dazu wird getestet, ob die aktuelle Position zu dicht am jeweils anderen Objekt ist. Wenn ja, erfolgt eine Reflexion.
      An der Wand muss nur die jeweilige Geschwindigkeitskomponente invertiert werden, beim elastischen Stoß liefert die Physik die Theorie:
      de.wikipedia.org/wiki/Sto%C3%9F_(Physik)

      Final sind die markierten Gleichungen relevant, und mit der entsprechenden Vektor-Klasse kann man sie direkt so in den Code schreiben:

      C#-Quellcode

      1. Vector v1 = o1.Speed;
      2. Vector v2 = o2.Speed;
      3. float m1 = o1.Mass;
      4. float m2 = o2.Mass;
      5. Vector v11 = 2F * ((m1 * v1) + (m2 * v2)) / (m1 + m2) - v1;
      6. Vector v22 = 2F * ((m1 * v1) + (m2 * v2)) / (m1 + m2) - v2;
      7. o1.Speed = v11;
      8. o2.Speed = v22;
      Wie man sieht: Elementar einfach. :D
      Zur Illustration 3 Szenen im Abstand von je ca. einer Sekunde:

      Mit dem Button Next wird eine neue Kugel ins Spiel gebracht. Immer an derselben Position, aber mit Zufalls-Geschwindigkeiten.
      Hierbei wird momentan nicht getestet, ob sich an der Einfügeposition eine Kugel befindet, da kann also Unsinn passieren.
      Je kleiner die Zeiteinheiten sind (momentan 2 Einheiten) um so präziser werden die Stöße berechnet.
      Sicher ist noch nicht alles optimal, aber dies soll nur ein Beispiel zur Lösung sein.
      =====================
      Defektes Projekt entfernt,
      bitte den Anhang von @VaporiZed verwenden.
      =====================
      Anmerkung vom @ErfinderDesRades : Dieses Projekt behandelt (momentan nur) den zentralen elastischen Stoß, d.h., die Kugeln verhalten sich so, als ob die Richtungsvektoren eine gemeinsame Gerade beschreiben.
      Den dezentralen Stoß reiche ich nach.
      =====================
      Neue Version vom 11.04.2018, unterschiedliche Massen und Reflexion an der Wand werden gut behandelt.
      Collision.zip
      Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
      Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
      Ein guter .NET-Snippetkonverter (der ist verfügbar).
      Programmierfragen über PN / Konversation werden ignoriert!

      Dieser Beitrag wurde bereits 6 mal editiert, zuletzt von „RodFromGermany“ ()

      Du scheinst da nachträglich noch was umbenannt zu haben. Das von Dir gepostete vom 30.03. erzeugt folgende Fehlermeldung, da die Projekteinstellungen nicht zu den tatsächlichen Dateinamen passen:

      Hier die sonst unveränderte Version mit umbenannten Form-Dateien: Kollision dateinamenkorrigiert.zip

      Manchmal werden die Bälle, wenn sie parallel zur Wand verlaufen, unregelmäßig abgebremst und wieder beschleunigt.
      Durch zu knappe Kollisionen mit Wand und einem anderen Ball kann es zu 1-Frame-Ballpositionswechseln und dauerhaft zu Verschiebungen außerhalb des Feldes kommen.
      Das alles sind nur Beobachtungen für Verbesserungen. Ich habe leider weder die Kenntnis noch die Zeit, diese selber auszubessern.
      Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

      Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
      Danke @VaporiZed und @Bluespide, ich hatte Form1 in MainForm umbenannt.
      Das mit den Randstößen ist mir auch schon aufgefallen und ich arbeite an der nächsten Version.
      Status:
      Nach der Zeitscheibe wird erkannt, dass eine Kollision eingetreten ist, es wird mit der aktuellen Position weitergerechnet, die aber eine Überschneidung der Kugeln beschreibt.
      Plan:
      Den rückwärtigen Zeitpunkt ermitteln, an dem die Kollision tatsächlich stattfindet und von dieser Position aus weiterrechnen.
      Für die Reflexion an der Wand ist dies bereits umgesetzt.
      Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
      Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
      Ein guter .NET-Snippetkonverter (der ist verfügbar).
      Programmierfragen über PN / Konversation werden ignoriert!
      Dank dem @ErfinderDesRades kommt nun die nächste Version, die den dezentralen Stoß gleicher Massen beschreibt.
      Die Reflexion an er Wand ist noch nicht perfekt, das kommt in der nächsten Version.
      Ich habe folgende auswählbare Spezialfälle eingebaut:
      Zentraler Stoß, v2 = -v1; v2 = 0;
      Dezentraler Stoß, v2 = -v1; v2 = 0; mit wählbarem Abstand der beiden horizontalen Achsen
      Dezentraler Stoß, beide Achsen stehen senkrecht aufeinander, wählbarem Abstand des Stoßpunktes.
      Kollision.zip
      Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
      Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
      Ein guter .NET-Snippetkonverter (der ist verfügbar).
      Programmierfragen über PN / Konversation werden ignoriert!
      gugget auch mal Kein Pong - Erstaunliches mit ItemsControl.Itemspanel , Abschnitt "2-dimensionaler Stoß".
      Zum einen weil ich's da glaub mathematisch korrekt abgehandelt hab, zum anderen, wegen der Verwendung der Vector-Structure, die's im Framework bereits gibt, sehr komfortabel und von lupenreiner Architktur:
      Scalar-Multiplikation, ScalarProdukt (himmelweiter Unterschied das!), Kreuzprodukt, Länge, LängeQuadrat, Normalisiern, Determinante, Winkel, Gleichheits-Operator
      Dank dem @ErfinderDesRades kommt nun die nächste Version, die den dezentralen Stoß unterschiedlicher Massen beschreibt.
      Die Reflexion an er Wand sieht nun gut auch aus.
      Die Testfälle können nun mit { m1=m2; m1<m2; m1>m2 } durchgeführt werden, die schwerere Kugel hat den größeren Radius.
      Ich packe das Projekt in den Post #1.
      Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
      Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
      Ein guter .NET-Snippetkonverter (der ist verfügbar).
      Programmierfragen über PN / Konversation werden ignoriert!