/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package visad;
/**
*
* @author rink
*/
public class Trajectory {
/* The manager to which this trajectory belongs */
TrajectoryManager trajMan;
/* Current location (spatial set) of massless tracer particle */
float[] startPts = new float[3];
/* grid point neighbors and interp weights for current location */
int[] startCell;
float[] cellWeights;
int[][] indices = new int[1][];
float[][] weights = new float[1][];
/* unit vector from last to current location*/
float[] uVecPath = new float[] {Float.NaN, Float.NaN, Float.NaN};
int[] guess3D = new int[] {-1,-1,-1};
int[] guess2D = new int[] {-1,-1};
byte[] startColor;
byte[] stopColor;
float[] stopPts = new float[3];
float[][] startPts2D = new float[2][1];
float[][] startPts3D = new float[3][1];
/* first and current time and associated set indices */
public int initialTimeIndex = 0;
public int currentTimeIndex = 0;
public double initialTime = 0;
public double currentTime = 0;
/* Flag indicating particle has moved out of the grid, or position
cannot be determined - Trajectory obj will be removed from list.
*/
boolean offGrid = false;
int clrDim;
GriddedSet spatial_set;
int manifoldDimension;
int npairs = 0;
int[] indexes = new int[60];
float[] lastPtD = null;
float[] lastPtC = null;
float[] lastPtDD = null;
float[] lastPtCC = null;
float[][] circleXYZ;
float[][] last_circleXYZ;
float[] lastTvec = new float[3];
float[] lastSvec;
static float[][] circle;
public Trajectory(TrajectoryManager trajMan, float startX, float startY, float startZ, int[] startCell, float[] cellWeights, byte[] startColor, double initialTime) {
startPts[0] = startX;
startPts[1] = startY;
startPts[2] = startZ;
this.startCell = startCell;
this.cellWeights = cellWeights;
this.indices[0] = startCell;
this.weights[0] = cellWeights;
clrDim = startColor.length;
stopColor = new byte[clrDim];
this.startColor = startColor;
this.initialTime = initialTime;
this.trajMan = trajMan;
}
public void forward(FlowInfo info, float[][] flow_values, byte[][] color_values, GriddedSet spatial_set, int direction, float timeStep)
throws VisADException {
if (offGrid) return;
clrDim = color_values.length;
float[] intrpClr = new float[clrDim];
this.spatial_set = spatial_set;
this.manifoldDimension = spatial_set.getManifoldDimension();
float[][] flowLoc = new float[3][1];
float[][] flowVec = new float[3][1];
float[] intrpFlow = new float[3];
if (indices[0] != null) {
java.util.Arrays.fill(intrpFlow, 0f);
java.util.Arrays.fill(intrpClr, 0);
for (int j=0; j<indices[0].length; j++) {
int idx = indices[0][j];
flowLoc[0][0] = info.spatial_values[0][idx];
flowLoc[1][0] = info.spatial_values[1][idx];
flowLoc[2][0] = info.spatial_values[2][idx];
flowVec[0][0] = flow_values[0][idx];
flowVec[1][0] = flow_values[1][idx];
flowVec[2][0] = flow_values[2][idx];
float[][] del = TrajectoryManager.computeDisplacement(info, flowLoc, flowVec, timeStep);
intrpFlow[0] += weights[0][j]*(direction)*del[0][0];
intrpFlow[1] += weights[0][j]*(direction)*del[1][0];
intrpFlow[2] += weights[0][j]*(direction)*del[2][0];
intrpClr[0] += weights[0][j]*ShadowType.byteToFloat(color_values[0][idx]);
intrpClr[1] += weights[0][j]*ShadowType.byteToFloat(color_values[1][idx]);
intrpClr[2] += weights[0][j]*ShadowType.byteToFloat(color_values[2][idx]);
if (clrDim == 4) {
intrpClr[3] += weights[0][j]*ShadowType.byteToFloat(color_values[3][idx]);
}
//markGrid[idx] = true;
//markGridTime[idx] = currentTimeIndex;
}
stopPts[0] = startPts[0] + intrpFlow[0];
stopPts[1] = startPts[1] + intrpFlow[1];
stopPts[2] = startPts[2] + intrpFlow[2];
stopColor[0] = ShadowType.floatToByte(intrpClr[0]);
stopColor[1] = ShadowType.floatToByte(intrpClr[1]);
stopColor[2] = ShadowType.floatToByte(intrpClr[2]);
if (clrDim == 4) {
stopColor[3] = ShadowType.floatToByte(intrpClr[3]);
}
addPair(startPts, stopPts, startColor, stopColor);
uVecPath[0] = stopPts[0] - startPts[0];
uVecPath[1] = stopPts[1] - startPts[1];
uVecPath[2] = stopPts[2] - startPts[2];
float mag = (float) Math.sqrt(uVecPath[0]*uVecPath[0] + uVecPath[1]*uVecPath[1] + uVecPath[2]*uVecPath[2]);
uVecPath[0] /= mag;
uVecPath[1] /= mag;
uVecPath[2] /= mag;
update();
}
}
public void addPair(float[] startPt, float[] stopPt, byte[] startColor, byte[] stopColor) {
indexes[npairs] = trajMan.getCoordinateCount();
trajMan.addPair(startPt, stopPt, startColor, stopColor);
npairs++;
int clrDim = startColor.length;
// grow arrays
if (indexes.length == npairs) {
int[] tmp = new int[npairs+40];
System.arraycopy(indexes, 0, tmp, 0, npairs);
indexes = tmp;
}
}
private void update() throws VisADException {
startPts[0] = stopPts[0];
startPts[1] = stopPts[1];
startPts[2] = stopPts[2];
startColor[0] = stopColor[0];
startColor[1] = stopColor[1];
startColor[2] = stopColor[2];
if (clrDim == 4) {
startColor[3] = stopColor[3];
}
if (manifoldDimension == 2) {
startPts2D[0][0] = startPts[0];
startPts2D[1][0] = startPts[1];
spatial_set.valueToInterp(startPts2D, indices, weights, guess2D);
}
else if (manifoldDimension == 3) {
startPts3D[0][0] = startPts[0];
startPts3D[1][0] = startPts[1];
startPts3D[2][0] = startPts[2];
spatial_set.valueToInterp(startPts3D, indices, weights, guess3D);
}
startCell = indices[0];
cellWeights = weights[0];
if (indices[0] == null) {
offGrid = true;
}
}
public VisADGeometryArray makeCylinderStrip(float[] T, float[] S, float[] pt0, float[] pt1, byte[][] clr0, byte[][] clr1, float size,
int npts, float[] coords, byte[] colors, float[] normls, int[] vertCnt) {
VisADTriangleStripArray array = new VisADTriangleStripArray();
int clrDim = clr0.length;
if (circle == null) {
circle = new float[2][npts];
float intrvl = (float) (2*Math.PI)/(npts-1);
for (int i=0; i<npts; i++) {
circle[0][i] = (float) Math.cos(intrvl*i); // s
circle[1][i] = (float) Math.sin(intrvl*i); // t
}
}
int vcnt = vertCnt[0];
int idx = 3*vcnt;
int cidx = clrDim*vcnt;
if (circleXYZ == null) {
circleXYZ = new float[3][npts];
}
if (last_circleXYZ == null) { // first time
float[][] ptsXYZ = new float[3][npts];
for (int k=0; k<npts; k++) {
float s = size*circle[0][k];
float t = size*circle[1][k];
ptsXYZ[0][k] = pt0[0] + s*S[0] + t*T[0];
ptsXYZ[1][k] = pt0[1] + s*S[1] + t*T[1];
ptsXYZ[2][k] = pt0[2] + s*S[2] + t*T[2];
}
last_circleXYZ = new float[3][npts];
System.arraycopy(ptsXYZ[0], 0, last_circleXYZ[0], 0, npts);
System.arraycopy(ptsXYZ[1], 0, last_circleXYZ[1], 0, npts);
System.arraycopy(ptsXYZ[2], 0, last_circleXYZ[2], 0, npts);
}
for (int k=0; k<npts; k++) {
float s = size*circle[0][k];
float t = size*circle[1][k];
circleXYZ[0][k] = pt1[0] + s*S[0] + t*T[0];
circleXYZ[1][k] = pt1[1] + s*S[1] + t*T[1];
circleXYZ[2][k] = pt1[2] + s*S[2] + t*T[2];
}
for (int k=0; k<npts; k++) {
float x = last_circleXYZ[0][k];
float y = last_circleXYZ[1][k];
float z = last_circleXYZ[2][k];
float delx = x - pt0[0];
float dely = y - pt0[1];
float delz = z - pt0[2];
float mag = (float) Math.sqrt(delx*delx+dely*dely+delz*delz);
normls[idx] = delx/mag;
coords[idx++] = x;
normls[idx] = dely/mag;
coords[idx++] = y;
normls[idx] = delz/mag;
coords[idx++] = z;
if (clrDim == 3) {
colors[cidx++] = clr0[0][0];
colors[cidx++] = clr0[1][0];
colors[cidx++] = clr0[2][0];
}
else { // must be four
colors[cidx++] = clr0[0][0];
colors[cidx++] = clr0[1][0];
colors[cidx++] = clr0[2][0];
colors[cidx++] = clr0[3][0];
}
vcnt++;
x = circleXYZ[0][k];
y = circleXYZ[1][k];
z = circleXYZ[2][k];
delx = x - pt1[0];
dely = y - pt1[1];
delz = z - pt1[2];
mag = (float) Math.sqrt(delx*delx+dely*dely+delz*delz);
normls[idx] = delx/mag;
coords[idx++] = x;
normls[idx] = dely/mag;
coords[idx++] = y;
normls[idx] = delz/mag;
coords[idx++] = z;
if (clrDim == 3) {
colors[cidx++] = clr1[0][0];
colors[cidx++] = clr1[1][0];
colors[cidx++] = clr1[2][0];
}
else { // must be four
colors[cidx++] = clr1[0][0];
colors[cidx++] = clr1[1][0];
colors[cidx++] = clr1[2][0];
colors[cidx++] = clr1[3][0];
}
vcnt++;
}
System.arraycopy(circleXYZ[0], 0, last_circleXYZ[0], 0, npts);
System.arraycopy(circleXYZ[1], 0, last_circleXYZ[1], 0, npts);
System.arraycopy(circleXYZ[2], 0, last_circleXYZ[2], 0, npts);
lastTvec[0] = T[0];
lastTvec[1] = T[1];
lastTvec[2] = T[2];
vertCnt[0] = vcnt;
return array;
}
}