Ich hatte erwartet, etwas Zufälliges zu bekommen (weißes Rauschen). Interessant ist aber die Ausgabe:
Kennen Sie den Grund dafür?
Bearbeiten
Jetzt ist klar, dass es nichts damit zu tun hat rand().
Versuchen Sie auch diesen Code:
for (x=0; x<pixel_width; ++x)
for (y=0; y<pixel_height; ++y)
{
r[x][y] = (x+y);
g[x][y] = (y-x);
/* b[x][y] = rand()%2? x : y; */
}
cos rand ist nicht rand – schöne Demo davon. Es ist 100% deterministisch
– pm100
21. September 2018 um 23:08 Uhr
stackoverflow.com/questions/822323/…
– pm100
21. September 2018 um 23:09 Uhr
@ pm100: Wie die Antwort von bames53 so gut erklärt, würden Sie das gleiche Muster erhalten, selbst wenn Sie einen perfekten Zufallszahlengenerator verwenden würden.
– TonyK
22. September 2018 um 14:04 Uhr
Entschuldigen Sie eine Frage: Da Sie die x- und y-Koordinaten verwenden, um die Pixelwerte zu berechnen, warum sollten Sie erwarten, dass diese Werte unabhängig von den Koordinaten sind? Wenn das Bild zu gleichmäßig zufällig aussieht, würden Sie das brauchen, oder?
– Thomas Padron-McCarthy
23. September 2018 um 7:15 Uhr
Gelernte Lektionen: Zufällige Dinge mit Zufallszahlen zu tun führt nicht zu zufälligen Ergebnissen 🙂
– Hagen von Eitzen
23. September 2018 um 20:03 Uhr
Namen53
Ich wollte anfangs die gleiche Antwort wie alle anderen haben und dies den Problemen zuordnen rand(). Ich habe es mir jedoch besser überlegt und stattdessen die Verteilung analysiert, die Ihre Mathematik tatsächlich erzeugt.
TL;DR: Das Muster, das Sie sehen, hat nichts mit dem zugrunde liegenden Zufallszahlengenerator zu tun, sondern ist einfach darauf zurückzuführen, wie Ihr Programm die Zahlen manipuliert.
Ich bleibe bei deiner blauen Funktion, da sie alle ähnlich sind.
Jeder Pixelwert wird aus einer von drei Funktionen ausgewählt: (x + y) % rand(), (x - y) % rand()und rand();
Schauen wir uns die Bilder an, die von jedem dieser allein erzeugt werden.
rand()
Das ist, was Sie erwarten würden, nur Rauschen. Nennen Sie dies “Bild C”
(x + y) % rand()
Hier addieren Sie die Pixelkoordinaten und nehmen den Rest aus der Division durch eine Zufallszahl. Wenn das Bild 1024 x 1024 groß ist, liegt die Summe im Bereich [0-2046]. Die Zufallszahl, nach der Sie tauchen, liegt im Bereich [0,RAND_MAX], wobei RAND_MAX mindestens 32k und auf einigen Systemen 2 Milliarden beträgt. Mit anderen Worten, es besteht bestenfalls eine Chance von 1 zu 16, dass der Rest nicht gerecht ist (x + y). Diese Funktion erzeugt also größtenteils nur einen Gradienten mit zunehmendem Blau in Richtung + x + y.
Sie verwenden jedoch nur die niedrigsten 8 Bits, da Sie a zurückgeben uint8_tsodass Sie 256 Pixel breite Farbverlaufsstreifen haben.
Nennen Sie dies “Bild A”
(x - y) % rand()
Hier machen Sie etwas Ähnliches, aber mit Subtraktion. Solange x größer als y ist, haben Sie etwas Ähnliches wie im vorherigen Bild. Aber wo y größer ist, ist das Ergebnis eine sehr große Zahl, weil x und y sind unsigned (negative Ergebnisse werden bis zum Anfang des Bereichs des unsigned-Typs umbrochen), und dann die the % rand() Tritt ein und Sie bekommen tatsächlich Geräusche.
Nennen Sie dies “Bild B”
Jedes Pixel in Ihrem endgültigen Bild wird mithilfe von Funktionen aus einem dieser drei Bilder entnommen rand() % 2 und ((x * y % 1024) % rand()) % 2. Die erste davon kann so gelesen werden, dass Sie mit einer Wahrscheinlichkeit von 50 % auswählen (Ignorieren von Problemen mit rand() und seine niederwertigen Bits.)
Hier ist eine Nahaufnahme, wo rand() % 2 wahr ist (weiße Pixel), also wird Bild A ausgewählt.
Die zweite Funktion ((x * y % 1024) % rand()) % 2 hat wieder das Problem wo rand() ist normalerweise größer als das, was Sie dividieren, (x * y % 1024)was höchstens 1023 ist. Dann (x*y%1024)%2 erzeugt nicht gleich oft 0 und 1. Jede ungerade Zahl multipliziert mit einer beliebigen geraden Zahl ist gerade. Jede gerade Zahl multipliziert mit einer beliebigen geraden Zahl ist auch gerade. Nur eine ungerade Zahl multipliziert mit einer ungeraden Zahl ist ungerade, und so %2 bei Werten, die drei Viertel der Zeit gerade sind, wird in drei Vierteln der Zeit 0 ergeben.
Hier ist eine Nahaufnahme, wo ((x * y % 1024) % rand()) % 2 wahr ist, sodass Bild B ausgewählt werden konnte. Es wählt genau dort aus, wo beide Koordinaten ungerade sind.
Und hier ist eine Nahaufnahme, wo Bild C ausgewählt werden könnte:
Wenn Sie die Bedingungen hier schließlich kombinieren, wird Bild B ausgewählt:
Und wo Bild C ausgewählt ist:
Die resultierende Kombination kann gelesen werden als:
Verwenden Sie mit 50% Wahrscheinlichkeit das Pixel von Bild A. Wählen Sie für den Rest der Zeit zwischen Bild B und Bild C, B, wo beide Koordinaten ungerade sind, C, wo eine gerade ist.
Da Sie schließlich dasselbe für drei verschiedene Farben tun, aber mit unterschiedlichen Ausrichtungen, sind die Muster in jeder Farbe unterschiedlich ausgerichtet und erzeugen die sich kreuzenden Streifen oder Gittermuster, die Sie sehen.
Vorlagentypdef
Viele der Berechnungen, die Sie in Ihrem Code durchführen, führen nicht zu wirklich zufälligen Werten. Diese scharfen Linien, die Sie sehen, entsprechen Stellen, an denen die relativen Werte Ihrer x- und y-Koordinaten miteinander handeln, und wenn das passiert, verwenden Sie grundlegend unterschiedliche Formeln. Rechenleistung zum Beispiel (x + y) % rand() geben Ihnen in der Regel den Wert zurück x + yseit rand() wird (normalerweise) eine viel, viel größere Zahl als zurückgeben x + y gegeben das RAND_MAX ist normalerweise eine ziemlich große Zahl. In diesem Sinne sollten Sie nicht erwarten, weißes Rauschen zurückzubekommen, da der Algorithmus, den Sie zum Generieren von Dingen verwenden, davon abweicht, weißes Rauschen zu erzeugen. Wenn Sie weißes Rauschen wünschen, stellen Sie einfach jedes Pixel auf ein rand(). Wenn Sie ein schönes Muster wie das oben gezeigte möchten, aber hier und da ein wenig Zufälligkeit hinzugefügt haben, verwenden Sie den Code, den Sie geschrieben haben.
Darüber hinaus, wie @pm100 in den Kommentaren angemerkt hat, die rand -Funktion gibt keine echten Zufallszahlen zurück, sondern verwendet stattdessen eine Pseudozufallsfunktion, um ihre Werte zu erzeugen. Die Standardimplementierung von rand verwendet auf vielen Systemen eine Art Pseudozufallszahlengenerator namens a linearer Kongruenzgenerator das erzeugt Zahlen, die in kurzen Bursts zufällig erscheinen können, die aber in der Praxis entschieden nicht zufällig sind. Hier ist zum Beispiel eine Animation aus Wikipedia, die zeigt, wie zufällige Punkte im Raum, die mit einem linearen Kongruenzgenerator ausgewählt wurden, letztendlich in eine feste Anzahl von Hyperebenen fallen:
Wenn Sie die x-, y- und z-Koordinaten durch die R-, G- und B-Koordinaten ersetzen, sieht dies so aus bemerkenswert ähnlich der Ausgabe, die von Ihrem Programm erzeugt wird. Ich vermute, dass dies hier wahrscheinlich nicht der Kernpunkt ist, da der andere oben genannte Aspekt wahrscheinlich viel ausgeprägter sein wird.
Wenn Sie nach qualitativ hochwertigeren Zufallszahlen suchen, müssen Sie eine qualitativ hochwertigere Zufallsquelle verwenden. In C könnten Sie in Betracht ziehen, Bytes von zu lesen /dev/urandom/ (auf einem Linux-ähnlichen System), was ziemlich gleichmäßig zufällige Werte liefert. C++ hat jetzt in seinen Standardbibliotheken eine Reihe guter Primitive zur Generierung von Zufallszahlen, falls Ihnen diese zur Verfügung stehen.
14250300cookie-checkWarum erhalte ich dieses spezielle Farbmuster, wenn ich rand() verwende?yes
cos rand ist nicht rand – schöne Demo davon. Es ist 100% deterministisch
– pm100
21. September 2018 um 23:08 Uhr
stackoverflow.com/questions/822323/…
– pm100
21. September 2018 um 23:09 Uhr
@ pm100: Wie die Antwort von bames53 so gut erklärt, würden Sie das gleiche Muster erhalten, selbst wenn Sie einen perfekten Zufallszahlengenerator verwenden würden.
– TonyK
22. September 2018 um 14:04 Uhr
Entschuldigen Sie eine Frage: Da Sie die x- und y-Koordinaten verwenden, um die Pixelwerte zu berechnen, warum sollten Sie erwarten, dass diese Werte unabhängig von den Koordinaten sind? Wenn das Bild zu gleichmäßig zufällig aussieht, würden Sie das brauchen, oder?
– Thomas Padron-McCarthy
23. September 2018 um 7:15 Uhr
Gelernte Lektionen: Zufällige Dinge mit Zufallszahlen zu tun führt nicht zu zufälligen Ergebnissen 🙂
– Hagen von Eitzen
23. September 2018 um 20:03 Uhr