BEARBEITEN / AKTUALISIEREN: Meine derzeit größte Frage ist, ob die "t = ..." - Gleichung von Schritt 3 eine gute Idee ist oder eine bessere Möglichkeit, dies zu tun. Die meisten anderen Probleme wurden teilweise oder vollständig behoben, aber keine Kommentare oder Antworten haben dieses Problem wirklich berührt. Auch hier ist wahrscheinlich eine analytische Lösung erforderlich, die Geschwindigkeiten und Abstände sind zu groß und die Objekte zu klein, für jede iterative / rekursive Lösung (einige sind unten in den Kommentaren vorgeschlagen), die ich mir vorstellen kann (obwohl, wenn es welche gibt) eine spezielle iterative / rekursive Lösung, die mit solchen Situationen gut zurechtkommt, dann bin ich definitiv offen dafür). Vielen Dank für Ihre bisherige Hilfe, Sie sind alle großartig und ich schätze Ihre Gedanken und Ihre Hilfe sehr!
Ich versuche, Kollisionen zwischen kleinen, schnellen Objekten zu erkennen. Dies ist eine Situation, in der das Tunneln selbst bei relativ niedrigen Geschwindigkeiten sehr leicht erfolgen kann.
Ray Casting funktioniert nicht, da hierdurch eine Kollision zwischen zwei Hochgeschwindigkeitsobjekten erkannt wird, nicht zwischen einem Objekt und einer stationären Wand. (Es sei denn, ich verstehe Ray Casting falsch?) Leistung ist SEHR wichtig. wenn möglich, möchte ich einen großen Leistungseinbruch vermeiden. Ich habe bereits einen funktionalen und sehr effektiven Quadtree ( http://en.wikipedia.org/wiki/Quadtree ) implementiert, daher werde ich ihn wie unten beschrieben modifizieren und verwenden.
Bearbeiten: Das Verringern des Zeitintervalls funktioniert nicht. Die Geschwindigkeiten sind für diese Lösung zu hoch, was bedeutet, dass die Leistungseinbußen zu hoch wären, während die überwiegende Mehrheit der Tunnelkollisionen noch ausbleibt . (Zum Beispiel könnte ich ein Objekt mit einer Größe von ungefähr 1 Einheit haben, das mit einer Geschwindigkeit läuft, die in Millionen von Einheiten pro Zeitintervall gemessen wird ...)
VORGESCHLAGENE LÖSUNG:
Schritt 1:
Erstellen Sie eine Box um die Bewegung jedes Objekts und fügen Sie diese in den Quadtree ein, um eine erste Liste möglicher Kollisionen zu erstellen. Siehe folgendes Bild (dieses Bild zeigt ein Kreisobjekt, das sich von einer Position zur nächsten bewegt, und die Bewegung, die ein Rechteck erzeugt, das in den Quadtree eingespeist wird):
Schritt 2: (Vielleicht möchten Sie diesen Schritt überspringen?)
Sehen Sie sich die Liste der möglichen Kollisionen an, die durch den Quadtree erzeugt wurden. Prüfen Sie, ob sich die Rechtecke bei jeder möglichen Kollision schneiden. Wenn ja, fahren Sie mit Schritt 3 fort.
BEARBEITEN: Unten schlug Sean Middleditch vor, überstrichene Volumina / den Schnittpunkt von Kapseln zu verwenden (wenn die Objekte Kreise sind). Damit bleiben drei Optionen: 1) Überspringen Sie Schritt 2 vollständig. 2) Mach Schritt 2 auf meine Weise. 3) Mach es wie Sean. Seans Weg wird rechenintensiver sein als meine Box-Idee, aber er wird mehr falsch-positive als meinen Weg aussortieren und verhindern, dass sie den letzten Schritt erreichen.
Kann jemand aus Erfahrung sagen, welche dieser drei Möglichkeiten die beste ist? (Ich beabsichtige, diese Physik-Engine für ein paar andere Zwecke zu verwenden. Daher suche ich nach der "allgemein besten" Lösung, die in den unterschiedlichsten Situationen am schnellsten funktioniert, und nicht nur nach einem bestimmten Testfall, in dem ich die Lösung problemlos messen kann ist am schnellsten).
Schritt 3:
Verwenden Sie die folgende t = -Gleichung, wenn die Diskriminante (dh der Teil unter der Quadratwurzel) negativ oder 0 ist, keine Kollision, wenn positiv, verwenden Sie den t-Wert als Kollisionszeitpunkt (danach ist es einfach, die Positionen entsprechend anzupassen. ..wenn beide Objekte nach der Kollision weiterhin existieren). Gleichung:
t = (-1/2 sqrt ((2 a w - 2 a x + 2 b y - 2 b z - 2 c w + 2 c x - 2 d y + 2 d z) ^ 2-4 (w ^ 2- 2 w x + x ^ 2 + y ^ 2-2 y z + z ^ 2) (a ^ 2-2 a c + b ^ 2-2 b d + c ^ 2 + d ^ 2-r ^ 2-2 r ss ^ 2)) - a w + a xb y + b z + c wc x + d yd z) / (w ^ 2-2 w x + x ^ 2 + y ^ 2-2 y z + z ^ 2 ) .
Wobei (1 und 2 zur Bezeichnung der Objekte 1 und 2 verwendet werden):
t ist ein negativer Zeitwert zwischen 0 und -1, wobei 0 der aktuelle Frame und -1 der vorherige Frame ist;
a = x Position 1;
b = y Position 1;
c = x Position 2;
d = y Position 2;
w = x Geschwindigkeit 1;
x = x Geschwindigkeit 2;
y = y Geschwindigkeit 1;
z = y Geschwindigkeit 2;
r = Radius 1;
s = Radius 2;
Herleitung: (^ 2 bedeutet quadriert)
Nehmen Sie parametrische Gleichungen (zum Beispiel newxpos1 = a + t w) für die Bewegungen der Objekte und fügen Sie sie in die Abstandsformel ein (Quadrieren beider Seiten): Abstandsformel quadriert = (a + t w - (c + t x)) ^ 2 + (b + t y - (d + t * z)) ^ 2. Denken Sie daran, es wird negativ sein. Um den Kollisionszeitpunkt für zwei kreisförmige Objekte zu ermitteln, setzen wir die linke Seite gleich (r + s) ^ 2. Wenn wir t mit der quadratischen Gleichung (und einer Menge sehr langwieriger Algebra) lösen, erhalten wir die obige Gleichung "t = ...".
Meine Fragen:
1) Ist dies ein guter Weg, um es zu tun? Wird es überhaupt funktionieren? Werde ich auf unvorhergesehene Probleme stoßen? (Ich weiß, dass ich Probleme haben werde, wenn mehr als zwei Objekte auf einmal kollidieren, aber das ist mir egal, da ich nur Einwände dagegen habe, wenn sie niedrige Relativgeschwindigkeiten haben (wenn die Relativgeschwindigkeiten hoch sind) dann ist die "doof" -Lösung, die der Algorithmus liefert, "gut genug", und es ist für einen Menschen unmöglich, den Fehler zu sehen. Wenn mehr als 2 mit niedrigen relativen Geschwindigkeiten im selben Zeitschritt kollidieren, werden die meisten Lösungen trotzdem nah genug dran sein, da ich nicht vorhabe, ein paar unelastische Kollisionen zu haben)
2) Wird meine Leistung stark leiden? Ich glaube nicht, dass es so sein wird, aber wenn es so ist, gibt es einen besseren Weg, es zu tun?
3) Soll ich Schritt 2 überspringen und direkt von Schritt 1 nach 3 gehen? Offensichtlich ist Schritt 2 nicht unbedingt erforderlich, kann jedoch die Leistung verbessern (ODER es kostet möglicherweise mehr CPU-Zeit als es spart).
Alle anderen Kommentare, Vorschläge oder Kritik sind sehr willkommen. Danke für deine Hilfe!