Problem mit map<...>



  • Hallo,

    ich moechte einen z-Buffer-Algorithmus mit einer map<...> realisieren.
    Also ein Pixel als Schluessel liefert einen float als Wert.

    Leider funktioniert es nicht wie erwartet (siehe Ausgabe unten).

    Ein Problem ist, dass

    float z = z_buffer[einPixel];
    

    nicht zu funktionieren scheint.

    Wie koennte ich es sonst anstellen, aus einem gegebenen Pixel den
    zugehoerigen float zu erhalten?

    Weitere "Fehler":

    1. die if-Schleife nicht genommen
    2. erstes z_buffer.size() liefert 2 statt 1

    #include <iostream>
    	using std::cout;
    	using std::endl;
    #include <map>
    	using std::map;
    
    class Pixel
    {
    	public:
    		Pixel(int x, int y) { X = x; Y = y; }
    		~Pixel() {};
    
    		bool operator< (const Pixel&) const;
    
    		int x() const { return X; }
    		int y() const { return Y; }
    		void set(int x, int y) { X = x; Y = y; }
    
    	private:
    		int X;
    		int Y;
    };
    
    // "Less-Than"-Function for use in map<Pixel,float>
    bool Pixel::operator<(const Pixel& rhs) const
    {
    	if ((this->x() < rhs.x()) || 
    		((this->x() == rhs.x()) && (this->y() <= rhs.y())))
    
    		return true;
    	else
    		return false;
    }
    
    // use the output operator to write a Pixel
    std::ostream& operator<<(std::ostream& os, const Pixel& pixel)
    {
    	os << "(" << pixel.x() << ", " << pixel.y() << ")";
    	return os;
    }
    
    // here we go
    int main(int argc, char** argv)
    {
    	// a map from Pixel to float
    	map<Pixel,float> z_buffer;
    
    	float z = 3.14159;
    	float z2 = 3.14;
    
    	Pixel pixel(13,4);
    	// set z-value of 'pixel' at position ( x = 13, y = 4 ) to 'z'
    	z_buffer[pixel] = z;
    
    	// the "z-buffer-algorithm"
    	map<Pixel,float>::const_iterator it = z_buffer.find(pixel);
    
    	if (it != z_buffer.end()) // 'pixel' exists, i.e. it was set at least once before
    	{
    		cout << "if-Schleife genommen." << endl;
    		if (z_buffer[pixel] > z2)
    			z_buffer[pixel] = z2;	// update z-value of 'pixel'
    	}
    
    	// write the z-value of the Pixel
    	cout << pixel << " -> " << z_buffer[pixel] << endl;
    	cout << "z_buffer.size() = " << z_buffer.size() << endl;
    
    	// another Pixel for testing
    	Pixel pix2(13,3);
    	z_buffer[pix2] = 1.23456;
    
    	map<Pixel,float>::const_iterator it2 = z_buffer.begin();
    	cout << it2->first << " -> " << it2->second << endl;
    	cout << "z_buffer.size() = " << z_buffer.size() << endl;
    
    	return 0;
    }
    

    Ausgabe IST
    (13, 4) -> 0
    z_buffer.size() = 2
    (13, 3) -> 1.23456
    z_buffer.size() = 3

    Ausgabe SOLL
    if-Schleife genommen.
    (13, 4) -> 3.14
    z_buffer.size() = 1
    (13, 3) -> 1.23456
    z_buffer.size() = 2



  • a) Map ist hier völlig ungeeignet
    b) Debugger benutzen

    Bye, TGGC (Der Held lebt!)



  • Dein operator< liefert für gleiche Pixel true.



  • Mappa schrieb:

    Leider funktioniert es nicht wie erwartet (siehe Ausgabe unten).

    das ist die richtige Version von operator<

    bool Pixel::operator<(const Pixel& rhs) const 
    {
      if (x() < rhs.x())
        return true;
      else if(x() == rhs.x())
        return y() < rhs.y();
      else
        return false;
    }
    


  • Mappa schrieb:

    Hallo,

    ich moechte einen z-Buffer-Algorithmus mit einer map<...> realisieren.
    Also ein Pixel als Schluessel liefert einen float als Wert.

    Warum eine Map?

    float[sizex][sizey] tut's doch mindestens so gut.



  • Gast221212 schrieb:

    float[sizex][sizey] tut's doch mindestens so gut.

    und wenn man nur ein paar points braucht?

    point(0, 0)
    point(+10000, 100000)
    

    du rattest also statisch float[10000][100000] einlegen? man muss doch speicher sparen 😃

    //edit
    (10000 * 100000 * sizeof(float)) / (1024 * 1024) = c.a. 3815 MB
    wenn sizeof(float) == 4
    :p



  • ssm schrieb:

    Gast221212 schrieb:

    float[sizex][sizey] tut's doch mindestens so gut.

    und wenn man nur ein paar points braucht?

    zBuffer = man macht wohl 3d berechnung, und wenn du nicht nur ein paar pixel auf dem schirm haben willst, brauchst du schon [sizex][sizey]

    ssm schrieb:

    (10000 * 100000 * sizeof(float)) / (1024 * 1024) = c.a. 3815 MB
    wenn sizeof(float) == 4
    :p

    Bildschirm = sagen wir mal 1024 x 768 x sizeof(float) = 3 MB



  • TGGC schrieb:

    a) Map ist hier völlig ungeeignet
    b) Debugger benutzen)

    Zu a)
    Wieso sollte Map hier ungeeignet sein?

    1. kann ich damit sofort auf ein Pixel zugreifen/pruefen.
    2. werden nur die tatsaechlich benutzten Pixel in die Map geschrieben.
    3. passt sich die Map meiner Zeichenflaeche beim vergroessern/verkleinern automatisch an.

    Welche Struktur wuerdest Du mir denn sonst empfehlen, die diese Eigenschaften auch hat?

    Zu b)
    Ich habe erst mal auf die schnelle dieses kleine Programm geschrieben, um
    ueberhaupt zu sehen, ob und wie ich es mit der Map realisieren kann, und hab
    es dann sowohl mit dem Borland als auch mit den GNU C++ Compiler kompiliert.
    Das Ergebnis war die oben beschriebene Ausgabe.

    Nun habe ich es zum debuggen also in mein richtiges Programm implementiert,
    um es mit VC++ zu debuggen, und siehe da, hier funktioniert es so, wie es soll.

    😕 😕 😕
    Jetzt bin ich zwar noch mehr verwirrt, aber wenigstens gluecklich dabei 😃

    ssm schrieb:

    das ist die richtige Version von operator<

    bool Pixel::operator<(const Pixel& rhs) const 
    {
      if (x() < rhs.x())
        return true;
      else if(x() == rhs.x())
        return y() < rhs.y();
      else
        return false;
    }
    

    Wenn man es ganz genau nimmt, ist auch Deine Version nicht 100%ig optimal 😉 ,
    es wird naemlich eine if-Schleife zuviel getestet fuer den Fall, dass x() > rhs.x() ist.
    Trotzdem war meine natuerlich falsch *wurm*, und ist Deine natuerlich richtig.
    Danke Dir.

    bool Pixel::operator<(const Pixel& rhs) const
    {
    bool Pixel::operator<(const Pixel& rhs) const
    {
        if (x() < rhs.x())
            return true;
    	else if (x() > rhs.x())
    		return false;
        else
            return (y() < rhs.y());
    }
    


  • Mappa schrieb:

    Wenn man es ganz genau nimmt, ist auch Deine Version nicht 100%ig optimal 😉 ,
    es wird naemlich eine if-Schleife zuviel getestet fuer den Fall, dass x() > rhs.x() ist.

    😃
    in deinem Fall wird auch zuviel getestet, wenn x() == rhs.x() ist
    :p 😉



  • ssm schrieb:

    😃
    in deinem Fall wird auch zuviel getestet, wenn x() == rhs.x() ist
    :p 😉

    😃 🙄
    Looooool.

    Da wollte ich einmal den Klugscheisser spielen... 2:0 fuer Dich.



  • Mappa schrieb:

    Zu a)
    Wieso sollte Map hier ungeeignet sein?

    1. kann ich damit sofort auf ein Pixel zugreifen/pruefen.
    2. werden nur die tatsaechlich benutzten Pixel in die Map geschrieben.
    3. passt sich die Map meiner Zeichenflaeche beim vergroessern/verkleinern automatisch an.

    Welche Struktur wuerdest Du mir denn sonst empfehlen, die diese Eigenschaften auch hat?

    zu 1. nein, erst nachdem du den Pixel find()est
    zu 2. aber nicht gelöscht
    zu 3. und diesen Anpassen ist schön langsam

    Bye, TGGC (Der Held lebt!)


Anmelden zum Antworten