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...

Postby pepsi » Sat Mar 13, 2010 7:54 pm UTC

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:

Image

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...

Postby fazzone » Sat Mar 13, 2010 8:08 pm UTC

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.
*/

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

Re: Mother...

Postby jaap » Sat Mar 13, 2010 8:10 pm UTC

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...

Postby pepsi » Sat Mar 13, 2010 8:14 pm UTC

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...

Postby pepsi » Sat Mar 13, 2010 8:19 pm UTC

Jaap, I love you! It works perfectly! :)

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

Re: Mother...

Postby Cosmologicon » Sat Mar 13, 2010 8:48 pm UTC

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.

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

Re: Mother...

Postby notzeb » Sat Mar 13, 2010 11:24 pm UTC

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

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

Re: Mother...

Postby You, sir, name? » Sun Mar 14, 2010 12:14 am UTC

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.

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

Re: Mother...

Postby notzeb » Sun Mar 14, 2010 12:27 am UTC

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

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

Re: Mother...

Postby You, sir, name? » Sun Mar 14, 2010 12:32 am UTC

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.


Return to “Coding”

Who is online

Users browsing this forum: No registered users and 6 guests