Zufällige Richtung im 3d-Raum
Übersicht

![]() |
Mr.KeksBetreff: Zufällige Richtung im 3d-Raum |
![]() Antworten mit Zitat ![]() |
---|---|---|
Heyho allerseits.
Ich zermartere mir schon seit einer ganzen Weile den Kopf, wie ich möglichst schnell eine absolut zufällige Richtung im 3d-Raum ermittle. Ich bin auch nicht so ganz dahinter gekommen, wo ich für die dafür zweifelsohne existierende Formel nachschaun kann. Die meisten Texte scheinen es als selbstverständlich vorauszusetzen und nennen weder Code noch Formel ("Jetzt brauchen wir nur noch einen zufälligen Richtungsvektor: vec = ZufallsVektor(); ") Wenn ich die BlitzBasic-Rnd-Funktion einfach für die drei Komponenten eines Vektors im kubischen Raum nutze, so ist die Wahrscheinlichkeit von Vektoren in Richtung der Diagonalen erhöht. Wenn ich mir mit Rnd() zwei Winkel ausgeben lasse, die mir als Pitch und Yaw kugelgeometrisch eine Richtung bestimmen, so haben Richtungen entlang der ersten Drehachse (für gewöhnlich Yaw) eine erhöhte Wahrscheinlichkeit. Wie muss ich es also lösen, damit wirklich alle Richtungen gleich wahrscheinlich sind? Von meinem zweiten Ansatz ausgehend müsste die Wahrscheinlichkeit von einem Pitch-Winkel mit dem Umfang des Kreises, auf den der Winkel zeigt, abnehmen. Doch erscheint mir das nicht nur kompliziert, sondern auch noch vermutlich langsam und neue Probleme erzeugend (... dann wären die Pole z.B. nicht mehr definiert, weil da der Radius 0 wird...) |
||
MrKeks.net |
Dreamora |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
wieso sollte die diagonale erhöht sein bei 3x rnd?
Das ist definitiv nicht der fall. Die wahrscheinlichkeit das dabei 1,2,3 raus kommt ist so wahrscheinlich wie 3,3,3. von dem her gesehen gibt es unzählige gleich wahrscheinliche richtungen ... was ja eigentlich auch das ziel ist nicht ![]() die 3 können irgendwo sein also gleich wahrscheinlich auf der raumdiagonalen (0,0,0 -> 1,1,1) wie auch nicht auf der raum diagonalen. davon abgesehen das es derer ja auch 8 gibt im endeffekt wenn du einen zufälligen vektor hast der rnd -Wert,Wert erzeugt. Einzig das der zufällige vektor danach normiert werden sollte und mit einer 4ten RND gestreckt würd ich da noch anfügen, weil sonst erhälst du vermutlich effektiv leicht chaotisch daten. Denn erst sollte die zufallsrichtung festgelegt werden, dann die länge |
||
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen. |
- Zuletzt bearbeitet von Dreamora am Mi, Okt 17, 2007 15:19, insgesamt einmal bearbeitet
Code der Verwirrung |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
ich versteht auch net was an rnd falsch ist? ist dann doch zufall oder? | ||
![]() |
Mr.Keks |
![]() Antworten mit Zitat ![]() |
---|---|---|
ich will ja nicht einen zufälligen vektor, sondern eine zufällige richtung. also einen vektor aus der menge der normalisierten vektoren...
ich berechne ja einen zufälligen punkt. alle punkte haben dieselbe wahrscheinlichkeit. alle punkte, die auf einem strahl aus dem ursprung liegen, haben dieselbe richtung. entlang der diagonalen liegen mehr punkte als entlang der richtung, die direkt zu einer seitenfläche des würfels führt, weil die diagonalen schlicht länger sind. man beachte bei der kleinen lichtquelle rechts, die nahe bei der kugel ist, wie der lichtwurf auf die kugel in vier richtungen stärker erscheint als in den anderen... das passiert, weil sich meine netten zufälligen rays sich leider entlang der diagonalen mit etwas höherer wahrscheinlichkeit ausbreiten. ich bin inzwischen auf die idee gekommen, dass ich einfach solange rnd benutze, bis ein vektor entsteht, der kürzer als 1 ist. das sollte das problem lösen, auch wenn ich es für rechenzeitverschwendung halte und nach wie vor für andere lösungen offen bin. |
||
MrKeks.net |
![]() |
BladeRunnerModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
Wie wäre es mit 2 Achsen zufällig bestimmen und die Dritte so ergänzen dass ein Einheitsvektor draus wird ? | ||
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3 Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64 B3D BMax MaxGUI Stolzer Gewinner des BAC#48, #52 & #92 |
![]() |
stfighter01 |
![]() Antworten mit Zitat ![]() |
---|---|---|
Bladerunners vorschlag mal umgesetzt ( wenn ichs auf die schnelle richtig gemacht hab )
Code: [AUSKLAPPEN] alpha = rand(360) beta = rand(360) x=cos(alpha) * cos(beta) y=sin(alpha) * cos(beta) z=sin(beta) [edit] sorry, diese funktion ist schlecht, weil an den polen (zmax, zmin) eine häufung entsteht. [/edit] |
||
Denken hilft! |
![]() |
Mr.KeksBetreff: Re: Zufällige Richtung im 3d-Raum |
![]() Antworten mit Zitat ![]() |
---|---|---|
Man siehe mein erster Beitrag.Mr.Keks hat Folgendes geschrieben: Wenn ich mir mit Rnd() zwei Winkel ausgeben lasse, die mir als Pitch und Yaw kugelgeometrisch eine Richtung bestimmen, so haben Richtungen entlang der ersten Drehachse (für gewöhnlich Yaw) eine erhöhte Wahrscheinlichkeit.
Ich glaube zwar, dass Blade was anderes meinte, aber so wie ich es verstand, würde es vermutlich auch irgendwie nicht das Ergebnis bringen, das ich benötige. |
||
MrKeks.net |
![]() |
stfighter01 |
![]() Antworten mit Zitat ![]() |
---|---|---|
ja, ich glaub ich hab blade da falsch verstanden, weil mir gleich die lösung in den kopf geschossen ist.
grundsätzlich könnte mein code funktionieren, wenn man für die berechnung von beta eine ausgleichsfunktion schreiben würde, die den sammelpunkt von dem polen wegbringt. Aber am besten du bleibst bei deiner eigenen idee. mit durchschnittlich 6*rnd u 2*sqr pro wert bist du sicher ohnehin schneller als mit irgendwelchen komplizierten funktionen und sin / cos berechnungen. mfg stf |
||
Denken hilft! |
![]() |
Jan_Ehemaliger Admin |
![]() Antworten mit Zitat ![]() |
---|---|---|
Die Menge der Punkte muss anhand des Umfangs des Kugelabschnittes ermittelt werden (jedenfalls falls wir es rinfach scheibchen weiße machen wollen):
Code: [AUSKLAPPEN] Graphics3D (640,480,32,2)
SetBuffer BackBuffer() cam=CreateCamera() MoveEntity cam,0,0,-100 sun = CreateLight(1) RotateEntity sun,35,35,35 kugel=CreateSphere() ScaleEntity kugel,40,40,40 EntityColor kugel,255,255,0 EntityAlpha kugel,0.2 For i = -90 To 90 Step 2 For m=0 To Abs(Cos(i)*10.0) winkel#=Rand(360) x#=Sin(winkel#) z#=Cos(winkel#) y#=Cos(i) cube=CreateCube(kugel) PositionEntity cube,x#*y#,Sin(i),z#*y# ScaleEntity cube,0.02,0.02,0.02 Next Next Repeat TurnEntity kugel,0.2,0.1,0 RenderWorld Flip Until KeyHit(1) |
||
between angels and insects |
![]() |
stfighter01 |
![]() Antworten mit Zitat ![]() |
---|---|---|
Menge der Punkte bringt mich auf eine idee.
Leider ist meine Mathematik schon so eingestaubt das ichs im moment nicht zu Lösen vermag. Mein ansatz um Beta auszurechnen: H= Hypotenuse = 1. x= ahnkathete z= gegenkathete Wir arbeiten im x,z koordinatensystem ( x=horizontal, z=vertikal) die Menge der punkte(mp) an der höhe z ist mp = x*2pi wobei x= H*cos( asin (z/H) ) integriert über z(-1,1) könnte man die menge der punkte am umfang bekommen. über rnd( 0 , mp(max) ) einen Punkt auswählen u. über diesen Punkt wiederrum z berechnen. mit z den winkel Beta berechnen u. damit einen Punkt im Raum festlegen. hoffentlich mags wer lösen, sonst hab ich wieder eine schlaflose nacht ![]() mfg stf |
||
Denken hilft! |
![]() |
Mr.Keks |
![]() Antworten mit Zitat ![]() |
---|---|---|
Danke Jan_, das sieht vielversprechend aus. Ich wollte zwar lieber eine Funktion haben, die nur einen Wert gemäß seiner Wahrscheinlichkeit und des Zufalls zurückgibt, aber deinen Ansatz kann ich vielleicht auch bei einem der Dinge, wofür ich das brauche, verbauen. (Ich brauche sone Zufallsrichtung gegenwärtig bei gleich zwei Projekten ^^)
Hmm, stfighter, ich bin noch nicht ganz hinterhergekommen. Bin aber auch geade erst aus der Schule zurück und noch nicht ganz ausgeschlafen. Ich schaus mir nachher (nach meinem kleinen Mittagsnickerchen ![]() |
||
MrKeks.net |
![]() |
stfighter01 |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ich glaub ich habs jetzt gelöst
Allerdings sind meine sämtlichen Integralrechnungen in einer Sackgasse gelanded, darum hab ichs einfach intuitiv gelöst xD Ich hab also nur einen empirischen Beweis dafür, glaub aber das es ganz gut funktioniert. Die Ausgleichsformel ist quasi nichts anderes als wiederrum die Funktion des Kreises( klingt soweit ja auch logisch ) z = sqr( 1 - zufallswert^2 ) Code: [AUSKLAPPEN] Graphics3D 800,600,32 Global retx# Global rety# Global retz# Global timev1 Global timev2 Global maxtestcount = 100000 Function calcv3D_v1() ;Berechnung Version1 mittels versuch und Irrtum Repeat retx# = Rnd(-1,1) rety# = Rnd(-1,1) retz# = Rnd(-1,1) distance# = (retx*retx) + (rety*rety) + (retz*retz) Until distance# < 1 distance# = Sqr( distance# ) factor# = 1.0/distance# retx# = retx# * factor# rety# = rety# * factor# retz# = retz# * factor# End Function Function calcV3D_v2( ) ;Berechnung Version2 mittels 2 Rnd Werten und fixem algo alpha# = Rnd(0,360) zrnd# = Rnd(-1,1) z# = Sqr( 1 - (zrnd#*zrnd#) ) beta# = ACos(z#) retx#=Cos(alpha) * Cos(beta) rety#=Sin(alpha) * Cos(beta) retz#=Sin(beta) retz# = retz#*Sgn(zrnd#) End Function cam = CreateCamera() CameraRange cam, 0.001, 20 PositionEntity cam,0,0,-5 light = CreateLight(2, cam ) LightRange light, 1 Delay(3000) i=0 timev1 = MilliSecs() Repeat i = i +1 calcV3D_v1() calcV3D_v1() calcV3D_v1() calcV3D_v1() calcV3D_v1() calcV3D_v1() calcV3D_v1() calcV3D_v1() calcV3D_v1() calcV3D_v1() Until i=maxtestcount timev1 = MilliSecs() - timev1 i=0 timev2 = MilliSecs() Repeat i = i +1 calcV3D_v2() calcV3D_v2() calcV3D_v2() calcV3D_v2() calcV3D_v2() calcV3D_v2() calcV3D_v2() calcV3D_v2() calcV3D_v2() calcV3D_v2() Until i=maxtestcount timev2 = MilliSecs() - timev2 i = 0 Repeat i = i +1 calcV3D_v1() sp=CreateCube( ) EntityColor sp, Rand(255), Rand( 255), Rand(255) ScaleEntity sp, 0.01, 0.01, 0.01 PositionEntity sp, retx, rety, retz Until i=500 Repeat If MouseDown( 1 ) And MouseDown( 2 ) MoveEntity cam, -(MouseXSpeed()*0.1),(MouseYSpeed()*0.1),0 Else If MouseDown( 1 ) MoveEntity cam, 0,0,(MouseYSpeed()*0.1) EndIf If MouseDown( 2 ) TurnEntity cam, -(MouseYSpeed()*0.4),-(MouseXSpeed()*0.4),0 EndIf EndIf MouseYSpeed() MouseXSpeed() RenderWorld Locate 10,10 Print "Zeit - Version1:" + timev1 + "ms" Locate 10,30 Print "Zeit - Version2:" + timev2 + "ms" Flip Until KeyHit( 1 ) Im benchmark ist es aber so ziemlich unerheblich welche funktion verwendet wird. So, mir reichts, mir raucht der Kopf. Mfg stf |
||
Denken hilft! |
![]() |
Mr.Keks |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hey danke, das scheint zu laufen. Echt toll! (= Wobei es natürlich schade is, dass die mathematisch interessantere Lösung sich zumindest auf meinem Rechner als langsamer erweist. Immer diese Trigonometrie - und nichtmal ein Sqr ließ sich vermeiden... | ||
MrKeks.net |
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group