Loop verbessern



  • Ich habe den folgenden Code:

    class Obj{
      int x;
      int y;
      int width;
      int height;
    public:
      bool is_col(Obj&);
      void col(){ /*...*/ };
    };
    //...
    for(list<Obj>::iterator who=obj_reg.begin();who!=obj_reg.end();++who)
    for(list<Obj>::iterator with=obj_reg.begin();with!=obj_reg.end();++with)
    if(who!=with)
     who->is_col(*with)
       who->col(*with);
    //...
    bool Obj::is_col(Obj&other)
    {
     if(x+width<other.x)
       return false;
     if(other.x+other.width<x)
       return false;
     if(y+height<other.y)
       return false;
     if(other.y+other.height<y)
       return false; 
     return true; 
    }
    

    Was er macht ist die Memberfunktion col eines Obj aufzurufen für jedes andere Obj das mit ihm überlappt. Wenn die Anzahl der Objs klein ist dann ist das auch kein Problem allerdings bei nur 25 Obj muss ich 625 mal prüfen ob 2 Objs überlappen und das ganz wird zu langsam. Könnte jemand mir bitte helfen das irgendwie zu verbessern?
    Bin für jede Hilfe dankbar.

    PS:Mods, bitte nicht ins Graphic/Spiele Forum verschieben, bin unregistriert.



  • Du testest erst, A<->B und dann testest du nochmal B<->A.



  • Danke, daran hatte ich gar nicht gedacht. Also das wäre dann:

    for(list<Obj>::iterator who=obj_reg.begin();who!=obj_reg.end();++who)
    for(list<Obj>::iterator with=who;with!=obj_reg.end();++with)
    if(who!=with)
     who->is_col(*with)
     {
      who->col(*with);
      with->col(*who);
     }
    

    und braucht nur noch halb soviele Checks. Hat sonst noch jemand Verbesserungsvorschläge?



  • Die zweite Schleife muss nur bis a-1 laufen:

    for (int a = 0;  a < end;  ++a)
        for (int b = 0;  b < a-1;  ++b)
            a<->b;
    

    Damit sparst du dir auch den Vergleich, ob a == b.

    Bei is_col würde ich die Referenz const übergeben. Nicht wegen der Optimierung, aber sonst kannst du keine const-Objekte übergeben.

    Dann kannst du ganz allgemein Kollisionsprüfungen optimieren, indem du die Karte in Regionen einteilst und nur Objekte in der selben Region testest. Das bringt sowieso mehr als alles andere, je mehr high-level die Optimierung, desto mehr bringt das was.


Anmelden zum Antworten