• Main Page
  • Related Pages
  • Classes
  • Files
  • File List

WorldOfParticles.java

Go to the documentation of this file.
00001 
00002 import java.awt.Graphics;
00003 import java.awt.GraphicsConfiguration;
00004 import java.util.ArrayList;
00005 
00006 /**
00007  *  The <code>WorldOfParticles</code> is container for particles governed by 
00008  *  the common physical laws. Forces acting on particles belonging to this world
00009  *  are calculated in the main thread of the instance. The instance of the
00010  *  <code>WorldOfParticles</code> is rendered inside the <code>Component</code>, which
00011  *  acts as a parent.
00012  *   
00013  *  @author Mikica B Kocic
00014  */
00015 public class WorldOfParticles implements Runnable 
00016 {
00017     /**
00018      *  Provides rendering context interface for the <code>WorldOfParticles</code>.
00019      */
00020     public interface RenderingContext
00021     {
00022         public abstract void onParticleCountChanged( int newParticleCount );
00023         public abstract Barrier getBarrier ();
00024         public abstract GraphicsConfiguration getGraphicsConfiguration ();
00025     }
00026 
00027     //////////////////////////////////////////////////////////////////////////////////////
00028 
00029     /**
00030      *  Infinite Potential Barrier (2D-Box) class
00031      */
00032     protected class Barrier
00033     {
00034         public double xBeg;
00035         public double yBeg;
00036         public double xEnd;
00037         public double yEnd;
00038         
00039         public Barrier( double xBeg, double yBeg, double xEnd, double yEnd )
00040         {
00041             this.xBeg = xBeg; this.yBeg = yBeg;
00042             this.xEnd = xEnd; this.yEnd = yEnd;
00043         }
00044     }
00045     
00046     //////////////////////////////////////////////////////////////////////////////////////
00047     
00048     /**
00049      *  Collection of <code>Particles</code> that belongs to this world.
00050      */
00051     private ArrayList<Particle> particles = new ArrayList<Particle> ();
00052 
00053     /**
00054      *  World's time to 'real' world's time ratio. Slower if less then 1.
00055      */
00056     private volatile double timeScale = 0.5;
00057 
00058     /**
00059      *  Indicates whether forces between particles are calculated or not.
00060      *  The velocities of the particles are freezed if forces are not calculated.
00061      */
00062     private volatile boolean paused = false;
00063     
00064     /**
00065      *  Indicates whether to keep world's thread running or not.
00066      */
00067     private volatile boolean running = true;
00068     
00069     /**
00070      *  Each object (i.e. world) has it's own physical rules. Forces between particles 
00071      *  in our world are are calculated in object's main thread. 
00072      */
00073     private Thread mainThread;
00074 
00075     /**
00076      *  Particular instance with rendering context interface
00077      */
00078     private RenderingContext context;
00079 
00080     //////////////////////////////////////////////////////////////////////////////////////
00081 
00082     /**
00083      *  Creates and starts object's (world's) main thread.
00084      * 
00085      *  @param context  instance of the rendering context 
00086      */
00087     public WorldOfParticles( RenderingContext context ) 
00088     {
00089         this.context = context;
00090 
00091         mainThread = new Thread( this );
00092         mainThread.start ();
00093     }
00094 
00095     /**
00096      *  Returns indicator whether forces between particles are calculated or not.
00097      */
00098     public boolean isPaused ()
00099     {
00100         return paused;
00101     }
00102     
00103     /**
00104      *  Turns on/off calculations of forces between particles.
00105      */
00106     public void togglePaused ()
00107     { 
00108         paused = ! paused; 
00109     }
00110 
00111     /**
00112      *  Gets number of particles in our world.
00113      * 
00114      *  @return number of particles
00115      */
00116     public int getParticleCount ()
00117     {
00118         synchronized( this )
00119         {
00120             return particles.size ();
00121         }
00122     }
00123 
00124     /**
00125      *  Increments/decrements time scale
00126      *  
00127      *  @param factor  delta time
00128      */
00129     public void incTimeScale( double factor )
00130     {
00131         timeScale += factor;
00132         timeScale = Math.min( timeScale, 2.0 );
00133         timeScale = Math.max( timeScale, 0.1 );
00134     }
00135 
00136     /**
00137      *  Gets world's time to 'real' world's time ratio. 
00138      *  
00139      *  @return time scale; slower if less then 1.
00140      */
00141     public double getTimeScale ()
00142     {
00143         return timeScale;
00144     }
00145 
00146     /**
00147      *  Gets the GraphicsConfiguration associated with parent Component.
00148      * 
00149      * @return the GraphicsConfiguration used by parent's Component or null
00150      */
00151     public GraphicsConfiguration getGraphicsConfiguration()
00152     {
00153         return context.getGraphicsConfiguration ();
00154     }
00155 
00156     /** Adds one extra particle to the world.
00157      * 
00158      *  @param  M       mass of the <code>Particle</code> 
00159      *  @param  Q       electrical charge of the <code>Particle</code> 
00160      *  @param  X       initial position, x-component 
00161      *  @param  Y       initial position, y-component
00162      *  @param  R       radius range
00163      *  @param  T       life-time in seconds
00164      */
00165     public Particle addNewParticle( 
00166             double M, double Q, double X, double Y, double R, double T ) 
00167     {
00168         Particle p = null;
00169         
00170         synchronized( this )
00171         {
00172             p = new Particle ( this, M, Q, X, Y, R, T );
00173             
00174             particles.add ( p );
00175             
00176             // Inform parent that particle count has changed
00177             //
00178             context.onParticleCountChanged( particles.size () );
00179         }
00180         
00181         return p;
00182     }
00183 
00184     /** Removes the particle <code>p</code> from the world.
00185      * 
00186      *  @param  p    instance of the <code>Particle</code> to be removed 
00187      */
00188     public void removeParticle( Particle p ) 
00189     {
00190         synchronized( this )
00191         {
00192             particles.remove( p );
00193             
00194             /* Inform parent that number of particles has been changed
00195              */
00196             context.onParticleCountChanged( particles.size () );
00197         }
00198     }
00199 
00200     /** Dumps internal state for all particles to System.out (for debugging purposes).
00201      */
00202     public void dump ()
00203     {
00204         synchronized( this )
00205         {
00206             System.out.printf( "%8s %8s %8s %8s %8s %8s %8s\n", 
00207                     "lifetime", "xPos", "yPos", "vx", "vy", "ax", "ay" );
00208 
00209             for( Particle p : particles ) {
00210                p.dump ();
00211             }
00212             
00213             System.out.printf( "Total %d particles\n", getParticleCount () );
00214         }
00215     }
00216 
00217     /**
00218      *  Resets velocities for all particles to 0.
00219      */
00220     public void resetVelocities ()
00221     {
00222         synchronized( this )
00223         {
00224             for( Particle p : particles ) {
00225                 p.resetVelocity ();
00226              }
00227         }
00228     }
00229 
00230     /**
00231      *  Makes velocities for all particles to be centripetal to current
00232      *  particles' acceleration.
00233      */
00234     public void makeCentripetalVelocities ()
00235     {
00236         synchronized( this )
00237         {
00238             for( Particle p : particles ) {
00239                 p.makeCentripetalVelocity ();
00240              }
00241         }
00242     }
00243 
00244     /**
00245      *  Renders the world on <code>Graphics</code>.
00246      * 
00247      *  @param g         where to render
00248      *  @param annotate  annotate particle accelerations
00249      */
00250     public void paint( Graphics g, boolean annotate )
00251     {
00252         synchronized( this )
00253         {
00254             for( Particle p : particles ) {
00255                 p.paint( g, annotate );
00256              }
00257         }
00258     }
00259 
00260     /**
00261      *  Gets boundaries of infinite potential barrier keeping particles together.
00262      */
00263     public Barrier getBarrier ()
00264     {
00265         return context.getBarrier ();
00266     }
00267 
00268     /**
00269      *  Calculates forces acting on particles.
00270      */
00271     public void calculateInteractions ()
00272     {
00273         synchronized( this )
00274         {
00275             for ( Particle p : particles ) 
00276             {
00277                 /* The sum of all forces acting on particle p
00278                  */
00279                 p.resetForce ();
00280                 
00281                 /* Get sum of forces of interactions with other particles in the world
00282                  */
00283                 for ( Particle q : particles ) 
00284                 {
00285                     p.addForceFromParticle( q );
00286                 }
00287 
00288                 /* Apply summed forces 
00289                  */
00290                 p.applyForce ();
00291                 
00292                 /* Relax CPU usage
00293                  */
00294                 Thread.yield ();                
00295             }
00296             
00297         }
00298     }
00299 
00300     /**
00301      *  Main thread that calculates interactions (forces) between all particles
00302      *  in the world
00303      */
00304     @Override
00305     public void run () 
00306     {
00307         final int sleepMillis = 5; // ~200 Hz
00308         
00309         while( running )
00310         {
00311             try { 
00312                 Thread.sleep( sleepMillis );
00313             }
00314             catch( InterruptedException ie ) {
00315             }
00316 
00317             if ( ! paused ) {
00318                 calculateInteractions ();
00319             }
00320         }
00321     }
00322 }

Generated on Thu Dec 16 2010 12:28:54 for Multi-threaded World of Particles by  doxygen 1.7.2