Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

26.05.2015, 23:40

Pixel Collision bei rotiertem Objekt

Ich beschäftige mich momentan mit der Kollisionserkennung zwischen 2 Objekten.

Genauer gesagt um die Pixel genaue Erkennung, diese funktioniert soweit auch gut.

Ich würde diese Erkennung auch gerne auf rotierte Objekte anwenden.

Momentan wird bei mir im Konstruktor für jeden Pixel ein bool Wert erzeugt ob der Pixel transparent ist oder nicht(bzw ein doppel vektor für das gesamte Image).

Wenn das Objekt nicht rotiert ist überprüfe ich einfach ob 2 Pixel übereinander liegen die nicht transparent sind.

Ich wüsste eine Lösung wenn das Objekt um 90°, 180° oder 270° rotiert ist aber nicht wenn das OBjekt um z.B. 20° rotiert ist

2

27.05.2015, 00:40

Sagen wir du "pickst" mit der Maus auf ein Bild was rotiert ist, um da die Farbe an dieser Position zu bekommen. Dann musst du die Mausposition in den selben "Space" bringen wie das Bild.
Dieses kannst du über "Transformationsmatrizen" ganz elegant lösen. Dann kannst du das Bild skalieren, rotieren oder translaieren wie du möchtest.

3

27.05.2015, 18:48

Und wie geht das genau? Ich habe mir ebend die Klasse sf::Transform angeschaut, aber verstehe jetzt nicht wie ich genau damit die Pixel Collision schaffe

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

4

27.05.2015, 21:45

Du musst dir das so vorstellen. Es gibt einmal den Worldspace. Das ist im Prinzip das Koordinatensystem deiner Spielwelt. Dann gibt es den Cameraspace, dass ist ein Koordinatensystem welches den Ursprung im Zentrum der Kamera hat (die Kameraposition) und nach der Richtung der Kamera ausgerichtet ist. Das heißt, die Z-Achse geht in die Richtung in die auch die Kamera guckt, die Y-Achse zeigt aus der Sicht der Kamera nach oben und die X-Achse dann zur Seite. Und dann gibt es noch den Objectspace, das ist quasi für jedes Objekt ein lokales Koordinatensystem. Hier funktioniert es im Prinzip wie bei der Kamera auch, nur dass anstatt der Kamera jetzt eben Objekte betrachtet werden.
Das gilt für 3D. Für 2D hast du eine Achse weniger. Wenn du ein Objekt bewegst dann bewegst du das Koordinatensystem des Objektes mit. Rotierst du also dein Rechteck so rotierst du sein lokales Koordinatensystem mit.

(Link)

Hier kannst du dir das ganze mal ansehen. Das rote Koordinatensystem ist der Worldspace, die blauen sind jeweils Objectspaces von Objekten.

Dein Rechteck ist in seinem eigenen Objectspace selbst nach den Achsen des Koordinatensystems ausgerichtet. Der Cameraspace fällt bei dir möglicherweise weg da du ja vielleicht gar keine Kamera oder vergleichbare Konzepte nutzt. Was du jetzt machen kannst ist einen Punkt aus dem Worldspace in den Objectspace zu übertragen. Das heißt du nimmst die Koordinaten den der Punkt im Koordinatensystem der gesamten Welt hat und rechnest die Koordinaten im Objectspace des Punkts auf. Mal dir das ganze mal auf und mal dir die Achsen der jeweiligen Spaces mit ein. Dann siehst du dass ein Punkt welcher im Worldspace zum Beispiel an Position (7, 39) ist, im Objectspace völlig andere Koordinaten haben kann. Quasi aus der Sicht des Objektes. Überträgst du den Punkt jetzt aber in das andere Koordinatensystem dann interessiert dich danach nicht mehr ob das jeweiligen Objekt skaliert, rotiert oder verschoben wurde. Aus Sicht des Objekts ist das nämlich völlig unerheblich.

Im Objectspace ist das Objekt selbst quasi Zentrum der Welt. Die Umrechnung dazwischen ist nicht so schwer. Such mal nach "world to object space" oder "camera to object space". Da solltest du einige Informationen finden.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

5

28.05.2015, 01:14

Ich habe das jetzt so verstanden (korrigier mich falls ich falsch liege):

Ich habe einen Worldspace und mindestens 2 Objectspaces.

sollten sich die beiden Objekte berühren (also die ränder von der textur) weiß ich ja noch nicht ob die beiden Objekte kollidiert sind oder nicht (transparente Pixel..)

also bestimme ich den Bereich wo die Rechtecke sich überschneiden, auf dem Worldspace und berechne diese Koordinaten bei beiden Objectspaces und teste ob diese Pixel transparent sind oder nicht.

Sollten bei einer Koordinate beide Objeke einen farbigen Pixel haben, so weiß ich das die Objekte sich tatsächlich "berühren"?

6

28.05.2015, 02:20

http://www.austincc.edu/cchrist1/GAME134…edCollision.htm

Du hast ja sowas wenn beide im WorldSpace sind:
(Die Berechnungen werden dir schwer fallsen so)


(Link)



Transformiertst du aber dein eines Bild in den ObjektSpace des anderen, sieht es so aus:
(Die Berechnungen sind schon einfacher nun)

(Link)

Hier kannst du nun über eine Transformationmatrize bestimmen (beim Blauen), die Position jeden Pixel des blauenbildes wo er genau im Space des roten Bildes liegt.

Also kannst du mit einer for-schleife durch jeden diskreten Bildpunkt bei blauenbild laufen.

irgendwie so:

C#-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
matrix.setRotation(blau_rot);
matrix.setPosition(blau_pos)

for(i_blau = 0; i_blau < height_blau i_blau++) {
  for(j_blau = 0; j_blau < width_blau; j_blau++) {
    Vector2 result = matrix.mul(i_blau, j_blau);

    i_rot = (int) (result.y / height_rot);
    j_rot = (int) (result.x / width_rot);

    if(i_rot > 0 &&  i_rot < height_rot && j_rot > 0 &&j _rot < width_rot) {
            Color rotColor = image_rot[i][j];
            Color blueColor = image_blue[i][j];
    }
  }
}  


Hab mir den Link nicht wirlich durchgeguckt. Hatte ich über google Bilder gefunden. Aber ich sehe, der Code der da beschrieben wird ist ähnlich wie meiner hier.

Also so ganz falsch kann ich hier gerade nicht liegen.

Aber verwende lieber den auf der Seite. Meinen habe ich gerade so im müden Kopf zusammengeschustert.

Man kann auch irgendwie andersrum rechnen mittels einer inversen Matrix, so dass man sich glaube ich paar Berechnungen erspaart, wenn man nur das rote Bild durchiteriert und dann mittels einer inversen Matrix die blauen Pixel bestimmt.

Ich denke in dem Link wird das dann auch eher so gemacht. Befolge den Link am Besten. Meine Variante ist sicherlich falsch, in so fern.

Aber die Idee müsstest du jetzt haben denke ich. Must dich ein wenig mit beschäftigen denke ich. Ist nicht mal so eben.

Edit:
Hab noch ein wenig gegoogled für dich und habe eine Seite gefunden wo unten sogar ein Projekt drangeheftet ist. Ist aber mit XNA gemacht worden. Aber dennoch kannst da ja mal in den Code gucken.
http://xbox.create.msdn.com/en-US/educat…xel_transformed

Hier ein Video davon:


Hier ist nochmal eine Beschreibung:
http://www.silverlightshow.net/items/XNA…-detection.aspx

Sollte dazugehören.

Dieser Beitrag wurde bereits 8 mal editiert, zuletzt von »TypeOverride« (28.05.2015, 02:58)


TGGC

1x Rätselkönig

Beiträge: 1 799

Beruf: Software Entwickler

  • Private Nachricht senden

7

28.05.2015, 08:18

Wenn man schon Per Pixel Collisionen macht, dann sollte das nicht so aussehen, wie auf diesen Bildern. Der Vorteil von Per Pixel Kollision ist, das Objekte genau dann kollidieren, wenn sich bei der Anzeige auch wirklich ueberlappen. Kein Monitor kann rotierte Pixel so anzeigen, wie du das aufmalst, es wird als wieder Faelle geben, wo sich Objkete optisch beruehren und die Kollision ausbleibt und/ oder umgekehrt. Wieso dann ueberhaupt per Pixel berechnen?

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

8

28.05.2015, 08:32

Der Vorteil von Per Pixel Kollision ist, das Objekte genau dann kollidieren, wenn sich bei der Anzeige auch wirklich ueberlappen.

Schwierig wird's aber dann, wenn du zur Darstellung der rotierten Sprites Texturfilterung benutzt (was ja heute üblicherweise getan wird). Dann wird ein Monitorpixel zugleich von z. B. 4 Pixeln von Sprite A und 4 Pixeln von Sprite B beeinflusst. Da müsste man sich überlegen, ab wann man eine Kollision meldet.

Sacaldur

Community-Fossil

Beiträge: 2 301

Wohnort: Berlin

Beruf: FIAE

  • Private Nachricht senden

9

28.05.2015, 09:44

In einem anderen, ähnlichen Thema habe ich eine solche Antwort bereits gegeben:
Statt einer "pixelgenauen Prüfung" solltest du die Formen deiner Objekte lieber mit geometrischen Formen (Rechtecke und Kreise) annähern [...] und auf Überlappung dieser prüfen.

Spätestens bei unterschiedlichen Auflösungen, mit Animationen oder mit einer anderen Perspektive dürften noch weitere Probleme dazukommen.
Spieleentwickler in Berlin? (Thema in diesem Forum)
---
Es ist ja keine Schande etwas falsch zu machen, als Programmierer tu ich das täglich, [...].

10

28.05.2015, 13:48

Mein Ziel ist es nicht ein Spiel zu programmieren wo ich diese Art der Kollisionserkennung verwende, sondern ich möchte mich einfach nur einmal damit beschäftigt haben um es zu verstehen :)

@TypeOverride

Vielen dank für die Infos ich werde später wenn ich Zeit habe mir alles durchlesen :)

Werbeanzeige