Skip to main content
GameDev.net gamedev.net
🔒 Locked

Firefly help... rand() function

Started by bluknight Jul 13, 2004 at 7:01 PM 15 replies 1.1k views
Original Post
bluknight
bluknight
It doesn't seem like my fireflys are really spawning randomly... Here's the important bits of code:
#include <stdlib.h>

float random(void) {
  return ((float)rand() / (float)(RAND_MAX+1));
}

void ffly::init() {
  x=random()*2.0 - 1.0;
  y=random()*2.0 - 1.0;
  z=random()*-100.0;
}
It seems that they are all spawning close to the 100.0 distance rather then being randomly spread out. If I change it to be higher, like to 1000.0, they are all grouped up down there instead... Also, Is there a better way to generate the X and Y? because the way I have it they have a smaller and smaller box to spawn in the further away you get... I want all of them spread out nicely all over, not just in a little rectangular prism. Note: Sorry for posting so much, I'm just starting this up today really, and I have lots of questions.
CheeseMonger
CheeseMonger
When generating a random number within a range, use modulo instead of division. For example:

//generate a number between 0 and maxRandomaRandomNumber = rand() % maxRandom;//generate a number between -500 and 500aRandomNumber = (rand() % 1000) -500;//etc
CheeseMonger
bluknight
bluknight
Does it really matter?
I like working with a function that randomly generates a fraction between 1 and 0.
My random function works, they just don't seem to be as wide spread as they should be.
CheeseMonger
CheeseMonger
Can you not make the rectangle as large the area you want them generated in, the size of the level perhaps?

x = (random() * LEVEL_WIDTH) - (LEVEL_WIDTH / 2)


If the level width was 1000, it would generate one anywhere within -500 to 500.
CheeseMonger
_DarkWIng_
_DarkWIng_
Quote:
Original post by CheeseMonger
When generating a random number within a range, use modulo instead of division. For example:

*** Source Snippet Removed ***

No no no. Bad programmer. No cookie.[grin][grin][grin]

Using modulo on random numbers destroys uniform distribution of random numbers. Original method is better.
You should never let your fears become the boundaries of your dreams.
fractoid
fractoid
Actually, while CheeseMonger's modulo method is possibly faster, it's less random, since the lower-order bits of ye standard random number are more ordered than the higher order bits. For random numbers between 1 and 1000, say, it's probably OK, but if you want to flip a coin then (rand() % 2) will apparently give you fairly non-random results.

The variable-width box idea is good. Also, try printing out the Z coordinates of each one and graphing them - I'd guess they just *look* like they're grouped at the back due to perspective.

[edit: Darkwing beat me to the random-modulo comment. Curses! Foiled again! ;) ]
bluknight
bluknight
Quote:
Original post by CheeseMonger
Can you not make the rectangle as large the area you want them generated in, the size of the level perhaps?

*** Source Snippet Removed ***

If the level width was 1000, it would generate one anywhere within -500 to 500.


The problem with that is that I don't know how to find the level width.

I'm going to try printing out all the variables and then get back to you...
edit: I printed out all the variables, and that didn't help me so much, so then I created a variable to calculate the average.
It says that the average is about 55 when i'm going out of 100... so i guess it must be pretty random. Now my question is why it doesn't look like more of them are closer.
haphazardlynamed
haphazardlynamed
heres what i use for random... seems to work pretty well

((float)(rand()%100000))/100000.0f

that gives me a random quantity between 0 and 1, with a precision of 1/100000th i then multiply it by any scaling factor i want

the idea is that rand gives me some unknown large int -random bit field i guess,
so modulo by 100000 clamps it to be someplace in that range
then i convert to float and divide by 100000.0f to normalize it
Thunder_Hawk
Thunder_Hawk
Try scaling your x and y coordinates by the magnitude of the z coordinate and some dampening factor. It's possible to calculate more appropriate values using the projection matrix, but that's hardly necessary.
______________________________________________________________________________________The Phoenix shall arise from the ashes... ThunderHawk -- ¦þ"So. Any n00bs need some pointers? I have a std::vector<n00b*> right here..." - ZahlmanMySite | Forum FAQ | File Forma
Infuscare
Infuscare
maybe also add an 'srand(time(NULL))' in there...?
haven't programmed in a while, so i might be a bit off with the function and/or parameters, fairly sure tho...
___________"You're just jelous because the voices only talk to me"
bluknight
bluknight
Wouldn't that only matter if I want it to be newly randomized each time I open the program? I don't really care if it's the same each time I look at it... At least not yet.

I know all about seeding a random value. *nod nod*

Though, one question about the random function, does it eventually just loop around? At which point would seeding it again help it be more random?

... Right now I've got 500 fireflies going, each one calling about 4 rand functions each cycle.
Thunder_Hawk
Thunder_Hawk
It will take a _LONG_ time for rand() to loop around, if ever. You really should avoid seeding a random number generator more than once during a program's lifetime unless you are trying to accomplish a replay or something. If nothing else, you could implement a Mersenne Twister for your random numbers.

However, I'd bet that it's much more likely that your difficulty lies in what you do with that random number. You should post a screenshot demonstrating the problem.
______________________________________________________________________________________The Phoenix shall arise from the ashes... ThunderHawk -- ¦þ"So. Any n00bs need some pointers? I have a std::vector<n00b*> right here..." - ZahlmanMySite | Forum FAQ | File Forma
bluknight
bluknight
The problem was really just imagined...

But I have another question about the rand function...

Is there any way to jump to a particular point in a rand function's string of numbers? (Like if you seed it, can you quickly jump to like the 400th random number or something?)

The reason I ask this is because seeding a random function has the potential to store a hell of a lot of data in just one seed. (random data albiet, but still, that's a lot... Randomly generate an entire terrain for a world with just one seed...)

So I need to know if it's possible to seed a rand function, and then jump to a point in it, so for example, say i'm randomly generating an entire world, I just want to generate the immediate area around the character... So I need to be able to just jump to where the rand function is around where the character is...

Sorry if it's a tad bit confusing.
Ysaneya
Ysaneya
Quote:
Original post by haphazardlynamed
heres what i use for random... seems to work pretty well

((float)(rand()%100000))/100000.0f

that gives me a random quantity between 0 and 1, with a precision of 1/100000th i then multiply it by any scaling factor i want


Bad code, not portable. I don't know what compiler you are using but in MSVC, RAND_MAX is defined as 65536. In other word your code will generate a random number between 0 and 0.65535.

Y.
Dredge-Master
Dredge-Master
The functions for Random number generators loop. All you have to do is find the correct function for that generator (ie the pattern between each number). I forgot where I read it, but it had a bunch of them written out. Could have been a book or a website. Just google and you may strike it lucky.

Anyway, a random number generator can be written yourself.
One is the Middle Square method.

Lets say you have some pattern (series - these are our seeds) like

1
2
3
4
5


lets go and add 50 to each just to bump it up, multiply it by 10, and add the same number back on.

511
522
533
544
555

lets square them all

261121
272484
284089
295936
308025

that's the square bit done.

For the middle bit, just cut off lets say the first and last digits.


_6112_
_7248_
_8408_
_9593_
_0802_


so now the pattern is from this particular function:

1 >> 6112
2 >> 7248
3 >> 8408
4 >> 9593
5 >> 802

It's not the most perfect example, but the whole point is to get a pattern that APPEARS random. That's all the random generators do.

Anyway, I hope that helped a bit. So in the generation of your own terrain, just whip up your own (preferably more detailed) random number generator. Since you know how you created the apparently random numbers, you can easily get the number that wish at seed(x)+y where x is the original seed, and y is the offset that you require.

I hope that made some sense.
Beer - the love catalystgood ol' homepage
Scrime
Scrime
A little template that I whipped up to generate random numbers in a range using stdlib's rand() goes something like this:

#ifndef __RANDOM_H__#define __RANDOM_H__#include <stdlib.h>namespace random {	template<class T>	class TRandom	{	public:		static T MinMax(T minimum, T maximum) { 			// do a bit of sanity on the min/max values			if( minimum == maximum ) 				return minimum;			else if( minimum < maximum )				return static_cast<T>( ((static_cast<double>(rand()) / static_cast<double>(RAND_MAX+1)) * (maximum-minimum)) + minimum);			else				return static_cast<T>( ((static_cast<double>(rand()) / static_cast<double>(RAND_MAX+1)) * (minimum-maximum)) + maximum);		}	};}#ifndef RAND_FLOAT#define RAND_FLOAT(min,max) (random::TRandom<float>::MinMax((min),(max)))#endif#ifndef RAND_DOUBLE#define RAND_DOUBLE(min, max) (random::TRandom<double>::MinMax((min),(max)))#endif#ifndef RAND_INT#define RAND_INT(min, max) (random::TRandom<int>::MinMax((min),(max)+1)))#endif#endif // __RANDOM_H__


For random floats/doubles it generates a number from min up to, but not including, max [min,max). For ints, it generates a number from min to max, inclusive [min,max].
We are the music makers and we are the dreamers of the dreams. - WonkaAsking Smart Questions | BookPool
merlin9x9
merlin9x9
Most rand implementations aren't especially good, and don't give very even distributions. You may be happier using another pseudo-random number generator. Try Mersenne Twister.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.