package org.openpixi.pixi.physics.movement.boundary;
import org.openpixi.pixi.physics.force.Force;
import org.openpixi.pixi.physics.particles.Particle;
import org.openpixi.pixi.physics.solver.Solver;
import org.openpixi.pixi.physics.util.DoubleBox;
/**
* Maps the 8 possible boundary regions in 2D to actual boundaries.
*/
public class SimpleParticleBoundaries implements ParticleBoundaries {
private BoundaryRegions boundaryRegions;
private ParticleBoundary[] regionBoundaryMap =
new ParticleBoundary[BoundaryRegions.NUM_OF_REGIONS];
private ParticleBoundaryType boundaryType;
private DoubleBox simulationArea;
/**
* Box around the particle which is used to determine
* whether the particle lies outside of the simulation area or not.
*/
private DoubleBox particleBox = new DoubleBox(0,0,0,0);
public ParticleBoundaryType getType() {
return boundaryType;
}
public SimpleParticleBoundaries(DoubleBox simulationArea, ParticleBoundaryType boundaryType) {
this.boundaryType = boundaryType;
this.simulationArea = simulationArea;
boundaryRegions = new BoundaryRegions(simulationArea);
createBoundaryMap();
}
/**
* For run-time boundary type switching in interactive version.
*/
public void changeType(ParticleBoundaryType boundaryType) {
this.boundaryType = boundaryType;
createBoundaryMap();
}
/*
* In 3D case it might be easier to use for cycles for the mapping.
*/
private void createBoundaryMap() {
regionBoundaryMap[BoundaryRegions.X_MIN + BoundaryRegions.Y_MIN] =
boundaryType.createBoundary(-simulationArea.xsize(), -simulationArea.ysize());
regionBoundaryMap[BoundaryRegions.X_CENTER + BoundaryRegions.Y_MIN] =
boundaryType.createBoundary(0, -simulationArea.ysize());
regionBoundaryMap[BoundaryRegions.X_MAX + BoundaryRegions.Y_MIN] =
boundaryType.createBoundary(simulationArea.xsize(), -simulationArea.ysize());
regionBoundaryMap[BoundaryRegions.X_MIN + BoundaryRegions.Y_CENTER] =
boundaryType.createBoundary(-simulationArea.xsize(), 0);
regionBoundaryMap[BoundaryRegions.X_CENTER + BoundaryRegions.Y_CENTER] =
new EmptyBoundary(0, 0);
regionBoundaryMap[BoundaryRegions.X_MAX + BoundaryRegions.Y_CENTER] =
boundaryType.createBoundary(simulationArea.xsize(), 0);
regionBoundaryMap[BoundaryRegions.X_MIN + BoundaryRegions.Y_MAX] =
boundaryType.createBoundary(-simulationArea.xsize(), simulationArea.ysize());
regionBoundaryMap[BoundaryRegions.X_CENTER + BoundaryRegions.Y_MAX] =
boundaryType.createBoundary(0, simulationArea.ysize());
regionBoundaryMap[BoundaryRegions.X_MAX + BoundaryRegions.Y_MAX] =
boundaryType.createBoundary(simulationArea.xsize(), simulationArea.ysize());
}
public void applyOnParticleBoundingBox(
Solver solver, Force force, Particle particle, double timeStep) {
/*
* Since there can be a large number of particles,
* it is costly to create new bounding box for each particle in each time step;
* thus, we reuse single bounding box.
*/
boundaryType.getParticleBox(particle, particleBox);
int region = boundaryRegions.getRegion(particleBox);
regionBoundaryMap[region].apply(solver, force, particle, timeStep);
}
public void applyOnParticleCenter(
Solver solver, Force force, Particle particle, double timeStep) {
int region = boundaryRegions.getRegion(particle.getX(), particle.getY());
regionBoundaryMap[region].apply(solver, force, particle, timeStep);
}
}