# Appropriate procedural function for generation of an asteroid belt?

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

## Recommended Posts

I'm no mathematician, so please bear with me. I'm interested to know if there is an appropriate function that would generate a random point in a torus, or perhaps in a ring. What I want to do is as much is possible provide an even spread of points and for no point to be repeated (ie. just using "rand" won't work). That's right, I want a pseudo random distribution within a torus or ring. I'm not sure if this is Cambridge Tripos level stuff or not. I want this in order to procedurally generate an asteroid field around a star. Any ideas? Thanks in advance.

##### Share on other sites
Get a random radius, r, within the desired threshold.

Get a random angle, theta (0-360, or 0-2pi).

Then just a simple polar to cartesian conversion...

XLoc = r * cos(theta);
YLoc = r * sin(theta);

and if you want some z, throw in a bit of randomization for that too. That's it.

##### Share on other sites
#define NB_SLICES   360#define MAIN_RADIUS 10  // "big" torus radius#define SEC_RADIUS   1  // "small" torus radiusfloat rndSR, x, y, z, l;int i, rndDisplay;for (i = 0; i < NB_SLICES; i++){  rndDisplay = rand();  // only display some "points"  // no more than 1 point for each slice  if (rndDisplay > RAND_MAX / 2)  {    rndSR =  360.0f * rand() / (float)RAND_MAX;    l = SEC_RADIUS * cos(DEG2RAD(rndSR)) + MAIN_RADIUS;    z = SEC_RADIUS * sin(DEG2RAD(rndSR));    x = l * cos(DEG2RAD(i * 360.0f / NB_SLICES));    y = l * sin(DEG2RAD(i * 360.0f / NB_SLICES));  }}

if you want more points for each slice, you can do this:
#define NB_SLICES   360#define NB_SLICES2  60#define MAIN_RADIUS 10  // "big" torus radius#define SEC_RADIUS   1  // "small" torus radiusfloat rndSR, x, y, z, l;int i, j, rndDisplay;for (i = 0; i < NB_SLICES; i++){  rndDisplay = rand();  // only display some "slides"  if (rndDisplay > RAND_MAX / 2)  {    for (j = 0; j < NB_SLICES2; j++)    {      rndDisplay = rand();      // only display some "points"      if (rndDisplay > RAND_MAX / 3)      {        rndSR = j * 360.0f / NB_SLICES2;        l = SEC_RADIUS * cos(DEG2RAD(rndSR)) + MAIN_RADIUS;        z = SEC_RADIUS * sin(DEG2RAD(rndSR));        x = l * cos(DEG2RAD(i * 360.0f / NB_SLICES));        y = l * sin(DEG2RAD(i * 360.0f / NB_SLICES));      }    }  }}

##### Share on other sites
Interesting...

just wondering, what are you building this for?
and do you want these asteroids to have realistic orbits, or is this just a static background graphic thing?

##### Share on other sites
One thing to watch out for is floating point precision. The radius of the asteroid belt is about 4x1011 meters. At that scale, the resolution of a 32-bit float is about 40 km, and the resolution of a 64-bit float is about 0.1 mm.

Anyway, to answer the original question...

The previous suggestions don't actually generate uniform distribution. In those algorithms, the density closer to the center will be higher than the density farther from the center. However, the belt is narrow enough that it probably won't be noticeable. The easiest way to generate uniform distribution in complex shapes (such as a torus) would be to generate random locations in a bounding box and reject the ones that are not in the shape, doing this until you have enough points.

Good random number generators typically generate sequences that do not repeat for many iterations (231 or better). The problem is that when you convert the output to your range, unique locations cannot be guaranteed. If you want to guarantee unique locations, you could maintain a sorted list of locations and check against it.

##### Share on other sites
another way (coincidently which i use for placing asteroids so theyre not to close or far apart ) is to place all the points in the area. + then iterate over all the points checking if 2 points aint to close together if they are then move them apart

• 10
• 16
• 9
• 13
• 41