Ich versuche, ein Kollisionssystem in einem 2D-Spiel zu implementieren, das ich mache. Der Satz der Trennachse (wie im Kollisions-Tutorial von Metanet beschrieben ) scheint eine effiziente und robuste Methode für die Kollisionserkennung zu sein, aber ich mag die von ihnen verwendete Kollisionsreaktionsmethode nicht ganz. Durch blindes Verschieben entlang der Achse mit der geringsten Überlappung ignoriert der Algorithmus einfach die vorherige Position des sich bewegenden Objekts, was bedeutet, dass es nicht so sehr mit dem stationären Objekt kollidiert, wie es in dieses eindringt und dann abprallt.
Hier ist ein Beispiel für eine Situation, in der dies eine Rolle spielen würde:
Nach der oben beschriebenen SAT-Methode würde das Rechteck einfach senkrecht zu seiner Hypotenuse aus dem Dreieck herausspringen:
Realistisch sollte das Rechteck jedoch an der unteren rechten Ecke des Dreiecks anhalten, da dies der Punkt der ersten Kollision wäre, wenn es sich kontinuierlich entlang seines Verschiebungsvektors bewegen würde:
Nun, das ist vielleicht nicht wirklich wichtig während des Spiels, aber ich würde gerne wissen, ob es einen Weg gibt, auf diese Weise effizient und im Allgemeinen genaue Verschiebungen zu erzielen. Ich habe mir in den letzten Tagen den Kopf zerbrochen und möchte noch nicht aufgeben!
(Cross-posted von StackOverflow, hoffe das verstößt nicht gegen die Regeln!)
Antworten:
Hier ist die Methode, die ich gefunden habe. Es mag fehlerhaft sein, aber ich habe noch keine Probleme damit in meiner flüchtigen Analyse gefunden. Es funktioniert auch für beliebige Polygone mit ein paar geringfügigen Änderungen.
In den folgenden Abbildungen bewegt sich das blaue Objekt und das rote Objekt steht still. Schritt 1: Suchen Sie für jedes Polygon die beiden am weitesten entfernten Punkte entlang der Projektion dieses Polygons auf die Linie senkrecht zum Bewegungsvektor. Schritt 2: Teilen Sie jedes Polygon entlang der Verbindungslinie zwischen diesen Punkten. Die Hälfte des Polygons, die dem anderen Polygon entlang des Bewegungsvektors zugewandt ist, ist die "vordere Hülle". Dies ist der einzige Teil des Polygons, der möglicherweise kollidieren kann. Schritt 3:Projizieren Sie einen Vektor von jedem Punkt auf den "vorderen Rumpf" jedes Polygons entlang des Bewegungsvektors in Richtung des gegenüberliegenden Polygons und überprüfen Sie, ob er sich mit jeder Kante des "vorderen Rumpfs" des gegenüberliegenden Polygons schneidet. (Möglicherweise langsam, aber Computer sind heutzutage ziemlich schnell - richtig?) (Entschuldigen Sie den geneigten Pfeil. Alle Pfeile sollten parallel sein.) Schritt 4: Nehmen Sie den kürzesten Vektor. Dies ist die genaue Kollisionsentfernung. Schritt 5: Voila!
quelle
Schauen Sie sich diese ähnliche Frage an: Kollisionsauflösung
Und auch von http://www.metanetsoftware.com/technique/tutorialA.html#section5 (zu dem Sie einen Link gepostet haben :))
BEARBEITEN
Zusammenfassend und AFAIK gibt es ein paar Lösungen
quelle
Es hängt davon ab, ob Sie nur lineare Bewegungen möchten oder ob Sie auch mit Winkelbewegungen fertig werden müssen.
Eine Alternative zur Verwendung von SAT:
Im Falle von nur linear kann gegen den Minkowski-Unterschied der beiden Polygone vom Ursprung in Richtung der Delta-Lineargeschwindigkeit der Objekte gestrahlt werden.
Wenn der Strahl auf die MD trifft, kollidieren die beiden Objekte und der Trefferpunkt gibt die Zeit t an, zu der sie kollidierten.
Wenn sich die Objekte bewegen und drehen , wird es schwieriger, aber Sie können trotzdem eine ähnliche Technik anwenden. Mit Conservative Advancement können Sie sich mit diesem Fall befassen. Diese Technik ist iterativ; Jede Iteration generiert eine neue MD und bringt Sie der Zeit der Schnittmenge näher.
Hier ist der Originalentwurf zum konservativen Fortschritt:
http://www.continuousphysics.com/BulletContinuousCollisionDetection.pdf
Ich habe hier einen Artikel geschrieben, der die Technik ausführlich erklärt:
http://www.wildbunny.co.uk/blog/2011/04/20/collision-detection-for-dummies/
Hoffe diese Hilfe!
quelle