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 _scaleFactor = 1.0;
18 private double _altFactor = 1.0;
19 // MAYBE: How to store rods (lifts) in data?
20 private byte[] _pointTypes = null;
21 private byte[] _pointHeights = null;
23 private static final double MODEL_SIZE = 10.0;
25 // Constants for point types
26 public static final byte POINT_TYPE_WAYPOINT = 1;
27 public static final byte POINT_TYPE_NORMAL_POINT = 2;
28 public static final byte POINT_TYPE_SEGMENT_START = 3;
33 * @param inTrack Track object
35 public ThreeDModel(Track inTrack)
42 * @return the number of points in the model
44 public int getNumPoints()
46 if (_track == null) return 0;
47 return _track.getNumPoints();
51 * @param inFactor altitude exaggeration factor (default 1.0)
53 public void setAltitudeFactor(double inFactor)
55 if (inFactor >= 1.0) {
56 _altFactor = inFactor;
61 * Scale all points and calculate factors
65 // Use PointScaler to sort out x and y values
66 _scaler = new PointScaler(_track);
68 // Calculate scale factor to fit within box
70 if (_scaler.getMaximumHoriz() > 0.0 || _scaler.getMaximumVert() > 0.0)
72 if (_scaler.getMaximumHoriz() > _scaler.getMaximumVert())
74 // scale limited by longitude
75 _scaleFactor = MODEL_SIZE / _scaler.getMaximumHoriz();
79 // scale limited by latitude
80 _scaleFactor = MODEL_SIZE / _scaler.getMaximumVert();
83 // cap altitude scale factor if it's too big
84 double maxScaledAlt = _scaler.getMaxScaledAlt() * _altFactor;
85 if (maxScaledAlt > MODEL_SIZE) {
87 _altFactor = _altFactor * MODEL_SIZE / maxScaledAlt;
89 // calculate lat/long lines
90 _scaler.calculateLatLongLines();
92 // calculate point types and height codes
93 calculatePointTypes();
98 * Calculate the point types and height codes
100 private void calculatePointTypes()
102 int numPoints = getNumPoints();
103 _pointTypes = new byte[numPoints];
104 _pointHeights = new byte[numPoints];
105 // Loop over points in track
106 for (int i=0; i<numPoints; i++)
108 DataPoint point = _track.getPoint(i);
109 _pointTypes[i] = (point.isWaypoint()?POINT_TYPE_WAYPOINT:
110 (point.getSegmentStart()?POINT_TYPE_SEGMENT_START:POINT_TYPE_NORMAL_POINT));
111 _pointHeights[i] = (byte) (point.getAltitude().getValue(Altitude.Format.METRES) / 500);
117 * Get the scaled horizontal value for the specified point
118 * @param inIndex index of point
119 * @return scaled horizontal value
121 public double getScaledHorizValue(int inIndex)
123 return _scaler.getHorizValue(inIndex) * _scaleFactor;
127 * Get the scaled vertical value for the specified point
128 * @param inIndex index of point
129 * @return scaled vertical value
131 public double getScaledVertValue(int inIndex)
133 return _scaler.getVertValue(inIndex) * _scaleFactor;
137 * Get the scaled altitude value for the specified point
138 * @param inIndex index of point
139 * @return scaled altitude value
141 public double getScaledAltValue(int inIndex)
143 // if no altitude, just return 0
144 double altVal = _scaler.getAltValue(inIndex);
145 if (altVal < 0) return 0;
146 // scale according to exaggeration factor
147 return altVal * _altFactor;
152 * @return latitude lines
154 public double[] getLatitudeLines()
156 return _scaler.getLatitudeLines();
160 * @param inIndex index of line, starting at 0
161 * @return scaled position of latitude line
163 public double getScaledLatitudeLine(int inIndex)
165 return _scaler.getScaledLatitudeLines()[inIndex] * _scaleFactor;
169 * @return longitude lines
171 public double[] getLongitudeLines()
173 return _scaler.getLongitudeLines();
177 * @param inIndex index of line, starting at 0
178 * @return scaled position of longitude line
180 public double getScaledLongitudeLine(int inIndex)
182 return _scaler.getScaledLongitudeLines()[inIndex] * _scaleFactor;
186 * @param inIndex index of point, starting at 0
187 * @return point type, either POINT_TYPE_WAYPOINT or POINT_TYPE_NORMAL_POINT
189 public byte getPointType(int inIndex)
191 return _pointTypes[inIndex];
195 * @param inIndex index of point, starting at 0
196 * @return point height code
198 public byte getPointHeightCode(int inIndex)
200 return _pointHeights[inIndex];
204 * @return the current model size
206 public double getModelSize()