1
0
Fork 0

Make it possble to assign an offset to the seasons. Slowly adjust environment parameters too. Fix some calculations.

This commit is contained in:
Erik Hofman 2020-11-11 11:58:21 +01:00
parent 2683a27513
commit 3253a2e5fe
2 changed files with 189 additions and 151 deletions

View file

@ -47,6 +47,8 @@
// applications. Bull. Amer. Meteor. Soc., 86, 225-233.
// doi: http://dx.doi.org/10.1175/BAMS-86-2-225
#define MONTH (1.0/6.0)
FGClimate::FGClimate()
{
SGPath img_path = globals->get_fg_root() / "Geodata" / "koppen-geiger.png";
@ -118,6 +120,13 @@ void FGClimate::reinit()
_precipitation = -99999.0;
_wind = -99999.0;
_precipitation_annual = -99999.0;
_snow_level = -99999.0;
_snow_thickness = -99999.0;
_ice_cover = -99999.0;
_dust_cover = -99999.0;
_wetness = -99999.0;
_lichen_cover = -99999.0;
}
// Set all environment parameters based on the koppen-classicfication
@ -202,7 +211,7 @@ void FGClimate::update(double dt)
_temperature_sl = _temperature_gl + 9.8*alt_km;
_temperature_mean_sl = _temperature_mean_gl + 9.8*alt_km;
_snow_level = 1000.0 * _temperature_mean_sl / 9.8;
_set(_snow_level, 1000.0*_temperature_mean_sl/9.8);
// Mark G. Lawrence:
_dewpoint_sl = _temperature_sl - ((100.0 - _relative_humidity_sl)/5.0);
@ -234,7 +243,9 @@ void FGClimate::update_season_factor()
_season_summer = (23.5 + sign*_sun_latitude_deg)/(2.0*23.5);
_season_transistional = 2.0*(1.0 - _season_summer) - 1.0;
_year = (_is_autumn) ? 0.5+0.5*_season_summer : 0.5-0.5*_season_summer;
_season_transistional = 2.5*(1.0 - _season_summer) - 1.0;
if (_season_transistional < 0.0) _season_transistional = 0.0;
else if (_season_transistional > 1.0) _season_transistional = 1.0;
}
@ -307,24 +318,24 @@ void FGClimate::set_tropical()
relative_humidity = triangular(humidity_fact, 75.0, 85.0);
break;
case 2: // Am: equatorial, monsoonal
temp_night = triangular(summer, 17.5, 22.5);
temp_day = triangular(summer, 27.5, 32.5);
precipitation = season_even(summer, 75.0, 320.0);
relative_humidity = triangular(humidity_fact, 75.0, 85.0);
temp_night = triangular(summer, 17.5, 22.5, MONTH);
temp_day = triangular(summer, 27.5, 32.5, MONTH);
precipitation = season_even(summer, 75.0, 320.0, MONTH);
relative_humidity = triangular(humidity_fact, 75.0, 85.0, MONTH);
wind *= 2.0*_precipitation/320.0;
break;
case 3: // As: equatorial, summer dry
temp_night = season_long_high(summer, 15.0, 22.5);
temp_day = triangular(summer, 27.5, 35.0);
precipitation = season_even(summer , 35.0, 150.0);
relative_humidity = triangular(humidity_fact, 60.0, 80.0);
temp_night = season_long_high(summer, 15.0, 22.5, 1.5*MONTH);
temp_day = triangular(summer, 27.5, 35.0, MONTH);
precipitation = season_even(summer , 35.0, 150.0, 2.0*MONTH);
relative_humidity = triangular(humidity_fact, 60.0, 80.0, 2.0*MONTH);
wind *= 2.0*_precipitation/350.0;
break;
case 4: // Aw: equatorial, winter dry
temp_night = season_long_high(summer, 15.0, 22.5);
temp_day = triangular(summer, 27.5, 35.0);
precipitation = season_even(summer, 10.0, 230.0);
relative_humidity = triangular(humidity_fact, 60.0, 80.0);
temp_night = season_long_high(summer, 15.0, 22.5, 1.5*MONTH);
temp_day = triangular(summer, 27.5, 35.0, 2.0*MONTH);
precipitation = season_even(summer, 10.0, 230.0, 2.0*MONTH);
relative_humidity = triangular(humidity_fact, 60.0, 80.0, 2.0*MONTH);
wind *= 2.0*_precipitation/230.0;
break;
default:
@ -361,28 +372,28 @@ void FGClimate::set_dry()
switch(_code)
{
case 5: // BSh: arid, steppe, hot arid
temp_night = season_long_high(summer, 10.0, 22.0);
temp_day = triangular(summer, 27.5, 35.0);
precipitation = season_long_low(summer, 8.0, 117.0);
relative_humidity = triangular(humidity_fact, 20.0, 30.0);
temp_night = season_long_high(summer, 10.0, 22.0, MONTH);
temp_day = triangular(summer, 27.5, 35.0, 2.0*MONTH);
precipitation = season_long_low(summer, 8.0, 117.0, 2.0*MONTH);
relative_humidity = triangular(humidity_fact, 20.0, 30.0, 2.0*MONTH);
break;
case 6: // BSk: arid, steppe, cold arid
temp_night = season_even(summer, -14.0, 12.0);
temp_day = season_even(summer, 0.0, 30.0);
precipitation = season_even(summer, 15.0, 34.0);
relative_humidity = season_even(humidity_fact, 48.0, 67.0);
temp_night = season_even(summer, -14.0, 12.0, MONTH);
temp_day = season_even(summer, 0.0, 30.0, MONTH);
precipitation = season_even(summer, 15.0, 34.0, MONTH);
relative_humidity = season_even(humidity_fact, 48.0, 67.0, MONTH);
break;
case 7: // BWh: arid, desert, hot arid
temp_night = season_even(summer, 7.5, 22.0);
temp_day = season_even(summer, 22.5, 37.5);
precipitation = monsoonal(summer, 3.0, 18.0);
relative_humidity = monsoonal(humidity_fact, 25.0, 55.0);
temp_night = season_even(summer, 7.5, 22.0, 1.5*MONTH);
temp_day = season_long(summer, 22.5, 37.5, 1.5*MONTH);
precipitation = monsoonal(summer, 3.0, 18.0, 2.0*MONTH);
relative_humidity = monsoonal(humidity_fact, 25.0, 55.0, 2.0*MONTH);
break;
case 8: // BWk: arid, desert, cold arid
temp_night = season_even(summer, -15.0, 15.0);
temp_day = season_even(summer, -2.0, 30.0);
precipitation = linear(summer, 4.0, 14.0);
relative_humidity = linear(humidity_fact, 45.0, 61.0);
temp_night = season_even(summer, -15.0, 15.0, MONTH);
temp_day = season_even(summer, -2.0, 30.0, MONTH);
precipitation = linear(summer, 4.0, 14.0, MONTH);
relative_humidity = linear(humidity_fact, 45.0, 61.0, MONTH);
break;
default:
break;
@ -420,58 +431,58 @@ void FGClimate::set_temperate()
switch(_code)
{
case 9: // Cfa: warm temperature, fully humid hot summer
temp_night = season_even(summer, -3.0, 20.0);
temp_day = season_even(summer, 10.0, 33.0);
temp_night = season_even(summer, -3.0, 20.0, 1.5*MONTH);
temp_day = season_even(summer, 10.0, 33.0, 1.5*MONTH);
precipitation = season_even(summer, 60.0, 123.0);
relative_humidity = season_even(humidity_fact, 65.0, 80.0);
break;
case 10: // Cfb: warm temperature, fully humid, warm summer
temp_night = season_even(summer, -3.0, 10.0);
temp_day = season_even(summer, 5.0, 25.0);
precipitation = linear(0.5*(summer+_season_transistional), 44.0, 88.0);
relative_humidity = season_even(humidity_fact, 68.0, 87.0);
temp_night = season_even(summer, -3.0, 10.0, 1.5*MONTH);
temp_day = season_even(summer, 5.0, 25.0, 1.5*MONTH);
precipitation = season_long(summer, 44.0, 88.0);
relative_humidity = season_even(humidity_fact, 68.0, 87.0, 1.5*MONTH);
break;
case 11: // Cfc: warm temperature, fully humid, cool summer
temp_night = season_long_low(summer, -3.0, 8.0);
temp_day = season_long_low(summer, 2.0, 14.0);
precipitation = season_even(winter, 44.0, 88.0);
relative_humidity = season_long_low(humidity_fact, 70.0, 85.0);
temp_night = season_long_low(summer, -3.0, 8.0, 1.5*MONTH);
temp_day = season_long_low(summer, 2.0, 14.0, 1.5*MONTH);
precipitation = season_even(winter, 44.0, 88.0, 4.0*MONTH);
relative_humidity = season_long_low(humidity_fact, 70.0, 85.0, 1.5*MONTH);
break;
case 12: // Csa: warm temperature, summer dry, hot summer
temp_night = season_even(summer, 2.0, 16.0);
temp_day = season_even(summer, 12.0, 33.0);
precipitation = season_long_low(winter, 25.0, 70.0);
relative_humidity = season_even(humidity_fact, 58.0, 72.0);
temp_night = season_even(summer, 2.0, 16.0, MONTH);
temp_day = season_even(summer, 12.0, 33.0, MONTH);
precipitation = season_long_high(summer, 25.0, 70.0);
relative_humidity = season_even(humidity_fact, 58.0, 72.0, MONTH);
break;
case 13: // Csb: warm temperature, summer dry, warm summer
temp_night = linear(summer, -4.0, 10.0);
temp_day = linear(summer, 6.0, 27.0);
precipitation = season_short(winter, 25.0, 120.0);
relative_humidity = linear(humidity_fact, 50.0, 72.0);
temp_night = linear(summer, -4.0, 10.0, 1.5*MONTH);
temp_day = linear(summer, 6.0, 27.0, 1.5*MONTH);
precipitation = season_even(winter, 25.0, 120.0, MONTH);
relative_humidity = linear(humidity_fact, 50.0, 72.0, 1.5*MONTH);
break;
case 14: // Csc: warm temperature, summer dry, cool summer
temp_night = season_even(summer, -4.0, 5.0);
temp_day = season_even(summer, 5.0, 16.0);
precipitation = season_even(winter, 60.0, 95.0);
temp_night = season_even(summer, -4.0, 5.0, 0.5*MONTH);
temp_day = season_even(summer, 5.0, 16.0, 0.5*MONTH);
precipitation = season_even(winter, 60.0, 95.0, -MONTH);
relative_humidity = season_even(humidity_fact, 55.0, 75.0);
break;
case 15: // Cwa: warm temperature, winter dry, hot summer
temp_night = season_even(summer, 4.0, 20.0);
temp_day = season_long_low(summer, 15.0, 30.0);
precipitation = season_long_low(summer, 10.0, 320.0);
relative_humidity = season_even(humidity_fact, 60.0, 79.0);
temp_night = season_even(summer, 4.0, 20.0, MONTH);
temp_day = season_long_low(summer, 15.0, 30.0, MONTH);
precipitation = season_long_low(summer, 10.0, 320.0, MONTH);
relative_humidity = season_even(humidity_fact, 60.0, 79.0, MONTH);
break;
case 16: // Cwb: warm temperature, winter dry, warm summer
temp_night = season_even(summer, 1.0, 13.0);
temp_day = season_long_low(summer, 15.0, 27.0);
precipitation = season_long_low(summer, 10.0, 250.0);
relative_humidity = season_even(humidity_fact, 58.0, 72.0);
temp_night = season_even(summer, 1.0, 13.0, MONTH);
temp_day = season_long_low(summer, 15.0, 27.0, MONTH);
precipitation = season_long_low(summer, 10.0, 250.0, MONTH);
relative_humidity = season_even(humidity_fact, 58.0, 72.0, MONTH);
break;
case 17: // Cwc: warm temperature, winter dry, cool summer
temp_night = season_long_high(summer, -9.0, 6.0);
temp_day = season_long_high(summer, 6.0, 17.0);
precipitation = season_long_low(summer, 10.0, 200.0);
relative_humidity = season_long_high(humidity_fact, 50.0, 58.0);
temp_night = season_long_high(summer, -9.0, 6.0, MONTH);
temp_day = season_long_high(summer, 6.0, 17.0, MONTH);
precipitation = season_long_low(summer, 10.0, 200.0, MONTH);
relative_humidity = season_long_high(humidity_fact, 50.0, 58.0, MONTH);
break;
default:
break;
@ -507,75 +518,76 @@ void FGClimate::set_continetal()
switch(_code)
{
case 18: // Dfa: snow, fully humid, hot summer
temp_night = season_even(summer, -15.0, 13.0);
temp_day = season_even(summer, -5.0, 30.0);
temp_night = season_even(summer, -15.0, 13.0, MONTH);
temp_day = season_even(summer, -5.0, 30.0, MONTH);
precipitation = season_even(summer, 25.0, 65.0);
relative_humidity = season_even(humidity_fact, 68.0, 72.0);
break;
case 19: // Dfb: snow, fully humid, warm summer, warm summer
temp_night = season_even(summer, -17.5, 10.0);
temp_day = season_even(summer, -7.5, 25.0);
precipitation = season_even(summer, 30.0, 70.0);
relative_humidity = season_even(humidity_fact, 69.0, 81.0);
temp_night = season_even(summer, -17.5, 10.0, MONTH);
temp_day = season_even(summer, -7.5, 25.0, MONTH);
precipitation = season_even(summer, 30.0, 70.0, MONTH);
printf("### precipitation: %f\n", precipitation);
relative_humidity = season_even(humidity_fact, 69.0, 81.0, MONTH);
break;
case 20: // Dfc: snow, fully humid, cool summer, cool summer
temp_night = season_even(summer, -30.0, 4.0);
temp_day = season_even(summer, -20.0, 15.0);
precipitation = season_even(summer, 22.0, 68.0);
relative_humidity = season_even(humidity_fact, 70.0, 88.0);
temp_night = season_even(summer, -30.0, 4.0, MONTH);
temp_day = season_even(summer, -20.0, 15.0, MONTH);
precipitation = season_even(summer, 22.0, 68.0, 1.5*MONTH);
relative_humidity = season_even(humidity_fact, 70.0, 88.0, MONTH);
break;
case 21: // Dfd: snow, fully humid, extremely continetal
temp_night = season_short(summer, -45.0, 4.0);
temp_day = season_short(summer, -35.0, 10.0);
precipitation = season_long_low(summer, 7.5, 45.0);
relative_humidity = season_short(humidity_fact, 80.0, 90.0);
temp_night = season_even(summer, -45.0, 4.0, MONTH);
temp_day = season_even(summer, -35.0, 10.0, MONTH);
precipitation = season_long_low(summer, 7.5, 45.0, 1.5*MONTH);
relative_humidity = season_even(humidity_fact, 80.0, 90.0, MONTH);
break;
case 22: // Dsa: snow, summer dry, hot summer
temp_night = season_even(summer, -10.0, 10.0);
temp_day = season_even(summer, 0.0, 30.0);
precipitation = season_long_high(winter, 2.0, 70.0);
relative_humidity = season_even(humidity_fact, 48.0, 58.08);
temp_night = season_even(summer, -10.0, 10.0, 1.5*MONTH);
temp_day = season_even(summer, 0.0, 30.0, 1.5*MONTH);
precipitation = season_long_high(winter, 2.0, 70.0, 2.0*MONTH);
relative_humidity = season_even(humidity_fact, 48.0, 58.08, 1.5*MONTH);
break;
case 23: // Dsb: snow, summer dry, warm summer
temp_night = season_even(summer, -15.0, 6.0);
temp_day = season_even(summer, -4.0, 25.0);
precipitation = season_long_high(winter, 12.0, 73.0);
relative_humidity = season_even(humidity_fact, 50.0, 68.0);
temp_night = season_even(summer, -15.0, 6.0, 1.5*MONTH);
temp_day = season_even(summer, -4.0, 25.0, 1.5*MONTH);
precipitation = season_long_high(winter, 12.0, 73.0, 2.0*MONTH);
relative_humidity = season_even(humidity_fact, 50.0, 68.0, 1.5*MONTH);
break;
case 24: // Dsc: snow, summer dry, cool summer
temp_night = season_even(summer, -27.5, 2.0);
temp_day = season_even(summer, -4.0, 15.0);
precipitation = season_long_low(summer, 32.5, 45.0);
relative_humidity = season_even(humidity_fact, 50.0, 60.0);
temp_night = season_even(summer, -27.5, 2.0, MONTH);
temp_day = season_even(summer, -4.0, 15.0, MONTH);
precipitation = season_long_low(summer, 32.5, 45.0, MONTH);
relative_humidity = season_even(humidity_fact, 50.0, 60.0, MONTH);
break;
case 25: // Dsd: snow, summer dry, extremely continetal
temp_night = season_even(summer, -11.5, -6.5);
temp_day = season_even(summer, 14.0, 27.0);
precipitation = season_long_low(summer, 5.0, 90.0);
relative_humidity = season_even(humidity_fact, 48.0, 62.0);
temp_night = season_even(summer, -11.5, -6.5, MONTH);
temp_day = season_even(summer, 14.0, 27.0, MONTH);
precipitation = season_long_low(summer, 5.0, 90.0, MONTH);
relative_humidity = season_even(humidity_fact, 48.0, 62.0, MONTH);
break;
case 26: // Dwa: snow, winter dry, hot summer
temp_night = season_even(summer, -18.0, 16.5);
temp_day = season_even(summer, -5.0, 25.0);
precipitation = season_long_low(summer, 5.0, 180.0);
relative_humidity = season_even(humidity_fact, 60.0, 68.0);
temp_night = season_even(summer, -18.0, 16.5, MONTH);
temp_day = season_even(summer, -5.0, 25.0, MONTH);
precipitation = season_long_low(summer, 5.0, 180.0, 1.5*MONTH);
relative_humidity = season_even(humidity_fact, 60.0, 68.0, MONTH);
break;
case 27: // Dwb: snow, winter dry, warm summer
temp_night = season_even(summer, -28.0, 10.0);
temp_day = season_even(summer, -12.5, 22.5);
precipitation = season_long_low(summer, 10.0, 140.0);
relative_humidity = season_even(humidity_fact, 60.0, 72.0);
temp_night = season_even(summer, -28.0, 10.0, MONTH);
temp_day = season_even(summer, -12.5, 22.5, MONTH);
precipitation = season_long_low(summer, 10.0, 140.0, 1.5*MONTH);
relative_humidity = season_even(humidity_fact, 60.0, 72.0, MONTH);
break;
case 28: // Dwc: snow, winter dry, cool summer
temp_night = season_even(summer, -33.0, 5.0);
temp_day = season_even(summer, -20.0, 20.0);
precipitation = season_long_low(summer, 10.0, 110.0);
relative_humidity = season_even(humidity_fact, 60.0, 78.0);
temp_night = season_even(summer, -33.0, 5.0, MONTH);
temp_day = season_even(summer, -20.0, 20.0, MONTH);
precipitation = season_long_low(summer, 10.0, 110.0, 1.5*MONTH);
relative_humidity = season_even(humidity_fact, 60.0, 78.0, MONTH);
break;
case 29: // Dwd: snow, winter dry, extremely continetal
temp_night = season_even(summer, -57.5, 0.0);
temp_day = season_even(summer, -43.0, 15.0);
precipitation = season_even(summer, 8.0, 63.0);
temp_night = season_even(summer, -57.5, 0.0, MONTH);
temp_day = season_even(summer, -43.0, 15.0, MONTH);
precipitation = season_even(summer, 8.0, 63.0, 1.5*MONTH);
relative_humidity = 80.0;
break;
default:
@ -589,6 +601,7 @@ void FGClimate::set_continetal()
_set(_precipitation_annual, 990.0);
_set(_precipitation, precipitation);
printf("## _precipitation: %f\n", _precipitation);
_has_autumn = true;
_set(_wind, 3.0);
@ -611,16 +624,16 @@ void FGClimate::set_polar()
switch(_code)
{
case 30: // EF: polar frost
temp_night = season_long_low(summer, -35.0, -6.0);
temp_day = season_long_low(summer, -32.5, 0.0);
precipitation = season_even(summer, 50.0, 80.0);
relative_humidity = season_long_low(humidity_fact, 65.0, 75.0);
temp_night = season_long_low(summer, -35.0, -6.0, MONTH);
temp_day = season_long_low(summer, -32.5, 0.0, MONTH);
precipitation = season_even(summer, 50.0, 80.0, 3.0*MONTH);
relative_humidity = season_long_low(humidity_fact, 65.0, 75.0, MONTH);
break;
case 31: // ET: polar tundra
temp_night = season_even(summer, -30.0, 0.0);
temp_day = season_even(summer, -22.5, 8.0);
precipitation = season_even(summer, 15.0, 45.0);
relative_humidity = season_even(humidity_fact, 60.0, 88.0);
temp_night = season_even(summer, -30.0, 0.0, MONTH);
temp_day = season_even(summer, -22.5, 8.0, 1.5*MONTH);
precipitation = season_even(summer, 15.0, 45.0, 2*MONTH);
relative_humidity = season_even(humidity_fact, 60.0, 88.0, MONTH);
break;
default:
break;
@ -665,26 +678,26 @@ void FGClimate::set_environment()
}
// The temperature decreases by about 9.8°C per kilometer
_snow_thickness = pow(snow_fact, 2.0);
_ice_cover = pow(fact_lat, 2.5);
_set(_snow_thickness, pow(snow_fact, 2.0));
_set(_ice_cover, pow(fact_lat, 2.5));
// less than 20 mm/month of precipitation is considered dry.
if (_precipitation < 20.0 || _precipitation_annual < 240.0)
{
_dust_cover = 0.3 - 0.3*sqrtf(_precipitation/20.0);
_lichen_cover = 0.0;
_wetness = 0.0;
_set(_dust_cover, 0.3 - 0.3*sqrtf(_precipitation/20.0));
_set(_lichen_cover, 0.0);
_set(_wetness, 0.0);
}
else
{
double wetness = _precipitation - 20.0;
wetness = std::min(12.0*wetness/_precipitation_annual, 1.0);
_dust_cover = 0.0;
_wetness = pow(wetness, 3.0);
_set(_dust_cover, 0.0);
_set(_wetness, pow(wetness, 3.0));
double cover = std::min(_precipitation_annual, 990.0)/990.0;
_lichen_cover = 0.5*pow(wetness*cover, 1.5);
_set(_lichen_cover, 0.5*pow(wetness*cover, 1.5));
}
if (_weather_update)
@ -715,6 +728,7 @@ void FGClimate::set_environment()
}
// ---------------------------------------------------------------------------
const std::string FGClimate::_classification[MAX_CLIMATE_CLASSES] = {
"Ocean",
"Af", "Am", "As", "Aw",
@ -764,60 +778,81 @@ const std::string FGClimate::_description[MAX_CLIMATE_CLASSES] = {
};
// val is the progress indicator between 0.0 and 1.0
double FGClimate::linear(double val, double min, double max)
double FGClimate::linear(double val, double min, double max, double offs)
{
double diff = max-min;
val += fmod(offs, 1.0);
if (val > 1.0) val -= 1.0;
else if (val < 1.0) val += 1.0;
return min + val*diff;
}
// google: y=1-abs(-1+2*x)
// low season is around 0.0 and 1.0, high season around 0.5
double FGClimate::triangular(double val, double min, double max)
double FGClimate::triangular(double val, double min, double max, double offs)
{
double diff = max-min;
val -= fmod(offs, 1.0);
if (val > 1.0) val -= 1.0;
else if (val < 1.0) val += 1.0;
val = 1.0 - fabs(-1.0 + 2*val);
return min + val*diff;
}
// google: y =0.5-0.5*atan(cos(x))
// google: y=0.5-0.5*cos(x)
// the short low season is round 0.0, the short high season around 1.0
double FGClimate::season_short(double val, double min, double max)
double FGClimate::season_even(double val, double min, double max, double offs)
{
double diff = max-min;
return min + diff*(0.5 - 0.5*cos(SGD_PI*val));
val -= fmod(offs, 1.0);
if (val > 1.0) val -= 1.0;
else if (val < 1.0) val += 1.0;
return min + diff*(0.5 + 0.5*cos(SGD_PI*val));
}
// google: y =0.5-0.6366*atan(cos(x))
// google: y=0.5-0.6366*atan(cos(x))
// the medium long low season is round 0.0, medium long high season round 1.0
double FGClimate::season_even(double val, double min, double max)
double FGClimate::season_long(double val, double min, double max, double offs)
{
double diff = max-min;
return min + diff*(0.5 - 0.6366*atan(cos(SGD_PI*val)));
val -= fmod(offs, 1.0);
if (val > 1.0) val -= 1.0;
else if (val < 1.0) val += 1.0;
return min + diff*(0.5 + 0.6366*atan(cos(SGD_PI*val)));
}
// google: y=0.5-0.5*cos(x^1.5)
// 2.145 = pow(SGD_PI, 1.0/1.5)
// the long low season is around 0.0, the short high season around 1.0
double FGClimate::season_long_low(double val, double min, double max)
double FGClimate::season_long_low(double val, double min, double max, double offs)
{
double diff = max-min;
return min + diff*(0.5 - 0.5*cos(pow(2.145*val, 1.5)));
val -= fmod(offs, 1.0);
if (val > 1.0) val -= 1.0;
else if (val < 1.0) val += 1.0;
return min + diff*(0.5 + 0.5*cos(pow(2.145*val, 1.5)));
}
// google: y=0.5+0.5*cos(x^1.5)
// 2.14503 = pow(SGD_PI, 1.0/1.5)
// the long high season is around 0.0, the short low season around 1.0
double FGClimate::season_long_high(double val, double min, double max)
double FGClimate::season_long_high(double val, double min, double max, double offs)
{
double diff = max-min;
return max + diff*(0.5 + 0.5*cos(pow(2.14503 - 2.14503*val, 1.5)));
val -= fmod(offs, 1.0);
if (val > 1.0) val -= 1.0;
else if (val < 1.0) val += 1.0;
return max + diff*(0.5 - 0.5*cos(pow(2.14503 - 2.14503*val, 1.5)));
}
// goole: y=cos(atan(x*x))
// the monsoon is around 0.0
double FGClimate::monsoonal(double val, double min, double max)
double FGClimate::monsoonal(double val, double min, double max, double offs)
{
double diff = max-min;
val -= fmod(offs, 1.0);
if (val > 1.0) val -= 1.0;
else if (val < 1.0) val += 1.0;
val = 2.0*SGD_2PI*(1.0-val);
return min + diff*cos(atan(val*val));
}
@ -845,6 +880,8 @@ void FGClimate::report()
<< std::endl;
std::cout << " Description: " << _description[_code]
<< std::endl << std::endl;
std::cout << " Year: " << _year
<< std::endl;
std::cout << " Season (0.0 = winter .. 1.0 = summer): " << _season_summer
<< std::endl;
std::cout << " Daytime....(0.0 = night .. 1.0 = day): " << _day_noon

View file

@ -71,17 +71,17 @@ private:
void report();
#endif
inline void _set(double& prev, double val) {
prev = (prev < -1000.0) ? val : 0.95*prev + 0.05*val;
prev = (prev < -1000.0) ? val : 0.99*prev + 0.01*val;
}
// interpolate val (from 0.0 to 1.0) between min and max
double linear(double val, double min, double max);
double triangular(double val, double min, double max);
double season_short(double val, double min, double max);
double season_even(double val, double min, double max);
double season_long_low(double val, double min, double max);
double season_long_high(double val, double min, double max);
double monsoonal(double val, double min, double max);
double linear(double val, double min, double max, double offs = 0.0);
double triangular(double val, double min, double max, double offs = 0.0);
double season_even(double val, double min, double max, double offs = 0.0);
double season_long(double val, double min, double max, double offs = 0.0);
double season_long_low(double val, double min, double max, double offs = 0.0);
double season_long_high(double val, double min, double max, double offs = 0.0);
double monsoonal(double val, double min, double max, double offs = 0.0);
void set_ocean();
void set_dry();
@ -116,6 +116,7 @@ private:
double _adj_latitude_deg = 0.0; // viewer lat adjusted for sun lat
double _adj_longitude_deg = 0.0; // viewer lat adjusted for sun lon
double _year = 0.0;
double _day_noon = 1.0;
double _season_summer = 1.0;
double _season_transistional = 0.0;
@ -126,12 +127,12 @@ private:
// environment
bool _environment_adjust = false; // enable automatic adjestments
double _snow_level = 7500.0; // in meters
double _snow_thickness = 0.0; // 0.0 = thin, 1.0 = thick
double _ice_cover = 0.0; // 0.0 = none, 1.0 = thick
double _dust_cover = 0.0; // 0.0 = none, 1.0 = dusty
double _wetness = 0.0; // 0.0 = dry, 1.0 = wet
double _lichen_cover = 0.0; // 0.0 = none, 1.0 = mossy
double _snow_level = -99999.0; // in meters
double _snow_thickness = -99999.0; // 0.0 = thin, 1.0 = thick
double _ice_cover = -99999.0; // 0.0 = none, 1.0 = thick
double _dust_cover = -99999.0; // 0.0 = none, 1.0 = dusty
double _wetness = -99999.0; // 0.0 = dry, 1.0 = wet
double _lichen_cover = -99999.0; // 0.0 = none, 1.0 = mossy
// weather
bool _weather_update = false; // enable weather updates