Zufällige Richtung im 3d-Raum

Übersicht BlitzBasic Allgemein

Neue Antwort erstellen

Mr.Keks

Betreff: Zufällige Richtung im 3d-Raum

BeitragMi, Okt 17, 2007 14:34
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragMi, Okt 17, 2007 15:15
Antworten mit Zitat
Benutzer-Profile anzeigen
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 Smile
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

BeitragMi, Okt 17, 2007 15:17
Antworten mit Zitat
Benutzer-Profile anzeigen
ich versteht auch net was an rnd falsch ist? ist dann doch zufall oder?

Mr.Keks

BeitragMi, Okt 17, 2007 16:24
Antworten mit Zitat
Benutzer-Profile anzeigen
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.

user posted image
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

BladeRunner

Moderator

BeitragMi, Okt 17, 2007 16:28
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragSo, Okt 21, 2007 13:10
Antworten mit Zitat
Benutzer-Profile anzeigen
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.Keks

Betreff: Re: Zufällige Richtung im 3d-Raum

BeitragSo, Okt 21, 2007 21:53
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragSo, Okt 21, 2007 22:07
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragMo, Okt 22, 2007 8:53
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragMo, Okt 22, 2007 13:54
Antworten mit Zitat
Benutzer-Profile anzeigen
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 Rolling Eyes

mfg stf
Denken hilft!

Mr.Keks

BeitragMo, Okt 22, 2007 14:01
Antworten mit Zitat
Benutzer-Profile anzeigen
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 Wink) mal genauer an, danke soweit (=
MrKeks.net

stfighter01

BeitragDi, Okt 23, 2007 17:39
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragDi, Okt 23, 2007 19:51
Antworten mit Zitat
Benutzer-Profile anzeigen
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

Neue Antwort erstellen


Übersicht BlitzBasic Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group