]> gitweb.fperrin.net Git - GpsPrune.git/blobdiff - tim/prune/threedee/ThreeDModel.java
Version 16, February 2014
[GpsPrune.git] / tim / prune / threedee / ThreeDModel.java
index 929659bcd8ee92704bd0949b29d951f5579946a9..abe166c837f88d5c65def6dd947eeedd9b4209f7 100644 (file)
@@ -1,6 +1,5 @@
 package tim.prune.threedee;
 
-import tim.prune.data.Altitude;
 import tim.prune.data.DataPoint;
 import tim.prune.data.PointScaler;
 import tim.prune.data.Track;
@@ -13,19 +12,15 @@ import tim.prune.data.Track;
 public class ThreeDModel
 {
        private Track _track = null;
+       private Track _terrainTrack = null;
        private PointScaler _scaler = null;
-       private double _modelSize;
-       private int _altitudeCap = -1;
        private double _scaleFactor = 1.0;
        private double _altFactor = 1.0;
-       // TODO: How to store rods (lifts) in data?
+       private double _externalScaleFactor = 1.0;
+       // MAYBE: How to store rods (lifts) in data?
        private byte[] _pointTypes = null;
        private byte[] _pointHeights = null;
 
-       private static final double DEFAULT_MODEL_SIZE = 10.0;
-       /** Minimum altitude cap */
-       public static final int MINIMUM_ALTITUDE_CAP = 100;
-
        // Constants for point types
        public static final byte POINT_TYPE_WAYPOINT      = 1;
        public static final byte POINT_TYPE_NORMAL_POINT  = 2;
@@ -38,23 +33,18 @@ public class ThreeDModel
         */
        public ThreeDModel(Track inTrack)
        {
-               this(inTrack, DEFAULT_MODEL_SIZE);
+               _track = inTrack;
        }
 
 
        /**
-        * Constructor
-        * @param inTrack Track object
-        * @param inSize model size
+        * @param inTrack terrain track to set
         */
-       public ThreeDModel(Track inTrack, double inSize)
+       public void setTerrain(Track inTrack)
        {
-               _track = inTrack;
-               _modelSize = inSize;
-               if (_modelSize <= 0.0) _modelSize = DEFAULT_MODEL_SIZE;
+               _terrainTrack = inTrack;
        }
 
-
        /**
         * @return the number of points in the model
         */
@@ -64,20 +54,21 @@ public class ThreeDModel
                return _track.getNumPoints();
        }
 
-
        /**
-        * Set the altitude cap
-        * @param inAltitudeCap altitude range to cap to (ignored if less than data range)
+        * @param inFactor altitude exaggeration factor (default 1.0)
         */
-       public void setAltitudeCap(int inAltitudeCap)
+       public void setAltitudeFactor(double inFactor)
        {
-               _altitudeCap = inAltitudeCap;
-               if (_altitudeCap < MINIMUM_ALTITUDE_CAP)
-               {
-                       _altitudeCap = MINIMUM_ALTITUDE_CAP;
-               }
+               _altFactor = inFactor;
        }
 
+       /**
+        * @param inSize size of model
+        */
+       public void setModelSize(double inSize)
+       {
+               _externalScaleFactor = inSize;
+       }
 
        /**
         * Scale all points and calculate factors
@@ -86,40 +77,17 @@ public class ThreeDModel
        {
                // Use PointScaler to sort out x and y values
                _scaler = new PointScaler(_track);
-               _scaler.scale();
-               // Calculate scale factor to fit within box
-               _scaleFactor = 1.0;
-               if (_scaler.getMaximumHoriz() > 0.0 || _scaler.getMaximumVert() > 0.0)
-               {
-                       if (_scaler.getMaximumHoriz() > _scaler.getMaximumVert())
-                       {
-                               // scale limited by longitude
-                               _scaleFactor = _modelSize / _scaler.getMaximumHoriz();
-                       }
-                       else
-                       {
-                               // scale limited by latitude
-                               _scaleFactor = _modelSize / _scaler.getMaximumVert();
-                       }
-               }
-               // calculate altitude scale factor
-               _altFactor = 1.0;
-               if (_scaler.getMaximumAlt() >= 0)
+               _scaler.addTerrain(_terrainTrack);
+               _scaler.scale(); // Add 10% border
+
+               // cap altitude scale factor if it's too big
+               double maxAlt = _scaler.getAltitudeRange() * _altFactor;
+               if (maxAlt > 0.5)
                {
-                       // limit by altitude cap or by data range?
-                       if (_scaler.getMaximumAlt() > _altitudeCap)
-                       {
-                               // data is bigger than cap
-                               _altFactor = _modelSize / _scaler.getMaximumAlt();
-                       }
-                       else
-                       {
-                               // capped
-                               _altFactor = _modelSize / _altitudeCap;
-                       }
+                       // capped
+                       // System.out.println("Capped alt factor from " + _altFactor + " to " + (_altFactor * 0.5 / maxAlt));
+                       _altFactor = _altFactor * 0.5 / maxAlt;
                }
-               // calculate lat/long lines
-               _scaler.calculateLatLongLines();
 
                // calculate point types and height codes
                calculatePointTypes();
@@ -138,8 +106,9 @@ public class ThreeDModel
                for (int i=0; i<numPoints; i++)
                {
                        DataPoint point = _track.getPoint(i);
-                       _pointTypes[i] = (point.isWaypoint()?POINT_TYPE_WAYPOINT:(point.getSegmentStart()?POINT_TYPE_SEGMENT_START:POINT_TYPE_NORMAL_POINT));
-                       _pointHeights[i] = (byte) (point.getAltitude().getValue(Altitude.Format.METRES) / 500);
+                       _pointTypes[i] = (point.isWaypoint()?POINT_TYPE_WAYPOINT:
+                               (point.getSegmentStart()?POINT_TYPE_SEGMENT_START:POINT_TYPE_NORMAL_POINT));
+                       _pointHeights[i] = (byte) (point.getAltitude().getMetricValue() / 500);
                }
        }
 
@@ -151,7 +120,7 @@ public class ThreeDModel
         */
        public double getScaledHorizValue(int inIndex)
        {
-               return _scaler.getHorizValue(inIndex) * _scaleFactor;
+               return _scaler.getHorizValue(inIndex) * _scaleFactor * _externalScaleFactor;
        }
 
        /**
@@ -161,7 +130,7 @@ public class ThreeDModel
         */
        public double getScaledVertValue(int inIndex)
        {
-               return _scaler.getVertValue(inIndex) * _scaleFactor;
+               return _scaler.getVertValue(inIndex) * _scaleFactor * _externalScaleFactor;
        }
 
        /**
@@ -172,46 +141,47 @@ public class ThreeDModel
        public double getScaledAltValue(int inIndex)
        {
                // if no altitude, just return 0
-               int altVal = _scaler.getAltValue(inIndex);
-               if (altVal < 0) return 0;
-               // scale according to altitude cap
-               return altVal * _altFactor;
+               double altVal = _scaler.getAltValue(inIndex);
+               if (altVal <= 0.0) return 0.0;
+               // scale according to exaggeration factor
+               return altVal * _altFactor * _externalScaleFactor;
        }
 
 
        /**
-        * @return latitude lines
+        * Get the scaled horizontal value for the specified terrain point
+        * @param inIndex index of point
+        * @return scaled horizontal value
         */
-       public double[] getLatitudeLines()
+       public double getScaledTerrainHorizValue(int inIndex)
        {
-               return _scaler.getLatitudeLines();
+               return _scaler.getTerrainHorizValue(inIndex) * _scaleFactor * _externalScaleFactor;
        }
 
        /**
-        * @param inIndex index of line, starting at 0
-        * @return scaled position of latitude line
+        * Get the scaled vertical value for the specified terrain point
+        * @param inIndex index of point
+        * @return scaled vertical value
         */
-       public double getScaledLatitudeLine(int inIndex)
+       public double getScaledTerrainVertValue(int inIndex)
        {
-               return _scaler.getScaledLatitudeLines()[inIndex] * _scaleFactor;
+               return _scaler.getTerrainVertValue(inIndex) * _scaleFactor * _externalScaleFactor;
        }
 
        /**
-        * @return longitude lines
+        * Get the scaled altitude value for the specified terrain point
+        * @param inIndex index of point
+        * @return scaled altitude value
         */
-       public double[] getLongitudeLines()
+       public double getScaledTerrainValue(int inIndex)
        {
-               return _scaler.getLongitudeLines();
+               // if no altitude, just return 0
+               double altVal = _scaler.getTerrainAltValue(inIndex);
+               if (altVal <= 0.0) return 0.0;
+               // don't scale by scale factor, needs to be unscaled
+               return altVal * _altFactor;
        }
 
-       /**
-        * @param inIndex index of line, starting at 0
-        * @return scaled position of longitude line
-        */
-       public double getScaledLongitudeLine(int inIndex)
-       {
-               return _scaler.getScaledLongitudeLines()[inIndex] * _scaleFactor;
-       }
 
        /**
         * @param inIndex index of point, starting at 0
@@ -230,12 +200,4 @@ public class ThreeDModel
        {
                return _pointHeights[inIndex];
        }
-
-       /**
-        * @return the current model size
-        */
-       public double getModelSize()
-       {
-               return _modelSize;
-       }
 }