how to get rand vector

Started by
7 comments, last by iMalc 18 years, 10 months ago
I need rand direction to drive some function to work. how to get rand vector? I now use rand() to do ,but not work. rand()/RAND_MAX alway to constant and even it work ,it is unconvenient to create rand vector. are there better way?
Advertisement
Did you seed the random generator before using rand()?

srand(timeGetTime());
firstly you need %RAND_MAX not / RAND_MAX.

To get a random vector in any direction use this

void randomVec(Vec *v)
{
v->x = (rand() % (RAND_MAX*2)) - RAND_MAX;
v->y = (rand() % (RAND_MAX*2)) - RAND_MAX;
v->z = (rand() % (RAND_MAX*2)) - RAND_MAX;
}

That way you'll get a value between -max and +max. Its not very pretty, but its really the only way. And remember to seed ur rand() function as mentioned. If you put it in a function thats takes a pointer to your vector then you'll never have to look at it again :P
Quote:Original post by kaysik
x = (rand() % (RAND_MAX*2)) - RAND_MAX;

rand() returns values from 0 to RAND_MAX so mod with higher number is kind of pointles. Your line will give results from -RAND_MAX to zero.

Here is a bit of code from my project.. (in C# so you might need to change it a bit)
/// <summary>/// Generates random vector in box/// </summary>/// <param name="range">Box size</param>public void Random( float range ) {				float range2 = range * 2;	x = range2 * (float)Core.Random.NextDouble() - range;	y = range2 * (float)Core.Random.NextDouble() - range;	z = range2 * (float)Core.Random.NextDouble() - range;}/// <summary>/// Generates ranodm unit vector/// </summary>public void RandomUnit() {	double alpha = System.Math.PI * 2.0 * Core.Random.NextDouble();	z = 2.0f * (float)Core.Random.NextDouble() - 1.0f;	float r = (float)System.Math.Sqrt( 1.0 - z * z );	x = (float)System.Math.Sin( alpha );	y = (float)System.Math.Cos( alpha );	x *= r;	y *= r;}
You should never let your fears become the boundaries of your dreams.
All wrong [EDIT: except for DarkWing who posted intermediately]. First you should definitely not mod the value returned by rand(). Because not all of the bits are as random as others (high to low) this will yield less random results than expected. Moreover the OP is trying to get a float between [0,1] for which division is just good.

The problem is that, because rand() returns an integer and RAND_MAX is defined and defaults to an integer, the integer division operator is selected. You want a float division so you need a cast:

float r = rand() / (float)RAND_MAX;


If you use three of these successively to generate a random vector, know that this does not create vectors randomly distributed over the unit sphere! You lose the uniform distribution.

Greetz,

Illco
Quote:Original post by Illco
If you use three of these successively to generate a random vector, know that this does not create vectors randomly distributed over the unit sphere! You lose the uniform distribution.

That's where my RandomUnit() comes into play. It generates random vecotr on unit sphere with same random distribution as generator. It might look wierd by it actualy works as it was shown on *long* flipcode thread a few years ago.
You should never let your fears become the boundaries of your dreams.
I know. It is a quite normal way of doing random unit vectors. But I was referring to the OP who wanted (or at least I thought so) to do three successive random floats and then have a random unit vector.
Darkwing: In my hast I didn't realise he meant RAND_MAX as THE offical one - I figured it was just a constant he'd defined himself. Now you point it out its obviouse but if you pretend I was working with my own value of say 7 my code works fine :P

Although like Illco pointed out if he's after a floating point rand() then all he needs todo is case.
To get uniform distribution you should discard points outside the unit sphere. More like this:
void RandomVec(float length) {	float lenSqr;	do {		x = rand()*(1.f/RAND_MAX);		y = rand()*(1.f/RAND_MAX);		z = rand()*(1.f/RAND_MAX);		lenSqr = x*x + y*y + z*z;	} while (lenSqr < EPSILON || lenSqr > 1.f);	float scale = length/sqrt(lenSqr);	x *= scale;	y *= scale;	z *= scale;}
"In order to understand recursion, you must first understand recursion."
My website dedicated to sorting algorithms

This topic is closed to new replies.

Advertisement