Problem mit 2d Kollisionsabfrage
-
@randa
mal ne ganz doofe frage: wie mach ich sowas? wie setll ich fest "durch" welche seite der vektor geht?
@life
sry aber deds hab ich net so gnaz geblickt ^^oh mann, irgendwei si des sau schwer ahb auch schon auf englscihen seiten geguckst und so aber irgendwie hat da niemadn so richtig ne ahnung. aber es haben dioch schon so viele leute sowas programmiert
da fällt mir grad nich ein: ich hab ne lösung nur is das dann irgendwie komisch:
Also so... ich check die kollision wie oben ab. also jededn eckpunkt. is er "im" rect vom stein drin, dann guck ich noch ob ein banachtbarter eckpunkt uach drin is, dann is die richtung in die der ball abprallt ja schon logisch! und wenn echt NUR ein eck im steinrect is dann prüf ich um wie viel pixel es auf der x und auf der y acshe in den steion reingeht(is bissel doof zuu erklären). wenn der ball den stein so trifft wie ich oben gezeigt hab und er biespielsweise mehr nach rechts "in den stein reingeht" dann müsste er nach oben abprallen.
aber irgendwie wirkt dass dann komisch wenns viele steine nebeneinander gibt. der ball prallt da net ab sondern geht irgendwie trotzdem und macht viel zu viel stieen kaputt. ihr könnts euch ja mal angucken irh merkts wenn ihr ne ziet lang spielt... -> http://wallyshp.funpic.de/hb.zip
-
wenn ich dich richtig verstanden habe (was nicht leicht ist wegen der ganzen tippfehler
) gehts dir nur noch um die ecken. Du willst jetzt also wissen, ob er an die senkrechte seite geprallt ist oder an die waagerechte. Dazu guckst du wie weit er in x richtung und y richtung vom rand entfernt ist. Wenn er weiter in x richtung "drin" ist -> war wohl die waagerechte
Wenn er weiter in y richtung drin ist -> war wohl die senkrechteHab ich das richtig verstanden? Nun aufjedenfall kann dies falsch sein. An deinem bsp kann man z.b. nicht erkennen, wie der Ball nun weiter fliegen müsste, weil man halt nur den Endzustand sieht (der Ball ist im rect (was eigentlich meiner Meinung nach auch nicht sein sollte >_<)). Anhand des Endzustandes, lässt sich nicht bestimmen mit welcher Seite des Steinrechteckes er nun kollidiert ist. Er könnte ja auch mit der Senkrechten kollidieren, aber eine starke x bewegung (und kleine y bewegung) haben. Dann würde dein Programm aber so tun als ob der ball mit der waagerechten kollidiert wäre ... Also machs lieber wie ichs gesagt habe xD (oder wie randa es vorschlägt)
-
W@lly schrieb:
@randa
mal ne ganz doofe frage: wie mach ich sowas? wie setll ich fest "durch" welche seite der vektor geht?
Bitte lesen. Danke.
Bye, TGGC (Reden wie die Großen)
-
Ich würde es spontan so machen, Voraussetzung ist, dass die Steine in deiner Dateinstruktur von unten (niedrigerer y-Wert) nach oben (höherer y-Wert) sortiert sind.
[code]
-Loop durch alle Steine
//ball ist sowieso unter dem Steinen, also teste nicht weiter:
--if yPos des Balls + Radius < yPos des Steins - halbe Höhe d. Steins then break
//wenn ball nicht über dem stein ist, gabs vielleicht ne kollision
--else if yPos des Balls - Radius <= yPos des Steins + halbe Höhe
---if xPos Ball + radius >= xPos Stein - Steinbreite/2 oder
---xPos Ball - radius <= xPos Stein + Steinbreite/2
----finde mit beschriebender Methode heraus, ob x oder y - Kollision
----if y
-----ball_richtungsvector.y = -ball_richtungsvektor.y
----else
-----ball_richtungsvector.x = -ball_richtungsvektor.xDas wars glaub ich schon. Jetzt kannste einfach die Richtung normalisieren und auf die Position addieren. Fertig.
-
spl@t schrieb:
Ich würde es spontan so machen, Voraussetzung ist, dass die Steine in deiner Dateinstruktur von unten (niedrigerer y-Wert) nach oben (höherer y-Wert) sortiert sind.
[code]
-Loop durch alle Steine
//ball ist sowieso unter dem Steinen, also teste nicht weiter:
--if yPos des Balls + Radius < yPos des Steins - halbe Höhe d. Steins then break
//wenn ball nicht über dem stein ist, gabs vielleicht ne kollision
--else if yPos des Balls - Radius <= yPos des Steins + halbe Höhe
---if xPos Ball + radius >= xPos Stein - Steinbreite/2 oder
---xPos Ball - radius <= xPos Stein + Steinbreite/2
----finde mit beschriebender Methode heraus, ob x oder y - Kollision
----if y
-----ball_richtungsvector.y = -ball_richtungsvektor.y
----else
-----ball_richtungsvector.x = -ball_richtungsvektor.xDas wars glaub ich schon. Jetzt kannste einfach die Richtung normalisieren und auf die Position addieren. Fertig.
du hast dir den thread nicht durchgelesen oder?
-
Naja, hab ihn überflogen, weiß auch nicht wie ich gerade darauf gekommen bin dass die Richtungsänderung ein ungelöstes, und die Kollision ein gelöstes Problem ist... Sorry
Aber wenn man das Spiel spielt, merkt man nicht viel von Problemen bei der Kollision.
Trotzdem Nachtrag:
Wie würde es eigentlich aussehen, wenn du einfach immer annimmst, dass es sich um eine Kollision mit der Unter - bzw. Oberseite des Steines handelt, und immer den y-Vektor umkehrst? Bei den kleinen Steinen würde das wohl kaum auffallen, außerdem ensteht der Effekt, dass der Ball an der nächsten Schicht Steine abgeprallt ist, das Problem, dass der Ball zu viele Steine hintereinander abräumt sollte auch gelöst sein, und du kannst auf das Rechteck um den Ball verzichten und erreichst somit auch bei nem großen Ball pixelgenaue Kollision.Besser?
-
"Naja, hab ihn überflogen, weiß auch nicht wie ich gerade darauf gekommen bin dass die Richtungsänderung ein ungelöstes, und die Kollision ein gelöstes Problem ist... Sorry"
warum gehste dann nur auf die Kollision ein und nicht wie man rausfindet obs eine "x-Kollision" oder "y-Kollision" ist?
"Aber wenn man das Spiel spielt, merkt man nicht viel von Problemen bei der Kollision."
Mit der Kollision nicht, aber mit der RIchtungsänderung...
"Wie würde es eigentlich aussehen, wenn du einfach immer annimmst, dass es sich um eine Kollision mit der Unter - bzw. Oberseite des Steines handelt, und immer den y-Vektor umkehrst? "
Warum löst er nicht einfach das Problem anstatt es zu ignorieren?
"das Problem, dass der Ball zu viele Steine hintereinander abräumt sollte auch gelöst sein"
nein?
"und du kannst auf das Rechteck um den Ball verzichten und erreichst somit auch bei nem großen Ball pixelgenaue Kollision. "
Nein. Du legst auch ein Rechteck um den Ball..
-
Sag mal du Troll, irgendwie ergibt nicht ein einzelner Kommentar zu meinem Post auch nur den Hauch von Sinn, ich werde jetzt nicht darauf eingehen, ist ja wohl lächerlich.
Lies du lieber mal richtig.
-
@mods
Könnte man hier ent so ne art ignore-funktion einbinden? dann wär tggc bestimmt bei fast allen forum usern auf der ignore list... :pAber nichts destotrotz (oder wie auch immer man das schreibt) hab ich mir tggc's tip zu herzen genommen und meinen gehirnschmalz benutzt :p :
Hab mal im mathebuch von der 9. klasse geguckt und hab gedacht das konnte man ja mit linearen funktionen lösen. also wenn nur ein eck im steinrect drin is, dann stellt der ne funktion linearefuntion auf. und checkt dann ob der "funktionsgraph" durch die linke/rechte oder obere/untere seite geht.
aber dann muss ich halt nur vom mittelpunt des balles ausgehen!? kann das so ähnlich funktionieren?
-
guck lieber im mathebuch der klasse 12-13 unter vektorrechnung nach
übrigens war TGGC nicht immer so arrogant und selbstgefällig
Unter FAQ hat er nämlich nen paar tutorials zu total banalen Problemen geschrieben.. wirklich erstaunlich
-
eine genaue kollision zwischen stein/kreis kriegst du nur, wenn du die strahlgleichung in die kreisgleichung einsetzt nach s auflöst,und dann für jede seite testest.
hier mal en bissl arbeit abgenommen:
(xO+sxD)-xM)2+(yO+syD)-yM)2=r2
.
O ist der startpunkt eines strahls des rechtecks
D ist die steigung des Strahls
M ist der mittelpunkt des Kreises
s ist die stelle der Strecke, an der Der Kreis den Strahl trifft(es gibt 0,1,oder 2 lösungen).
um den echten treffpunkt rauszubekommen,brauchst du nurnoch s*D+O rechnen.nu viel spaß beim umformen^^
-
life schrieb:
übrigens war TGGC nicht immer so arrogant und selbstgefällig
Unter FAQ hat er nämlich nen paar tutorials zu total banalen Problemen geschrieben.. wirklich erstaunlich
Um ihm jetzt zuvor zu kommen...:
Er _IST_ es halt!!
-
otze schrieb:
eine genaue kollision zwischen stein/kreis kriegst du nur, wenn du die strahlgleichung in die kreisgleichung einsetzt nach s auflöst,und dann für jede seite testest.
hier mal en bissl arbeit abgenommen:
(xO+sxD)-xM)2+(yO+syD)-yM)2=r2
.
O ist der startpunkt eines strahls des rechtecks
D ist die steigung des Strahls
M ist der mittelpunkt des Kreises
s ist die stelle der Strecke, an der Der Kreis den Strahl trifft(es gibt 0,1,oder 2 lösungen).
um den echten treffpunkt rauszubekommen,brauchst du nurnoch s*D+O rechnen.nu viel spaß beim umformen^^
dann musste aber noch abfragen, dass s nicht größer als die länge der Strecke wird und nicht kleiner als 0..
einfacher, aber langsamer ist es, wenn du es so machst:
(Rect.x + n1 - Ball.x)² + (Rect.y + n2 - Ball.y)² <= r²
Und n1 und n2 dürfen nur Werte von 0-Rect.breite bzw 0-Recht.höhe annehmen. Müsste eigentlich auch funktionierenDas funktioniert dann übrigens auch wenn bei ihm der Ball mal wieder mit einem Zug mitten ins Rect fliegt
btw. musste dann bei meiner Variante das ganze mit ner doppelten for-schleife oder so durchgehen..edit: mit der performancesparenden Variante von otze bekomm ich übrigens mit derive folgendes für s heraus :D:
s = - (sqrt(r2·(xd2 + yd^2) - xd2·(ym2 - 2·ym·yo + yo^2) + yd·(xm - xo)·(2·xd·(ym - yo) - yd·(xm - xo))) + xd·(xo - xm) + yd·(yo - ym))/(xd^2 + yd^2) s = (sqrt(r2·(xd2 + yd^2) - xd2·(ym2 - 2·ym·yo + yo^2) + yd·(xm - xo)·(2·xd·(ym - yo) - yd·(xm - xo))) + xd·(xm - xo) + yd·(ym - yo))/(xd^2 + yd^2)
-
So...gtu ich glaub das projekt hat sich dann schon für mich erledigt...
bin jetzt grad mal in der zehnten klasse und hab von euren gleichungen net wirklich ne ahung.
so'n dreck...
naja ich schau mal ob ich's irgendwie gebacken krieg. wenn noch irgendwer n tip hat, wär ich trotzdem dankbar.
-
ich bin auch in der 10. who cares?
ist das ein grund, eine einfache quadratische gleichung nicht auflösen zu können? oder mal im internet nach kreisgleichung oder strahlengleichung zu googlen?@life jo und nu stell dir das mal im 3d raum vor,dann weiste, was ich da für ne arbeit hatte^^
-
ich versteh nicht ganz, wieso alle meinen Post ignorieren. Weil life irgendwelchen unpassenden Kommentare dazu gegeben hat?
Ich glaub ich mach doch folgendes:life schrieb:
"Naja, hab ihn überflogen, weiß auch nicht wie ich gerade darauf gekommen bin dass die Richtungsänderung ein ungelöstes, und die Kollision ein gelöstes Problem ist... Sorry"
warum gehste dann nur auf die Kollision ein und nicht wie man rausfindet obs eine "x-Kollision" oder "y-Kollision" ist?
Ich bin auf die Richtungsänderung (Umkehrung des Vektors) eingegangen, nicht auf den entsprechenden Kollisionsalgorithmus zum bestimmen ob x-oder y-Kollision. Ich weiß wie geschrieben, dass das falsch war.
life schrieb:
"Aber wenn man das Spiel spielt, merkt man nicht viel von Problemen bei der Kollision."
Mit der Kollision nicht, aber mit der RIchtungsänderung...
Nein, die Richtungsänderungen stimmen, der Ball prallt ordentlich von den Wänden ab, die Kollision ist das Problem.
life schrieb:
"Wie würde es eigentlich aussehen, wenn du einfach immer annimmst, dass es sich um eine Kollision mit der Unter - bzw. Oberseite des Steines handelt, und immer den y-Vektor umkehrst? "
Warum löst er nicht einfach das Problem anstatt es zu ignorieren?
Das Problem wird nicht ignoriert sondern auf sehr einfache Art gelöst.
life schrieb:
"das Problem, dass der Ball zu viele Steine hintereinander abräumt sollte auch gelöst sein"
nein?
Wenn er von der Seite kommt, würde er seine Richtung frühzeitiger ändern und eine Kollision mit der nächsten Schicht wäre nicht möglich.
life schrieb:
"und du kannst auf das Rechteck um den Ball verzichten und erreichst somit auch bei nem großen Ball pixelgenaue Kollision. "
Nein. Du legst auch ein Rechteck um den Ball..
Quatsch, wo denn
? Es wird der Radius des Balls mit benutzt (bezieht sich ja alles auf den Pseudocode von oben).
Übrigens hab ich selbst erst die Kollision bei einem Pingpongsspiel so realisiert, und wenn ich mit mehreren Bällen spiele, ist die Kollision der Bälle untereinander eindeutig pixelgenau (naja, fast), selbst wenn diese den viertel Bildschirm ausfüllen.
Wo verdammt nochmal liegt das Problem? Ich sage ja nicht, dass es auf beschriebene Weise 100% gut aussehen muss, aber nen Versuch wärs wert.
-
Vielleicht ist es so etwas vertsändlicher:
du hast die zwei geraden, die seite(n) deines Steins und den vektor.
Die gerdanegleichung der seite deines Steins (wir nennen sie a):
a: ax+bx=0
und des vektors b:
b: dx+ex=0Die Koordinaten des Schnittpunkts sind die, die bei den beiden obigen gleichungen gültige Werte erzeugen.
Setze die eine gleichung in die andere ein, und löse auf.Soviel hab ich noch im kopf, ich bin mir nicht sicher obs im Detail stimmt, aber im großen und ganzen...
Sowas hat man übrigens bis zur zehnten schon gemacht, erinnere dich dunkel an funktionen (in der 8?) bzw. quadratische funktionen (9te?).
Du kannst ja auch deine(n) Mathelehrer(in) fragen.
-
spl@t schrieb:
ich versteh nicht ganz, wieso alle meinen Post ignorieren. Weil life irgendwelchen unpassenden Kommentare dazu gegeben hat?
Ich glaub ich mach doch folgendes:life schrieb:
"Naja, hab ihn überflogen, weiß auch nicht wie ich gerade darauf gekommen bin dass die Richtungsänderung ein ungelöstes, und die Kollision ein gelöstes Problem ist... Sorry"
warum gehste dann nur auf die Kollision ein und nicht wie man rausfindet obs eine "x-Kollision" oder "y-Kollision" ist?
Ich bin auf die Richtungsänderung (Umkehrung des Vektors) eingegangen, nicht auf den entsprechenden Kollisionsalgorithmus zum bestimmen ob x-oder y-Kollision. Ich weiß wie geschrieben, dass das falsch war.
Klar bist du auf den Kollisionsalgorithmus eingegangen. Lies dir einfach mal deinen eigenen post durch
spl@t schrieb:
life schrieb:
"Aber wenn man das Spiel spielt, merkt man nicht viel von Problemen bei der Kollision."
Mit der Kollision nicht, aber mit der RIchtungsänderung...
Nein, die Richtungsänderungen stimmen, der Ball prallt ordentlich von den Wänden ab, die Kollision ist das Problem.
Die Erkennung, wie die Richtungsänderung genau aus sehen muss, ist das Problem. Diese hängt nämlich davon ab, welche seite ich vom rechteck treffe (oben/unten oder links/rechts). Die Kollision selber wird aber zuverlässig erkannt..
spl@t schrieb:
life schrieb:
"Wie würde es eigentlich aussehen, wenn du einfach immer annimmst, dass es sich um eine Kollision mit der Unter - bzw. Oberseite des Steines handelt, und immer den y-Vektor umkehrst? "
Warum löst er nicht einfach das Problem anstatt es zu ignorieren?
Das Problem wird nicht ignoriert sondern auf sehr einfache Art gelöst.
du löst es, indem du es ignorierst
spl@t schrieb:
life schrieb:
"das Problem, dass der Ball zu viele Steine hintereinander abräumt sollte auch gelöst sein"
nein?
Wenn er von der Seite kommt, würde er seine Richtung frühzeitiger ändern und eine Kollision mit der nächsten Schicht wäre nicht möglich.
er würde seine y richtung ändern und wenn unter dem getroffenen Stein wieder ein Stein ist, würde er wieder hochfliegen und damit gleich 2 reihen aufeinmal abräumen
spl@t schrieb:
life schrieb:
"und du kannst auf das Rechteck um den Ball verzichten und erreichst somit auch bei nem großen Ball pixelgenaue Kollision. "
Nein. Du legst auch ein Rechteck um den Ball..
Quatsch, wo denn
? Es wird der Radius des Balls mit benutzt (bezieht sich ja alles auf den Pseudocode von oben).
Übrigens hab ich selbst erst die Kollision bei einem Pingpongsspiel so realisiert, und wenn ich mit mehreren Bällen spiele, ist die Kollision der Bälle untereinander eindeutig pixelgenau (naja, fast), selbst wenn diese den viertel Bildschirm ausfüllen.
ist sie nicht. Beispiel:
ypos des Balles: 100
xpos des Balles: 100
radius des Balles: 50
xpos vom rechteck: 200
ypos vom rechteck: 200
breite des rechteckes: 100
untere Ecke vom Rechteck ist damit bei 150/150 und damit NICHT im kreis (50^2 + 50^2 > 50^2)
Also eine Kollision darf hier eindeutig NICHT stattfinden. Mal sehn was dein Algorithmus dazu sagt:"if yPos des Balls + Radius < yPos des Steins - halbe Höhe "
if(100+50 < 200-50) --> false
also weiter
"if yPos des Balls - Radius <= yPos des Steins + halbe Höhe "
if(100-50 <= 200+50) --> true
also weiter
"if xPos Ball + radius >= xPos Stein - Steinbreite/2 oder xPos Ball - radius <= xPos Stein + Steinbreite/2 "
(muss und heißen sonst machts eh keinen sinn daher: )
if(100+50 >= 200-50 und 100-50 <= 200+50) --> beides true also kollisionSoviel zu "pixelgenau"
spl@t schrieb:
Wo verdammt nochmal liegt das Problem? Ich sage ja nicht, dass es auf beschriebene Weise 100% gut aussehen muss, aber nen Versuch wärs wert.
naja.. dein Algorithmus löst nunmal nicht das eigentliche Problem. Warum sollte man einen Argorithmus ausprobieren, der mit dem Problem garnix zutun hat? oO
-
achja, noch ne sache zu der gleichung oben:
um im endeffekt rauszubekommen, wie der ball abprallen muss, muss man den winkel des schnittpunkts in relation zur bewegungsrichtung kennen und dann einfallswinkel gleich ausfallswinkel gelten lassen.
-
otze schrieb:
achja, noch ne sache zu der gleichung oben:
um im endeffekt rauszubekommen, wie der ball abprallen muss, muss man den winkel des schnittpunkts in relation zur bewegungsrichtung kennen und dann einfallswinkel gleich ausfallswinkel gelten lassen.das hatte er ja schon gelöst ..