Das Separating Axis Theorem (SAT) macht es einfach, den Minimum Translation Vector zu bestimmen, dh den kürzesten Vektor, der zwei kollidierende Objekte trennen kann. Was ich jedoch brauche, ist der Vektor, der die Objekte entlang des Vektors trennt, den das eindringende Objekt bewegt (dh den Kontaktpunkt).
Ich habe ein Bild gezeichnet, um es zu verdeutlichen. Es gibt eine Kiste, die sich von der Vorher- zur Nachher-Position bewegt. In seiner Nachposition schneidet es das graue Polygon. SAT kann das MTV, das der rote Vektor ist, leicht zurückgeben. Ich suche den blauen Vektor zu berechnen.
Meine aktuelle Lösung führt eine binäre Suche zwischen den Vorher- und Nachher-Positionen durch, bis die Länge des blauen Vektors bis zu einem bestimmten Schwellenwert bekannt ist. Es funktioniert, ist aber eine sehr teure Berechnung, da die Kollision zwischen Formen bei jeder Schleife neu berechnet werden muss.
Gibt es eine einfachere und / oder effizientere Möglichkeit, den Kontaktpunktvektor zu finden?
Antworten:
Über was Sie sprechen, ist ziemlich schwierig, wenn Sie es so strukturieren, dass Sie zuerst ein Objekt bewegen, dann auf Kollision prüfen und dann zurücktreten, bis Sie das Objekt verlassen. Es ist wahrscheinlich besser, sich dies als dynamischen Kreuzungstest vorzustellen : ein sich bewegendes Objekt gegen ein stationäres Objekt.
Trennachsentests können Ihnen hier zum Glück weiterhelfen! Hier ist eine Beschreibung des Algorithmus mit freundlicher Genehmigung von Ron Levine :
Mit anderen Worten, Sie durchlaufen alle Achsen, die Sie normalerweise bei einem statischen Test der Trennachse ausführen würden. Anstatt frühzeitig loszufahren, wenn Sie keine Überlappung feststellen, fahren Sie fort und überprüfen die projizierte Geschwindigkeit des sich bewegenden Objekts. Wenn es sich vom statischen Objekt wegbewegt, dann bitte hier klicken -out. Andernfalls können Sie die früheste und späteste Kontaktzeit relativ einfach ermitteln (es ist ein 1D-Intervall, das sich in Richtung eines anderen 1D-Intervalls bewegt). Wenn Sie dies für alle Achsen tun und das Maximum der frühesten Schnittzeit und das Minimum der spätesten Schnittzeit beibehalten, wissen Sie, ob und wann Ihr sich bewegendes Objekt auf das statische Objekt trifft. So können Sie Ihr sich bewegendes Objekt genau bis zu dem Punkt vorschieben, an dem es auf das statische Objekt trifft.
Hier ist ein grober und völlig unverifizierter Pseudocode für den Algorithmus:
Hier ist ein Gamasutra-Artikel darüber, der für ein paar verschiedene Primitivtests implementiert wurde. Beachten Sie, dass dies genau wie SAT konvexe Objekte erfordert.
Auch dies ist etwas komplizierter als ein einfacher Trennachsentest. Seien Sie absolut sicher, dass Sie es brauchen, bevor Sie es versuchen. Bei einer sehr großen Anzahl von Spielen werden die Objekte einfach entlang des minimalen Übersetzungsvektors auseinander geschoben, da sie in einem bestimmten Frame einfach nicht sehr weit ineinander eindringen und visuell so gut wie nicht wahrnehmbar sind.
quelle
Sie möchten das Ausschneiden von Polygonen verwenden. Dies lässt sich am besten mit Bildern erklären, die ich nicht habe, aber dieser Typ hat es getan, also lasse ich ihn es erklären.
http://www.codezealot.org/archives/394
Der Kontaktverteiler gibt einen Punkt auf einem der Objekte zurück, der für die Kollision "am verantwortlichsten" ist, nicht den direkten Kollisionspunkt. Sie brauchen diesen direkten Kollisionspunkt jedoch nicht wirklich. Sie können die Objekte einfach mit der bereits vorhandenen Eindringtiefe und der normalen Eindringtiefe auseinanderdrücken und mithilfe des Kontaktverteilers andere physikalische Effekte anwenden (z. B. die Box den Hang hinunterstürzen / rollen lassen).
Beachten Sie, dass Ihr Bild ein kleines Problem darstellt: Der Punkt auf dem blauen Vektor, nach dem Sie fragen, wird in keiner physikalischen Simulation gefunden, da dort eigentlich nicht die Box treffen würde. Die Box würde mit ihrer unteren linken Ecke irgendwo weiter oben am Hang treffen, wenn nur ein kleines Stück der Ecke eindringt.
Die Eindringtiefe ist relativ gering, und wenn Sie die Box einfach entlang der Eindringnormalen aus dem Gefälle schieben, wird die Box nahe genug an die "richtige" Position gebracht, um in der Praxis fast unbemerkt zu bleiben, insbesondere wenn die Box hüpfen und taumeln wird , oder trotzdem nachrutschen.
quelle
Projizieren Sie einfach den MAT-Vektor auf den Richtungsvektor. Der resultierende Vektor kann zum Richtungsvektor hinzugefügt werden, um das Eindringen zu kompensieren. Projizieren Sie es genauso, wie Sie es beim SAT auf der Achse tun. Dadurch wird das Objekt genau an der Position festgelegt, an der es das andere Objekt berührt. Fügen Sie ein kleines Epsilon hinzu, um Gleitkommaprobleme zu bekämpfen.
quelle
Es gibt ein paar Vorbehalte bei meiner Antwort, die ich zuerst aus dem Weg räumen werde: Es geht nur um nicht rotierende Begrenzungsrahmen. Es wird davon ausgegangen, dass Sie versuchen, mit dem Tunnelbau umzugehen lösen, dh Probleme, die durch Objekte verursacht werden, die sich mit hoher Geschwindigkeit bewegen.
Sobald Sie das MTV identifiziert haben, kennen Sie die Kante / Oberflächennormale, gegen die Sie testen müssen. Sie kennen auch den Lineargeschwindigkeitsvektor des durchdringenden Objekts.
Sobald Sie festgestellt haben, dass zu einem bestimmten Zeitpunkt während des Frames eine Schnittmenge aufgetreten ist, können Sie binäre Halbschrittoperationen ausführen, die auf den folgenden Ausgangspunkten basieren:
Sobald Sie den Scheitelpunkt identifiziert haben, wird der binäre Halbschritt weitaus günstiger:
Dies ist einigermaßen genau, liefert jedoch nur einen einzigen Kollisionspunkt in einem einzigen Fall.
Die Sache ist, es ist normalerweise möglich, im Voraus zu sagen, ob sich ein Objekt pro Frame schnell genug bewegt, um so tunneln zu können. Daher ist es der beste Rat, die führenden Scheitelpunkte entlang der Geschwindigkeit zu identifizieren und einen Strahlentest entlang des Geschwindigkeitsvektors durchzuführen. Bei rotierenden Objekten müssen Sie eine Art binären Halbschritt-Slerp ausführen, um den korrekten Kontaktpunkt sicherzustellen.
In den meisten Fällen kann jedoch davon ausgegangen werden, dass sich die meisten Objekte in Ihrer Szene nicht schnell genug bewegen, um so weit in ein einzelnes Bild einzudringen. Daher ist kein halbes Springen erforderlich und eine diskrete Kollisionserkennung wird ausreichen. Hochgeschwindigkeitsobjekte wie Kugeln, die sich zu schnell bewegen, um gesehen zu werden, können für Kontaktpunkte verfolgt werden.
Interessanterweise können Sie mit dieser Halbschrittmethode auch die (fast) genaue Zeit ermitteln, zu der das Objekt während des Frames aufgetreten ist:
Wenn Sie eine Art physikalische Kollisionsauflösung durchführen, können Sie die Position von A folgendermaßen korrigieren:
dann kannst du deine physik normal von dort aus machen. Der Nachteil ist, dass das Objekt, wenn es sich relativ schnell bewegt, entlang seines Geschwindigkeitsvektors zurück teleportiert.
quelle