## Mother...

A place to discuss the implementation and style of computer programs.

Moderators: phlip, Moderators General, Prelates

pepsi
Posts: 53
Joined: Wed Jul 08, 2009 11:22 pm UTC

### Mother...

This is upsetting me.

I want to make a bunch of objects travel in random directions. You'd think that y_velocity=Math.sqrt(1-Math.pow(x_velocity,2)), right? But squaring and square rooting numbers leads to the loss of some really important information and I end up with a not so uniform distribution:

Is there any way that I can a uniform distribution? So far I have this, were sign(double a) just gives a random sign and object is an array list of objects:

Code: Select all

`   void ring()   {      for(int a=0;a<1000;a++)      {         object b=new object(width/2,height/2);         object.add(b);         b.yv=sign(Math.sqrt(1-Math.pow(b.xv=sign(random.nextDouble()),2)));      }   }`

fazzone
Posts: 186
Joined: Wed Dec 10, 2008 9:38 pm UTC
Location: A boat

### Re: Mother...

pepsi wrote:

Code: Select all

`   void ring()   {      for(int a=0;a<1000;a++)      {         object b=new object(width/2,height/2);         object.add(b);         b.yv=sign(Math.sqrt(1-Math.pow(b.xv=sign(random.nextDouble()),2)));      }   }`

So "object" is an instantiable type that either inherits from or contains an ArrayList<object> of all its instances? What? First, why would you want to do this, ever, and second, if you have to do it, why not just add stuff to the ArrayList automatically in the constructor? Maybe it's just a typo...

Getting back to the point, you could always blame the PRNG. I know that the java.util.Random class is just a simple LCM PRNG, so that could easily be the cause of your problems. You could try using Xorshift, a simple-to-implement and significantly more 'random' PRNG, but I'm sure that there are approximately six million Java serious PRNG projects that use the Mersenne Twister or what-have-you. I doubt that your math is to blame for the non-random distribution.
*/

jaap
Posts: 2094
Joined: Fri Jul 06, 2007 7:06 am UTC
Contact:

### Re: Mother...

Try randomly choosing an angle z between 0 and 2*pi, and then let xv=cos(z), yv=sin(z).

At the moment you are uniformly choosing xv, which means the near vertical parts of the circle have fewer points since they span a smaller range of xv.

pepsi
Posts: 53
Joined: Wed Jul 08, 2009 11:22 pm UTC

### Re: Mother...

fazzone wrote:
pepsi wrote:

Code: Select all

`   void ring()   {      for(int a=0;a<1000;a++)      {         object b=new object(width/2,height/2);         object.add(b);         b.yv=sign(Math.sqrt(1-Math.pow(b.xv=sign(random.nextDouble()),2)));      }   }`

So "object" is an instantiable type that either inherits from or contains an ArrayList<object> of all its instances? What? First, why would you want to do this, ever, and second, if you have to do it, why not just add stuff to the ArrayList automatically in the constructor? Maybe it's just a typo...

Getting back to the point, you could always blame the PRNG. I know that the java.util.Random class is just a simple LCM PRNG, so that could easily be the cause of your problems. You could try using Xorshift, a simple-to-implement and significantly more 'random' PRNG, but I'm sure that there are approximately six million Java serious PRNG projects that use the Mersenne Twister or what-have-you. I doubt that your math is to blame for the non-random distribution.

Object is simply an ArrayList of objects. An object is just a class I created to stores a few doubles.

pepsi
Posts: 53
Joined: Wed Jul 08, 2009 11:22 pm UTC

### Re: Mother...

Jaap, I love you! It works perfectly!

Cosmologicon
Posts: 1806
Joined: Sat Nov 25, 2006 9:47 am UTC
Location: Cambridge MA USA
Contact:

### Re: Mother...

Another technique that works for 3 dimensions as well as 2 is to choose a random point in the unit circle (or sphere), then normalize it. You can choose a random point uniformly from the unit circle by choosing vx and vy uniformly from [-1, 1], and repeating until vx^2 + vy^2 <= 1.

For 2-D I usually go with jaap's solution, though.

notzeb
Without Warning
Posts: 629
Joined: Thu Mar 08, 2007 5:44 am UTC
Location: a series of tubes

### Re: Mother...

Choose x and y independently from a Gaussian normal distribution. Then normalize the resulting vector.

This works because the probability density of being at point (x,y) is e^(-x^2)*e^(-y^2) = e^(-x^2-y^2) = e^(-r^2), which is rotationally invariant.

This trick works in any number of dimensions.

Edit: coincidentally, in three dimensions any individual coordinate will end up uniformly distributed between -1 and 1, so you can choose a random point on the sphere by first choosing the z coordinate uniformly at random and then choosing a random angle to determine the x and y coordinates. This doesn't work in any number of dimensions other than three, though.
Zµ«V­jÕ«ZµjÖ­Zµ«VµjÕ­ZµkV­ZÕ«VµjÖ­Zµ«V­jÕ«ZµjÖ­ZÕ«VµjÕ­ZµkV­ZÕ«VµjÖ­Zµ«V­jÕ«ZµjÖ­ZÕ«VµjÕ­ZµkV­ZÕ«ZµjÖ­Zµ«V­jÕ«ZµjÖ­ZÕ«VµjÕ­Z

You, sir, name?
Posts: 6983
Joined: Sun Apr 22, 2007 10:07 am UTC
Location: Chako Paul City
Contact:

### Re: Mother...

Cosmologicon wrote:Another technique that works for 3 dimensions as well as 2 is to choose a random point in the unit circle (or sphere), then normalize it. You can choose a random point uniformly from the unit circle by choosing vx and vy uniformly from [-1, 1], and repeating until vx^2 + vy^2 <= 1.

For 2-D I usually go with jaap's solution, though.

Is there any particular reason not to use

phi = rand(): 0 < phi < 2pi
theta = rand() : 0 < theta < pi

x = sin(theta)cos(phi)
y = sin(theta)sin(phi)
z = cos(theta)

For 3D?
I edit my posts a lot and sometimes the words wrong order words appear in sentences get messed up.

notzeb
Without Warning
Posts: 629
Joined: Thu Mar 08, 2007 5:44 am UTC
Location: a series of tubes

### Re: Mother...

You, sir, name? wrote:
Cosmologicon wrote:Another technique that works for 3 dimensions as well as 2 is to choose a random point in the unit circle (or sphere), then normalize it. You can choose a random point uniformly from the unit circle by choosing vx and vy uniformly from [-1, 1], and repeating until vx^2 + vy^2 <= 1.

For 2-D I usually go with jaap's solution, though.

Is there any particular reason not to use

phi = rand(): 0 < phi < 2pi
theta = rand() : 0 < theta < pi

x = sin(theta)cos(phi)
y = sin(theta)sin(phi)
z = cos(theta)

For 3D?
Yes.

It doesn't work.

In my post above I wrote what actually does work in 3d. (Why doesn't what you wrote work? Think about the rule for integrating in spherical coordinates - you have to multiply the integrand by rsin(theta), not r.)
Zµ«V­jÕ«ZµjÖ­Zµ«VµjÕ­ZµkV­ZÕ«VµjÖ­Zµ«V­jÕ«ZµjÖ­ZÕ«VµjÕ­ZµkV­ZÕ«VµjÖ­Zµ«V­jÕ«ZµjÖ­ZÕ«VµjÕ­ZµkV­ZÕ«ZµjÖ­Zµ«V­jÕ«ZµjÖ­ZÕ«VµjÕ­Z

You, sir, name?
Posts: 6983
Joined: Sun Apr 22, 2007 10:07 am UTC
Location: Chako Paul City
Contact:

### Re: Mother...

Hmm, I guess that makes sense.
I edit my posts a lot and sometimes the words wrong order words appear in sentences get messed up.