#### Archived

This topic is now archived and is closed to further replies.

# random vector

This topic is 5360 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

How to generate a random vector of unit length? v.x = rand(); v.y = rand(); v.z = rand(); v.Normalize(); obviously won''t work, since it won''t be distributed evenly. My Site

##### Share on other sites
Get two random angles (known conventially as azimuth and elevation). You then convert the resulting spherical polar angle to cartesians. eg:

x=sin(phi)*cos(theta)
y=sin(phi)*sin(theta)
z=cos(phi)

That should be uniformly distributed as you require.

EDIT: Its a unit vector already btw

[edited by - dmounty on November 9, 2003 3:07:22 PM]

##### Share on other sites
or:
create a vector where all components are between [-1,1]
find its magnitude
if magnitude>1 then start over again
divide all componenst by the magnitude and voila.

##### Share on other sites
dmounty''s solution will be a much worse approximation of a uniform distribution than your (quasar3d) original method.

A better idea would be to generate a random vector in a unit cube, then throw out the vector if it''s magnitude is larger than 1. If it''s smaller, renormalize it to magnitude 1. If it''s larger, generate a new one. If you want to avoid too many regenerations, worst case scenario, limit the retries to 5 or so, and just renormalize whatever you get. The difference in distribution should be minimal.

##### Share on other sites
This is from FlipCode (COTD/TOTD). Proven to be totaly unform.

void CVector3::RandomUnit() {   z = Random.GetFloat( 1.0f, -1.0f );   const float angle = Random.GetFloat( PI * 2.0f );		   const float r = Math::Sqrt( 1.0f - z*z );   Math::SinCos( angle , x, y );   x *= r;   y *= r;}

You should never let your fears become the boundaries of your dreams.

##### Share on other sites
quote:
Original post by Geoff the Medio
dmounty''s solution will be a much worse approximation of a uniform distribution than your (quasar3d) original method.

Why do you think that?

##### Share on other sites
AP: The two-angle solution would have a much higher concentration of points at the poles, not very uniform at all.

Does any one know: If you took a random axis and angle, and rotate the vector (1,0,0) around the axis by the angle, will you get a uniform distribution?

Tom

##### Share on other sites
actually the solution in the first post works perfectly...

##### Share on other sites
thanks everybody.

I think I will just use the trial and error way, because I think it''s the lessest expensive to compute. Darkwings seemed to work perfectly, but it seems very expensive to compute.

quote:
Original post by _DarkWIng_
This is from FlipCode (COTD/TOTD). Proven to be totaly unform.

void CVector3::RandomUnit() {   z = Random.GetFloat( 1.0f, -1.0f );   const float angle = Random.GetFloat( PI * 2.0f );		   const float r = Math::Sqrt( 1.0f - z*z );   Math::SinCos( angle , x, y );   x *= r;   y *= r;}

You should never let your fears become the boundaries of your dreams.

You say it''s proven to be totaly uniform. Can you tell me that proof, please? I always like to understand this sort of things

My Site

##### Share on other sites
The reason the 2 angle approach isn''t uniform is because the surface of the solid angle near the poles has a smaller area where as a solid angle near the equator has a larger surface area. Therefore the the distribution gets ''squeezed'' near the poles and ''stretched'' near the equator.

1. 1
2. 2
Rutin
24
3. 3
JoeJ
19
4. 4
5. 5

• 17
• 40
• 23
• 13
• 13
• ### Forum Statistics

• Total Topics
631729
• Total Posts
3001918
×