Elemente innerhalb einer ArrayList vergleichen

Eichelhäer

Bekanntes Mitglied
Hallo,

Ich hab ne ArrayList mit Rechtecken (jedes hat ne eigene ID) und möchte diese auf Überschneidungen prüfen. Das Problem ist, dass sich erstens die Rechtecke auch selber prüfen und ich zweitens nicht weiß wie man mittels ID die Rechtecke in einer for-Schleife unterscheidet.

Weiß jemand Rat?

Gruß Eichelhäer
 
Braucht ein Rechteck hier wirklich eine ID?
Java:
public class RectIntersets
{

    public static void main(String[] args)
    {
        Rectangle[] array = {new Rectangle(0, 0, 10, 10), new Rectangle(0, 0, 15, 15)};
        Rectangle a = new Rectangle(11, 11, 13, 13);
        for(int i = 0; i < array.length; i++)
        {
            if(a.intersects(array[i]))
            {
                System.out.println(array[i].toString() + ", on Place: " + i);
            }
        }
    }
   
}
/** Output */
java.awt.Rectangle[x=0,y=0,width=15,height=15], on Place: 1
 
Damn, hab mich zu früh gefreut.

Java:
@Override
    public int hashCode() {
        return id;
    }

    @Override
    public boolean equals(Object o) {
        Sprite s = (Sprite) o;
        if(o instanceof Sprite) {
            if(s.id != this.id) {
                return true;
            }
        }
        return false;
    }

Und anschließender Prüfung in der for schleife liefert kein true.

Versteh aber nicht warum.

Hier noch kurz der Aufruf:

Java:
for(int p = 0;p<peasants.size();p++) {
            peasants.get(p).update();
            if(peasants.get(p).equals(peasants.get(p))) {
                if(Tools.collision(peasants.get(p),peasants.get(p))) {
                    peasants.get(p).x = peasants.get(p).getLastX();
                    peasants.get(p).y = peasants.get(p).getLastY();
                   
                }
            }
           
        }
 
Hallo nochmal,

ich möchte es so und so funktioniert es, allerdings für 100 Sprites ist das verdammt viel arbeit:

Java:
if(Tools.collision(peasants.get(0),peasants.get(1))) {
                peasants.get(0).x = peasants.get(0).getLastX();
                peasants.get(0).y = peasants.get(0).getLastY();   
            }
            if(Tools.collision(peasants.get(0),peasants.get(2))) {
                peasants.get(0).x = peasants.get(0).getLastX();
                peasants.get(0).y = peasants.get(0).getLastY();   
            }
            if(Tools.collision(peasants.get(1),peasants.get(2))) {
                peasants.get(1).x = peasants.get(1).getLastX();
                peasants.get(1).y = peasants.get(1).getLastY();   
            }
            if(Tools.collision(peasants.get(1),peasants.get(0))) {
                peasants.get(1).x = peasants.get(1).getLastX();
                peasants.get(1).y = peasants.get(1).getLastY();   
            }
            if(Tools.collision(peasants.get(2),peasants.get(1))) {
                peasants.get(2).x = peasants.get(2).getLastX();
                peasants.get(2).y = peasants.get(2).getLastY();   
            }
            if(Tools.collision(peasants.get(2),peasants.get(0))) {
                peasants.get(2).x = peasants.get(2).getLastX();
                peasants.get(2).y = peasants.get(2).getLastY();   
            }
 
@Eichelhäer
Schau dir Java-Docs zum Thema "Rectangle" mal an, für dich ist die Methode "
public boolean intersects(Rectangle r)" interessant..
Ich würde von Rechteck nicht auf Rectangle schließen, das ist oftmals ne ungeeignete Klasse 😉

Bei der ID Stimm ich dir aber zu, die ist für sowas wie Rechtecke Unsinn (außer für die awt-Rectangle-Klasse 😛 )

Hallo nochmal,

ich möchte es so und so funktioniert es, allerdings für 100 Sprites ist das verdammt viel arbeit:

Java:
if(Tools.collision(peasants.get(0),peasants.get(1))) {
                peasants.get(0).x = peasants.get(0).getLastX();
                peasants.get(0).y = peasants.get(0).getLastY(); 
            }
            if(Tools.collision(peasants.get(0),peasants.get(2))) {
                peasants.get(0).x = peasants.get(0).getLastX();
                peasants.get(0).y = peasants.get(0).getLastY(); 
            }
            if(Tools.collision(peasants.get(1),peasants.get(2))) {
                peasants.get(1).x = peasants.get(1).getLastX();
                peasants.get(1).y = peasants.get(1).getLastY(); 
            }
            if(Tools.collision(peasants.get(1),peasants.get(0))) {
                peasants.get(1).x = peasants.get(1).getLastX();
                peasants.get(1).y = peasants.get(1).getLastY(); 
            }
            if(Tools.collision(peasants.get(2),peasants.get(1))) {
                peasants.get(2).x = peasants.get(2).getLastX();
                peasants.get(2).y = peasants.get(2).getLastY(); 
            }
            if(Tools.collision(peasants.get(2),peasants.get(0))) {
                peasants.get(2).x = peasants.get(2).getLastX();
                peasants.get(2).y = peasants.get(2).getLastY(); 
            }
Überleg doch mal, wenn man die Zahlen durch eine Schleife generieren kann...😉


In deiner equals-Methode castest du btw, bevor du prüfst, ob es die passende Klasse ist - das solltest du andersrum machen.
 
Ich würde von Rechteck nicht auf Rectangle schließen
Da aber Rectangle zu Deutsch Rechteck heißt und ein Rechteck als solcher angesehen wird, wenn alle seine Winkel rechte Winkel sind, auch die "Rechtecke", welche im Volksmund als Quadrate bekannt sind, sehe ich persönlich da kein wirklichen Unterschied. So, jetzt aber genug geklugscheißert, Zeit fürs Bett, in dem Sinn schönen Abend noch 🙂
 
Da aber Rectangle zu Deutsch Rechteck heißt und ein Rechteck als solcher angesehen wird, wenn alle seine Winkel rechte Winkel sind, auch die "Rechtecke", welche im Volksmund als Quadrate bekannt sind, sehe ich persönlich da kein wirklichen Unterschied.
Okay, mein Satz in genauer: Rechteck nicht auf java.awt.Rectangle schließen 😛
 
if(Tools.collision(peasants.get(0),peasants.get(1))) {
peasants.get(0).x = peasants.get(0).getLastX();
peasants.get(0).y = peasants.get(0).getLastY();
}
//...
if(Tools.collision(peasants.get(1),peasants.get(0))) {
peasants.get(1).x = peasants.get(1).getLastX();
peasants.get(1).y = peasants.get(1).getLastY();
}

Ohne deine Semantik zu kennen macht das für mich perse nicht wirklich Sinn zu fragen ob A intersects B + B intersects A

if(peasants.get(p).equals(peasants.get(p))) {

Bitte was?
 
Naja, ich hab halt ne List mit allen Sprites und möchte die unterscheiden können. Das Problem ist halt das bei meinem Aufruf sich die Rechtecke selbst auf intersects prüfen und genau das möchte ich nicht. Stattdessen soll jedes Rechteck in der Liste als einziges angesehen werden.

Es macht schon Sinn, denn gehardcodet geht's ja.
 
Jedes Objekt in einer Liste unterscheidet sich nur durch seine ID.

Wenn ich aber mit equals prüfe zwei Rectecke sind verschieden wenn die id verschieden ist geht's auch nicht. Kein Plan warum?
 
@Eichelhäer
Prüfe doch, wie bereits erwähnt, mit hashcode(). Alternativ kann man noch mit compareTo(Object obj) prüfen, dazu musst du aber das Interface Comporable<T> implementieren.
Java:
public class Beispiel
{
    /** A */
    public static void main(String[] args)
    {
        int position_in_x = 10;
        int position_in_y = 10;
        Rechteck a = new Rechteck(position_in_x, position_in_y, 10, 10);
        Rechteck b = new Rechteck(position_in_x, position_in_y, 10, 10);
        System.out.println(a.compareTo(b));
        System.out.println(a.equals(b));
    }
/** Output */
0
true
}
Java:
public class Beispiel
{
    /** B */
    public static void main(String[] args)
    {
        int position_in_x = 10;
        int position_in_y = 10;
        Rechteck a = new Rechteck(position_in_x, position_in_y, 10, 10);
        Rechteck b = new Rechteck(position_in_x, position_in_y, 11, 10);
        System.out.println(a.compareTo(b));
        System.out.println(a.equals(b));
    }
/** Output */
-1
false
}

Wie willst du denn die Rechtecke prüfen, bzw. den die selbe ID zuweisen, wenn diese die gleichen Positionen und Maße haben?
 
HH,
Ok.
Bleiben wir bei den Rechtecken. Auf einem Spielfeld sind größengleiche Rechtecke an verschiedenen Positionen verteilt. Klickt man auf ein Rechteck, kann man es mit den Pfeiltasten bewegen. ich möchte halt nicht hundert einzelne Rechtecke per Hand eingeben und diese dann per Hand auf intersects prüfen was ja eig. gehen sollte (erstmal unabhängig von dem eigtl. sin ddahinter). Diese Rechtecke möchte ich alle in ner liste halten und eben mit möglichst wenig aufwand auf intersects prüfen. Wie gesagt gehardcodet geht ja.
 
Klickt man auf ein Rechteck, kann man es mit den Pfeiltasten bewegen.
Dann musst du ja schon mal nicht jedes Rechteck mit jedem anderen Rechteck vergleichen, sondern "nur" das eine, das sich bewegt, mit allen anderen.

peasants.intersectsWith(movingPeasant)

Die Methode "intersectsWith" musst du dir halt für die Klasse "Peasants" (die die Liste enthält) noch schreiben. Darin gehst du in einer Schleife einfach durch die Liste und vergleichst.

Java:
class Peasants {

    List<Peasant> peasants;

    public boolean intersectsWith(Peasant p) {
        for (Peasant peasant : peasants) {
            // ...
        }
    }
}
 
Zuletzt bearbeitet:
Jo. Ok.
Erstmal danke dafür. Ich denke ich habs soweit kapiert.
Allerdings hab ich jetzt ohne equals und hasCode zu überschreiben einfach direkt die ids verglichen in den schleifen und bekomm genau die werte die ich für die Bestimmung haben wollte (siehe hardcodet Variante die ich postete).

Hier kurz die schleifen:

Java:
       for(int i = 0;i<peasants.size();i++) {
            for(int j = 0;j<peasants.size();j++) {
                peasants.get(i).update();
                if(peasants.get(i).id!=peasants.get(j).id) {
                    System.out.println(peasants.get(i).id + "    " + peasants.get(j).id);
                    if(Tools.pixelCollision(peasants.get(peasants.get(i).id),peasants.get(peasants.get(j).id))) {
                        peasants.get(peasants.get(i).id).x = peasants.get(peasants.get(i).id).getLastX();
                        peasants.get(peasants.get(i).id).y = peasants.get(peasants.get(i).id).getLastY();
                        System.out.println(true);
                    }
                }
            }
        }

Die Kollision wird zwar erkannt, aber lastX greift nicht mehr.
Liegt das an der Laufzeit?
 
HHHHHHH,
Ich habs. Zu blöd wenn man update gleichzeitig mit aufruft.

Hier der Code:
Java:
for(int i = 0;i<peasants.size();i++) {
            peasants.get(i).update();
        }
       
        for(int i = 0;i<peasants.size();i++) {
            for(int j = 0;j<peasants.size();j++) {
                if(peasants.get(i).id!=peasants.get(j).id) {
                    if(Tools.pixelCollision(peasants.get(peasants.get(i).id),peasants.get(peasants.get(j).id))) {
                        peasants.get(peasants.get(i).id).x = peasants.get(peasants.get(i).id).getLastX();
                        peasants.get(peasants.get(i).id).y = peasants.get(peasants.get(i).id).getLastY();
                    }
                }
            }
        }

update Methode separat und gut is.

Vielen dank trotzdem an alle Thema hiermit geschlossen mir reicht das so. Auch wenn mich das mit hashCode und equals überschreiben interessiert hat. 🙂

Gruß Eichelhäer
 
Hallo mal wieder,
das mit der ID war doch keine gute Idee. Damit stößt man schnell an Grenzen für weitere Implementationen.
Ich habe ne Klasse die von Rectangle erbt. Wie muss ich denn die hashCode() bzw. die equals Methode überschreiben?
Also meine versuche schlugen fehl.
 
Schreib doch einfach mal, was Du jetzt eigentlich genau haben willst. Einmal schreibst Du von Rechtecken, dann kasperst Du mit irgendwelchen Sprites herum, dann geht es einmal um Überschneidungen aller Rechtecke, dann wieder nur von einem mit allen anderen usw. usw. Jetzt von Rectangle abgeleitete Klasse... Das kann doch nicht sein, dass man für ein (scheinbar) triviales Problem mittlerweile 34 Kommentare braucht und immer noch nicht weiß, was nun eigentlich rauskommen soll.
 

Zurück
Oben