Sign in to follow this  
derek7

how to get rand vector

Recommended Posts

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?

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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;
}



Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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;
}

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this