package org.openpixi.pixi.distributed.movement.boundary;
import org.openpixi.pixi.physics.util.DoubleBox;
import org.openpixi.pixi.physics.util.Point;
/**
* Identifies different border regions of the simulation area.
* Border regions are mainly within the simulation area.
*/
public class BorderRegions {
public static final int X_BOUNDARY_MIN = 0;
public static final int X_BORDER_MIN = 1;
public static final int X_CENTER = 2;
public static final int X_BORDER_MAX = 3;
public static final int X_BOUNDARY_MAX = 4;
public static final int Y_BOUNDARY_MIN = 0;
public static final int Y_BORDER_MIN = 5;
public static final int Y_CENTER = 10;
public static final int Y_BORDER_MAX = 15;
public static final int Y_BOUNDARY_MAX = 20;
public static final int NUM_OF_REGIONS = X_BOUNDARY_MAX + Y_BOUNDARY_MAX + 1;
/** Regions which share an edge with the inner simulation area. */
public static int[] EDGE_REGIONS = {
X_BORDER_MIN + Y_CENTER,
X_BORDER_MAX + Y_CENTER,
Y_BORDER_MIN + X_CENTER,
Y_BORDER_MAX + X_CENTER
};
/** Regions which share a corner with the inner simulation area. */
public static int[] CORNER_REGIONS = {
X_BORDER_MIN + Y_BORDER_MIN,
X_BORDER_MAX + Y_BORDER_MIN,
X_BORDER_MIN + Y_BORDER_MAX,
X_BORDER_MAX + Y_BORDER_MAX
};
/**
* Special border regions,
* which are outside of the simulation area,
* present only under hardwall boundaries.
*/
public static int[] OUTSIDE_CORNER_REGIONS = {
X_BORDER_MIN + Y_BOUNDARY_MIN,
X_BORDER_MIN + Y_BOUNDARY_MAX,
X_BORDER_MAX + Y_BOUNDARY_MIN,
X_BORDER_MAX + Y_BOUNDARY_MAX,
Y_BORDER_MIN + X_BOUNDARY_MIN,
Y_BORDER_MIN + X_BOUNDARY_MAX,
Y_BORDER_MAX + X_BOUNDARY_MIN,
Y_BORDER_MAX + X_BOUNDARY_MAX,
};
private DoubleBox simulationArea;
/** Inner simulation area (without border cells). */
private DoubleBox innerArea;
public BorderRegions(DoubleBox simulationArea, DoubleBox innerArea) {
this.simulationArea = simulationArea;
this.innerArea = innerArea;
}
public int getRegion(double x, double y) {
int xidx;
if (x < simulationArea.xmin()) {
xidx = X_BOUNDARY_MIN;
} else if (x < innerArea.xmin()) {
xidx = X_BORDER_MIN;
} else if (x < innerArea.xmax()) {
xidx = X_CENTER;
} else if (x < simulationArea.xmax()) {
xidx = X_BORDER_MAX;
} else {
xidx = X_BOUNDARY_MAX;
}
int yidx;
if (y < simulationArea.ymin()) {
yidx = Y_BOUNDARY_MIN;
} else if (y < innerArea.ymin()) {
yidx = Y_BORDER_MIN;
} else if (y < innerArea.ymax()) {
yidx = Y_CENTER;
} else if (y < simulationArea.ymax()) {
yidx = Y_BORDER_MAX;
} else {
yidx = Y_BOUNDARY_MAX;
}
return xidx + yidx;
}
/**
* Decomposes the region id to X and Y components.
*/
public Point decomposeRegionID(int regionID) {
int y = findHighestPossibleY(regionID);
int x = findX(y, regionID);
return new Point(x, y);
}
private int findX(int y, int regionID) {
int potentialX = regionID - y;
assert X_BOUNDARY_MIN <= potentialX && potentialX <= X_BOUNDARY_MAX;
return potentialX;
}
private int findHighestPossibleY(int regionID) {
int highetsY = -1;
for (int y = Y_BOUNDARY_MIN; y <= Y_BOUNDARY_MAX; ++y) {
if (y <= regionID) {
highetsY = y;
}
}
assert highetsY != -1;
return highetsY;
}
}