[]operator für 3D-Array



  • Es geht um ein 3D-Array, was ich als einfaches 1D-Array implementieren will.
    Es soll mal dazu dienen ein Bild aufzunehmen (also height*width*3)
    Und nun will ich den operator [] so überladen, dass ich auf jeden Wert zugreifen kann (also r,g,b) So sieht es bisher aus:

    class CArray3D
    {
    	private:
    		int PixelData[300];	
    		int width,height;
    	private:	
    		class Proxy
    		{
    			public:
    				__forceinline Proxy(int *p) : m_p(p) { }
    
    				__forceinline int* operator[](int const x_index)
    				{
    					return &m_p[x_index*3];
    				}
    			private:
    				int *m_p;
    		};
    	public:
    		CArray3D(int width_,int height_) : width(width_),height(height_) {}
    
    		__forceinline Proxy operator[] (int const y_index)
    		{
    			return Proxy(&PixelData[y_index*width*3]);
    		}
    };
    

    Kennt jemand eine bessere Lösung? Wie kann man es schneller machen?



  • also hier sind noch ein paar wege http://www.c-plusplus.net/forum/viewtopic.php?t=39489 aber ich würde zu boost greifen



  • Sollte das ganze nicht so aussehen, dass du ne Klasse Color hast, die deine RGB-Werte speichert und du ein zweidimensionalen Container benutzt, der Objekte des Typs Color verwaltet.

    class ColorContainer : public vector<vector<Color> > {
       // Hier Konstruktoren und weitere Methoen definieren, die dein Feld braucht
    };
    

    Jetzt kannst du beispielsweise per meinBild[x][y].red() direkt den Rot-Anteil des entsprechenden Pixels auslesen.



  • ein vector<vector> kann aber sehr viel speicher brauchen



  • In wie fern? Ich muss doch jeden Punkt des Bilds speichern. Und so groß müssen die Vektoren eben sein.



  • Bei einem vector<vector<Color> > wird aber für jeden vector<Color> noch extra die Größe gespeichert: Verschwendung, wenn die Dimensionen gleich groß sein sollen.



  • SlimTimmy schrieb:

    Es geht um ein 3D-Array, was ich als einfaches 1D-Array implementieren will.
    Es soll mal dazu dienen ein Bild aufzunehmen (also height*width*3)
    Und nun will ich den operator [] so überladen, dass ich auf jeden Wert zugreifen kann (also r,g,b) So sieht es bisher aus:
    ...
    Kennt jemand eine bessere Lösung? Wie kann man es schneller machen?

    mach die proxies auf jeden fall so, daß sie bei verwendung von [][][] nur noch Array3D::at(size_t,size_t,size_t) aufrufen. wenn nicht stirbste bei dem versuch, später mal das speicherlayout des containers zu ändern oder endlich assert einzubauen. Hände weg von standard-containern ohne assert.



  • \aleph_0 schrieb:

    Bei einem vector<vector<Color> > wird aber für jeden vector<Color> noch extra die Größe gespeichert: Verschwendung, wenn die Dimensionen gleich groß sein sollen.

    außerdem allokiert ein vector normalerweise immer mehr speicher an, als verwendet wird.



  • davie schrieb:

    außerdem allokiert ein vector normalerweise immer mehr speicher an, als verwendet wird.

    Stimmt. Ein ordentlicher Allokator könnte z.B. immer auf 2^n "aufrunden". Der vom VC++ macht das leider nicht. 😞



  • \aleph_0 schrieb:

    davie schrieb:

    außerdem allokiert ein vector normalerweise immer mehr speicher an, als verwendet wird.

    Stimmt. Ein ordentlicher Allokator könnte z.B. immer auf 2^n "aufrunden". Der vom VC++ macht das leider nicht. 😞

    du beklagst dich, daß er NICHT aufrundet und zugleich, daß er speicher verschwendet (wie diese aufrundenden buddy-allokatoren). da stimmt was nicht.



  • Egal, ob jetzt Fertiger Container oder selbst angelegtes Array. ich würde auf jedenfall zu einem zweidimensionalen Feld dessen Elemente eine Farbstruktur sind raten statt ein dreidimentsionales Feld zu verwenden. Die Drei komponenten rot, gruen und blau schreien doch fast nach einer benennung statt sie mit 0 1 und 2 anzusprechen.



  • Das Array ist auch normal 1-dimensional. (das geht schneller zum Laden von Farbinformationen und das schreiben) Sonst müsste ich es immer konvertieren.
    Aber ich möchte es eben mit [y][x][farbwert] ansprechen.



  • Dann könntest du am einfachsten doch erstmal den ()-Operator überladen.

    char operator() (int x, int y, int color_as_index)
    {
       return PixelData[y * width *3 + x*3 + color_as_index;
    }
    

    aber meinet wegen:

    class Picture {
    public:
       Picture (int width, int height)
          : width_m(width), height_m(height)
       {
          picture_m = new int[width*height];
       }
       ~Picture ()
       {
          delete [] picture_m;
       }
    
       class Row {
       public:
    
          class Color {
          public:
             Color (int * adress)
                : adress_m(adress)
             {}        
    
             int operator [] (int i)
             {
                return *(adress_m+i); 
             }
    
          private:
             int * adress_m;
          }
    
          Row (int * adress)
             : adress_m(adress)
          {}        
    
          Color operator [] (int i)
          {
             return Color(adress_m+i*3); 
          }
    
       private:
          int * adress_m;  
       };
    
       Row operator[] (int i)
       {
          return Row(picture_m + i*3*height_m);
       }
    
    private:
       int width_m, height_m;
       int * picture_m;
    };
    

    Irgendwie so was. (ungetestet)



  • volkard schrieb:

    \aleph_0 schrieb:

    davie schrieb:

    außerdem allokiert ein vector normalerweise immer mehr speicher an, als verwendet wird.

    Stimmt. Ein ordentlicher Allokator könnte z.B. immer auf 2^n "aufrunden". Der vom VC++ macht das leider nicht. 😞

    du beklagst dich, daß er NICHT aufrundet und zugleich, daß er speicher verschwendet (wie diese aufrundenden buddy-allokatoren). da stimmt was nicht.

    Ich beklage mich, dass der vector beim VC++ nicht aufrundet, und habe mich nicht beklagt, dass er Speicher verschwendet.
    Ich habe nur darauf hingewiesen, dass ich ein mehrdimensionales Array mit gleichen Dimensionen nicht mit verschachtelten vectoren darstellen würde. (Sondern mit einem Wrappen um einen eindimensionalen vector mit der Größe x*y.)



  • Helium schrieb:

    aber meinet wegen:
    [cpp]
    class Row {
    ...
    private:
    int number_of_rows_m;
    Color * rows_m;
    };

    war das nur ein test?



  • Ja. Habs nochmal editiert. Keine Ahnung, was ich da geschrieben hatte.


Anmelden zum Antworten