Approach:

First the motion of a single particle is described. Following this is a discussion of the interaction of the particles with walls and how to generate the particles.

Moving each particle:

In this program each particle is treated as a point mass subject to Newtonian forces. At each time step of the simulation the particles forces, velocity and position are updated using Euler's method for numerical integration.

Each particle is represented as a node in a linked list. At each time step the net force is calculated as follows:

F = sum( external forces ) = mass*net acceleration

F = m a

From this we can get the net acceleration of the particle and determine its change in velocity over a small time interval:

a = F/m = dv/dt

dv = a*dt;

v= v+ dv

From the velocity the small changes in position can be calculated as follows:

dx/dt = v

dx = v* dt

x = x + dx

Using these equations velocity and position updates the particles position over time can be tracked.

The forces model in this simulation include gravity(Fgrav), wind(Fext), and drag(Fdrag). Drag is a force proportional to the negative of the velocity and thus acts to continuously slow a particle down:

Fdrag = -k v

In this simulation the force equation is:

Fnet = Fgrav + Fdrag + Fext

Also important is the forces a particle undergoes when colliding with a wall.

Collision detection:

Since the particles in this system are contained within a box, interaction of the particles with the walls of the environment must be included in the system. When a particle hits a wall it must bounce off. This is done by representing each wall as a plane, though a point P and its normal N, a unit normal pointing to the interior space.

If a particle is moving toward the wall and is on or behind the wall it collides with the wall and its velocity(v) and position(Ppart) must be adjusted. In terms of the geometry of the scene this means:

Moving towards the wall = v* N < 0

Behind the wall = (Ppart - P) * N <=0

(* denotes dot product )

Thus if (v * N < 0) and (Ppart -P) * N <= 0 then a particle collides with the wall. When a particle collides with a wall it undergoes an impulsive force to correct its direction. This force when applied over a small time interval is strong enough to change the direction of the particle so that it no longer moves into the wall. It can also change the direction of the particle so that it bounces away. The impulse force also must cancel out the component of the net forces acting normal to the surface. To do this the impulsive force must be:

Fimp = -(1+a)(v*N)N/dt - (Fnet*N)N

Where a is a constant ranging for 0 to 1 that controls the elasticity of the collision. If a = 0 we have a perfectly in inelastic collision, and if a 1 we have a perfectly elastic collision

So at the next time step the change in velocity is:

dv = -(1+a)(v*N)N - ((Fnet*N)N + Fnet)dt

dv =- (1+a)(v*N)N - ((Fpar)dt

Where Fpar is the component of the force parallel to the plane. This dv will change the velocity so the particle won't further penetrate the wall and cancel out any forces normal to the wall.

To update the particle the component of the velocity along the normal of the wall can be adjusted by (1+a)(v*N)N. (since velocity is updated after force in this simulation we only need to update the velocity). Once this is done the particle is free to move again as it will move in the proper direction ( away from the wall) and is subject to forces. Due to numerical error some times the particle will jump behind a wall. One could attempt to reposition the particle by finding its exact point of intersection with the plane up to a tolerance (bisection) but this approach would be to costly. Instead we just bring the particle back to the plane by:

xcorr = x - ((x-p) * N)N

Where p is a point on the plane and N is the unit normal of the plane. We found in practice that if dt is small just updating in this way is sufficient for visual acceptance.

Particle generation:

Now that an individual particle can be traced through the scene we must manage a collection of particles to give the effect of a water fountain. To due this random number generators must be used as each particle cannot be identical.

The randomness we introduce into the system is :

Random Birth rate

Random Life time

Random initial direction and velocity

When generating a spout we give each particle an in initial life time, and velocity and perturb it as follow:

X = X + rand;

Thus the velocity and life time will be perturbations from some average value. The random number generator used is a guassian distribution thus particles velocities and life times will be centered around an average value, giving a more spout like effect.

To implement the random birth rate an accumulator, initially set to zero, is updated by the time step + a random perturbation. When the accumulator exceeds a threshold ( 1/Birthrate), a particle is born and the accumulator is reset to zero. So at each time step:

accum = accum + dtime + randDelta()

if (accum > 1/birthrate ) {

create particle;

accum = accum - 1/birthrate

}

Hosted by www.Geocities.ws

1