/*
* 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;
import visad.util.CubicInterpolator;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import visad.data.text.TextAdapter;
/**
*
* @author rink
*/
public class TrajectoryManager {
static float[][] circle;
private int coordCnt = 0;
private int colorCnt = 0;
private int vertCnt = 0;
private int totNpairs = 0;
private int dataDomainLength;
private float[] coordinates = null;
private byte[] colors = null;
private int clrDim = 3;
private int numSpatialPts;
private boolean[] markGrid;
private int[] markGridTime;
private int cnt=0;
public static boolean doStartOffset = false;
public static int[] o_j = new int[] {0, 0, 1, 1};
public static int[] o_i = new int[] {0, 1, 0, 1};
float[][] startPts;
byte[][] startClrs;
public static final int LINE = TrajectoryParams.LINE;
public static final int RIBBON = TrajectoryParams.RIBBON;
public static final int CYLINDER = TrajectoryParams.CYLINDER;
public static final int DEFORM_RIBBON = TrajectoryParams.DEFORM_RIBBON;
public static final int POINT = TrajectoryParams.POINT;
public static final String PPOP_TRAJECTORY_START_POINTS_FILE = "visad.trajectory.startPointsFile";
double trajVisibilityTimeWindow;
double trajRefreshInterval;
double trajLifetime;
boolean manualIntrpPts;
boolean trajDoIntrp = true;
boolean trajCachingEnabled = false;
boolean doHysplit = true;
float trcrSize = 1f;
boolean trcrEnabled;
int numIntrpPts;
int trajSkip;
TrajectoryParams.SmoothParams smoothParams;
int direction;
int trajForm = LINE; // Default
float cylWidth = 0.01f;
float ribbonWidthFac = 1f;
int zStart = 0;
int zSkip = 0;
float[] intrpU;
float[] intrpV;
float[] intrpW;
float[] intrpU_1;
float[] intrpV_1;
float[] intrpW_1;
CubicInterpolator uInterp;
CubicInterpolator vInterp;
CubicInterpolator wInterp;
float[][] values0;
float[][] values1;
float[][] values2;
float[][] values3;
float[][] values0_last;
RealTupleType startPointType = Display.DisplaySpatialCartesianTuple;
ScalarMap altToZ;
ArrayList flowInfoList;
ArrayList trajectories;
//- Listener per FlowControl for ProjectionControl events to auto resize tracer geometry.
public static HashMap scaleChangeListeners = new HashMap();
// Listener for ScalarMapControlEvent.CONTROL_REMOVED to remove above classes for garbage collection.
public static HashMap removeListeners = new HashMap();
public TrajectoryManager(DataRenderer renderer, TrajectoryParams trajParams, ArrayList flowInfoList, int dataDomainLength, double time) throws VisADException {
this(renderer, trajParams, flowInfoList, dataDomainLength, time, null);
}
public TrajectoryManager(DataRenderer renderer, TrajectoryParams trajParams, ArrayList flowInfoList, int dataDomainLength, double time, ScalarMap altToZ) throws VisADException {
this.flowInfoList = flowInfoList;
this.dataDomainLength = dataDomainLength;
trajVisibilityTimeWindow = trajParams.getTrajVisibilityTimeWindow();
trajRefreshInterval = trajParams.getTrajRefreshInterval();
trajLifetime = trajRefreshInterval; // Default. Should be greater than or equal to refresh interval
manualIntrpPts = trajParams.getManualIntrpPts();
numIntrpPts = trajParams.getNumIntrpPts();
trajSkip = trajParams.getStartSkip();
smoothParams = trajParams.getSmoothParams();
direction = trajParams.getDirection();
startPts = trajParams.getStartPoints();
trajDoIntrp = trajParams.getDoIntrp();
trcrSize = trajParams.getMarkerSize();
trcrEnabled = trajParams.getMarkerEnabled();
trajCachingEnabled = trajParams.getCachingEnabled();
trajForm = trajParams.getTrajectoryForm();
cylWidth = trajParams.getCylinderWidth();
ribbonWidthFac = trajParams.getRibbonWidthFactor();
zStart = trajParams.getZStartIndex();
zSkip = trajParams.getZStartSkip();
startPointType = trajParams.getStartType();
if (!trajDoIntrp) {
numIntrpPts = 1;
}
this.altToZ = altToZ;
FlowInfo info = flowInfoList.get(0);
Gridded3DSet spatial_set0 = (Gridded3DSet) info.spatial_set;
GriddedSet spatialSetTraj = makeSpatialSetTraj(spatial_set0);
byte[][] color_values = info.color_values;
if (info.trajColors != null) color_values = info.trajColors;
clrDim = color_values.length;
numSpatialPts = spatial_set0.getLength();
markGrid = new boolean[numSpatialPts];
markGridTime = new int[numSpatialPts];
java.util.Arrays.fill(markGrid, false);
java.util.Arrays.fill(markGridTime, 0);
startClrs = new byte[clrDim][];
if (startPts == null) {
try {
startPts = getStartPointsFromFile(renderer, altToZ, startClrs);
}
catch (Exception e) {
e.printStackTrace();
}
}
if (startPts == null) { //get from domain set
float[][] vec;
if (true) {
float[][] flowVals = convertFlowUnit(info.flow_values, info.flow_units);
vec = ShadowType.adjustFlowToEarth(info.which, flowVals, spatial_set0.getSamples(false), 1f, renderer);
}
startPts = new float[3][];
getStartPointsFromDomain(trajForm, trajSkip, zStart, zSkip, spatial_set0, color_values, startPts, startClrs, vec, ribbonWidthFac);
}
else {
int[] clrIdxs;
if (spatialSetTraj.getManifoldDimension() == 2) {
clrIdxs = spatialSetTraj.valueToIndex(new float[][] {startPts[0], startPts[1]});
} else {
clrIdxs = spatialSetTraj.valueToIndex(startPts);
}
int num = clrIdxs.length;
startClrs[0] = new byte[num];
startClrs[1] = new byte[num];
startClrs[2] = new byte[num];
if (clrDim == 4) startClrs[3] = new byte[num];
for (int i=0; i();
java.util.Arrays.fill(markGrid, false);
makeTrajectories(direction*time, startPts, startClrs, spatialSetTraj);
}
public void addPair(float[] startPt, float[] stopPt, byte[] startColor, byte[] stopColor) {
coordinates[coordCnt++] = startPt[0];
coordinates[coordCnt++] = startPt[1];
coordinates[coordCnt++] = startPt[2];
vertCnt++;
coordinates[coordCnt++] = stopPt[0];
coordinates[coordCnt++] = stopPt[1];
coordinates[coordCnt++] = stopPt[2];
vertCnt++;
totNpairs++;
int clrDim = startColor.length;
colors[colorCnt++] = startColor[0];
colors[colorCnt++] = startColor[1];
colors[colorCnt++] = startColor[2];
if (clrDim == 4) {
colors[colorCnt++] = startColor[3];
}
colors[colorCnt++] = stopColor[0];
colors[colorCnt++] = stopColor[1];
colors[colorCnt++] = stopColor[2];
if (clrDim == 4) {
colors[colorCnt++] = stopColor[3];
}
}
public int getCoordinateCount() {
return coordCnt;
}
public int getColorCount() {
return colorCnt;
}
public int getNumberOfTrajectories() {
return trajectories.size();
}
public static int getNumIntrpPts(FlowInfo info, float maxSpd, double timeStep) throws VisADException {
int numIntrpPts;
float[][] del = computeDisplacement(info, new float[][] {{0f}, {0f}, {0f}}, new float[][] {{maxSpd},{0f},{0f}}, (float)timeStep);
double intrvl = (del[0][0]/0.10);
if (intrvl < 2) {
numIntrpPts = 2;
}
else {
numIntrpPts = (int) intrvl;
}
return numIntrpPts;
}
public static float[][] computeDisplacement(FlowInfo info, float[][] spatial_values, float[][] flow_values, float timeStep) throws VisADException {
return ShadowType.adjustFlowToEarth(info.which, flow_values, spatial_values, info.flowScale,
info.renderer, false, true, timeStep);
}
public VisADGeometryArray computeTrajectories(int k, double timeAccum, double[] times, double[] timeSteps, VisADGeometryArray[] auxArray) throws VisADException, RemoteException {
int i = (direction < 0) ? ((dataDomainLength-1) - k) : k;
VisADGeometryArray array = null;
FlowInfo info = flowInfoList.get(i);
byte[][] color_values = info.color_values;
Gridded3DSet spatial_set = (Gridded3DSet) info.spatial_set;
GriddedSet spatialSetTraj = makeSpatialSetTraj(spatial_set);
if (!manualIntrpPts && trajDoIntrp) {
numIntrpPts = getNumIntrpPts(info, 50f, timeSteps[i]);
}
float timeStep = (float) timeSteps[i]/numIntrpPts;
if ((timeAccum >= trajRefreshInterval)) { // for non steady state trajectories (refresh frequency)
trajectories = new ArrayList();
java.util.Arrays.fill(markGrid, false);
makeTrajectories(direction*times[i], startPts, startClrs, spatialSetTraj);
}
if (trajForm == POINT) {
array = makePointGeometry();
}
// commented out when not using markGrid logic for starting/ending trajs
//Trajectory.makeTrajectories(times[i], trajectories, 6, color_values, setLocs, lens);
/*
Trajectory.checkTime(i); // for steady-state only
if ((i % 4) == 0) { // use for steady-state wind field
Trajectory.makeTrajectories(direction*times[i], trajectories, trajSkip, color_values, setLocs, lens);
}
*/
double x0 = (double) direction*i;
double x1 = (double) direction*(i+direction*1);
double x2 = (double) direction*(i+direction*2);
double x3 = (double) direction*(i+direction*3);
FlowInfo flwInfo;
if (k == 0) {
flwInfo = flowInfoList.get(i);
values0 = convertFlowUnit(flwInfo.flow_values, flwInfo.flow_units);
flwInfo = flowInfoList.get(i+direction*1);
values1 = convertFlowUnit(flwInfo.flow_values, flwInfo.flow_units);
flwInfo = flowInfoList.get(i+direction*2);
values2 = convertFlowUnit(flwInfo.flow_values, flwInfo.flow_units);
}
if (k < dataDomainLength-3) {
flwInfo = flowInfoList.get(i+direction*3);
values3 = convertFlowUnit(flwInfo.flow_values, flwInfo.flow_units);
}
if (values0_last != null) {
values0 = smooth(values0_last, values0, values1, smoothParams);
}
values1 = smooth(values0, values1, values2, smoothParams);
values2 = smooth(values1, values2, values3, smoothParams);
// ------- end smoothing
// update interpolator
if (k < dataDomainLength-2) {
uInterp.next(x0, x1, x2, values0[0], values1[0], values2[0]);
vInterp.next(x0, x1, x2, values0[1], values1[1], values2[1]);
wInterp.next(x0, x1, x2, values0[2], values1[2], values2[2]);
}
int numTrajectories = trajectories.size();
reset();
for (int ti=0; ti 4) {
markGridTime[k] = timeIdx;
markGrid[k] = false;
}
}
}
/* Remove trajectories from list:
(1) That have left the grid (marked offGrid).
(2) That have time length (duration) greater than some threshold.
*/
public void clean() {
ArrayList newList = new ArrayList();
Iterator iter = trajectories.iterator();
while (iter.hasNext() ) {
Trajectory traj = iter.next();
if (!traj.offGrid && ((traj.currentTime - traj.initialTime) < trajLifetime)) {
newList.add(traj);
}
}
trajectories = newList;
}
public void cleanDefStrp() {
Iterator iter = trajectories.iterator();
ArrayList removeList = new ArrayList();
while (iter.hasNext() ) {
Trajectory traj = iter.next();
if (traj.offGrid || ((traj.currentTime - traj.initialTime) > trajLifetime)) {
int idxA;
int idxB;
int idx = trajectories.indexOf(traj);
if ((idx % 2) == 0) {
idxA = idx;
idxB = idx+1;
}
else {
idxB = idx;
idxA = idx-1;
}
removeList.add(trajectories.get(idxA));
removeList.add(trajectories.get(idxB));
}
}
for (int t=0; t 0) {
System.arraycopy(startPts[0], 0, tmpPts[0], 0, lenA);
System.arraycopy(startPts[1], 0, tmpPts[1], 0, lenA);
System.arraycopy(startPts[2], 0, tmpPts[2], 0, lenA);
System.arraycopy(startClrs[0], 0, tmpClrs[0], 0, lenA);
System.arraycopy(startClrs[1], 0, tmpClrs[1], 0, lenA);
System.arraycopy(startClrs[2], 0, tmpClrs[2], 0, lenA);
if (clrDim == 4) {
System.arraycopy(startClrs[3], 0, tmpClrs[3], 0, lenA);
}
}
System.arraycopy(pts[0], 0, tmpPts[0], lenA, lenB);
System.arraycopy(pts[1], 0, tmpPts[1], lenA, lenB);
System.arraycopy(pts[2], 0, tmpPts[2], lenA, lenB);
System.arraycopy(clrs[0], 0, tmpClrs[0], lenA, lenB);
System.arraycopy(clrs[1], 0, tmpClrs[1], lenA, lenB);
System.arraycopy(clrs[2], 0, tmpClrs[2], lenA, lenB);
if (clrDim == 4) {
System.arraycopy(clrs[3], 0, tmpClrs[3], lenA, lenB);
}
startPts[0] = tmpPts[0];
startPts[1] = tmpPts[1];
startPts[2] = tmpPts[2];
startClrs[0] = tmpClrs[0];
startClrs[1] = tmpClrs[1];
startClrs[2] = tmpClrs[2];
if (clrDim == 4) {
startClrs[3] = tmpClrs[3];
}
lenA = startPts[0].length;
}
}
public void getStartPointsFromDomain2D(int trajForm, int skip, float[][] setLocs, int lenX, int lenY, byte[][] color_values, float[][] startPts, byte[][] startClrs, float[][] flowValues, float ribbonWidthFac) throws VisADException {
int clrDim = color_values.length;
int m = 0;
if (doStartOffset) {
m = cnt % 4;
cnt++;
}
int jA = 1+o_j[m]*(skip/2);
int jB = lenY-skip;
int iA = 1+o_i[m]*(skip/2);
int iB = lenX-skip;
int numJ = 1 + ((jB-1)-jA)/skip;
int numI = 1 + ((iB-1)-iA)/skip;
int num = numJ*numI;
if (trajForm == TrajectoryParams.DEFORM_RIBBON) {
num *= 2;
}
startPts[0] = new float[num];
startPts[1] = new float[num];
startPts[2] = new float[num];
startClrs[0] = new byte[num];
startClrs[1] = new byte[num];
startClrs[2] = new byte[num];
if (clrDim == 4) {
startClrs[3] = new byte[num];
}
float[] norm = new float[] {0f, 0f, 1f};
float[] traj = new float[3];
float width = ribbonWidthFac*0.006f;
num = 0;
for (int j=1+o_j[m]*(skip/2); j anchors, float scale) {
int nShapes = anchors.size();
int numVertsPerShape = array.vertexCount/nShapes;
VisADGeometryArray scldArray = new VisADTriangleArray();
scldArray.coordinates = new float[3*array.vertexCount];
scldArray.colors = array.colors;
scldArray.normals = array.normals;
scldArray.vertexCount = array.vertexCount;
for (int k=0; k anchors, int direction, float trcrSize, double[] scale, boolean fill) {
int numTrajs = trajectories.size();
VisADGeometryArray array = null;
float[] coords;
byte[] colors;
float[] normals;
int numPts;
int numVerts;
float[] allCoords = new float[3*2*6*numTrajs];
byte[] allColors = new byte[3*2*6*numTrajs];
double barblen = 0.02*trcrSize;
float[] norm = new float[] {0, 0, 1f};
float[] trj_u = new float[3];
for (int k=0; k keepPts = new ArrayList();
ArrayList keepVal = new ArrayList();
for (int k=0; k 1
float[][] clrTbl = new float[colors.length][256];
BaseColorControl.initTableVis5D(clrTbl);
for (int i=0; i 1f) tval = 1f;
int ci = (int) (tval*256f);
colors[0][i] = (byte) (256f * clrTbl[0][ci]);
colors[1][i] = (byte) (256f * clrTbl[1][ci]);
colors[2][i] = (byte) (256f * clrTbl[2][ci]);
if (colors.length == 4) colors[3][i] = (byte) (256f * clrTbl[3][ci]);
}
latlonalt[2] = altToZ.scaleValues(latlonalt[2]);
CoordinateSystem dspCoordSys = renderer.getDisplayCoordinateSystem();
float[][] fltVals = new float[3][latlonalt[0].length];
for (int i=0; i
Ads help maintain this website.