/*
* Copyright 2006, United States Government as represented by the Administrator
* for the National Aeronautics and Space Administration. No copyright is
* claimed in the United States under Title 17, U.S. Code. All Other Rights
* Reserved.
*
* Created on Mar 30, 2004
*/
package gov.nasa.ial.mde.util;
import gov.nasa.ial.mde.math.MultiPointXY;
import gov.nasa.ial.mde.solver.GraphTrail;
import java.util.ArrayList;
/**
* The <code>TrailUtil</code> class is a utility for handling point trails.
*
* @author Dan Dexter
* @author Dr. Robert Shelton
* @version 1.0
* @since 1.0
*/
public class TrailUtil {
/*
* Splits the ragged array f into separate trails or branches. A branch is a
* double[][2] containing a list of ordered pairs (x,y) to be drawn sequentially.
* The input array f is a so-called "ragged" array which means that the length of
* f[i] varies with i. The value of f[i][0] is the x value, and f[i][j] are any
* corresponding y values, j = 1, ... An individual branch b is obtained by
* taking a slice of f, b[j1-L][0] = f[j1][0] and b[j1-L][1] = f[j1][k] for some
* k > 0 and j ranging from l to h, where L and H are indices for which
* f[i].length changes.
*
* @param p the array of multiple point arrays.
* @param maxJump the maximum value jump between segment boundaries.
* @return the branches from the multiple point arrays.
*/
public static double[][][] getBranchesFrom(MultiPointXY[] p, double maxJump) {
int i;
int[] segmentBoundaries = getSegmentBoundariesFrom(p, maxJump);
double[][] f = MathUtil.multiToRagged(p);
// first count the branches
int numBranches = 0, numSegments = segmentBoundaries.length - 1;
for (i = 0; i < numSegments; i++) {
numBranches += (f[segmentBoundaries[i]].length - 1);
}
// accounts for f[i][0] being the x value. we have a branch for each y value
int k = 0; // counts over new branches
double[][][] r = new double[numBranches][0][0]; // the array of branches to return
for (i = 0; i < numSegments; i++) {
int l = segmentBoundaries[i]; // low boundary of current segment
int b = f[l].length - 1; // the number of branches in the ith segment
int h = segmentBoundaries[i + 1]; // high boundary of current segment
for (int j = 0; j < b; j++, k++) {
r[k] = new double[h - l][2]; // allocate the kth branch
for (int j1 = l; j1 < h; j1++) {
// fill in the values
r[k][j1 - l][0] = f[j1][0];
r[k][j1 - l][1] = f[j1][j + 1];
} // end for j1
} // end for j
} // end for i
return r;
} // end getBranchesFrom
/**
* Returns the graph trails from the multiple point arrays and the specified
* maximum jump between segment boundaries.
*
* @param p the array of multiple point arrays.
* @param maxJump the maximum value jump between segment boundaries.
* @return the graph trail from the multiple point arrays.
*/
public static GraphTrail[] getGraphTrailsFrom(MultiPointXY[] p, double maxJump) {
double[][][] f = getBranchesFrom(p, maxJump);
int n = f.length;
ArrayList<GraphTrail> gt = new ArrayList<GraphTrail>();
for (int i = 0; i < n; i++) {
GraphTrail g = new GraphTrail(f[i]);
if (g.getLength() > 1) {
gt.add(g);
}
} // end for i
return gt.toArray(new GraphTrail[gt.size()]);
} // end getGraphTrailsFrom
/**
* Returns the segment boundaries from the multiple point arrays and the
* specified maximum jump between segment boundaries.
*
* @param data the array of multiple point arrays.
* @param maxJump the maximum value jump between segment boundaries.
* @return an array containing the indexes to the segment boundaries.
*/
public static int[] getSegmentBoundariesFrom(MultiPointXY[] data, double maxJump) {
int i, n = data.length;
ArrayList<Integer> segmentBoundaries = new ArrayList<Integer>(data.length);
segmentBoundaries.add(new Integer(0));
for (i = 1; i < n; i++) {
// If number of y's changes
if (data[i] == null || data[i - 1] == null) {
continue;
}
if (data[i].yArray.length != data[i - 1].yArray.length) {
segmentBoundaries.add(new Integer(i));
continue;
} // end if
int j, k = data[i].yArray.length;
for (j = 0; j < k; j++) {
if (Math.abs(data[i].yArray[j] - data[i - 1].yArray[j]) > maxJump) {
segmentBoundaries.add(new Integer(i));
break;
} // end if
}
} // end for i
segmentBoundaries.add(new Integer(n));
int[] r = new int[n = segmentBoundaries.size()];
for (i = 0; i < n; i++) {
r[i] = segmentBoundaries.get(i).intValue();
}
return r;
} // end getSegmentBoundariesFrom
}