Sortierung eines Punktes und anschl. radiale Verteilung



  • Muss ich eigentlich mit Schluckauf meines Prozessors (P6 1,6GHZ) rechnen wenn ich ein Array von 5000 Elementen sortiere und oben genannte Vergleichsarie einbeziehe?



  • Die Vergleichsfunktion ist trivial wenn du erstmal r berechnet hast (auch wenn du das gerade nicht siehst ;)):

    int compare(const void *a, const void *b){
        // a und b entsprechend zu Strukturpointern casten
        // a->r und b->r berechnen
        if(a->r < b->r){
            return +1;
        }
        else if(a->r > b->r){
            return -1;
        }
        else{
            return 0;
        }
    }
    

    Und nein, 5000 Werte sollten kein Problem sein.



  • TactX schrieb:

    int compare(const void *a, const void *b){
        // a und b entsprechend zu Strukturpointern casten
        // a->r und b->r berechnen
        if(a->r < b->r){
            return +1;
        }
        else if(a->r > b->r){
            return -1;
        }
        else{
            return 0;
        }
    }
    

    Ok, super! Ich habe jetzt ein qsort() implementiert, jedoch - muss ich zu meiner Schande gestehen - bin ich natürlich prompt über "Strukturpointer casten" gestolpert. In meiner Vergleichsroutine werden jetzt zwei Strukturen vom Typ POINT verglichen, was natürlich Quatsch-Hoch-Acht ist. Nachfolgend mein phänomenaler, überaus atemberaubender Supercode:

    static int pixel_sorter (const void *a, const void *b) {
    	int *pa = *(int **) a;                 // < Was genau passiert hier eiegentlcih?
    	int *pb = *(int **) b;                 //
    	if             (pa > pb) return  1;    // < Wie bekomme ich hier Zugriff auf
    	else if        (pb > pa) return -1;    // < POINT.x um X als Vergleichsoperator
    	else return 0;                         // < zu benutzen???
    }
    

    Einfach alle Integer in POINT zu tauschen geht ja nicht, das habe ich gleich mal probiert und anschließend versucht mit pa->x und pb->x die X-Werte zu vergleichen. Kompiliert zwar klaglos, aber *patsch* direkt nach dem Starten die Lieblingsmeldung auf dem Bildschirm. Was habe ich denn jetzt schon wieder nicht verstanden?



  • Warum castest du denn nach (int **)? Du willst doch Elemente vom Typ POINT * vegleichen, oder? 😉



  • TactX schrieb:

    Warum castest du denn nach (int **)? Du willst doch Elemente vom Typ POINT * vegleichen, oder? 😉

    Mh, weil ich folgendes erfolglos ausprobiert habe:

    static int pixel_sorter (const void *a, const void *b) {
    	POINT *pa = *(POINT **) a;
    	POINT *pb = *(POINT **) b;
    	if        (pa->x > pb->x) return  1;
    	else if   (pb->x > pa->x) return -1;
    	else return 0;
    }
    

    Das wird zwar klaglos kompiliert, aber *patsch*: "das programm wurde unerwartet rhabarber ..." 😞



  • Und warum jetzt (POINT **)? Imho wäre (POINT 😉 zielführender 😉

    Aber eigentlich habe ich dich hier unnötig verwirrt, da du gar nicht casten musst.

    const POINT *pa = a;
    

    Sollte eigentlich reichen 😉



  • TactX schrieb:

    Und warum jetzt (POINT **)? Imho wäre (POINT 😉 zielführender 😉

    Weil ich noch ein mächtig grünes Greenhorn bin und nicht wirklich verstehe was hier eigentlich abgeht, aber ich arbeite daran. 😉

    TactX schrieb:

    Aber eigentlich habe ich dich hier unnötig verwirrt, da du gar nicht casten musst.

    const POINT *pa = a;
    

    Sollte eigentlich reichen 😉

    Ein Cast ist auch weiterhin notwenig, ohne expliziten Cast (POINT 😉 geht es nicht, siehe:

    .\ifs.cpp(158) : error C2440: 'Initialisierung': 'const void *' kann nicht in 'const POINT *' konvertiert werden
    

    Ich machs jetzt funktionierenderweise wie folgt:

    static int pixel_sorter (const void *a, const void *b) {
    
        const POINT *pa = (POINT *) a;           // warum const?
        const POINT *pb = (POINT *) b;           // warum const?
    
        if        (pa->x > pb->x) return  1;
        else if   (pb->x > pa->x) return -1;
        else return 0;
    }
    
    static void sort_pixel (struct state *st) {
        qsort ((void *) st->pointbuf,            // das zu sort. Array
                        st->npoints,             // Anz. Elem. im Array
                        sizeof(*st->pointbuf),   // Größe eines Elementes (????)
                        pixel_sorter);           // Sortierroutine s.o.
    }
    

    Und das funktioniert ersteinmal hervorragend, allerdings zur Zeit nach X-Koordinate sortiert. Ich werde in der Struktur jetzt mal ein "r" einbauen und das ganze mit Polarkoordinaten probieren. Das erscheint mir vielversprechender.
    Vielen dank für deine ausführliche Hilfe, hat mir sehr geholfen. 👍



  • timmix schrieb:

    TactX schrieb:

    Und warum jetzt (POINT **)? Imho wäre (POINT 😉 zielführender 😉

    Weil ich noch ein mächtig grünes Greenhorn bin und nicht wirklich verstehe was hier eigentlich abgeht, aber ich arbeite daran. 😉

    TactX schrieb:

    Aber eigentlich habe ich dich hier unnötig verwirrt, da du gar nicht casten musst.

    const POINT *pa = a;
    

    Sollte eigentlich reichen 😉

    Ein Cast ist auch weiterhin notwenig, ohne expliziten Cast (POINT 😉 geht es nicht, siehe:

    .\ifs.[b]cpp[/b](158) : error C2440: 'Initialisierung': 'const void *' kann nicht in 'const POINT *' konvertiert werden
    

    Kein Wunder wenn du den Code als C++ kompilierst 😉



  • TactX schrieb:

    Kein Wunder wenn du den Code als C++ kompilierst 😉

    Ja, ne? Hätte ich wohl erwähnen sollen, oder? Liegt es daran, das CPP eine striktere Typüberprüfung durchführt, oder warum würden deine Angaben in purem C funkionieren?

    Auch auf die Gefahr hin mich jetzt ins Newbie-Nest zu setzen, ich finde die Kommentare mit // einfach angenehm und überaus praktisch beim Lernen von C, man kann an beliebiger Stelle mal schnell was auskommentieren oder was hinschreiben, das abschließende */ bei reinem C ist ja sowas von nervig! Aber klar, wo du es jetzt sagst, natürlich ist das nicht der einzige Unterschied zwischen C und CPP, das wird mir jetzt gerade erst so richtig bewusst. Na ja, irgendwann wird es wohl auch bei mir C++ werden; ich dachte mir bringe, ich bringe mir erstal die HARDCOREBASICS bei dann könnte ich wenigsten mitreden (ich sehe gerade Luke Skywalker diesem rotschäuzigen Sith gegenüber stehen und mit Pointern und Zeigern und blitzenden Adressen um sich werfend den anderen darniederscheppernd - oha, der Wein macht sich bemerkbar!). 😉

    Insofern ... alles wird gut!

    Anmerkung: der Dornfelder von Aldi ist gar nicht mal schlecht!



  • timmix schrieb:

    TactX schrieb:

    Kein Wunder wenn du den Code als C++ kompilierst 😉

    Ja, ne? Hätte ich wohl erwähnen sollen, oder? Liegt es daran, das CPP eine striktere Typüberprüfung durchführt, oder warum würden deine Angaben in purem C funkionieren?

    Exakt.

    timmix schrieb:

    Auch auf die Gefahr hin mich jetzt ins Newbie-Nest zu setzen, ich finde die Kommentare mit // einfach angenehm und überaus praktisch beim Lernen von C, man kann an beliebiger Stelle mal schnell was auskommentieren oder was hinschreiben, das abschließende */ bei reinem C ist ja sowas von nervig!

    Es ist zwar richtig, dass es in altem C (C89) nur die /**/ Kommentare gibt, seit C99 gehören aber auch die // Kommentare dazu. Aber trotzdem unterstützen auch wohl die meisten alten Compiler die // Kommentare. Und die aktuellen sowieso. Demnach sind Kommentare kein Grund einen C++-Comiler für C zu verwenden 😉


Anmelden zum Antworten