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
00008
00009
00010
00011
00012
00013
00014
00015 public class WorldOfParticles implements Runnable
00016 {
00017
00018
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
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
00050
00051 private ArrayList<Particle> particles = new ArrayList<Particle> ();
00052
00053
00054
00055
00056 private volatile double timeScale = 0.5;
00057
00058
00059
00060
00061
00062 private volatile boolean paused = false;
00063
00064
00065
00066
00067 private volatile boolean running = true;
00068
00069
00070
00071
00072
00073 private Thread mainThread;
00074
00075
00076
00077
00078 private RenderingContext context;
00079
00080
00081
00082
00083
00084
00085
00086
00087 public WorldOfParticles( RenderingContext context )
00088 {
00089 this.context = context;
00090
00091 mainThread = new Thread( this );
00092 mainThread.start ();
00093 }
00094
00095
00096
00097
00098 public boolean isPaused ()
00099 {
00100 return paused;
00101 }
00102
00103
00104
00105
00106 public void togglePaused ()
00107 {
00108 paused = ! paused;
00109 }
00110
00111
00112
00113
00114
00115
00116 public int getParticleCount ()
00117 {
00118 synchronized( this )
00119 {
00120 return particles.size ();
00121 }
00122 }
00123
00124
00125
00126
00127
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
00138
00139
00140
00141 public double getTimeScale ()
00142 {
00143 return timeScale;
00144 }
00145
00146
00147
00148
00149
00150
00151 public GraphicsConfiguration getGraphicsConfiguration()
00152 {
00153 return context.getGraphicsConfiguration ();
00154 }
00155
00156
00157
00158
00159
00160
00161
00162
00163
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
00177
00178 context.onParticleCountChanged( particles.size () );
00179 }
00180
00181 return p;
00182 }
00183
00184
00185
00186
00187
00188 public void removeParticle( Particle p )
00189 {
00190 synchronized( this )
00191 {
00192 particles.remove( p );
00193
00194
00195
00196 context.onParticleCountChanged( particles.size () );
00197 }
00198 }
00199
00200
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
00219
00220 public void resetVelocities ()
00221 {
00222 synchronized( this )
00223 {
00224 for( Particle p : particles ) {
00225 p.resetVelocity ();
00226 }
00227 }
00228 }
00229
00230
00231
00232
00233
00234 public void makeCentripetalVelocities ()
00235 {
00236 synchronized( this )
00237 {
00238 for( Particle p : particles ) {
00239 p.makeCentripetalVelocity ();
00240 }
00241 }
00242 }
00243
00244
00245
00246
00247
00248
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
00262
00263 public Barrier getBarrier ()
00264 {
00265 return context.getBarrier ();
00266 }
00267
00268
00269
00270
00271 public void calculateInteractions ()
00272 {
00273 synchronized( this )
00274 {
00275 for ( Particle p : particles )
00276 {
00277
00278
00279 p.resetForce ();
00280
00281
00282
00283 for ( Particle q : particles )
00284 {
00285 p.addForceFromParticle( q );
00286 }
00287
00288
00289
00290 p.applyForce ();
00291
00292
00293
00294 Thread.yield ();
00295 }
00296
00297 }
00298 }
00299
00300
00301
00302
00303
00304 @Override
00305 public void run ()
00306 {
00307 final int sleepMillis = 5;
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 }