This is the web version of EJS interface
EJS version 4.3.0
1. CaptureTools=false
2. DataTools=false
3. LanguageTools=false
4. EmersionSupport=false
5. UseInterpreter=true
6. AuxiliaryFiles=_data/moon2.gif;_data/play.gif;_data/pause.gif;_data/reset.gif;
7. DetectedFiles=_data/moon2.gif;_data/pause.gif;_data/play.gif;_data/reset.gif;

# Particles 3D

This is a simulation of a set of particles moving freely inside a 3D cube and colliding with a moveable floor.

The state it is now, the example is just a show-off of the 3D capabilities of Ejs, but... can you think of an application to gas dynamics?

NameValueTypeDimension
NameValueTypeDimension
NameValueTypeDimension
NameValueTypeDimension
for (int i=0; i<wallPoints; i++) { for (int j=0; j<wallPoints; j++) { wallData[i][j][0] = minimum + i*(maximum-minimum)/(wallPoints-1); wallData[i][j][1] = minimum + j*(maximum-minimum)/(wallPoints-1); } }
double factor = boxSize/10; for (int i=0; i<nx; i++) { for (int j=0; j<ny; j++) { for (int k=0; k<nz; k++) { field[i][j][k][0] = minimum + i*(maximum-minimum)/(nx-1); field[i][j][k][1] = minimum + j*(maximum-minimum)/(ny-1); field[i][j][k][2] = minimum + k*(maximum-minimum)/(nz-1); double r = field[i][j][k][0]*field[i][j][k][0] + field[i][j][k][1]*field[i][j][k][1] + field[i][j][k][2]*field[i][j][k][2]; r = Math.sqrt(r); if (Math.abs(r)<1.0e-4) field[i][j][k][3] = field[i][j][k][4] = field[i][j][k][5] = 0; else { field[i][j][k][3] = -field[i][j][k][0]*factor/r; field[i][j][k][4] = -field[i][j][k][1]*factor/r; field[i][j][k][5] = -field[i][j][k][2]*factor/r; } field[i][j][k][6] = r; } } }
for (int i=0; i<wallPoints; i++) { for (int j=0; j<wallPoints; j++) { wallData[i][j][2] = wallz; } }
double factor = boxSize/10; double cons = Math.sin(time); for (int i=0; i<nx; i++) { for (int j=0; j<ny; j++) { for (int k=0; k<nz; k++) { double r = field[i][j][k][0]*field[i][j][k][0] + field[i][j][k][1]*field[i][j][k][1] + field[i][j][k][2]*field[i][j][k][2]; r = Math.sqrt(r); if (Math.abs(r)<1.0e-4) field[i][j][k][3] = field[i][j][k][4] = field[i][j][k][5] = 0; else { field[i][j][k][3] = -cons*field[i][j][k][0]*factor/r; field[i][j][k][4] = -cons*field[i][j][k][1]*factor/r; field[i][j][k][5] = -cons*field[i][j][k][2]*factor/r; } field[i][j][k][6] = cons*r; } } }
void checkBoxIntersection (int i) { double ref = maximum; if (x[i]>ref) { x[i] = (ref+ref)-x[i]; vx[i] = -vx[i]; } ref = minimum; if (x[i]<ref) { x[i] = (ref+ref)-x[i]; vx[i] = -vx[i]; } ref = maximum; if (y[i]>ref) { y[i] = (ref+ref)-y[i]; vy[i] = -vy[i];} ref = minimum; if (y[i]<ref) { y[i] = (ref+ref)-y[i]; vy[i] = -vy[i];} ref = maximum; if (z[i]>ref) { z[i] = (ref+ref)-z[i]; vz[i] = -vz[i];} ref = minimum; if (z[i]<ref) { z[i] = (ref+ref)-z[i]; vz[i] = -vz[i];} }
void checkWallIntersection (int i) { double ref = wallz; if ( (z[i]>=ref && zPrevious[i]<ref) || (z[i]<=ref && zPrevious[i]>ref) ) { zPrevious[i] = z[i]; z[i] = (ref+ref)-z[i]; vz[i] = -vz[i]; } } public void movingWall () { for (int i=0; i<numParticles; i++) { if (z[i]<wallz) { zPrevious[i] = z[i] = wallz; vz[i] = Math.abs(vz[i]); } } }
public void removeParticles () { for (int i=0; i<maxParticles; i++) { visible[i] = showVel[i] = showTrace[i] = false; } numParticles = 0; } public void addParticles () { double size = (maximum-minimum); double sizeZ = (maximum-wallz); for (int i=0; i<addHowMany; i++) { addAParticle (minimum+size*Math.random (), minimum+size*Math.random (), wallz+sizeZ*Math.random (), speed*(Math.random ()-0.5), speed*(Math.random ()-0.5), speed*(Math.random ()-0.5)); } } public void addAParticle (double x1, double y1, double z1, double vx1, double vy1, double vz1) { if (numParticles>=maxParticles) return; x[numParticles] = x1; y[numParticles] = y1; z[numParticles] = z1; vx[numParticles] = vx1; vy[numParticles] = vy1; vz[numParticles] = vz1; diameter[numParticles] = defaultSize; visible[numParticles] = true; showVel[numParticles] = showSpeeds; showTrace[numParticles] = showTraces; numParticles++; }
public void collapse () { double zpos = wallz + (maximum-wallz)/2; for (int i=0; i<maxParticles; i++) { x[i] = 0.0; y[i] = 0.0; z[i] = zpos; vx[i] = speed*(Math.random ()-0.5); vy[i] = speed*(Math.random ()-0.5); vz[i] = speed*(Math.random ()-0.5); } _clearView(); }
public void showVelocities () { for (int i=0; i<numParticles; i++) showVel[i] = showSpeeds; } public void showTraces () { for (int i=0; i<numParticles; i++) showTrace[i] = showTraces; // _clearView(); // This clears previous traces _clearView(); }
EJSVIEW: Click link to view it's content
 Control variables:(testing)double
 title = Particles in 3D layout = border visible = true location = "139,105" size = "489,380"
 position = west layout = border
 position = north layout = grid:0,1,0,0 background = 200,220,208
 image = "_data/play.gif" enabled = _isPaused action = _play() size = "90,35"
 image = "_data/pause.gif" enabled = _isPlaying action = _pause() size = "90,35"
 image = "_data/reset.gif" action = _reset() size = "90,35"
 text = Collapse action = collapse() background = DARKGRAY foreground = 64,255,0
 text = Clear action = removeParticles() background = DARKGRAY foreground = 64,255,0
 text = Add action = addParticles() background = DARKGRAY foreground = 64,255,0
 variable = addHowMany format = 0 background = BLACK foreground = YELLOW
 variable = showSpeeds text = Velocities action = showVelocities() foreground = 128,0,0
 variable = showTraces text = Traces action = showTraces() foreground = 128,0,0
 variable = rotate text = Rotate foreground = 128,0,0
 variable = showField selected = false text = Field foreground = 128,0,0
 position = east variable = wallz minimum = minimum maximum = maximum format = Z = 0.# orientation = vertical ticks = 9 ticksFormat = 0.# dragaction = movingWall() background = GRAY foreground = YELLOW
 position = center minimumX = minimum maximumX = maximum minimumY = minimum maximumY = maximum minimumZ = minimum maximumZ = maximum alpha = alpha beta = beta zoom = zoom background = black foreground = blue
 data = wallData secondaryColor = darkGray color = darkGray
 elementnumber = maxParticles x = x y = y z = z sizex = vx sizey = vy sizez = vz visible = showVel color = cyan
 elementnumber = maxParticles x = x y = y z = z sizex = diameter sizey = diameter sizez = diameter scalex = 3.0 scaley = 3.0 scalez = 3.0 visible = visible enabled = true image = "_data/moon2.gif" elementposition = CENTERED
 elementnumber = maxParticles x = x y = y z = z visible = showTrace maxpoints = 20 norepeat = true connected = true color = gray
 data = field autoscale = false minimum = -170.0 maximum = 170.0 visible = showField levels = 16 mincolor = blue maxcolor = red