3D Theory - Programming Particle Systems - forum discussion

By: nobody ( Nobody/Anonymous )
file Random distribution of points / vectors  
2004-02-14 18:04

When building particle engines you want the emitter to expell particles with a certain range of velocity. Restraints on the direction ther are expeled are given by a direction and an angle.
The direction is the general direction of particle expulsion and the angle defines an angular variance. So what you get is particles expelled in a cone volume oriented on the direction axis. What is the best way for generating uniformly distributed direction vectors for these particles.
Initially I thought I needed only a random angle and random direction in (360 degrees) so I could build my new particle velocity.
This does not give uniform distribution over the cone. There is a more concentrated distribution torwards the direction axis. Intuitively I can explain this to myself by generating 100 random points on a circumference. Take any 100 random points on a circle of circumference of 5 and project then outward to a circle ten times the circumference. Obviously in that case there is more space between points.
Some may argue that this is actually a better particle emitter since it echos a tendency for particles to deviate less and less as they get further from the source. A sort of bell curve distribution.
Anyways I am now implementing a version where I pick a random point on a disk using methods described on the Wolfram math website. ( You have probably run across this by now and it is a useful reasources for all kinds of general and isoteric math often providing several different approachs or ways of looking at the same situation ). I am firing my direction vector through that point to the hull of the sphere. Which actually gives me a different but also biased mapping.
So what I am looking for is a way to generate points uniformly distributed on the intersection between a cone and a sphere.


By: martinbaker

particles

Can I first check if I have understood correctly by taking the simpler 2 dimensional case.

So how do we define the velocity distribution? I can think of the following possibilities:

  1. magnitude fixed, direction evenly distributed on circle - It seems to me that this is equivalent to choosing a random angle between theta and -theta. I guess this might happen if watering the garden with some sort of diffuser attached to the hose.
  2. Magnitude fixed, perpendicular direction evenly distributed - so sin(theta) = perpendicular/radius. This would seem to apply where say, a jet of water is being sprayed in one direction, but random collisions are generating some velocity component perpendicular to hose.
  3. Magnitude and direction variable, direction as in 1 or 2. Magnitude is a random number between 0 and vmax.
  4. Magnitude and direction variable, direction as in 1 or 2. Magnitude is a random number between vmin and vmax. I guess this might happen where all particles start out with velocity vAverage but due to random events the velocity range expands between vmin and vmax.
  5. Magnitude and direction variable, values are evenly distributed within the bounds of the red line above. I guess this could be generated by taking random points on plane between -xmax and xmax and between -ymax and ymax, then rejecting all points which lie outside red line.

As you suggest, I suspect that real physics examples would give more of a bell shaped distribution.

Martin

By: nobody ( Nobody/Anonymous )
file RE: Random distribution of points / vectors  
2004-02-15 09:50

Exactly as I thought of it. Anyways here is my solutions which may be flawed but appears to work well. I took functions for uniformly ditributing points on a sphere from wolfram site and started fooling with them.
Here is code for generating a point on the sphere:

vec3 Gen_Rand_Point_on_Unit_Sphere(){
float u,v;
float alpha, omega;
vec3 orient( 0, 1, 0 );

u = RANDOM( 1 );
v = RANDOM( 2 ) - 1;

omega = 2*Q_PI*u;
alpha = acos( v );

orient = orient.Rot_z( alpha );
orient = orient.Rot_y( omega );

return orient;
}

you can see my orientation vector is always pointed along the y axis. To base everything on a different direction just rotate all generated points.
On this first function it doesn't make a difference but in the following 2 it will.
Anyways I looked at the results and it looked pretty even to me.

I changed the constraints on the v value in the next to get 2 variations. The first one generates points in the cone around the y axis. The second one generates points in a ring between 2 angles passed to the function:

/*******************************************************
Given an angle in radians generate a random vector
around the y axis
*******************************************************/
vec3 Gen_Rand_Point_in_angle_on_Unit_Sphere( float ang ){
float u,v;
float alpha, omega;
double ht;
vec3 orient( 0, 1, 0 );

if( (ang<0) || (ang>Q_PI) ) return vec3( 0, 0, 1 );

ht = cos( ang );

u = RANDOM( 1 );
v = RANDOM( 1-ht ) + ht;

omega = 2*Q_PI*u;
alpha = acos( v );

orient = orient.Rot_z( alpha );// rotates around the z axis
orient = orient.Rot_y( omega );// rotates around the y axis

return orient;
}

/*******************************************************
Given t angles in radians generate a random vector
around the y axis in between the 2 angles specified
*******************************************************/
vec3 Gen_Rand_Point_in_band_on_Unit_Sphere( float ang1, float ang2 ){
float u,v;
float alpha, omega;
double sc, ht1, ht2;
vec3 orient( 0, 1, 0 );

if( (ang1>ang2) ) return vec3( 0, 0, 1 );
if( (ang1<0) || (ang1>Q_PI) ) return vec3( 0, 0, 1 );
if( (ang2<0) || (ang2>Q_PI) ) return vec3( 0, 0, 1 );

ht1 = cos( ang1 );
ht2 = cos( ang2 );
sc = fabs( ht1 - ht2 );

u = RANDOM( 1 );
v = RANDOM( sc ) + ht2;

omega = 2*Q_PI*u;
alpha = acos( v );

orient = orient.Rot_z( alpha );// rotates around the z axis
orient = orient.Rot_y( omega );// rotates around the y axis

return orient;
}

Since this was a quick solution I suspect I may have messed up in one of the following ways:
- I assumed v as a value between -1 and 1 in the original algorithm refers to a height range. All I do in the other functions is restrict the height range based on the height of the angle cos(ang). I suspect doing this destroys the uniformed distribution. I am I little lacking in attention to really study up and follow through on this but I suspect it so be warned.
- Maybe my use of the cos(ang) as a height restriction does not accurately reflect the angle desired. It appears to be correct in testing but I am just eyeballing it.

By: nobody ( Nobody/Anonymous )
file RE: Random distribution of points / vectors  
2004-02-15 09:53

Here is also a the link I am using to the Wolfram site:
http://mathworld.wolfram.com/SpherePointPicking.html

 


metadata block
see also:

 

Correspondence about this page

This site may have errors. Don't use for critical systems.

Copyright (c) 1998-2023 Martin John Baker - All rights reserved - privacy policy.