Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs

Simulate fuzzy phenomena with particle systems

Use particle systems to simulate explosion rings, fireworks explosions, vapor trails, and more

  • Print
  • Feedback

Page 4 of 5

  • Accuracy: When you simulate with integer values, you'll lose some information due to truncation. My original integer-based vapor trail simulation resulted in unsightly empty streaks appearing in the trail. This was caused by the discrete nature of integers as opposed to the continuous nature of floating-point values.
  • Simplify transition to 3D: At some point, I'll want to transition this particle system software to 3D. A 3D graphics package often provides the capability to plot points in world coordinates using floating-point values.


The engine

The PS class is the engine of my particle system software. It models and generates particles, updates the particle system during an animation loop, and kills off those particles that die naturally or prematurely. After creating a Display object, your application or applet creates a PS object by invoking the PS(Display display) constructor to initialize the engine. Initialization saves the Display object for later access by the particle system update logic, creates four color tables describing shades of green, red, white, and yellow, and creates an array of particle objects that each describe an individual particle.

After creating the PS object, your animation logic can call the following PS methods:

  • void generateParticle(int type, int color_type, int lifetime, int age, double x, double y, double xv, double yv) attempts to generate a new particle for the particle system. Because PS has an upper limit (identified by constant PS.MAX_PARTICLES) on the maximum number of particles that can be modeled and manipulated, this method silently returns if there is no more room for a new particle.

    Each particle has a type that determines what happens to the particle's color (which can be thought of as signifying particle energy in simulations where it makes sense to think about energy) as the particle ages. Pass to type one of the constants PS.PARTICLE_TYPE_CONSTANT (particle's color remains the same throughout its life), PS.PARTICLE_TYPE_FADE (particle's color fades to black as the particle ages), or PS.PARTICLE_TYPE_FLICKERFADE (particle's color flickers while it fades to black as the particle ages).

    The range of colors that a particle can take on during its life (PS.PARTICLE_TYPE_FADE and PS.PARTICLE_TYPE_FLICKERFADE) or the brightest of these colors (PS.PARTICLE_TYPE_CONSTANT) is determined by the value passed to color_type. Pass to color_type one of the constants PS.PARTICLE_COLOR_TYPE_GREEN, PS.PARTICLE_COLOR_TYPE_RED, PS.PARTICLE_COLOR_TYPE_WHITE, or PS.PARTICLE_COLOR_TYPE_YELLOW. In addition to specifying values for type and color_type, you must specify values for six other parameters when generating a new particle:

    • lifetime determines the maximum number of animation frames that the particle will live. Pass a value greater than zero, otherwise an IllegalArgumentException results.
    • age determines the number of animation frames that the particle has already lived. Pass a value greater than or equal to zero and less than lifetime's value, otherwise an IllegalArgumentException results.
    • x and y determine the particle's initial position in world coordinates.
    • xv and yv determine the particle's horizontal and vertical velocities (and directions), respectively.
  • boolean isFinished() returns true if all particles are dead (the particle system is finished). Use this method to determine when to stop the animation loop.
  • void reset() resets the engine. All particles are marked dead (in case any are still alive from the premature termination of a prior simulation), and the gravity and wind are reset to their zero defaults. Call this method before entering the animation loop.
  • static int rnd(int min, int max) returns a random integer ranging from min inclusive to max inclusive. Use this method to randomly choose an initial particle age, a particle's departure angle, and so on.
  • void setGravity(double g) establishes the global gravity for all particles. Specify a negative g value to pull particles toward the bottom of the window.
  • void setWind(double w) establishes the global wind for all particles. Specify a positive w value to blow particles toward the window's right.
  • void update() updates the particle system by transitioning all particles to their next state. Call this method after clearing the display. The update() method determines if a particle has left the window's bounds by comparing the particle's position with Display's wl, wr, wb, and wt variables. If the particle's position exceeds these bounds, the particle is killed off. A particle is also killed off when it fades or flicker-fades to black, or when its age reaches its lifetime (whichever comes first). This method calls plot() to plot particles.


Let's find out how this engine is used in a simulation. The following code fragment creates a particle system that simulates a single white particle moving in an upper-left direction. It assumes the Display object was created by the earlier code fragment:

  • Print
  • Feedback

Resources