Dem Zufall auf die Sprünge helfen?

Kennt jemand eine gute Methode dem Zufall einwenig Unterstützung zuleisten? Ich möchte gern einen zufälligen Wert haben diesen aber geringfügig manipulieren sodass ich ein gewünschtes Ergebnis erhalte.

Genauer: Ich habe bspw. 300 Vektoren, diese bekommen als Startpunkt die Koordinaten (0, 0, 0). Ein weiterer Vektor, der Geschwidnigkeitsvektor, wird nun mit „Zufallszahlen“ versehen und einmal um die Y-Achse und einmal um die Z-Achse rotiert(Somit zeigen die Vektoren zu einem „Mantel“ der Kugel), ebenfalls mit einem zufälligem Winkel(theta). Das Ergebnis gefällt mir allerdings so nicht ganz, ich habe zwar nun eine Kugel, aber da ich nur 300 Vektoren habe sieht man das nicht wirklich, denn die Vektoren sind ja sehr zufällig angeordnet(siehe Anhang). Wie kann man nun den Zufall so beeinflussen das die Vektoren etwas „korrekter“ angeordnet sind und man so eine Kugel eher erkennen kann?

Solltet ihr irgendwas genaueres wissen wollen dann sagt bitte bescheid, ich hoffe mir ist noch zu helfen … :o)

Gut Schuß
VuuRWerK :wink:

berechne die perfekte 300er-Anordnung, also verteile die Vektoren so auf die Fläche, dass sie alle den gleichen Abstand haben,
und dann modifiziere jeden Vektor soweit wie du möchtest,
lasse sie nur maximal den halben Weg zum nächsten Vektor schwanken oder den ganzen Weg oder den doppelten oder im Extremfall wieder um die ganze Kugel und dann ist die Vorgabe für die Katz,

das war die von (von mir ausgedachte :wink: ) Theorie dazu, muss man natürlich noch irgendwie in Zahlen umsetzen

Genau die Zahlen oder wenigstens eine mathematische Formel wäre da nicht schlecht. Ich hab mir auch so gedacht das man sich das ähnlich wie das Grad-Netz um den Globus händeln könnte, jeder schnittpunkt eines längen und eines breiten grades wäre die Richtung eines Vektors, gleicher Abstand zu einander.

Ich hab auch schon etliches über Spheren und Kugeln ergooglet aber alles was man dazu findet wird mithilfe von Meshes umgesetzt und nicht mit Punkten.

Gut Schuß
VuuRWerK :wink:

Hiho,

am einfachsten ist, erst einmal eine Gleichverteilung der Vektoren um die 360° zu berechnen.

Bei einem Vollkreis und 300 Partikeln ergibt sich somit ein Winkel von 1,2° zwischen den Vektoren. Nun lässt du deine Vektoren aber in einem Gewissen Varianzbereich um die berechneten Winkelweiten streuen.

Im Bild sind die schwarzen die berechneten und die roten die mit der Varianz versehenen Vektoren.

Im Endeffekt hast du bei 300 Vektoren bei allen ganzzahligen Vielfachen von 1,2° die Gleichverteilung im Kreis. Nun berechne einfach für jeden Vektor 1,2° + random(-a°…+a°) mit a = 0,5° beispielsweise.

bye Saxony

dummerweise ist eine Kugel 3D, aber da wirds doch auch Verfahren geben,
das Meshing z.B. schadet ja nicht, auch wenn man am Ende nur die Eckpunkte braucht,
ich kann dazu aber nix sagen

Ja aber dann funktioniert das analog ebenso.

Ich habe 300 Vektoren und nehme 30 Kreise welche ich - wieder mit Varianz - um das KugelZentrum verteile. Auf jedem dieser Kreise verteile ich nun - auch wieder mit Varianz - 10 Vektoren.

Im Bild unten ist jede Linie innerhalb des Kreises(das ist die Kugel!) so ein oben beschriebener Kreis.
Im Endeffekt ist nämlich ein um den Durchmesser rotierender Kreis im R3 eine Kugel → siehe Rotationskörper.

Man kann dann auch noch die Anzahl der Vektoren pro Kreis variieren lassen, so das auf einem mal 8 und auf einem anderen mal 12 sind.

bye Saxony

das sind die bereits erwähnten Längen- und Breitengrade des Globus’,
schon recht gut, mit dem kleinen Nachteil, dass die Punkte an den Polen dichter sind als am Äquator
(ich muss zu allem ein Kommentar abgeben, wieder ordentlich Posts sammeln :wink: )

Hiho,

ja das mit den Polen stimmt. Hmm ich überleg da mal weiter! :wink:

bye Saxony

PS: Ja, das erste mal, dass ich mehr Posts als SlaterB habe! :slight_smile:

Im Redbook gibt’s im Kapitel 2 (ganz unten http://fly.cc.fer.hr/~unreal/theredbook/chapter02.html ) eine Methode wie man eine Kugel trianguliert, so dass sie nur aus gleichseitigen Dreiecken besteht (und damit die Punkte „gleichverteilt“ auf der Oberfläche sind). Allerdings ist man da natürlich auf eine Menge von bestimmten Anzahlen Dreiecksflächen festgelegt.

Ein anderer Ansatz - der von der Programmierung her wohl recht einfach aber vermutlich SEHR ineffizient ist: 100 Iterationen lang für jeden Punkt z.B. die 5 nächstgelegenen Punkte zu ermitteln (ja, quadratische Laufzeit!) und den Punkt dann in den Schwerpunkt dieser Punkte zu legen. Wenn man dafür die Punkte in ein Dreiecksnetz legen würde, könnte man das auf O(n) drücken, aber das Netz aufzubauen wäre halt ein bißchen mehr Programmierarbeit.

Hm - ist aber alles nicht so optimal :confused:

Hiho,

heute früh beim Einschlafen kam mir eine neue Idee, wie man das Problem mit den Polen lösen kann, aber ohne gleich zu komplex zu werden um mit Meshes oder Einteilung der Oberfläche in Dreiecke zu arbeiten.

Diesmal verteilen wir nicht die Kreise per Rotation um eine gedachte Hochachse(Durchmesser). Sondern wir zwängen der Kugel gleichverteilt sogenannte Reifen (Analogie zum Bierfaß :wink: ) auf. Diese Reifen entsprechen den zovor schon beschrieben Kreisen - mit dem Unterschied, dass man nun in Abhängikeit des Durchmessers eines solchen Kreises die Anzahl der zu verteilenden Punkte angeben kann. Somit bekommen polnahe Kreise weniger Punkte zugeteilt als Äquatornahe.

Die Verteilung der Reifen entlang des Durchmessers der Kugel, sollte benfalls wie die Verteilung der Punkte auf den Kreisen mit Varianz erfolgen. Also immer ± irgendwas.

Ich habe dies ebenso mal skizzenhaft dargestellt. Man verzeihe mir die Darstellung aber bei meinem Paint habe ich keine Funktion zum malen einer Kugel gefunden. Deswegen die stümperhafte Zwei-FeldProjektion.

bye Saxony

So noch eine Anmerkung!

Erzeugt man zu jedem Kreis ein Duplikat und lässt diese um eine bestimmte Achse um 90° rotieren, erhält man ein recht gut gleichverteiltes Gitternetz, wo man die Schnittpunkte als Richtung für die Vektoren unter Einhaltung der Streubereiche hernehmen kann.

Lässt man diese Streubereiche weg, kann man eine nahezu perfekte Kugel aus einer Partikelwolke erzeugen. :slight_smile:

bye Saxony

Vollendet für alle drei Achse sähe es dann so aus:

Ich denke aber die Variante mit zwei Achsen dürfte ausreichen.

bye Saxony

Hi Saxony,

die Idee mit den Kreisen in vetikaler/horizontaler Verteilung klingt schonmal richtig gut, ich werde mich bei Gelegenheit mal fix ransetzen und versuche dies umzusetzen, wobei mich interessiert wie es schon ausschaut wenn man erstmal nor die horizontalen Kreise hat. Gestern kam ich gar nicht mehr dazu etwas daran zu arbeiten, musste erstmal klassisch bis halb 10 arbeiten ^^
Aber vielleicht find ich dann in der Mittagspause nochmal ein paar minuten um genau das umzusetzen, vielen Dank für die hilfe ich melde mich sobald es was zu berichten gibt, oder ich nicht weiß wie ichs machen soll :o)

Gut Schuß
VuuRWerK :wink:

Ich wollte nur kurz einen Zwischenstand ausrufen, habe alles schon umgesetzt und in der tat, ich habe eine Kugel :slight_smile: Wie ich es gemacht habe, sofern es jemanden interessiert, kann ich ja noch schreiben, bin nur im Moment auf Arbeit und da recht gut eingespannt sodass ich in einer freien Meinute nochmal kurz erläuter wie ich es nun gemacht habe :slight_smile:

Gut Schuß
VuuRWerK :wink:

Yup gib mal bescheid wie du es gelöst hast, sobald du mal eine Minute Luft hast! :wink:

bye Saxony

Alsooo … :slight_smile:

Wie vielleicht schon aufgefallen ist habe ich zu Anfangs einen falschen Weg eingeschlagen, ich musste nicht dem Zufall auf die Sprünge helfen, sondern ich musste erstmal eine Kugel hinbekommen!
Durch die Idee von Saxony musste ich also erstmal diese Gitternetz erzeugen.

Beispielsweise so:

final double r = 1.0d;    // radius
for(double theta = 0; theta <= Math.PI; theta += Math.PI / 20.0d) {
    for(double phi = 0; phi <= Math.PI * Math.PI; phi += Math.PI / 10.0d) {
        final Particle p = new Particle();
        p.setPosition(new Vector3d(0.0d));    // Koordinatenursprung
        p.setDirection(new Vector3d(r * Math.cos(phi) * Math.sin(theta),
                                               r * Math.sin(phi) * Math.sin(theta),
                                               r * Math.cos(theta)));
    }
}

Jetzt haben wir ein Gitternetz :o)

Und damit es meinem Vorhaben entsprechend nun nicht so akkurat ausschaut, müssen wir, jetzt noch ein wenig den Zufall ins Spiel bringen, das war allerdings dann nicht mehr das Problem.

final double r = 1.0d;    // radius
for(double theta = 0; theta <= Math.PI; theta += Math.PI / 20.0d) {
    for(double phi = 0; phi <= Math.PI * Math.PI; phi += Math.PI / 10.0d) {
        final Particle p = new Particle();
        p.setPosition(new Vector3d(0.0d));    // Koordinatenursprung
        final double x = Math.random() / 1000.0d;
        final double y = Math.random() / 1000.0d;
        final double z = Math.random() / 1000.0d;
        p.setDirection(new Vector3d(r * Math.cos(phi) * Math.sin(theta) + x,
                                               r * Math.sin(phi) * Math.sin(theta) + y,
                                               r * Math.cos(theta) + z));
    }
}

So erkennt man zwar noch ansatzweise das Gitter aber es ist dennoch ein wenig „verschoben“, so soll es ja auch erstmal sein.

Also nochmal vielen Dank für den Denkanstoß mit dem Gitter, hat mir sehr geholfen :wink:

Gut Schuß
VuuRWerK :wink:

Hiho,

na super - hat es also so funktioniert. Kannst du mal bitte noch so ein Bild von der Partikelwolke posten?

bye Saxony

Sorry, total vergessen, der Screen :slight_smile:

Gut Schuß
VuuRWerK :wink:

Hiho,

sieht ja ganz schnucklig aus! :slight_smile:

bye Saxony