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 double _scaleFactor = 1.0;
19 private double _altFactor = 1.0;
20 // MAYBE: How to store rods (lifts) in data?
21 private byte[] _pointTypes = null;
22 private byte[] _pointHeights = null;
24 private static final double DEFAULT_MODEL_SIZE = 10.0;
26 // Constants for point types
27 public static final byte POINT_TYPE_WAYPOINT = 1;
28 public static final byte POINT_TYPE_NORMAL_POINT = 2;
29 public static final byte POINT_TYPE_SEGMENT_START = 3;
34 * @param inTrack Track object
36 public ThreeDModel(Track inTrack)
38 this(inTrack, DEFAULT_MODEL_SIZE);
44 * @param inTrack Track object
45 * @param inSize model size
47 public ThreeDModel(Track inTrack, double inSize)
51 if (_modelSize <= 0.0) _modelSize = DEFAULT_MODEL_SIZE;
56 * @return the number of points in the model
58 public int getNumPoints()
60 if (_track == null) return 0;
61 return _track.getNumPoints();
65 * @param inFactor altitude exaggeration factor (default 1.0)
67 public void setAltitudeFactor(double inFactor)
69 if (inFactor >= 1.0) {
70 _altFactor = inFactor;
75 * Scale all points and calculate factors
79 // Use PointScaler to sort out x and y values
80 _scaler = new PointScaler(_track);
82 // Calculate scale factor to fit within box
84 if (_scaler.getMaximumHoriz() > 0.0 || _scaler.getMaximumVert() > 0.0)
86 if (_scaler.getMaximumHoriz() > _scaler.getMaximumVert())
88 // scale limited by longitude
89 _scaleFactor = _modelSize / _scaler.getMaximumHoriz();
93 // scale limited by latitude
94 _scaleFactor = _modelSize / _scaler.getMaximumVert();
97 // cap altitude scale factor if it's too big
98 double maxScaledAlt = _scaler.getMaxScaledAlt() * _altFactor;
99 if (maxScaledAlt > _modelSize) {
101 _altFactor = _altFactor * _modelSize / maxScaledAlt;
103 // calculate lat/long lines
104 _scaler.calculateLatLongLines();
106 // calculate point types and height codes
107 calculatePointTypes();
112 * Calculate the point types and height codes
114 private void calculatePointTypes()
116 int numPoints = getNumPoints();
117 _pointTypes = new byte[numPoints];
118 _pointHeights = new byte[numPoints];
119 // Loop over points in track
120 for (int i=0; i<numPoints; i++)
122 DataPoint point = _track.getPoint(i);
123 _pointTypes[i] = (point.isWaypoint()?POINT_TYPE_WAYPOINT:
124 (point.getSegmentStart()?POINT_TYPE_SEGMENT_START:POINT_TYPE_NORMAL_POINT));
125 _pointHeights[i] = (byte) (point.getAltitude().getValue(Altitude.Format.METRES) / 500);
131 * Get the scaled horizontal value for the specified point
132 * @param inIndex index of point
133 * @return scaled horizontal value
135 public double getScaledHorizValue(int inIndex)
137 return _scaler.getHorizValue(inIndex) * _scaleFactor;
141 * Get the scaled vertical value for the specified point
142 * @param inIndex index of point
143 * @return scaled vertical value
145 public double getScaledVertValue(int inIndex)
147 return _scaler.getVertValue(inIndex) * _scaleFactor;
151 * Get the scaled altitude value for the specified point
152 * @param inIndex index of point
153 * @return scaled altitude value
155 public double getScaledAltValue(int inIndex)
157 // if no altitude, just return 0
158 double altVal = _scaler.getAltValue(inIndex);
159 if (altVal < 0) return 0;
160 // scale according to exaggeration factor
161 return altVal * _altFactor;
166 * @return latitude lines
168 public double[] getLatitudeLines()
170 return _scaler.getLatitudeLines();
174 * @param inIndex index of line, starting at 0
175 * @return scaled position of latitude line
177 public double getScaledLatitudeLine(int inIndex)
179 return _scaler.getScaledLatitudeLines()[inIndex] * _scaleFactor;
183 * @return longitude lines
185 public double[] getLongitudeLines()
187 return _scaler.getLongitudeLines();
191 * @param inIndex index of line, starting at 0
192 * @return scaled position of longitude line
194 public double getScaledLongitudeLine(int inIndex)
196 return _scaler.getScaledLongitudeLines()[inIndex] * _scaleFactor;
200 * @param inIndex index of point, starting at 0
201 * @return point type, either POINT_TYPE_WAYPOINT or POINT_TYPE_NORMAL_POINT
203 public byte getPointType(int inIndex)
205 return _pointTypes[inIndex];
209 * @param inIndex index of point, starting at 0
210 * @return point height code
212 public byte getPointHeightCode(int inIndex)
214 return _pointHeights[inIndex];
218 * @return the current model size
220 public double getModelSize()