2D Collision Response
Übersicht

![]() |
FetzeBetreff: 2D Collision Response |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hi, ich mal wieder ^^
Habe jetzt 4 1/2 Stunden an einer Function für Collision Response gesessen und ich kriegs einfach nicht hin. Bitte dringend um Hilfe. Folgendes: 2 Raumschiffe kollidieren. Ich habe den Punkt der Kollision, die Schwerpunkte (=Drehpunkte) der Raumschiffe, ihre Massen, ihre Drehbewegungen in Grad/Frame sowie ihre Bewegungsvektoren, deren Betrag in Pixel/Frame angegeben wird. Hier erstmal eine Skizze dazu: www.fetzenet.de/skizze.png Daraus will ich nun, wie in der Skizze zu sehen ist, für beide Schiffe errechnen, welche ->zusätzliche<- DrehBewegung und Bewegung sie jeweils durch die Kollision erhalten, die ich zu deren Variablen addieren kann, um ihre neue Bewegung zu erhalten Das Problem ist... tja, gar nicht mal so was konkretes. Ich hab einfach keine Ahnung, wie ich das ganze berechnen soll. Ich habs jetzt wie gesagt ne ganze Weile versucht, aber ich komme nicht wirklich weiter. Ich wäre sehr dankbar, falls mir jemand einfach ein paar kommentierte Codezeilen mit Pseudovariablen geben könnte, die ich bei mir einbauen kann. |
||
Dreamora |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Schau mal auf normalen Physikseiten nach dem Drehimpulssatz oder wenn du ein Physikbuch hast, kannst du natürlich auch da drin schauen.
Es ist in der Physik allgemein immer so, dass wenn es um Stossreaktionen geht, der Impulssatz (oder der Drehimpulssatz) zum tragen kommt. |
||
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen. |
![]() |
Fetze |
![]() Antworten mit Zitat ![]() |
---|---|---|
So weit war ich schon. Da ich im Physikunterricht bisher nichtmal Vektoren wirklich hatte und so nur das grundlegendste davon kann, bzw. auch von Impulsen oder dergleichen bisher nicht mehr als den Namen gehört habe, bin ich so nicht viel weiter gekommen. :/ | ||
Dreamora |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Da bleibt dir nicht viel anderes, als dir das Wissen anzueignen, das hinter Vektoren und Impuls (oder besser erst einmal Bewegung und Kraft) steckt.
Wird nicht so schwer, wenn du wirklich an der Materie interessiert bist. |
||
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen. |
![]() |
Fetze |
![]() Antworten mit Zitat ![]() |
---|---|---|
Nunja, da gäbe es noch die Möglichkeit, jemand, der diese Formeln bereitsaufgestellt hat, postet sie hier. Das ist ein Aufwand von geschätzt einer Minute. Wohingegen ich wahrscheinlich weitere 5 Stunden benötigen würde. Wie wäre es also, wenn ihr so nett seid, mir das zu ersparen und ein paar Formeln zu posten, und sei es nur, damit ic hverstehe, wie das funktioniert? ![]() ![]() Oder, eine weitere ALternative: Jemand erklärt mir Schritt für Schritt, wie ich das ganze selber zusammen bekomme. Klar, zur Not muss ich dann eben wieder zum Physikbuch greifen. Aber ich denke nach 4 1/2 Stunden Arbeit darf ich es doch wohl mal wagen, um Hilfe zu bitten. |
||
Dreamora |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Gewiss.
Deswegen gab ich dir ja den Hinweis mit dem Impulssatz ![]() Dir fertigen Code und dergleichen zu liefern bringt nichts, da du ihn dann bei bedarf nicht anpassen kannst und ich denke, das ist in einem Spiel wo physik an verschiedenen orten einfliesst, zwingend notwendig, da du sonst unter Umstäden die Physik so einbaust, dass sie sich gegenseitig stört oder garnicht funktioniert. |
||
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen. |
![]() |
Fetze |
![]() Antworten mit Zitat ![]() |
---|---|---|
Naja, in meinem Fall würde das schon was bringen. Bin wirklich kein Physik-Phobiker und ich denke, ich verstehe die Formeln, wenn ich sie sehe, d.h. anpassen sollte kein Problem sein. Stören kann sich da ebenfalls nichts, weil ich diese Physik-Spielerei genau ein Mal im gesamten Spiel benötige, nämlich für Schiff-Schiff-Kollision ^^
Edit: Hier übrigens das letzte, was ich zustande gebracht hab. Den Drehmoment hab ich bisher bewusst weggelassen, aber auch so scheint hier irgendwas nicht zu funktionieren. :/ Code: [AUSKLAPPEN] 'Impulsübertragung: Local fImpMult:Float = 0.1 * fTimeMult Local iLoop:Int For iLoop = 0 To fColX.length - 1 Local fColDist1:Float Local fColAngle1:Float Local fColX1:Float Local fColY1:Float Local fImpX2:Float Local fImpY2:Float Local fTransDist1:Float Local fTransX1:Float Local fTransY1:Float Local fColDist2:Float Local fColAngle2:Float Local fColX2:Float Local fColY2:Float Local fImpX1:Float Local fImpY1:Float Local fTransDist2:Float Local fTransX2:Float Local fTransY2:Float fColDist1 = Distance(shipPar.fX, shipPar.fY, shipPar.fX + fColX[iLoop], shipPar.fY + fColY[iLoop]) fColAngle1 = Angle(shipPar.fX, shipPar.fY, shipPar.fX + fColX[iLoop], shipPar.fY + fColY[iLoop]) fColX1 = Sin(fColAngle1) fColY1 = -Cos(fColAngle1) fImpX2 = (shipPar2.fXSpeed * shipPar2.fRealMass) * fImpMult fImpY2 = (shipPar2.fYSpeed * shipPar2.fRealMass) * fImpMult fTransDist1 = ((fColX1 * fImpX2) + (fColY1 * fImpY2)) fTransX1 = fColX1 * fTransDist1 fTransY1 = fColY1 * fTransDist1 fColDist2 = Distance(shipPar2.fX, shipPar2.fY, shipPar.fX + fColX[iLoop], shipPar.fY + fColY[iLoop]) fColAngle2 = Angle(shipPar2.fX, shipPar2.fY, shipPar.fX + fColX[iLoop], shipPar.fY + fColY[iLoop]) fColX2 = Sin(fColAngle2) fColY2 = -Cos(fColAngle2) fImpX1 = (shipPar.fXSpeed * shipPar.fRealMass) * fImpMult fImpY1 = (shipPar.fYSpeed * shipPar.fRealMass) * fImpMult fTransDist2 = ((fColX2 * fImpX1) + (fColY2 * fImpY1)) fTransX2 = fColX2 * fTransDist2 fTransY2 = fColY2 * fTransDist2 shipPar.fXSpeed:+ (fTransX1 / shipPar.fRealMass) shipPar.fYSpeed:+ (fTransY1 / shipPar.fRealMass) shipPar2.fXSpeed:- fImpX2 shipPar2.fYSpeed:- fImpY2 shipPar2.fXSpeed:+ (fTransX2 / shipPar2.fRealMass) shipPar2.fYSpeed:+ (fTransY2 / shipPar2.fRealMass) shipPar.fXSpeed:- fImpX1 shipPar.fYSpeed:- fImpY1 Next Ich gehe jeden Kollisionspunkt durch und versuche an jedem Kollisionspunkt zu bestimmen, welcher Teil des Impulses direkt zum Schwerpunkt des entsprechenden Schiffes zeigt und sich so direkt darauf auswirkt. Diesen Teil teile ich anschließend wieder durch die Masse des Empfängerschiffes und addiere ihn zu dessen Geschwindigkeitsvektor. Irgendwie scheint sich die Geschwindigkeit da drinnen jedoch zu potenzieren, denn mir fliegen dadurch die Schiffe teilweise übers halbe Spielfeld weg - weil ich sie sachte angestupst hab. Edit2: Okay, einen Fehler hab ich gefunden. Hab von der Geschwindigkeit des Impulsdonators den gesamten Impuls abgezogen, ohne zuvor wieder durch die Masse zu dividieren... aber irgendwas funktioniert immernoch nicht. Die Vektoren der Schiffe fangen bei Kollision an, zu "zucken", in verschiedene Richtungen, nahezu willkürlich scheinend. Dabei sollten sie - bei einem Frontalzusammenstoß zwei ähnlicher Schiffe - rein theoretisch langsam und relativ gleichmäßig abnehmen. Tun sie aber nicht. Code: [AUSKLAPPEN] 'Impulsübertragung: Local fImpMult:Float = 0.1 * fTimeMult Local iLoop:Int For iLoop = 0 To fColX.length - 1 Local fColDist1:Float Local fColAngle1:Float Local fColX1:Float Local fColY1:Float Local fImpX2:Float Local fImpY2:Float Local fTransDist1:Float Local fTransX1:Float Local fTransY1:Float Local fColDist2:Float Local fColAngle2:Float Local fColX2:Float Local fColY2:Float Local fImpX1:Float Local fImpY1:Float Local fTransDist2:Float Local fTransX2:Float Local fTransY2:Float fColDist1 = Distance(shipPar.fX, shipPar.fY, shipPar.fX + fColX[iLoop], shipPar.fY + fColY[iLoop]) fColAngle1 = Angle(shipPar.fX, shipPar.fY, shipPar.fX + fColX[iLoop], shipPar.fY + fColY[iLoop]) fColX1 = Sin(fColAngle1) fColY1 = -Cos(fColAngle1) fImpX2 = (shipPar2.fXSpeed * shipPar2.fRealMass) * fImpMult fImpY2 = (shipPar2.fYSpeed * shipPar2.fRealMass) * fImpMult fTransDist1 = ((fColX1 * fImpX2) + (fColY1 * fImpY2)) fTransX1 = fColX1 * fTransDist1 fTransY1 = fColY1 * fTransDist1 fColDist2 = Distance(shipPar2.fX, shipPar2.fY, shipPar.fX + fColX[iLoop], shipPar.fY + fColY[iLoop]) fColAngle2 = Angle(shipPar2.fX, shipPar2.fY, shipPar.fX + fColX[iLoop], shipPar.fY + fColY[iLoop]) fColX2 = Sin(fColAngle2) fColY2 = -Cos(fColAngle2) fImpX1 = (shipPar.fXSpeed * shipPar.fRealMass) * fImpMult fImpY1 = (shipPar.fYSpeed * shipPar.fRealMass) * fImpMult fTransDist2 = ((fColX2 * fImpX1) + (fColY2 * fImpY1)) fTransX2 = fColX2 * fTransDist2 fTransY2 = fColY2 * fTransDist2 shipPar.fXSpeed:+ (fTransX1 / shipPar.fRealMass) shipPar.fYSpeed:+ (fTransY1 / shipPar.fRealMass) shipPar2.fXSpeed:- (fImpX2 / shipPar2.fRealMass) shipPar2.fYSpeed:- (fImpY2 / shipPar2.fRealMass) shipPar2.fXSpeed:+ (fTransX2 / shipPar2.fRealMass) shipPar2.fYSpeed:+ (fTransY2 / shipPar2.fRealMass) shipPar.fXSpeed:- (fImpX1 / shipPar.fRealMass) shipPar.fYSpeed:- (fImpY1 / shipPar.fRealMass) Next |
||
![]() |
regaa |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ich denke bei so komplizierten Sachen ist es von Vorteil einen ausführfähiges rar auszuliefern damit derjenige, der sich mit der Materie beschäftigen will, sofort anfangen kann im Code nach Fehlern zu suchen und nicht erst eine halbe Stunde eine bmx zusammenstellen und die dazugehörigen Objekte/Grafiken muss um dir weiter zu helfen. | ||
UltraMixer Professional 3 - Download
QB,HTML,CSS,JS,PHP,SQL,>>B2D,B3D,BP,BlitzMax,C,C++,Java,C#,VB6 , C#, VB.Net |
![]() |
Fetze |
![]() Antworten mit Zitat ![]() |
---|---|---|
Habe mich gerade ne Stunde an die Programmierung eines Tesgeländes gesetzt und schließlich mit dem Fazit aufgegeben, dass das ganze zu komplex ist, um mal eben ein Testgelände zu schreiben. :/
Und den gesamten Sourcecode meines Spiels kann ich euch schlecht geben. Wäre nett, wenn jemand auch so mal über den Code schauen würde. ![]() Hier, aktuelle Version. Funktioniert selektiv, d.h. in bestimmten Aufprallswinkeln oder bei bestimmten Aufprallsvektoren oder wasweisich. Jedenfalls funktioniert es, wenn man frontal gegen ein Raumschiff fliegt, aber nicht, wenn man sich von hinten annähert. Dann wird man aufgesogen und hindurch katapultiert. Ich habe mal eine Funktion geschrieben, die die Krafteinwirkung berechnet. Der obere Teil ohne Funktion ist der, der bei Kollision ausgeführt wird und der Fehler wird wohl in der Methode "Push" stecken. Code: [AUSKLAPPEN] 'Impulsübertragung: Local fImpMult:Float = 1.0 * fTimeMult 'fTimeMult gleicht FPS-Schwankungen aus. Local iLoop:Int For iLoop = 0 To fColX.length - 1 Local fImpX1:Float Local fImpY1:Float Local fImpX2:Float Local fImpY2:Float fImpX1 = (shipPar.fXSpeed * shipPar.fRealMass) * fImpMult fImpY1 = (shipPar.fYSpeed * shipPar.fRealMass) * fImpMult fImpX2 = (shipPar2.fXSpeed * shipPar2.fRealMass) * fImpMult fImpY2 = (shipPar2.fYSpeed * shipPar2.fRealMass) * fImpMult shipPar.Push(fColX[iLoop], fColY[iLoop], fImpX2, fImpY2) shipPar2.Push(shipPar.fX - shipPar2.fX + fColX[iLoop], shipPar.fY - shipPar2.fY + fColY[iLoop], fImpX1, fImpY1) shipPar.Push(fColX[iLoop], fColY[iLoop], -fImpX1, -fImpY1) shipPar2.Push(shipPar.fX - shipPar2.fX + fColX[iLoop], shipPar.fY - shipPar2.fY + fColY[iLoop], -fImpX2, -fImpY2) Next 'Schubst das Schiff vom angegebenen Punkt aus mit dem angegebenen Impuls Method Push:Byte(fParX:Float, fParY:Float, fParXImp:Float, fParYImp:Float) Local fAngleTemp:Float 'Winkel von Schiffs-Schwerpunkt zu angegebenem Kraftpunkt (Dem Punkt, an dem die Kraft wirkt) Local fNormPPVecX:Float 'Normalisierter Vektor von Schiffs-Schwerpunkt zu angegebenen Kraftpunkt Local fNormPPVecY:Float Local fTransVec:Float 'Länge des Translationsvektors (Des (Impuls-)Vektors, der in die Bewegung des Schwerpunktes eingerechnet wird) Local fTransVecX:Float 'Translationsvektor (Impuls) Local fTransVecY:Float 'Winkel von Schwerpunkt des Schiffes zu Kraftpunkt (dem Punkt, an dem die Kraft wirkt) 'berechnen fAngleTemp = Angle(fX, fY, fX + fParX, fY + fParY) 'Normalisierten Vektor (Vektor der Länge 1) dorthin errechnen fNormPPVecX = Sin(fAngleTemp) fNormPPVecY = -Cos(fAngleTemp) 'Per Skalarprodukt den Impulsvektor auf den normalisierten (Muss normalisiert sein!) 'Schwerpunkt-Kraftpunkt-Vektor projizieren und so die Länge des Translationsvektors 'errechnen. fTransVec = ((fNormPPVecX * fParXImp) + (fNormPPVecY * fParYImp)) 'Diese Länge mit dem normalisierten Schwerpunkt-Kraftpunkt-Vektor multiplizieren, um 'daraus den Translationsvektor zu erhalten fTransVecX = fTransVec * fNormPPVecX fTransVecY = fTransVec * fNormPPVecY 'Translationsvektor in Geschwindigkeit einrechnen. Durch Masse teilen, da es sich hier um 'einen Impuls handelt. fXSpeed:+ (fTransVecX / fRealMass) fYSpeed:+ (fTransVecY / fRealMass) Return True End Method |
||
Dreamora |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Ich hätte dir auf die schnelle eine prinzipielle Idee anzubieten:
Voraussetzung: - Du kennst den Kollisionspunkt - Du hast einen Massemittelpunkt Nun kannst du über Vektorenprojektion bestimmen, ob das andere Schiff von links oder rechts dagegen gescheppert ist. Dazu muss der Bewegungsvektor des aufprallenden Schiffes auf die unitäre Richtung Massemittelpunkt - Kollisionspunkt projiziert werden ( uni_direction = (vecKollisionspunkt - vecMassemittelpunkt)/Länge des Vektors ). Dies erfolgt durch die Formel projectedVec = Skalarprodukt(uni_direction,Bewegungsvektor) (Das Skalarprodukt zweier Vektoren A,B zb ist A.x*B.x + A.y*B.y + A.z*B.z ) Nun kannst du 2 Punkte bestimmen: - A = Kollisionspunkt - Bewegungsvektor - B = Kollisionspunkt - projectedVec Nun kannst du den Winkel bestimmen zwischen A und B bestimmen aus sicht des Massemittelpunktes und weisst in welche Richtung sich dein Schiff drehen muss. Wie stark sich das Schiff drehen wird, hängt von der Normale ab welcher projectedVec und den Punkt A verbindet. Die Normalen ist dabei: Bewegungsvektor - projectedVec. Mittels der Länge der Normale und der Richtung kannst du nun dein Schiff drehen. Hoffe, das hilft dir. Natürlich kannst du, wenn du Masse nutzt auch den Impulsvektor anstatt dem Bewegungsvektor nutzen. Habe deinen Code leider nur überflogen, kann dir diesbezüglich daher leider keine Hilfestellung bieten. |
||
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen. |
![]() |
Fetze |
![]() Antworten mit Zitat ![]() |
---|---|---|
Wenn ich dich richtig verstanden habe, hast du mir genau das vorgeschlagen, was ich da versuche, allerdings mehr im Bezug auf Drehung.
Mir meinem Code funktioniert das auch bereits einwandfrei, mit einer Ausnahme: Kollidiere ich im falschen Winkel, heben sich die errechneten Translationsvektoren eines Schiffes auf oder zeigen in die Falsche Richtung, sodass das kleinere Schiff mehr oder weniger in das größere eingesaugt wird. Ein paar Frames später wird es dann mit überhöhter Geschwindigkeit hinauskatapultiert. Momentan suche ich die Ursache dafür, habe aber bisher noch keinen Ansatz :/ Trotzdem danke ![]() |
||
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group