Informatiker Board (http://www.informatikerboard.de/board/index.php)
- Themengebiete (http://www.informatikerboard.de/board/board.php?boardid=1)
-- Praktische Informatik (http://www.informatikerboard.de/board/board.php?boardid=6)
--- Pixel-Perfekt-Kollision (http://www.informatikerboard.de/board/thread.php?threadid=3191)


Geschrieben von Tommy1234 am 28.08.2016 um 22:41:

  Pixel-Perfekt-Kollision

Hallo zusammen,

schreibe gerade eine Pixelkollisionsmethode und komme am Knackpunkt nicht weiter.

Zu meiner Vorgehensweise:

Ich habe zwei Bilder deren Pixel ich mit getRGB(() ausgelesen habe. Anschließend habe ich jeweils auf den Alpha-Wert geprüft und wenn der Pixel NICHT-Transparent war diesen dann an der Stelle in einem zweidimensionalen boolean Array auf true gesetzt, so dass ich sozusagen ein Schwarz-Weissbild erhalte, wobei Weiss für transparent und Schwarz für NICHT-transparent steht.

Nun habe ich jeweils ein Rectangle um die Bilder gezeichnet und mit intersects auf Überschneidung geprüft. Wenn diese Prüfung true ergibt, berechne ich die Schnittfläche des einen Bildes mit dem anderen.

So und nun das Knackpunktproblem:

Wie ermittelt man nun in den beiden booleanArrays, wann es zu einer Überschneidung kommt? Also die jeweiligen Stellen im boolean Array?

Die finale Überprüfung ist ja dann klar.

Hier mal der Code der Kollisionsmethode:
code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
public boolean collide(GameObject sprite1,GameObject sprite2) {
		raster1 = new boolean[sprite1.image.getWidth()][sprite1.image.getHeight()];
		raster2 = new boolean[sprite2.image.getWidth()][sprite2.image.getHeight()];
		
		for(int x = 0;x<sprite1.image.getWidth();x++){
			for(int y = 0;y<sprite1.image.getHeight();y++){
				int argb = sprite1.image.getRGB(x,y);
				if(argb==0){
					raster1[x][y] = false;
				}
				else{
					raster1[x][y] = true;
				}
			}
		}
		
		for(int x = 0;x<sprite2.image.getWidth();x++){
			for(int y = 0;y<sprite2.image.getHeight();y++){
				int argb = sprite2.image.getRGB(x,y);
				if(argb==0){
					raster2[x][y] = false;
				}
				else{
					raster2[x][y] = true;
				}
			}
		}
		
		if(sprite1.boundingbox.intersects(sprite2.boundingbox)){
			
			startx = sprite2.getBoundingbox().x;
			endx = (sprite1.getBoundingbox().x+sprite1.getBoundingbox().width)-sprite2.getBoundingbox().x;
			starty = sprite1.getBoundingbox().y;
			endy = (sprite2.getBoundingbox().y+sprite2.getBoundingbox().height)-sprite1.getBoundingbox().y;
			
			
			boolean nontransparent1 = raster1[endx][endy]; //hier brauche ich Hilfe um die Stelle zu berechnen
			boolean nontransparent2 = raster2[endy][endx];
								
			if(nontransparent1 && nontransparent2){
				return true;
			}
		}
		
		return false;
	} {


Wäre für Hilfe Dankbar,

Gruß Tommy



Geschrieben von Tommy1234 am 31.08.2016 um 21:58:

 

Noch ein Nachtrag zum besseren Verständnis.

Nach der Überprüfung der allgemeinen Rechteckkollision, entsteht eine Fläche, in der die Pixel durchlaufen werden.

Das Problem ist, dass ich die Koordinaten des neuen Überschneidungsrechtecks allgemein für jede Richtung (also z.B. von links oben kommend etc.) lösen möchte.

Gibt's da eine Formel oder sowas oder komme ich um eine explizite Überprüfung jeder Richtung nicht herum?



Geschrieben von eulerscheZahl am 01.09.2016 um 16:33:

 

Nochmal zum Sachverhalt:
Du hast zwei Objekte, die du mit Rechtecken umrandet hast (grün, blau).
Die mögliche Kollision hast du jetzt schon auf die orange Fläche eingegrenzt, oder?

Es geht dir darum, nicht jedes Pixel in der orangen Fläche zu testen?
Darum wirst du denke ich nicht herumkommen. Du könntest mit dem Rand anfangen. Dann hättest du zumindest im Kollisionsfall mit hoher Wahrscheinlichkeit schnell einen Treffer.
Kannst du die Form der Objekte weiter einschränken (z.B. konvex/konkav)?


Forensoftware: Burning Board, entwickelt von WoltLab GmbH