package tim.prune.data; /** * Class to manage the scaling of points, used by the ThreeDModel */ public class PointScaler { /** Original data */ private Track _track = null; /** Secondary data for terrain grid */ private Track _terrainTrack = null; // Scaled values for data track private double[] _xValues = null; private double[] _yValues = null; private double[] _altValues = null; // Scaled values for terrain track, if any private double[] _terrainxValues = null; private double[] _terrainyValues = null; private double[] _terrainAltValues = null; // Altitude range private double _altitudeRange = 0.0; private double _minAltitudeMetres = 0.0; // Horizontal distance private double _horizDistanceMetres = 0.0; /** * Constructor * @param inTrack Track object */ public PointScaler(Track inTrack) { _track = inTrack; } /** * @param inTrack terrain track to add */ public void addTerrain(Track inTrack) { _terrainTrack = inTrack; } /** * Scale the points */ public void scale() { // Work out extents TrackExtents extents = new TrackExtents(_track); extents.applySquareBorder(); _horizDistanceMetres = Math.max(extents.getHorizontalDistanceMetres(), 1.0); final int numPoints = _track.getNumPoints(); // Find altitude range (including terrain) DoubleRange altRangeMetres = extents.getAltitudeRange(); if (_terrainTrack != null) { altRangeMetres.combine(new TrackExtents(_terrainTrack).getAltitudeRange()); } _altitudeRange = altRangeMetres.getRange() / _horizDistanceMetres; _minAltitudeMetres = altRangeMetres.getMinimum(); // create new arrays for scaled values if (_xValues == null || _xValues.length != numPoints) { _xValues = new double[numPoints]; _yValues = new double[numPoints]; _altValues = new double[numPoints]; if (_terrainTrack != null) { _terrainxValues = new double[_terrainTrack.getNumPoints()]; _terrainyValues = new double[_terrainTrack.getNumPoints()]; _terrainAltValues = new double[_terrainTrack.getNumPoints()]; } } final double midXvalue = extents.getXRange().getMidValue(); final double midYvalue = extents.getYRange().getMidValue(); final double xyRange = extents.getXRange().getRange(); // Calculate scaled values for (int p=0; p<numPoints; p++) { DataPoint point = _track.getPoint(p); if (point != null) { _xValues[p] = (_track.getX(p) - midXvalue) / xyRange; _yValues[p] = (midYvalue - _track.getY(p)) / xyRange; // y values have to be inverted _altValues[p] = (point.getAltitude().getMetricValue() - _minAltitudeMetres) / _horizDistanceMetres; } } if (_terrainTrack != null) { for (int p=0; p<_terrainTrack.getNumPoints(); p++) { _terrainxValues[p] = (_terrainTrack.getX(p) - midXvalue) / xyRange; _terrainyValues[p] = (midYvalue - _terrainTrack.getY(p)) / xyRange; // y values have to be inverted _terrainAltValues[p] = (_terrainTrack.getPoint(p).getAltitude().getMetricValue() - _minAltitudeMetres) / _horizDistanceMetres; } } } /** * Get the horizontal value for the specified point * @param inIndex index of point, starting at 0 * @return scaled horizontal value */ public double getHorizValue(int inIndex) { return _xValues[inIndex]; } /** * Get the vertical value for the specified point * @param inIndex index of point, starting at 0 * @return scaled vertical value */ public double getVertValue(int inIndex) { return _yValues[inIndex]; } /** * Get the altitude value for the specified point * @param inIndex index of point, starting at 0 * @return scaled altitude value */ public double getAltValue(int inIndex) { return _altValues[inIndex]; } /** * @return altitude range as fraction of horizontal range */ public double getAltitudeRange() { return _altitudeRange; } /** * Get the horizontal value for the specified point * @param inIndex index of point, starting at 0 * @return scaled horizontal value */ public double getTerrainHorizValue(int inIndex) { return _terrainxValues[inIndex]; } /** * Get the vertical value for the specified point * @param inIndex index of point, starting at 0 * @return scaled vertical value */ public double getTerrainVertValue(int inIndex) { return _terrainyValues[inIndex]; } /** * @param inIndex index of point in terrain track * @return scaled altitude value for the specified terrain point */ public double getTerrainAltValue(int inIndex) { if (_terrainAltValues != null) { return _terrainAltValues[inIndex]; } return 0.0; } }