1 package tim.prune.threedee;
3 import tim.prune.data.Altitude;
4 import tim.prune.data.DataPoint;
5 import tim.prune.data.PointScaler;
6 import tim.prune.data.Track;
9 * Class to hold a 3d model of the track data,
10 * including all points and scaling operations.
11 * Used by java3d and also Pov export functions
13 public class ThreeDModel
15 private Track _track = null;
16 private PointScaler _scaler = null;
17 private double _modelSize;
18 private int _altitudeCap = -1;
19 private double _scaleFactor = 1.0;
20 private double _altFactor = 1.0;
21 // TODO: How to store rods (lifts) in data?
22 private byte[] _pointTypes = null;
23 private byte[] _pointHeights = null;
25 private static final double DEFAULT_MODEL_SIZE = 10.0;
26 /** Minimum altitude cap */
27 public static final int MINIMUM_ALTITUDE_CAP = 100;
29 // Constants for point types
30 public static final byte POINT_TYPE_WAYPOINT = 1;
31 public static final byte POINT_TYPE_NORMAL_POINT = 2;
32 public static final byte POINT_TYPE_SEGMENT_START = 3;
37 * @param inTrack Track object
39 public ThreeDModel(Track inTrack)
41 this(inTrack, DEFAULT_MODEL_SIZE);
47 * @param inTrack Track object
48 * @param inSize model size
50 public ThreeDModel(Track inTrack, double inSize)
54 if (_modelSize <= 0.0) _modelSize = DEFAULT_MODEL_SIZE;
59 * @return the number of points in the model
61 public int getNumPoints()
63 if (_track == null) return 0;
64 return _track.getNumPoints();
69 * Set the altitude cap
70 * @param inAltitudeCap altitude range to cap to (ignored if less than data range)
72 public void setAltitudeCap(int inAltitudeCap)
74 _altitudeCap = inAltitudeCap;
75 if (_altitudeCap < MINIMUM_ALTITUDE_CAP)
77 _altitudeCap = MINIMUM_ALTITUDE_CAP;
83 * Scale all points and calculate factors
87 // Use PointScaler to sort out x and y values
88 _scaler = new PointScaler(_track);
90 // Calculate scale factor to fit within box
92 if (_scaler.getMaximumHoriz() > 0.0 || _scaler.getMaximumVert() > 0.0)
94 if (_scaler.getMaximumHoriz() > _scaler.getMaximumVert())
96 // scale limited by longitude
97 _scaleFactor = _modelSize / _scaler.getMaximumHoriz();
101 // scale limited by latitude
102 _scaleFactor = _modelSize / _scaler.getMaximumVert();
105 // calculate altitude scale factor
107 if (_scaler.getMaximumAlt() >= 0)
109 // limit by altitude cap or by data range?
110 if (_scaler.getMaximumAlt() > _altitudeCap)
112 // data is bigger than cap
113 _altFactor = _modelSize / _scaler.getMaximumAlt();
118 _altFactor = _modelSize / _altitudeCap;
121 // calculate lat/long lines
122 _scaler.calculateLatLongLines();
124 // calculate point types and height codes
125 calculatePointTypes();
130 * Calculate the point types and height codes
132 private void calculatePointTypes()
134 int numPoints = getNumPoints();
135 _pointTypes = new byte[numPoints];
136 _pointHeights = new byte[numPoints];
137 // Loop over points in track
138 for (int i=0; i<numPoints; i++)
140 DataPoint point = _track.getPoint(i);
141 _pointTypes[i] = (point.isWaypoint()?POINT_TYPE_WAYPOINT:(point.getSegmentStart()?POINT_TYPE_SEGMENT_START:POINT_TYPE_NORMAL_POINT));
142 _pointHeights[i] = (byte) (point.getAltitude().getValue(Altitude.Format.METRES) / 500);
148 * Get the scaled horizontal value for the specified point
149 * @param inIndex index of point
150 * @return scaled horizontal value
152 public double getScaledHorizValue(int inIndex)
154 return _scaler.getHorizValue(inIndex) * _scaleFactor;
158 * Get the scaled vertical value for the specified point
159 * @param inIndex index of point
160 * @return scaled vertical value
162 public double getScaledVertValue(int inIndex)
164 return _scaler.getVertValue(inIndex) * _scaleFactor;
168 * Get the scaled altitude value for the specified point
169 * @param inIndex index of point
170 * @return scaled altitude value
172 public double getScaledAltValue(int inIndex)
174 // if no altitude, just return 0
175 int altVal = _scaler.getAltValue(inIndex);
176 if (altVal < 0) return 0;
177 // scale according to altitude cap
178 return altVal * _altFactor;
183 * @return latitude lines
185 public double[] getLatitudeLines()
187 return _scaler.getLatitudeLines();
191 * @param inIndex index of line, starting at 0
192 * @return scaled position of latitude line
194 public double getScaledLatitudeLine(int inIndex)
196 return _scaler.getScaledLatitudeLines()[inIndex] * _scaleFactor;
200 * @return longitude lines
202 public double[] getLongitudeLines()
204 return _scaler.getLongitudeLines();
208 * @param inIndex index of line, starting at 0
209 * @return scaled position of longitude line
211 public double getScaledLongitudeLine(int inIndex)
213 return _scaler.getScaledLongitudeLines()[inIndex] * _scaleFactor;
217 * @param inIndex index of point, starting at 0
218 * @return point type, either POINT_TYPE_WAYPOINT or POINT_TYPE_NORMAL_POINT
220 public byte getPointType(int inIndex)
222 return _pointTypes[inIndex];
226 * @param inIndex index of point, starting at 0
227 * @return point height code
229 public byte getPointHeightCode(int inIndex)
231 return _pointHeights[inIndex];
235 * @return the current model size
237 public double getModelSize()