The Particle
encapsulates both particle physical properties and visual properties needed for rendering during animation.
More...
Public Member Functions | |
Particle (WorldOfParticles parent, double M, double Q, double X, double Y, double R, double T) | |
Creates a new instance of Particle. | |
double | getX () |
Gets the x-component of particle position. | |
double | getY () |
Gets the y-component of particle position. | |
double | getKineticEnergy () |
Gets the kinetic energy for the particle. | |
void | dump () |
Dumps x/y-components of position, velocity and acceleration to System.out . | |
void | resetVelocity () |
Resets velocity and acceleration for particle to 0. | |
void | makeCentripetalVelocity () |
Makes velocity centripetal to acceleration. | |
void | resetForce () |
Resets total force to 0 ( so it could be summed up again). | |
void | addForceFromParticle (Particle p) |
Calculates particular force that acts on this particle when interacting with some other remote particle p . | |
void | applyForce () |
Applies accumulated (summed up) total force on the particle. | |
void | moveParticle (double dx, double dy) |
Moves the particle (overriding forces) and resets its velocity. | |
void | forceBarrier (WorldOfParticles.Barrier barrier) |
Keeps the particle inside infinite potential barrier. | |
void | paint (Graphics gr, boolean annotate) |
Renders the particle in Graphics context. | |
void | kill () |
Kills the particle by setting particle's life time to 0. | |
void | interruptibleSleep (long millis) |
Thread.sleep wrapper. | |
void | run () |
Main thread that solves Newton's laws of motion, effectively moving the particle in the parent WorldOfParticles (unless the world is paused i.e. | |
Private Member Functions | |
void | initBlurTrail (int size) |
Creates blur trail context (faded ghost images for particle) | |
void | integrateNewtonLaws (double dT) |
Moves the particle using numerical integration of differential equations of the motion by Euler's method. | |
void | drawGradCircle (Graphics2D g2d, float x, float y, float radius, Color color) |
Draws the circle with radial gradient from the center. | |
void | createParticleImage () |
Creates the image of the particle that will be animated. | |
Private Attributes | |
WorldOfParticles | world |
Particle always belong to some world of particles. | |
double | mass = 1 |
double | charge = 1 |
double | radius = 1 |
double | xPos = 0 |
double | yPos = 0 |
double | vx = 0 |
double | vy = 0 |
double | vsq = 0 |
double | ax = 0 |
double | ay = 0 |
double | asq = 0 |
double | Fx = 0 |
double | Fy = 0 |
double | lifeTime = Double.POSITIVE_INFINITY |
Particle's life time. | |
Thread | mainThread |
Each object (i.e. | |
BufferedImage | image = null |
Image of the particle that is rendered during animation. | |
Color | color = Color.BLUE |
Particle color. | |
int | aliasedEdges = 10 |
Depth (levels) of anti-aliased edges (anti-aliasing disabled if 0). | |
boolean | showTrail = false |
int | trailSize = 0 |
int | trailRatioC = 0 |
int | trailRatio = 0 |
int[] | trailX = null |
int[] | trailY = null |
float[] | trailFade = null |
Static Private Attributes | |
static final double | k_e = 5e6 |
static final double | k_G = 1e-5 |
static final double | k_x = 1e-4 |
static final double | minRsq = 91 |
static final double | maxVsq = 4e4 |
The Particle
encapsulates both particle physical properties and visual properties needed for rendering during animation.
Physical behavior of the particle is governed by gravitational and electrical forces conducted by Newton's law of motion in form of differential equations (applied to particle's mass, charge, position, velocity and acceleration) and solved (integrated) using numerical Euler's method. Each particle has separate thread integrating equations thus effectively "moving" particle.
Forces acting on the particle are set by particle's WorldOfParticle
that overviews interactions between all particles and calculates summary forces for each single particles.
The resulting 'motion' of the particle is then rendered to WorldOfParticle
's Graphics
context. Particle image is generated once and kept in image
internal object. Charged particles are either rendered in Red (positive) or Green (negative). Neutral particles are rendered in Blue.
Definition at line 37 of file Particle.java.
Particle.Particle | ( | WorldOfParticles | parent, |
double | M, | ||
double | Q, | ||
double | X, | ||
double | Y, | ||
double | R, | ||
double | T | ||
) |
Creates a new instance of Particle.
parent | the world to which Particle belongs to |
M | mass of the Particle |
Q | electrical charge of the Particle |
X | initial position, x-component |
Y | initial position, y-component |
R | radius range (0 for random radius) |
T | life time in seconds |
Definition at line 123 of file Particle.java.
References asq, ax, ay, charge, color, initBlurTrail(), lifeTime, mainThread, mass, radius, vsq, vx, vy, world, xPos, and yPos.
{ world = parent; mass = M; charge = Q; lifeTime = T; /* Initial position */ xPos = X; yPos = Y; /* Random initial velocity */ vx = -100 + 200 * Math.random (); vy = -100 + 200 * Math.random (); vsq = Math.pow( vx, 2 ) + Math.pow( vy, 2 ); /* No initial acceleration */ ax = 0; ay = 0; asq = 0; /* If the radius is not specified (<=0) then randomize radius */ radius = R > 0 ? R : 10.0 + ( 10.0 - R ) * Math.random (); /* Set color depending on charge: Blue (0), Green (+) Red (-) */ if ( charge == 0 ) { color = new Color( 0, 0, 1f ); } else if ( charge > 0 ) { color = new Color( (float)charge, 0, 0 ); } else { color = new Color( 0, -(float)charge, 0 ); } /* Setup ghost trail */ initBlurTrail( 10 ); /* Start moving (solving differential equations for) the particle... */ mainThread = new Thread( this ); mainThread.start (); }
void Particle.addForceFromParticle | ( | Particle | p ) |
Calculates particular force that acts on this
particle when interacting with some other remote particle p
.
p | remote particle |
Definition at line 273 of file Particle.java.
References charge, Fx, Fy, k_e, k_G, mass, minRsq, xPos, and yPos.
{ if ( p == this ) { return; } /* Rsq = squared distance R between particles */ double Rsq = Math.pow( p.xPos - xPos, 2 ) + Math.pow( p.yPos - yPos, 2 ); /* Quantum-mechanics allows distances between particles above some limit * (like Pauli's Exclusion Principle and nuclear forces) * This suppresses that we have infinite interaction forces between particles. */ if ( Rsq < minRsq ) { Rsq = minRsq; } /* Radius vector Cartesian coordinate components */ double cos = ( p.xPos - xPos ) / Math.sqrt( Rsq ); double sin = ( p.yPos - yPos ) / Math.sqrt( Rsq ); /* Coulomb's force between electrical charges */ double e_force = -k_e * charge * p.charge / Rsq; Fx += e_force * cos; Fy += e_force * sin; /* Gravitational force between particle masses */ double g_force = k_G * mass * p.mass / Rsq; Fx += g_force * cos; Fy += g_force * sin; }
void Particle.applyForce | ( | ) |
void Particle.createParticleImage | ( | ) | [private] |
Creates the image of the particle that will be animated.
Definition at line 419 of file Particle.java.
References aliasedEdges, color, drawGradCircle(), WorldOfParticles.getGraphicsConfiguration(), image, radius, and world.
Referenced by paint().
{ GraphicsConfiguration gc = world.getGraphicsConfiguration (); if ( gc == null ) { return; } int diameter = (int)( radius * 2 ); image = gc.createCompatibleImage( diameter, diameter, Transparency.TRANSLUCENT ); Graphics2D gImg = image.createGraphics (); if ( aliasedEdges > 0 ) { drawGradCircle(gImg, (int)radius, (int)radius, (int)radius, color ); } else { gImg.setColor( color ); gImg.fillOval( 0, 0, diameter, diameter ); } gImg.dispose (); }
void Particle.drawGradCircle | ( | Graphics2D | g2d, |
float | x, | ||
float | y, | ||
float | radius, | ||
Color | color | ||
) | [private] |
Draws the circle with radial gradient from the center.
Definition at line 393 of file Particle.java.
Referenced by createParticleImage().
{ Point2D center = new Point2D.Float( x, y ); float[] dist = { 0.0f, 1.0f }; float[] c = { color.getRed()/255f, color.getGreen()/255f, color.getBlue()/255f }; Color[] colors = { new Color( c[0] * 1.0f, c[1] * 1.0f, c[2] * 1.0f, 1.0f ), // base color new Color( c[0] * 0.8f, c[1] * 0.8f, c[2] * 0.8f, 0.0f ) // fade out }; g2d.setPaint( new RadialGradientPaint( center, radius, dist, colors, CycleMethod.NO_CYCLE ) ); g2d.fill( new Ellipse2D.Float( x - radius, y - radius, 2*radius, 2*radius ) ); }
void Particle.dump | ( | ) |
void Particle.forceBarrier | ( | WorldOfParticles.Barrier | barrier ) |
Keeps the particle inside infinite potential barrier.
barrier | boundaries of infinite potential barrier given as array {x1,y1,x2,y2} of coordinates |
Definition at line 347 of file Particle.java.
References vx, vy, xPos, and yPos.
Referenced by integrateNewtonLaws().
{ final double k = 0.5; // in-elastic collision coefficient if ( xPos < barrier.xBeg ) { xPos = barrier.xBeg; vx = -k * vx; } else if ( xPos > barrier.xEnd ) { xPos = barrier.xEnd; vx = -k * vx ; } if ( yPos < barrier.yBeg ) { yPos = barrier.yBeg; vy = -k * vy; } else if ( yPos > barrier.yEnd ) { yPos = barrier.yEnd; vy = -k * vy; } }
double Particle.getKineticEnergy | ( | ) |
double Particle.getX | ( | ) |
Gets the x-component of particle position.
Definition at line 179 of file Particle.java.
References xPos.
{ return xPos; }
double Particle.getY | ( | ) |
Gets the y-component of particle position.
Definition at line 185 of file Particle.java.
References yPos.
{ return yPos; }
void Particle.initBlurTrail | ( | int | size ) | [private] |
Creates blur trail context (faded ghost images for particle)
size | trail depth (number of ghost images to show) |
Definition at line 203 of file Particle.java.
References showTrail, trailFade, trailRatio, trailRatioC, trailSize, trailX, and trailY.
Referenced by Particle().
{ showTrail = true; trailSize = size; trailRatioC = 3; trailRatio = 0; /* Create blur arrays with x,y positions and fading for ghost images */ trailX = new int [ trailSize ]; trailY = new int [ trailSize ]; trailFade = new float[ trailSize ]; float incrementalFactor = .2f / ( trailSize + 1 ); for( int i = 0; i < trailSize; ++i ) { /* Default values for positions -1 indicates * not to render these until with real values */ trailX[ i ] = -1; trailY[ i ] = -1; /* The ghost is more faded as it is further away from the particle */ trailFade[i] = ( .2f - incrementalFactor ) - i * incrementalFactor; } }
void Particle.integrateNewtonLaws | ( | double | dT ) | [private] |
Moves the particle using numerical integration of differential equations of the motion by Euler's method.
dT | integration interval in seconds |
Definition at line 374 of file Particle.java.
References ax, ay, forceBarrier(), WorldOfParticles.getBarrier(), vsq, vx, vy, world, xPos, and yPos.
Referenced by run().
void Particle.interruptibleSleep | ( | long | millis ) |
Thread.sleep wrapper.
Definition at line 565 of file Particle.java.
References lifeTime.
Referenced by run().
{ synchronized( this ) { try { Thread.sleep( 10 ); } catch( InterruptedException ie ) { lifeTime = 0; // kill thread } } }
void Particle.kill | ( | ) |
Kills the particle by setting particle's life time to 0.
Particle is dead (moving thread exits) if its life time < 0.
Definition at line 554 of file Particle.java.
References lifeTime, and mainThread.
{ lifeTime = 0.0; if ( mainThread != null ) { mainThread.interrupt (); } }
void Particle.makeCentripetalVelocity | ( | ) |
void Particle.moveParticle | ( | double | dx, |
double | dy | ||
) |
Moves the particle (overriding forces) and resets its velocity.
dx | delta x-position |
dy | delta y-position |
Definition at line 335 of file Particle.java.
References resetVelocity(), xPos, and yPos.
Referenced by JPWorld.keyPressed().
{ xPos += dx; yPos += dy; resetVelocity (); }
void Particle.paint | ( | Graphics | gr, |
boolean | annotate | ||
) |
Renders the particle in Graphics context.
gr | the Graphics context in which particle is rendered |
annotate | indicator whether additional info about particle's acceleration is displayed or not |
Definition at line 451 of file Particle.java.
References asq, ax, ay, charge, color, createParticleImage(), image, lifeTime, radius, showTrail, trailFade, trailRatio, trailRatioC, trailSize, trailX, trailY, xPos, and yPos.
{ if ( image == null ) { createParticleImage(); if ( image == null ) { return; } } Graphics2D g = (Graphics2D)gr.create (); /* Convert (px,py) at the center of the particle to (x,y) as base of the image */ int px = (int)xPos; int py = (int)yPos; int x = (int)( xPos - radius ); int y = (int)( yPos - radius ); /* Base fade for the particle is derived its life time (fades out at the end). */ float baseFade = (float)( lifeTime < 0 ? 0 : lifeTime > 1 ? 1 : lifeTime ); if ( showTrail ) { /* Draw previous locations of the particle as a trail of ghost images */ for( int i = 0; i < trailSize; ++i ) { if( trailX[i] >= 0 ) { /* Render each particle ghost with fading */ g.setComposite( AlphaComposite.SrcOver.derive( baseFade * trailFade[i] ) ); g.drawImage( image, trailX[i], trailY[i], null ); } } --trailRatio; if ( trailRatio <= 0 ) { trailRatio = trailRatioC; /* Shift the ghost trail positions in array (from newest to eldest) */ for( int i = trailSize - 1; i > 0; --i ) { trailX[ i ] = trailX[ i - 1 ]; trailY[ i ] = trailY[ i - 1 ]; } trailX[ 0 ] = x; trailY[ 0 ] = y; } } g.setComposite( AlphaComposite.SrcOver.derive( baseFade ) ); if ( annotate && asq > 0.0 ) { /* Vector pointing in force direction with length proportional to * the logarithm of acceleration (with small linear fix for dramatic purpose) */ int dx = asq < 1e-9 ? 0 : (int)( 1e-3 * ax + 3 * ax * Math.log( 1 + asq ) / Math.sqrt( asq ) ); int dy = asq < 1e-9 ? 0 : (int)( 1e-3 * ay + 3 * ay * Math.log( 1 + asq ) / Math.sqrt( asq ) ); Color cText = new Color( color.getRGB () ).darker (); /* Draw acceleration vector */ g.setColor( cText.darker () ); g.drawLine( px, py, px + dx, py + dy ); g.drawArc( px + dx - 4, py + dy - 4, 8, 8, 0, 360 ); /* Show acceleration values */ g.setColor( cText ); Font f = new Font( Font.MONOSPACED, Font.PLAIN, 14 ); // TODO: static? g.setFont( f ); g.drawString( String.format( "%+7.1f", ax ), px + dx - 4, py + dy - 4 - 14 ); g.drawString( String.format( "%+7.1f", ay ), px + dx - 4, py + dy - 4 ); } g.drawImage( image, x, y, null ); if ( annotate && true ) { g.setColor( Color.BLACK ); int R = (int)( radius / 3 ); if ( charge != 0 ) { g.drawLine( px - R, py, px + R, py ); } if ( charge > 0 ) { g.drawLine( px, py - R, px, py + R ); } } g.dispose (); }
void Particle.resetForce | ( | ) |
void Particle.resetVelocity | ( | ) |
Resets velocity and acceleration for particle to 0.
Definition at line 245 of file Particle.java.
Referenced by moveParticle().
void Particle.run | ( | ) |
Main thread that solves Newton's laws of motion, effectively moving the particle in the parent WorldOfParticles
(unless the world is paused i.e.
freezed). Thread also keeps particle's life time and after it expires, particle is removed from the belonging world.
Definition at line 585 of file Particle.java.
References WorldOfParticles.getTimeScale(), integrateNewtonLaws(), interruptibleSleep(), WorldOfParticles.isPaused(), lifeTime, WorldOfParticles.removeParticle(), and world.
{ final int sleepMillis = 5; // ~200 Hz long oldTime = System.nanoTime (); while( lifeTime >= 0 ) // particle is dead when its life time becomes lt. 0 { interruptibleSleep( sleepMillis ); long currentTime = System.nanoTime (); /* Calculates sleep time dT in seconds. dT is not necessarily the same as * the intentioned sleep time. It can be scaled further to speed up or * slow-down particle's motion. */ double dT = world.getTimeScale () * (double)( currentTime - oldTime ) / 1e9; if ( ! world.isPaused () ) { integrateNewtonLaws( dT ); } lifeTime -= dT; oldTime = currentTime; } /* Cleans-up dead particle */ world.removeParticle( this ); }
int Particle.aliasedEdges = 10 [private] |
Depth (levels) of anti-aliased edges (anti-aliasing disabled if 0).
Definition at line 97 of file Particle.java.
Referenced by createParticleImage().
double Particle.asq = 0 [private] |
Definition at line 66 of file Particle.java.
Referenced by applyForce(), paint(), and Particle().
double Particle.ax = 0 [private] |
Definition at line 64 of file Particle.java.
Referenced by applyForce(), dump(), integrateNewtonLaws(), makeCentripetalVelocity(), paint(), and Particle().
double Particle.ay = 0 [private] |
Definition at line 65 of file Particle.java.
Referenced by applyForce(), dump(), integrateNewtonLaws(), makeCentripetalVelocity(), paint(), and Particle().
double Particle.charge = 1 [private] |
Definition at line 54 of file Particle.java.
Referenced by addForceFromParticle(), paint(), and Particle().
Color Particle.color = Color.BLUE [private] |
Particle color.
Definition at line 92 of file Particle.java.
Referenced by createParticleImage(), paint(), and Particle().
double Particle.Fx = 0 [private] |
Definition at line 67 of file Particle.java.
Referenced by addForceFromParticle(), applyForce(), and resetForce().
double Particle.Fy = 0 [private] |
Definition at line 68 of file Particle.java.
Referenced by addForceFromParticle(), applyForce(), and resetForce().
BufferedImage Particle.image = null [private] |
Image of the particle that is rendered during animation.
Definition at line 87 of file Particle.java.
Referenced by createParticleImage(), and paint().
final double Particle.k_e = 5e6 [static, private] |
Definition at line 39 of file Particle.java.
Referenced by addForceFromParticle().
final double Particle.k_G = 1e-5 [static, private] |
Definition at line 40 of file Particle.java.
Referenced by addForceFromParticle().
final double Particle.k_x = 1e-4 [static, private] |
Definition at line 41 of file Particle.java.
Referenced by applyForce().
double Particle.lifeTime = Double.POSITIVE_INFINITY [private] |
Particle's life time.
Must be positive number or positive infinity. Negative values indicates dead particle.
Definition at line 74 of file Particle.java.
Referenced by dump(), interruptibleSleep(), kill(), paint(), Particle(), and run().
Thread Particle.mainThread [private] |
Each object (i.e.
particle) follows the Newton's laws of motion (differential equations) that are solved (integrated) in object's (particle's) main thread.
Definition at line 80 of file Particle.java.
Referenced by kill(), and Particle().
double Particle.mass = 1 [private] |
Definition at line 53 of file Particle.java.
Referenced by addForceFromParticle(), applyForce(), getKineticEnergy(), and Particle().
final double Particle.maxVsq = 4e4 [static, private] |
Definition at line 43 of file Particle.java.
Referenced by applyForce().
final double Particle.minRsq = 91 [static, private] |
Definition at line 42 of file Particle.java.
Referenced by addForceFromParticle().
double Particle.radius = 1 [private] |
Definition at line 55 of file Particle.java.
Referenced by createParticleImage(), paint(), and Particle().
boolean Particle.showTrail = false [private] |
Definition at line 102 of file Particle.java.
Referenced by initBlurTrail(), and paint().
float [] Particle.trailFade = null [private] |
Definition at line 108 of file Particle.java.
Referenced by initBlurTrail(), and paint().
int Particle.trailRatio = 0 [private] |
Definition at line 105 of file Particle.java.
Referenced by initBlurTrail(), and paint().
int Particle.trailRatioC = 0 [private] |
Definition at line 104 of file Particle.java.
Referenced by initBlurTrail(), and paint().
int Particle.trailSize = 0 [private] |
Definition at line 103 of file Particle.java.
Referenced by initBlurTrail(), and paint().
int [] Particle.trailX = null [private] |
Definition at line 106 of file Particle.java.
Referenced by initBlurTrail(), and paint().
int [] Particle.trailY = null [private] |
Definition at line 107 of file Particle.java.
Referenced by initBlurTrail(), and paint().
double Particle.vsq = 0 [private] |
Definition at line 63 of file Particle.java.
Referenced by applyForce(), getKineticEnergy(), integrateNewtonLaws(), Particle(), and resetVelocity().
double Particle.vx = 0 [private] |
Definition at line 61 of file Particle.java.
Referenced by applyForce(), dump(), forceBarrier(), integrateNewtonLaws(), makeCentripetalVelocity(), Particle(), and resetVelocity().
double Particle.vy = 0 [private] |
Definition at line 62 of file Particle.java.
Referenced by applyForce(), dump(), forceBarrier(), integrateNewtonLaws(), makeCentripetalVelocity(), Particle(), and resetVelocity().
WorldOfParticles Particle.world [private] |
Particle always belong to some world of particles.
This is our world.
Definition at line 48 of file Particle.java.
Referenced by createParticleImage(), integrateNewtonLaws(), Particle(), and run().
double Particle.xPos = 0 [private] |
Definition at line 59 of file Particle.java.
Referenced by addForceFromParticle(), dump(), forceBarrier(), getX(), integrateNewtonLaws(), moveParticle(), paint(), and Particle().
double Particle.yPos = 0 [private] |
Definition at line 60 of file Particle.java.
Referenced by addForceFromParticle(), dump(), forceBarrier(), getY(), integrateNewtonLaws(), moveParticle(), paint(), and Particle().