Random function help please.

Soldato
Joined
18 Jun 2010
Posts
6,641
Location
Essex
I'm making an asteroid belt for my project it consists of a lot of objects that are random put 300 pixels from the sun then add Math.random() * 300 so that it will randomly be between 300-600 distance away from the sun. However I wanted it to be less far away and more nearer to the sun, so I did the following:

300 + Math.random()*300*Math.random()

Therefore it is less likely to be nearer to 600 and more likely to be nearer to 300.

What I want now is for there to be lots in the middle of the range 300-600 and less near the sun and less far away but I can't get my head around how to do it.

Any help would be appreciated, cheers.

EDIT:

Wow, the second I stopped writing I figured it out.

if (Math.random() < 0.5)
{
450 + Math.random() * 150 * Math.random()
}
else
{
450 - Math.random() * 150 * Math.random()
}
 
Last edited:
Soldato
OP
Joined
18 Jun 2010
Posts
6,641
Location
Essex
Just use a normal distribution.

See my edit, it's fine now.

Looks like this now ^^

orrery.png
 
Last edited:
Soldato
OP
Joined
18 Jun 2010
Posts
6,641
Location
Essex
Thanks man! There's way more to it, (it's animated) and loads of different modes.

Obviously the art side of it is terrabad but it's a computer science degree not an art degree ^^ :).
 
Soldato
OP
Joined
18 Jun 2010
Posts
6,641
Location
Essex
I had a rethink of this the other day, pointless bump but in case anyone was wondering.

You could do something along the lines of
//would return a number between 1 and -1 multiplied by the range
// e.g. range = 3. between 3 and -3.
Math.sin(Math.random() * 2 * Math.pi) * range

It's one line rather than a conditional. Then you could also times it all by Math.random() again if you wished to make things more likely to be closer to the middle ^^
 
Permabanned
Joined
9 Aug 2009
Posts
12,234
Location
UK
I would write this more like the english language used to describe it.

I'd start by defining the distribution, so I could easily tweak it.

300-400 : 50%
400-500 : 30%
500-600 : 20%

If you have that in whatever data structure you want, you can tweak the distribution without much thought.

Then all you have to do is generate the right numbers, which is the easy bit.

- Take the total number of asteroids you want to draw
- Loop through each "distribution" row
- Multiply the total asteroid count by the distribution's chance
- Generate that amount of random numbers between the distribution's range
 
Last edited:
Associate
Joined
23 Dec 2012
Posts
78
You don't say which language, but you also might want to rethink your implementation of the Math.random() function.

Math.random() generally returns a floating point number in the range 0 >= Math.random() < 1
If you want to generate random numbers within a given range, then you need to apply a multiplier to the Math.random() function. However, it's possible for a value of 0 to be returned which might have unforeseen consquences, for example when you apply your multiplier e.g., when Math.random() = 0, then Math.random() * 300 = 0.

You also need to consider how to round these numbers because the two most obvious methods are inherently flawed when applied to Math.random().

Math.round() rounds to the nearest whole number but it will also skew the distribution of your random numbers. Numbers at the endpoints of your intended range will have 50% less chance of being generated than numbers elsewhere in your range. Take the following code as an example, which is supposed to generate random integers in the range 0 - 5:

Code:
for (i = 0; i < 10000; i++) {
	num = Math.round(Math.random() * 5);
	if (num == 0) {
		zero += 1;
	} else if (num == 1) {
		one += 1;
	} else if (num == 2) {
		two += 1;
	} else if (num == 3) {
		three += 1;
	} else if (num == 4) {
		four += 1;
	} else {
		five += 1;
	}
}
If you trace the outputs, you'll find that the values for 0 and 5 will occur exactly 50% less than the values between 1 and 4.

Using Math.ceil() will also introduce errors. Because the Math.random() function can theoretically produce a value of 0, Math.ceil(Math.random() * multiplier) will also produce a value of 0. Also, because Math.random() never returns a value of 1, this means that the highest value in your intended range is less likely to be generated than the other values in your range.

The correct way to generate random numbers in a given range, such that they all have an equal chance of being generated, is to use Math.floor(Math.random() * multiplier). This will always give an equal distribution of integers from 0 upto, but not including, the multiplier. If you want to generate equally distributed numbers between 1 and including your multiplier, you should use Math.floor((Math.random() * multiplier) + 1).
 
Back
Top Bottom