Sortierung eines Punktes und anschl. radiale Verteilung
-
TactX schrieb:
Zu 1.: http://de.wikipedia.org/wiki/Polarkoordinaten
Die Berechnung kannst dann natürlich in die Vergleichsfunktion vom qsort() einbauen. Wenn du den Radius aber noch öfters benötigst, könntest du die Struktur um ein Member "r" erweitern.
Aha, danke! Also, qsort()! Mal sehen ob ich das hinbekomme. Als Vergleich für qsort() würde ja (glaube ich) der Radius reichen, der Winkel ist ja für das konzentrische einfärben uninteressant. Es würde ja ausreichen die Punkte anhand ihrer Entfernung zum Mittelpunkt zu sorteiren.
Mal sehen, ich komme für den Radius eines (angenommenen und beispielhaften) Punktes auf folgendes:
int xCenter = cxScreen/2; // Verschiebung des Nullpunktes ins int yCenter = cyScreen/2; // Zentrum des Bidschirme double r; //Potzblitz, ein Radius... int xPK; // X für Polarkoordinate (-xCenter ... xCenter) int yPK; // Y für Polarkoordinate (-yCenter ... yCenter) // Und los gehts .... x[1] = 520; // beispielhaft y[1] = 340; // beispielhaft if (x[1] < xCenter) xPK = -(xCenter - x[1]); // negative X-Richtung else xPK = (x[1] - xCenter); // positive X-Richtung if (y[1] < yCenter) yPK = (yCenter - y[1]); // positive Y-Richtung else yPK = -(y[1] - yCenter); // negative Y-Richtung // laut Wikipedia ist kartesisch zu polar für "r" folgendes: r = sqrt(pow(xPK,2) + pow(yPK,2));
Wie quetsche ich den ganzen Kladderatsch jetzt in eine Bedingung für qsort()? Entweder, es gibt mir einer einen heißen Tipp, oder ich mach morgen weiter, denn mir raucht der Schädel (Φ
Σ→λ∫Λωχ≠Π )und ich habe bis vorhin noch nicht mal gewusst dass es eine Funktion qsort() gibt. Ich hätte wahrscheinlich die langsamste Schleife entworfen die je geschrieben wurde. However, das wird ein hartes Stück Brot, aber ich habe neulich bei Deutschlandfunk gehört, dass Erfolgserlebnisse beim Lernen glücklich machen.
In diesem Sinne, eine schöne Nacht noch und vielen Dank nochmal.
-
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