.| Autor | Beitrag |
|---|---|
|
000 13.09.2002, 19:30 the_viking |
Ich progge grad zur Übung mal nen Arkanoid-Clone. Ich hab nur ein Problem: Für die Bricks habe ich jeweils ein Rechteck: RECT rBrickCollisionRect; und für den Ball ne Bounding-Sphere: POINT pBallPosition; Collision-Detection kann ich ja noch machen, aber wie weiss ich nun, auf welche Seite des Bricks der Ball auftrifft?? --thx, cu, MfG the_viking (( My =]=H=O=M=E=> Page! )) |
|
Profil || Suche |
|
001 14.09.2002, 17:10 Prefect |
Häh? Ist das nicht eigentlich Bestandteil der Collision-Detection? Ich hoffe, die Kollision besteht nicht darin, daß du einfach schaust, ob der Ball in dem Stein drin ist, das funktioniert nämlich nicht (stell dir vor, der Ball ist so schnell, daß er einfach durch den Stein durchfliegt). Hier mal ein Denkansatz. Beschreibe die Bewegung des Balls als f(t) = x0 + t*v Du hast jetzt eine Möglichkeit, die Flugbahn des Balles zu beschreiben. Wenn die Flugbahn einen Block schneidet kommt es zur Kollision - klar. Du mußt jetzt für jede Seite jeden Blockes überprüfen, ob die Flugbahn in diese Seite hineingeht. Nimm z.B. die linke Seite eines Blockes. Die linke Seite eines Blockes ist eine Strecke, wenn du die ins unendliche verlängerst hast du eine Gerade. Ihre Geradengleichung ist: x = x0 + t*vx Damit kannst du die x/y-Position des Balles zu jedem Zeitpunkt berechnen. Nun mußt zu herausfinden, zu welchem Zeitpunkt t der Ball die Gerade der Blockseite schneidet. Das ist ein sehr einfaches Gleichungssystem, das du lösen kannst, in dem du obiges x = const. einsetz: const = x0 + t*vx umgeformt: t = (const - x0) / vx Interessant an dieser Gleichung ist der Nenner, vx. Wenn vx gleich 0 ist ist t nicht definiert (Division durch 0 ist nicht erlaubt). Das ist aber logisch, denn wenn vx=0 ist, dann bewegt sich der Ball vertikal nach oben oder unten, d.h. er kann mit der ebenfalls vertikale Seite des Blockes gar nicht zusammenstoßen! Im Programm mußt du natürlich den Fall vx==0 überprüfen, damit es keine Division durch 0 gibt. Mit t = (const-x0)/vx kannst du natürlich den Zeitpunkt, zu dem sich die Flugbahn und die Gerade der Blockseite schneiden, bestimmen. Wenn t < 0 ist oder t > 1 ist, dann bedeutet das, daß sie sich in diesem Frame erst gar nicht schneiden. Du kannst diese Seite des Blocks also getrost ignorieren (die anderen Seiten des Blockes mußt du aber nach wie vor überprüfen!). Nun wissen wir also, daß der Ball in diesem Frame die Gerade dieser Seite des Blocks schneiden wird. Es kann aber sein, daß der Ball unterhalb oder überhalb der eigentlichen Seite vorbeifliegt. Um das zu überprüfen mußt du die y-Koordinate berechnen, an der sich die Gerade mit der Flugbahn schneidet. Oben hatten wir: y = y0 + t*vy In diese Gleichung setzt du einfach das vorher berechnete t ein, dann kannst du y errechnen. Wenn y unterhalb der Oberkante und oberhalb der Unterkante des Blocks ist kommt es zur Kollision. Du mußt jetzt diese Berechnung für alle Seiten des Blockes durchführen (für die Ober- bzw. Unterseite müssen x und y natürlich vertauscht werden). Wenn der Ball mit keiner Seite kollidiert ist alles in Ordnung. Wenn er mit mehr als einer Seite kollidiert mußt du die t-Werte für die Kollisionen vergleichen - die Seite mit dem niedrigsten t-Wert ist die Seite, mit der die Kollision stattgefunden hat. Du hast jetzt also den exakten Kollisionspunkt. Je nachdem, ob du eine horizontale oder eine vertikale Seite getroffen hast mußt du entweder vy := -vy oder vx := -vx zuweisen. Um perfekte Physik zu erreichen mußt du den Ball nach einer Kollision in einem Frame noch weiterbewegen. Wenn der Ball zum Zeitpunkt t = 0.1 kollidiert, muß er noch um (1.0-t)*v, d.h. um 0.9*v weiterbewegt werden - natürlich mit der neuen Bewegungsrichtung. Und auch für die Abprallbewegung, die nur noch (1.0-t)*v weit geht mußt du wieder Kollision durchführen. Und dann paßt alles =) cu, Widelands - Gemütliche Aufbaustrategie, Free Software |
|
Profil || Suche |
|
002 14.09.2002, 17:18 TheTinySteini |
... womit die Aussage "zur Übung" in ein ganz anderes Licht gerückt wäre =) --TheTinySteini |
|
Profil || Suche |
|
003 25.09.2002, 09:57 the_viking |
*PERFECT*, Prefect! *g* thx... beschäftige mich damit --thx, cu, MfG the_viking (( My =]=H=O=M=E=> Page! )) Dieser Beitrag wurde am 25.09.2002 um 09:57 von the_viking bearbeitet. |
|
Profil || Suche |
|
004 17.11.2002, 17:28 TheVoice |
*Thread Ausgrab* Omg, ja auch ich muss mich bei Prefect für diesen überaus belehrenden Thread bedanken :)) Auf der Basis der von Prefect genannten Technik, habe ich die ganze Sache so weit umgeschrieben, damit es auch für Hitboxes im 2D-Raum funktioniert. Anfänglich hatte ich ein paar Schierigkeiten (z.B. wegen Konzentrationsmangel ein fatales || anstelle eines && geschrieben =) aber ca 3h langem Überlegen und auf Zetteln-Rumkritzeln und 1000x Nachrechnen hat's dann geklappt :) => Ich finde dieser Thread gehört verschoben dieses C ya :) --Against TCPA | Resourcecode.de | Blender 3D | [ Darkzone | Pandorra | Alpine ] |
|
Profil || Suche |
|
005 11.01.2003, 13:03 gerk |
Sorry, dass auch ich den Thread wieder ausgrabe, aber taten sich einige Fragen auf (2 um genau zu sein): -)Was ist const, in der obigen Rechnung? Nein, fangen wirs anders an: Was ist eine Geradengleichung überhaupt? -)Was bedeutet ':=' ? Grüße und Vielen Dank, „Und da wir uns ja seit heute etwas näher gekommen sind, kann ich nur sagen: Mir hilft da immer Norther volle Lautstärke (so wie jetzt), sodass die ganzen unrasierten, Wasserpfeife rauchenden, alternativen Wichsstudenten aus ihren, aus Bananenschalen und Abfall gebastelten, Sitzkissen fliegen.“ Dieser Beitrag wurde am 11.01.2003 um 13:04 von Zgerk bearbeitet. |
|
Profil || Suche |
|
006 11.01.2003, 14:25 theDon |
:= bedeutet "ist definitiert als" --\o tanz den naziprau! o/ And more than ever, I hope to never fall, |
|
Profil || Suche |
|
007 11.01.2003, 16:23 TheVoice |
const ist nichts anderes als konstant, d.h. ein Wert bleibt immer gleich und verändert sich nicht. C++: Nun, im Mathematikunterricht habt ihr sicherlich schonmal Diagramme gezeichnet oder euch welche angeschaut. Evtl habt ihr da schonmal sowas gesehen:
Als Mathematiker ist man natürlich fasziniert von solchen Geraden (rote Linie) und möchte unbedingt in der Lage sein den Y-Wert der Geraden zu jeder Stelle (X-Wert) zu ermitteln. Das ist der Punkt an dem die Geradengleichungen zum Einsatz kommen. Eine Geradengleichung sieht so aus: f(x) = mx + b Hierbei ist x eine Variable, an dessen Stelle ein Wert in f(x) eingesetzt werden kann. Zum Beispiel: f(5) = m*5 + b Nun haben wir hier aber noch 2 unbekannte "Variablen" im Funktionsterm. Fangen wir bei m an. Bei m handelt es sich im Grunde genommen um eine Konstante, die die Steigung des Graphen angibt. Schaust du nochmal in die Skizze, siehst du ein paar blaugezeichnete Dreiecke. Solche Dreiecke nennt man Steigungsdreieck, mit dem man (zumindest bei einer Geraden) an jeder x-beliebigen Stelle des Graphen die Steigung der Geraden errechnen kann. m ist eine Konstante (2) nun sind wir schon so weit: f(x) = 2x + b So, what's left ? Klar, da ist noch dieses b ! Okay.. nun sind wir so weit: f(x) = 2x + 0 bzw. f(x) = 2x Möchten wir nun also den y-Wert an der Stelle 5 errechnen, so können wir das nun tatsächlich machen, indem wir für x den Wert 5 einsetzen: f(5) = 2 * 5 = 10 (ein Blick in den Graphen verrät uns, dass das stimmt!) Das war aber reichlich langweilig, da wir diesen Wert auch locker vom Graphen ablesen hätten können. Probieren wir doch mal etwas, das wir mit dem Geodreieck nicht hätten messen können.. wie wär's mit 7,662 ? Kein Problem: f(7,662) = 2 * 7,662 = 15,324 Wunderbar! Die entsprechende C/C++ Funktion sähe dann so aus: float y(float x) bzw. um das ganze etwas variabler zu gestalten: float y(float x, float m, float b) Ein Aufruf für unseren Fall sähe dann so aus: y(5, 2, 0); Aber irgendwann wird's auch echt mal langweilig, wenn man nur die y-Werte errechnen kann. Jedoch gibt es ja noch so Sachen wie Termumformungen. Mit Hilfe solcher Techniken, lässt sich die oben gezeigte Funktion z.B. so umstellen, dass wir einen Y-Wert in die Funktion einsetzen und dann den X-Wert (also die Stelle) ermitteln, an dem der Y-Wert im Graphen dem eingesetzten Wert entspricht. Gehen wir also zur Ausgangsfunktion zurück und machen uns das Leben ein wenig einfacher, indem wir für f(x) nun y einsetzen: y = mx + b Dazu subtrahiere ich zunächst b vom Term und erhalte: y - b = mx f(10) = 10/2 = 5 (siehe Graph: stimmt) Nun.. das ist eigentlich schon (fast) das ganze Geheimnis von Geradengleichungen. Natürlich kannst du das Ganze auch noch nach b umformen.. aber das muss ich jetzt wohl nicht mehr vorführen. Ich hoffe das hier hat dir etwas geholfen und unterstützt dich beim Verstehen dieses Threads. Viel Spaß noch dabei ;-) --Against TCPA | Resourcecode.de | Blender 3D | [ Darkzone | Pandorra | Alpine ] |
|
Profil || Suche |
|
008 11.01.2003, 17:41 gerk |
Also erstmal riesiges Thx, TheVoice für die Arbeit, die du dir gemacht hast =) Langsam, denke ich, fange ich an es zu verstehen. Das einzige, was mir immer noch nicht einleuchtet ist das x = const der linken Seite eines Blocks. Soll das dafür stehen, dass der Graph/die linke Seite keine Steigung hat? Also das leuchtet noch nicht ganz ein :) Grüße, /edit: Ack das Zeichen geht nicht. „Und da wir uns ja seit heute etwas näher gekommen sind, kann ich nur sagen: Mir hilft da immer Norther volle Lautstärke (so wie jetzt), sodass die ganzen unrasierten, Wasserpfeife rauchenden, alternativen Wichsstudenten aus ihren, aus Bananenschalen und Abfall gebastelten, Sitzkissen fliegen.“ Dieser Beitrag wurde am 11.01.2003 um 17:42 von Zgerk bearbeitet. |
|
Profil || Suche |
|
009 11.01.2003, 18:00 CerberusTM |
@Zgerk (grr, ich wollte grad lag schreiben): ¢Æ /edit [MfG Cerberus] Dieser Beitrag wurde am 11.01.2003 um 18:00 von CerberusTM bearbeitet. |
|
Profil || Suche |
|
010 12.01.2003, 12:41 Prefect |
Voice hat leider nur die halbe Wahrheit gesagt was Geraden angeht. Deswegen beschreibt man Gerade (im 2-dimensionalen Raum) auch gerne als Wenn in meinem ursprünglichen Post x = const steht ist das const also der x-Wert der vertikalen Gerade, die die Seite eines Blockes bildet. Wenn du schräge Blöcke haben willst mußt du halt die volle Form ax + by + c = 0 verwenden und a und b richtig setzen. Weil ich nicht alles immer wieder schreiben will, http://www.resourcecode.de/?tutorial=1&id=78 (ist zwar mehr auf 3D ausgelegt, aber weil Geraden in 2D und Ebenen im 3D letztendlich dasselbe sind paßt es auch teilweise). cu, Widelands - Gemütliche Aufbaustrategie, Free Software |
|
Profil || Suche |
|
011 14.01.2003, 19:45 gerk |
Vielen Dank an Prefect und TheVoice. Zusammen mit dem Ray-Polygon-Collision Tutorial (wo auch die Ebenengleichung verwendet wird) von Gametutorials, denke ich es zu verstehen und auch implementieren zu können. Leider fehlt mir zu letzterem im Moment die Zeit, aber das werde ich nachholen. Also vielen Dank euch beiden, nochmal :) Grüße, „Und da wir uns ja seit heute etwas näher gekommen sind, kann ich nur sagen: Mir hilft da immer Norther volle Lautstärke (so wie jetzt), sodass die ganzen unrasierten, Wasserpfeife rauchenden, alternativen Wichsstudenten aus ihren, aus Bananenschalen und Abfall gebastelten, Sitzkissen fliegen.“ |
|
Profil || Suche |
|
012 25.03.2003, 15:55 Smeagol |
man KANN eine vertikale ganz einfach so beschreiben: x=5 (zb ... ) |
|
Profil || Suche |

