+void
+FGEnvironment::_recalc_alt_temperature ()
+{
+ if (elevation_ft < 38000) {
+ temperature_degc =
+ (temperature_sea_level_degc + 273.15) *
+ _temperature_degc_table->interpolate(elevation_ft) - 273.15;
+ } else {
+ temperature_degc = -56.49; // Stratosphere is constant
+ }
+}
+
+void
+FGEnvironment::_recalc_sl_dewpoint ()
+{
+ // 0.2degC/1000ft
+ // FIXME: this will work only for low
+ // elevations
+ dewpoint_sea_level_degc = dewpoint_degc + (elevation_ft * .0002);
+ if (dewpoint_sea_level_degc > temperature_sea_level_degc)
+ dewpoint_sea_level_degc = temperature_sea_level_degc;
+}
+
+void
+FGEnvironment::_recalc_alt_dewpoint ()
+{
+ // 0.2degC/1000ft
+ // FIXME: this will work only for low
+ // elevations
+ dewpoint_degc = dewpoint_sea_level_degc + (elevation_ft * .0002);
+ if (dewpoint_degc > temperature_degc)
+ dewpoint_degc = temperature_degc;
+}
+
+void
+FGEnvironment::_recalc_sl_pressure ()
+{
+ pressure_sea_level_inhg =
+ pressure_inhg / _pressure_inhg_table->interpolate(elevation_ft);
+}
+
+void
+FGEnvironment::_recalc_alt_pressure ()
+{
+ pressure_inhg =
+ pressure_sea_level_inhg * _pressure_inhg_table->interpolate(elevation_ft);
+}
+
+void
+FGEnvironment::_recalc_density ()
+{
+ double pressure_psf = pressure_inhg * 70.7487;
+
+ // adjust for humidity
+ // calculations taken from USA Today (oops!) at
+ // http://www.usatoday.com/weather/basics/density-calculations.htm
+ double temperature_degk = temperature_degc + 273.15;
+ double pressure_mb = pressure_inhg * 33.86;
+ double vapor_pressure_mb =
+ 6.11 * pow(10.0, 7.5 * dewpoint_degc / (237.7 + dewpoint_degc));
+ double virtual_temperature_degk = temperature_degk / (1 - (vapor_pressure_mb / pressure_mb) * (1.0 - 0.622));
+ double virtual_temperature_degr = virtual_temperature_degk * 1.8;
+
+ density_slugft3 = pressure_psf / (virtual_temperature_degr * 1718);
+}
+
+
+\f
+////////////////////////////////////////////////////////////////////////
+// Functions.
+////////////////////////////////////////////////////////////////////////
+
+static inline double
+do_interp (double a, double b, double fraction)
+{
+ double retval = (a + ((b - a) * fraction));
+ return retval;
+}
+
+static inline double
+do_interp_deg (double a, double b, double fraction)
+{
+ a = fmod(a, 360);
+ b = fmod(b, 360);
+ if (fabs(b-a) > 180) {
+ if (a < b)
+ a += 360;
+ else
+ b += 360;
+ }
+ return fmod(do_interp(a, b, fraction), 360);
+}
+
+void
+interpolate (const FGEnvironment * env1, const FGEnvironment * env2,
+ double fraction, FGEnvironment * result)
+{
+ result->set_visibility_m
+ (do_interp(env1->get_visibility_m(),
+ env2->get_visibility_m(),
+ fraction));
+
+ result->set_temperature_sea_level_degc
+ (do_interp(env1->get_temperature_sea_level_degc(),
+ env2->get_temperature_sea_level_degc(),
+ fraction));
+
+ result->set_dewpoint_degc
+ (do_interp(env1->get_dewpoint_sea_level_degc(),
+ env2->get_dewpoint_sea_level_degc(),
+ fraction));
+
+ result->set_pressure_sea_level_inhg
+ (do_interp(env1->get_pressure_sea_level_inhg(),
+ env2->get_pressure_sea_level_inhg(),
+ fraction));
+
+ result->set_wind_from_heading_deg
+ (do_interp_deg(env1->get_wind_from_heading_deg(),
+ env2->get_wind_from_heading_deg(),
+ fraction));
+
+ result->set_wind_speed_kt
+ (do_interp(env1->get_wind_speed_kt(),
+ env2->get_wind_speed_kt(),
+ fraction));
+
+ result->set_elevation_ft
+ (do_interp(env1->get_elevation_ft(),
+ env2->get_elevation_ft(),
+ fraction));
+
+ result->set_turbulence_magnitude_norm
+ (do_interp(env1->get_turbulence_magnitude_norm(),
+ env2->get_turbulence_magnitude_norm(),
+ fraction));
+
+ result->set_turbulence_rate_hz
+ (do_interp(env1->get_turbulence_rate_hz(),
+ env2->get_turbulence_rate_hz(),
+ fraction));
+}
+
+// end of environment.cxx