Probleme beim Zufalls-Punkte erzeugen [gelöst]

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
reox
Beiträge: 2463
Registriert: 06.06.2006 22:09:47
Lizenz eigener Beiträge: MIT Lizenz

Re: Probleme beim Zufalls-Punkte erzeugen

Beitrag von reox » 05.01.2019 11:41:07

Interessant, ich habs mal in python implementiert:

Code: Alles auswählen

import numpy as np
import matplotlib.pyplot as plt

N = 10000

r = 1

winkel = 2 * np.pi * np.random.rand(N)
radius = r * np.random.rand(N)
x = np.sin(winkel) * radius;
y = np.cos(winkel) * radius;

plt.scatter(x, y)
plt.show()
und komme auf das hier:
1994

Ich berechne mir den Winkel aber direkt in radians, da np.random.rand() mir eine uniforme verteilung zwischen [0, 1] liefert.
Vermutlich ist das mit dem Modulo einfach nicht so gut.
Das die punktwolke mit zunehmendem radius weniger dicht ist, erscheint mir logisch.


Hier noch eine andere Idee:
man erzeugt Koordinatenpaare (x, y) und testet ob diese innerhalb des Kreises liegen. Dadurch erzeugt man eine homogene Punktverteilung innerhalb der Ebene und nicht eine homogene Verteilung der Polarkoordinaten.
Hier mal für den ersten Quadraten - man müsste eben die Vorzeichen für x und y noch variieren...

Code: Alles auswählen

import random
import matplotlib.pyplot as plt

def points(N, r):
    c = 0
    while c < N:
        x = random.random()
        y = random.random()
        if x**2 + y**2 <= r**2:
            c += 1
            yield x, y

x, y = zip(*points(10000, 1))

plt.scatter(x, y)
plt.show()
1995
Zuletzt geändert von reox am 05.01.2019 11:56:32, insgesamt 2-mal geändert.

Benutzeravatar
rvb
Beiträge: 2
Registriert: 18.12.2018 12:20:57
Wohnort: Nowosibirsk
Kontaktdaten:

Re: Probleme beim Zufalls-Punkte erzeugen

Beitrag von rvb » 05.01.2019 11:50:55

reox hat geschrieben: ↑ zum Beitrag ↑
05.01.2019 11:41:07
Vermutlich ist das mit dem Modulo einfach nicht so gut.
Ein einfaches Beispiel: angenommen, du hättest einen perfekten Zufallsgenerator, der Zahlen zwischen 0 und 8 absolut gleichverteilt liefert, aber möchtest eine Zufallszahl im Intervall [0,5] haben. Wenn du dazu einfach das Ergebnis des Zufallsgenerators modulo 6 nimmst, dann kriegst du zwar eine Zufallszahl im Intervall [0,5], aber die landet mit 2/3 Wahrscheinlichkeit im Intervall [0,2] und nur mit 1/3 Wahrscheinlichkeit im Intervall [3,5].

Das beste /dev/urandom hilft also nichts, wenn man hinterher ein Modulo dranhängt.
Zuletzt geändert von rvb am 05.01.2019 14:16:57, insgesamt 1-mal geändert.

Benutzeravatar
hikaru
Moderator
Beiträge: 13585
Registriert: 09.04.2008 12:48:59

Re: Probleme beim Zufalls-Punkte erzeugen

Beitrag von hikaru » 05.01.2019 12:33:45

Lohengrin hat geschrieben: ↑ zum Beitrag ↑
05.01.2019 03:55:23
Demnach ist der Sinus nicht ungewöhnlich häufig nahe bei 0. Das scheint mir ein Artefakt bei der grafischen Darstellung zu sein.
Nachdm ich eine Nacht darüber geschlafen habe, denke ich, dass das doch ein Effekt der Sinus- bzw. Kosinusfunktion ist, bzw. heinz' Erzeugung der Werte für den Winkel in Grad als Integer.
Schauen wir uns mal das Diagramm zu den Funktionen an. [1] Der Radius den heinz mit 2000 definiert hat, wird hier auf der Hochachse auf ±1 normiert und die Werte sollten durch den Zufallsgenerator gleichmäßig in diesem Wertebereich verteilt sein.
Nun haben aber die Funktionen an ihren Nullstellen jeweils einen großen Anstieg, die gleichmäßig auf der Hochachse verteilten Punkte haben also einen kleinen horizontalen Abstand, während es nahe den Maxima genau andersrum ist. So erzeugt in heinz' Code die Sinusfunktion den "Balken" auf der y-Achse, während die Kosinusfunktion den "Balken" auf der x-Achse erzeugt.

Um ein halbwegs anschauliches Beispiel zu bringen, schauen wir uns mal 4 Punkte an, die alle auf dem Rarius r liegen:
A: φ=0°; B: φ=1°; C: φ=45°; D: φ=46°

Der Kosinus von A und B unterscheidet sich erst bei 10^-4, während C und D sich schon bei 10^-2 unterscheiden. Der Abstand zwischen A und B ist nahe 1, da sie kartesisch fast die selbe x-Koordinate haben. C und D unterscheiden sich dagegen in x unyd y um jeweils 1, was dazu führt, dass ihr Abstand nicht 1 sondern Wurzel 2 ist.
Was man tun müsste, wäre die Wahrscheinlichkeit eines Winkels nicht gleich zu verteilen, sondern an die Summe seines Sinus+Kosinus zu koppeln.

Oder man erzeugt gleich Radians wie reox' Beispiel zeigt.

rendegast hat geschrieben: ↑ zum Beitrag ↑
05.01.2019 07:27:20
Wurzel ( Zufall(0,1) ) * Kreisradius
?
Sieht gut aus!
In reox' Beispiel:

Code: Alles auswählen

radius = r * np.sqrt ( np.random.rand(N) )

[1] https://de.wikipedia.org/wiki/Datei:Sin ... period.svg

reox
Beiträge: 2463
Registriert: 06.06.2006 22:09:47
Lizenz eigener Beiträge: MIT Lizenz

Re: Probleme beim Zufalls-Punkte erzeugen

Beitrag von reox » 05.01.2019 13:49:50

hikaru hat geschrieben: ↑ zum Beitrag ↑
05.01.2019 12:33:45
In reox' Beispiel:

Code: Alles auswählen

radius = r * np.sqrt ( np.random.rand(N) )
In der tat, das erzeugt eine bessere verteilung:
1996

Benutzeravatar
smutbert
Moderator
Beiträge: 8331
Registriert: 24.07.2011 13:27:39
Wohnort: Graz

Re: Probleme beim Zufalls-Punkte erzeugen

Beitrag von smutbert » 05.01.2019 13:53:02

Ich liebe das Debianforum für solche Threads!!

reox hat (leider :wink:) die Idee mit dem Verwerfen von Koordinaten, die außerhalb des Kreises liegen schon gepostet, sonst hätte ich auch etwas posten können (ich meine etwas anderes als nur die Feststellung, dass ich solche Thread gerne lese).

Benutzeravatar
MSfree
Beiträge: 10752
Registriert: 25.09.2007 19:59:30

Re: Probleme beim Zufalls-Punkte erzeugen

Beitrag von MSfree » 05.01.2019 14:07:57

reox hat geschrieben: ↑ zum Beitrag ↑
05.01.2019 11:41:07
Interessant, ich habs mal in python implementiert:
und ich habe mal schnell C-Code zusammengeklöppelt: NoPaste-Eintrag40569

Dabei habe ich die von mir oben vorgeschlagenen MyRandom-Funktion verwendet, allerdings in "double" statt "float". Ich kann dabei keine Kreuzstruktur erkennen. Die Häufung um die Mitte ist ja schon erklärt worden, wer mag, kann das C-Programm ja noch entsprechend anpassen :wink:

1997

Benutzeravatar
hikaru
Moderator
Beiträge: 13585
Registriert: 09.04.2008 12:48:59

Re: Probleme beim Zufalls-Punkte erzeugen

Beitrag von hikaru » 05.01.2019 14:19:16

smutbert hat geschrieben: ↑ zum Beitrag ↑
05.01.2019 13:53:02
die Idee mit dem Verwerfen von Koordinaten,
Die Idee ist algorithmisch gut, aber um ehrlich zu sein finde ich den Weg als Lösung der Aufgabe hässlich.
Das Ziel ist ja, Punkte in einem Kreis zu erzeugen. Übertragen wir das in die Praxis:
Ich stelle eine Zielscheibe auf, gebe dir ein Paintball-Gewehr und stelle die Aufgabe, Kleckse auf der Zielscheibe zu erzeugen.
Nehmen wir an, du bist ein mäßiger Schütze, der zwar nur zufällig genau die Mitte trifft, aber es immerhin hinkriegt, zuverlässig die Scheibe zu treffen. Der naheliegende Lösungsweg wäre für dich, auf die Scheibe zu zielen und das Magazin leerzuballern.
Die Alternative wäre, wild um dich zu schießen und hinterher den Raum zu putzen. Gefällt mir als Putzmuffel jetzt nicht so sehr. ;)
MSfree hat geschrieben: ↑ zum Beitrag ↑
05.01.2019 14:07:57
Dabei habe ich die von mir oben vorgeschlagenen MyRandom-Funktion verwendet, allerdings in "double" statt "float". Ich kann dabei keine Kreuzstruktur erkennen.
Nein, kannst du nicht, denn du erzeugst deine Winkelwerte direkt als Gleitommawerte (ob float oder double sollte egal sein). Wenn ich es richtig verstehe, hat heinz hat seine Winkelwerte ursprünglich als Integer erzeugt und erst im zweiten Schritt ein Typecasting gemacht. Dadurch hat er im Gegensatz zu dir eine Diskretisierung seiner Werte, die nahe der Achsen in Folge des Verlaufs der trigonometrischen Funktionen als Balken zu sehen ist.

reox
Beiträge: 2463
Registriert: 06.06.2006 22:09:47
Lizenz eigener Beiträge: MIT Lizenz

Re: Probleme beim Zufalls-Punkte erzeugen

Beitrag von reox » 05.01.2019 14:26:31

hikaru hat geschrieben: ↑ zum Beitrag ↑
05.01.2019 14:19:16
smutbert hat geschrieben: ↑ zum Beitrag ↑
05.01.2019 13:53:02
die Idee mit dem Verwerfen von Koordinaten,
Die Idee ist algorithmisch gut, aber um ehrlich zu sein finde ich den Weg als Lösung der Aufgabe hässlich.
Ja, vor allem verbrät man unnötig Zeit mit dem Aussortieren. Andererseits, wie kann man einen (oder zwei) Werte generieren, welche gleich die Kreisbedingung erfüllen? Die Euklidischen Koordinate sind immer abhängig voneinander, die Polarkoordinaten nicht - eine Lösung mit Polarkoordinaten haben wir, insbesondere das mit der Wurzel gefällt mir sehr gut!
Was mir nur einfallen würde, aber eher auch wenig Sinn macht, wäre sowas wie eine Hilbert Kurve für Kreise zu haben, damit man jedem Punkt eine Zahl zuordnen kann. Dann brauche ich nur eine Zufallszahl generieren und kann mir daraus die Position innerhalb des Kreises errechnen.

Benutzeravatar
MSfree
Beiträge: 10752
Registriert: 25.09.2007 19:59:30

Re: Probleme beim Zufalls-Punkte erzeugen

Beitrag von MSfree » 05.01.2019 14:34:18

hikaru hat geschrieben: ↑ zum Beitrag ↑
05.01.2019 14:19:16
Nein, kannst du nicht, denn du erzeugst deine Winkelwerte direkt als Gleitommawerte (ob float oder double sollte egal sein).
Jein, denn rand() liefert immer ein int, das ich allerdings sofort in ein double umwandele.
Wenn ich es richtig verstehe, hat heinz hat seine Winkelwerte ursprünglich als Integer erzeugt und erst im zweiten Schritt ein Typecasting gemacht.
Wenn man die ursprüngliche Methode

Code: Alles auswählen

float winkel= (float) (rand()% 36000000) / 100000.0;
so steckt da zunächst

Code: Alles auswählen

rand()% 36000000
also der 100000-fache Winkelwert als int drin, der dann durch Division ein float ergibt. Das erklärt also die Häufung um die x- und y-Axen nicht.

Ich habe jetzt noch meinen Punktgenerator so implementiert, wie es Heinz ursprünglich hatte, also mit Modulus, aber mit double:

Code: Alles auswählen

void GeneratePoints( int numPts, double *x, double *y )
{
  int i;
  int method = 1;

  switch( method )
  {
    case( 0 ):
      for( i=0 ; i<numPts ; i++)
      {
        double winkel= MyRandom( 360.0 );
        double radius= MyRandom( 200.0 );
        x[i] = sin( winkel * (M_PI / 180.0) ) * radius;
        y[i] = cos( winkel * (M_PI / 180.0) ) * radius;
      }
      break;
    case( 1 ):
      for( i=0 ; i<numPts ; i++)
      {
        double winkel= (double) (rand()% 36000000) / 100000.0;
        double radius= (rand()% 2000) / 10.0;
        x[i] = sin( winkel * (M_PI / 180.0) ) * radius;
        y[i] = cos( winkel * (M_PI / 180.0) ) * radius;
      }
      break;
  }
}
Und, was soll ich sagen? Das ergebnis zeigt ebenfalls keine Häufung an den Achsen:
1998

Benutzeravatar
king-crash
Beiträge: 722
Registriert: 08.08.2006 12:07:56
Lizenz eigener Beiträge: MIT Lizenz

Re: Probleme beim Zufalls-Punkte erzeugen

Beitrag von king-crash » 05.01.2019 14:47:53

Das Problem ist der Modulo.
Ein einfaches Beispiel:
Eine 2 Bit Zahl, komplett zufällig, kann also folgende Werte annehmen:
00
01
10
11
Machst du jetzt Beispielsweise Moduo 3:
00 -> 00
01 -> 01
10 -> 10
11 -> 00
Somit kommt 0 mit der doppelten Wahrschinlichkeit vor.

Benutzeravatar
detix
Beiträge: 1702
Registriert: 07.02.2007 18:51:28
Wohnort: MK

Re: Probleme beim Zufalls-Punkte erzeugen

Beitrag von detix » 05.01.2019 15:59:53

hikaru hat geschrieben:Die Idee ist algorithmisch gut, aber um ehrlich zu sein finde ich den Weg als Lösung der Aufgabe hässlich.
Das halte ich für falsch!
Beim Kreis dreht sich alles um den Mittelpunkt, entsprechend ist die Verteilung dort größer als woanders.
Ein Quadrat, oder ein Rechteck bei einer Ellipse, drumherum gebaut verteilt den Zufall wesentlich gleichmäßiger, das zusätzliche Löschen diverser Punkte außerhalb ist auch noch eine Erhöhung des Zufalls...
Gruß an alle Debianer, und immer daran denken:
Macht ohne Haftung funktioniert nicht!

Benutzeravatar
Lohengrin
Beiträge: 3227
Registriert: 29.08.2004 00:01:05
Wohnort: Montsalvat

Re: Probleme beim Zufalls-Punkte erzeugen

Beitrag von Lohengrin » 05.01.2019 16:29:55

rvb hat geschrieben: ↑ zum Beitrag ↑
05.01.2019 11:50:55
reox hat geschrieben: ↑ zum Beitrag ↑
05.01.2019 11:41:07
Vermutlich ist das mit dem Modulo einfach nicht so gut.
Ein einfaches Beispiel: angenommen, du hättest einen perfekten Zufallsgenerator, der Zahlen zwischen 0 und 8 absolut gleichverteilt liefert, aber möchtest eine Zufallszahl im Intervall [0,5] haben. Wenn du dazu einfach das Ergebnis des Zufallsgenerators modulo 6 nimmst, dann kriegst du zwar eine Zufallszahl im Intervall [0,5], aber die landet mit 2/3 Wahrscheinlichkeit im Intervall [0,2] und nur mit 1/3 Wahrscheinlichkeit im Intervall [3,5].

Das beste /dev/urandom hilft also nichts, wenn man hinterher ein Modulo dranhängt.
Den Effekt gibt es, aber er ist hier nicht sonderlich groß.
Es geht um eine Zahl zwischen 0 und 2^31-1, die dann Modulo 36000000 genommen wird. Das kommen Zahlen zwischen 0 und 23483647 häufiger vor als Zahlen zwischen 23483648 und 35999999. Das Verhältnis ist 60 zu 59.
Mit einer Null mehr, also 360000000 statt 36000000 wäre der Effekt erkennbar, dann kämen Zahlen zwischen 0 und 347483647 häufiger vor als Zahlen zwischen 347483648 und 359999999, und das mit dem Verhältnis 6 zu 5.

Das Kreuz ist damit gar nicht zu erklären.
Harry, hol schon mal das Rasiermesser!

Benutzeravatar
Lohengrin
Beiträge: 3227
Registriert: 29.08.2004 00:01:05
Wohnort: Montsalvat

Re: Probleme beim Zufalls-Punkte erzeugen

Beitrag von Lohengrin » 05.01.2019 16:50:45

rendegast hat geschrieben: ↑ zum Beitrag ↑
05.01.2019 07:27:20
Wurzel ( Zufall(0,1) ) * Kreisradius
Ist richtig.
Betrachte den Kreisring mit Innenradius r und Breite b. Der hat eine Fläche von π(r+b)^2-πr^2.
Sei der Kreisradius R. Dann landet alles im Kreisring, wo der Zufallsgenerator zwischen (r/R)^2 und ((r+b)/R)^2 ausgegeben hat.
Die Punktedichte, also "Punkte im Kreisring" geteilt durch "Fläche des Kreisrings", ist unabhängig von r.
Harry, hol schon mal das Rasiermesser!

Benutzeravatar
Lohengrin
Beiträge: 3227
Registriert: 29.08.2004 00:01:05
Wohnort: Montsalvat

Re: Probleme beim Zufalls-Punkte erzeugen

Beitrag von Lohengrin » 05.01.2019 17:13:29

hikaru hat geschrieben: ↑ zum Beitrag ↑
05.01.2019 12:33:45
Der Radius den heinz mit 2000 definiert hat, wird hier auf der Hochachse auf ±1 normiert und die Werte sollten durch den Zufallsgenerator gleichmäßig in diesem Wertebereich verteilt sein.
Der ist nur ±1, wenn der passende Winkel dazukommt. Dass bei Winkel nahe 0 viele x nahe Radius sind, muss so sein, weil das auf ein großes Stück in y-Richtung verteilt wird.
Ich denke, dass das, so wie es programmiert ist, genau passen müsste, kann mir das Kreuz nicht erklären.
hikaru hat geschrieben: ↑ zum Beitrag ↑
05.01.2019 12:33:45
Um ein halbwegs anschauliches Beispiel zu bringen, schauen wir uns mal 4 Punkte an, die alle auf dem Rarius r liegen:
A: φ=0°; B: φ=1°; C: φ=45°; D: φ=46°

Der Kosinus von A und B unterscheidet sich erst bei 10^-4, während C und D sich schon bei 10^-2 unterscheiden. Der Abstand zwischen A und B ist nahe 1, da sie kartesisch fast die selbe x-Koordinate haben. C und D unterscheiden sich dagegen in x unyd y um jeweils 1, was dazu führt, dass ihr Abstand nicht 1 sondern Wurzel 2 ist.
Bei A und B läuft der Kreisbogen parallel zur y-Achse. Bei C und D läuft er π/4 dazu. Das erklärt die Wurzel 2. Auf gleich langem Kreisbogen müssen gleich viele Punkte landen.

Ich sehe nicht, wie dadurch das Kreuz zustanden kommen soll.
Harry, hol schon mal das Rasiermesser!

Benutzeravatar
detix
Beiträge: 1702
Registriert: 07.02.2007 18:51:28
Wohnort: MK

Re: Probleme beim Zufalls-Punkte erzeugen

Beitrag von detix » 06.01.2019 18:50:47

smutbert hat geschrieben:Ich liebe das Debianforum für solche Threads!!
Genauso ist es, und da man ja sonst nichts zu tun hat...
Ich hab weder Ahnung von inkscape noch von python, aber gar nicht feige in Vorhandenem mal rumzusuchen!
Herausgekommen ist eine Erweiterung (zu finden in Rendern) für inkscape, leider kein C.
Das sieht mit den gegebenen Einstellungen so aus, der Bildaufbau dauert hier ein paar Sekunden:
2000
Die beiden Erweiterungsdateien in ~/.config/inkscape/extensions/ speichern:
http://nopaste.debianforum.de/40572 als: Zufallspunkte_im_Kreis.inx
http://nopaste.debianforum.de/40573 als: Zufallspunkte_im_Kreis.py
Gruß an alle Debianer, und immer daran denken:
Macht ohne Haftung funktioniert nicht!

Benutzeravatar
heinz
Beiträge: 535
Registriert: 20.12.2007 01:43:49

Re: Probleme beim Zufalls-Punkte erzeugen

Beitrag von heinz » 06.01.2019 19:00:47

Hallo nochmal,

erstmal vielen Dank an alle fuer das rege Interesse an diesem Problem.

Zu meiner Schande muss ich gestehen, dass ich mit vielen der Mathe-Lastigen Kommentare nicht viel anfangen kann.

Aber ich hab mal weitergesucht und habe schliesslich das PGM mal in SDL ausprobiert.
Und siehe da, kein Kreuz...
NoPaste-Eintrag40575

Code: Alles auswählen

c++ z2z.cc -o z2z -I/usr/include/SDL -lSDL_gfx -lSDL -Wall
(Die haeufigkeit zur Mitte hin bekomme ich geloest und werd sie an/abschaltbar machen. Sieht ja auch nett aus...)

Die urspruengliche Aufgabe des Programms war, zufallswerte fuer Objekte in POV-Dateien einzusetzen.
Es scheint das irgendwie POVRAY fuer dieses seltsame Kreuz verantwortlich ist.
Obwohl ich nicht verstehe warum dem so ist.
Die Werte die in die POV-Datei eingetragen wurden sehen fuer mich korrekt aus.
NoPaste-Eintrag40574

Ich werde auf jeden Fall weiter experimentieren und falls ich auf eine Loesung stosse mich wieder melden.

Dankbare Gruesse,
heinz

Benutzeravatar
MSfree
Beiträge: 10752
Registriert: 25.09.2007 19:59:30

Re: Probleme beim Zufalls-Punkte erzeugen

Beitrag von MSfree » 06.01.2019 19:33:27

heinz hat geschrieben: ↑ zum Beitrag ↑
06.01.2019 19:00:47
Es scheint das irgendwie POVRAY fuer dieses seltsame Kreuz verantwortlich ist.
Obwohl ich nicht verstehe warum dem so ist.
Die Werte die in die POV-Datei eingetragen wurden sehen fuer mich korrekt aus.
NoPaste-Eintrag40574
Nein, wenn ich die Punkte, die du nach nopaste kopiert hast, mit meinem Testprogramm auftrage, kommt das raus:
2001

Das Kreuz ist also in den Daten vorhanden. In der Folge muß natürlich auch povray ein Kreuz anzeigen.

Benutzeravatar
heinz
Beiträge: 535
Registriert: 20.12.2007 01:43:49

Re: Probleme beim Zufalls-Punkte erzeugen

Beitrag von heinz » 06.01.2019 20:58:54

Hallo MSfree,
MSfree hat geschrieben: ↑ zum Beitrag ↑
06.01.2019 19:33:27
Nein, wenn ich die Punkte, die du nach nopaste kopiert hast, mit meinem Testprogramm auftrage, kommt das raus:
Das Kreuz ist also in den Daten vorhanden. In der Folge muß natürlich auch povray ein Kreuz anzeigen.
Danke fuers ausprobieren!

Ich kapiere es nicht...
Habe es nochmal direkt in Pov, mit den Pov-Bordmitteln versucht und da ist das Kreuz auch drin...
NoPaste-Eintrag40576
Die rand()-Funktion von POV verwendet Werte von 0.0 - 1.0 also kein Modulo notwendig...

Gruss heinz

Edit:
Habe auch gerade mal (pi/180) weggelassen:

Code: Alles auswählen

translate <sin(W)*(-200+400*rand(Z1)),cos(W)*(-200+400*rand(Z1)),0>
Immernoch ein Kreuz...

Benutzeravatar
MSfree
Beiträge: 10752
Registriert: 25.09.2007 19:59:30

Re: Probleme beim Zufalls-Punkte erzeugen

Beitrag von MSfree » 06.01.2019 21:34:11

Mit povray kenn ich mich zu wenig aus, um deinen Code aus dem Stegreif auf Logikfehler untersuchen zu könne. Mir fällt allerdings auf, daß du mit

Code: Alles auswählen

#declare Z1=seed(0);
etwas initialisierst. "seed" deutet für mich auf den Startwert des Zufallszahlengenerators. Wenn man den immer mit dem selben Wert (hier Null) initialisiert, bekommt man auch immer die selbe Zufallszahlenfolge.

Es ist denkbar, daß mit seed(0) das Kreuz besonders auffällig ist, mit anderen seeds aber nicht.

Benutzeravatar
heinz
Beiträge: 535
Registriert: 20.12.2007 01:43:49

Re: Probleme beim Zufalls-Punkte erzeugen

Beitrag von heinz » 06.01.2019 21:54:54

MSfree hat geschrieben: ↑ zum Beitrag ↑
06.01.2019 21:34:11
Es ist denkbar, daß mit seed(0) das Kreuz besonders auffällig ist, mit anderen seeds aber nicht.
Das ist es leider auch nicht...

Ich habe mir Deinen Code NoPaste-Eintrag40569 nochmal genauer angesehen.
Den einzigen Unterschied den ich erkennen kann ist die Art, wie Du die "Dinger" zeichnest.
Welchen Zweck hat Deine Funktion void DrawDots? Wozu skalierst Du da was...
Wenn Du die Koordinaten in x(i),y(i) direckt "Zeichnen" wuerdest, wuede da das gleiche Bild herauskommen? Also ohne Kreuz?

Gruss heinz

Benutzeravatar
MSfree
Beiträge: 10752
Registriert: 25.09.2007 19:59:30

Re: Probleme beim Zufalls-Punkte erzeugen

Beitrag von MSfree » 06.01.2019 22:12:20

heinz hat geschrieben: ↑ zum Beitrag ↑
06.01.2019 21:54:54
Das ist es leider auch nicht...
Schade. :wink:
Welchen Zweck hat Deine Funktion void DrawDots? Wozu skalierst Du da was...
Die Funktion malt Punkte und sie ist für den Allgemeinfall ausgelegt.

Der "buffer" ist ein Array, bei dem jedes Pixel des Bildes einem "char" entspricht. Dieses Feld kann beliebig groß sein, also eine beliebige Breite und Höhe haben. (OK, beliebig im Sinne von: "muß noch ins RAM passen").

Die Punktkoordinaten in x und y können ebenfalls eine beliebiege Ausdehnung haben

Also muß vorher die Ausdehnung der Punktmenge bestimmt werden und die Punktkoordinaten so skaliert werden, daß sie in den "buffer" hineinpassen.

Ich weiß, das hätte ich mir für deinen Spezialfall auch sparen können, die Funktionen stammen aber aus meiner eigenen Funktionssammlung und die habe ich einfach recycelt.
Wenn Du die Koordinaten in x(i),y(i) direckt "Zeichnen" wuerdest, wuede da das gleiche Bild herauskommen? Also ohne Kreuz?
Die Skalierung, die sich in meinem Fall ergibt,ist 1.0, denn die Punkte haben einen Wertebereich von -200 bis +200 und die Zeichenfläche ist 400 x 400 Pixel. Wie gesagt, die Skalierung ist in diesem Fall unnötig, aber für den Allgemeinfall ausgelegt.

Der "gemalte" "buffer" wird dann mit der Funktion write_JPEG_file direkt als Bilddatei im JPEG-Format rausgeschrieben.

Kreuze bekomme ich mit meinem Programm allerdings nicht, egal ob ich die Zufallswerte mit Modulus oder mit MyRandom erzeuge.

Benutzeravatar
heinz
Beiträge: 535
Registriert: 20.12.2007 01:43:49

Re: Probleme beim Zufalls-Punkte erzeugen

Beitrag von heinz » 06.01.2019 22:15:20

Oh verdammt...
Ich habe das Problem gefunden!

Ich habe den Radius nicht einmal berechnet und dann fuer sin und cos gemeinsam benutzt, sondern es so gemacht.
(Ich hatte vor auf diese Art auch einfach Ellipsen zu erstellen...)
for(int z=0 ; z<10000 ; z++)
{
float winkel=MyRandom(360.0);
float x = sin( winkel * (Pi / 180.0) ) * MyRandom(200.0);
float y = cos( winkel * (Pi / 180.0) ) * MyRandom(200.0);
}

Sorry, dass ich durch meine Dummheit Eure Zeit verschwendet habe... :oops:

Gruss heinz

Benutzeravatar
heinz
Beiträge: 535
Registriert: 20.12.2007 01:43:49

Re: Probleme beim Zufalls-Punkte erzeugen [gelöst] (eigene Dummheit)

Beitrag von heinz » 06.01.2019 22:50:55

Hallo MSfree,

Danke nochmal fuer Deine ausfuehrliche Erklaerung und Deine Geduld...

Gruss heinz

Benutzeravatar
hikaru
Moderator
Beiträge: 13585
Registriert: 09.04.2008 12:48:59

Re: Probleme beim Zufalls-Punkte erzeugen

Beitrag von hikaru » 07.01.2019 10:36:28

heinz hat geschrieben: ↑ zum Beitrag ↑
06.01.2019 22:15:20
Ich habe den Radius nicht einmal berechnet und dann fuer sin und cos gemeinsam benutzt, sondern es so gemacht.
(Ich hatte vor auf diese Art auch einfach Ellipsen zu erstellen...)
for(int z=0 ; z<10000 ; z++)
{
float winkel=MyRandom(360.0);
float x = sin( winkel * (Pi / 180.0) ) * MyRandom(200.0);
float y = cos( winkel * (Pi / 180.0) ) * MyRandom(200.0);
}
Ich verstehe noch nicht, warum das zu der Kreuzbildung führt. Wenn man zwei verschiedene Zufallszahlen für den Radius in x- und y-Richtung wählt, liegt der Punkt zwar auf einer Ellipse statt auf einem Kreis, aber gemittelt über 10000 Punkte würde ich trotzdem eine gleichmäßige Verteilung* erwarten.

*) über alle Winkel, nicht über den Radius

Benutzeravatar
Lohengrin
Beiträge: 3227
Registriert: 29.08.2004 00:01:05
Wohnort: Montsalvat

Re: Probleme beim Zufalls-Punkte erzeugen

Beitrag von Lohengrin » 07.01.2019 11:19:13

hikaru hat geschrieben: ↑ zum Beitrag ↑
07.01.2019 10:36:28
Ich verstehe noch nicht, warum das zu der Kreuzbildung führt. Wenn man zwei verschiedene Zufallszahlen für den Radius in x- und y-Richtung wählt, liegt der Punkt zwar auf einer Ellipse statt auf einem Kreis, aber gemittelt über 10000 Punkte würde ich trotzdem eine gleichmäßige Verteilung* erwarten.
Zuerst kommt der Winkel. Daraus entsteht ein Punkt auf dem Kreis mit Radius 200, und das gleichverteilt. Beachte nun das Rechteck, das den Ursprung und diesen Punkt gegenüber hat. In dieses Rechteck wird ein Punkt gesetzt, und das gleichverteilt..
Das Ganze geschieht 10000 mal.

Die y-Achse und die x-Achse sind immer dabei. Je näher am Ursprung desto häufiger wird getroffen.
Harry, hol schon mal das Rasiermesser!

Antworten