ACE3/addons/weather/functions/fnc_getApproximateAirTemp.sqf

71 lines
2.7 KiB
Plaintext
Raw Normal View History

#include "script_component.hpp"
/*
* Author: LorenLuke
* Returns an approximate representation of temperature at a unit's location.
*
* Arguments:
* 0: Unit <OBJECT>
*
* Return Value:
* None
*
* Example:
* [ACE_player] call ace_weather_fnc_getApproximateAirTemp
*
* Public: No
*/
params ["_unit"];
TRACE_1("params",_unit);
if (isNil (format ["%1", _unit getVariable "ACE_airTemperatureBias"])) then {
_unit setVariable ["ACE_airTemperatureBias", [-(random(3) + 1), random(3) + 1]];
};
private _temperature = ((getPosASL _unit) select 2) call EFUNC(weather,calculateTemperatureAtHeight);
private _humidity = EGVAR(weather,currentHumidity);
private _heatIndex = [_temperature, _humidity] call EFUNC(weather,calculateHeatIndex);
private _chill = [_temperature, _humidity] call EFUNC(weather,calculateWindChill);
private _e = 2^(1/(ln 2));
/*
// Windchill calc with wind vars; https://en.wikipedia.org/wiki/Wind_chill#Australian_Apparent_Temperature
private _windspeed = [getPosASL _unit, true, true, true] call EFUNC(weather,calculateWindSpeed);
private _water_vapor_pressure = _humidity * 6.105 *(_e ^ ((17.27 * _temperature)/(237.7 + _temperature))) / 100;
private _chill = _temperature + (0.33 * _water_vapor_pressure) - (0.70 * _windspeed) - 400;
*/
// sigmoid = f(x) = L / (1 + e^(-k * (x - x_0)));
// L max value, e = euler, k = steepness,
// L = max value
private _sigmoid_L = 1;
// x_0 = sigmoid midpoint, aka 50% proportion; 18.5C, ~65F
private _sigmoid_midpoint = 18.5;
// place +- midpoint with desired proportion
private _sigmoid_valuation = 8.5;
// desired upper and proportion on sigmoid
private _sigmoid_proportion_at_valuation = 0.95;
private _sigmoid_proportion_at_lower_valuation = 1 - _sigmoid_proportion_at_valuation;
// k = steepness
private _sigmoid_k = (ln ((_sigmoid_proportion_at_lower_valuation^-1) - 1) ) / _sigmoid_valuation;
// 5$/95% @ 10C/27C; [5% and 95% values at 50F and ~80F];
// 5% = 0.05 = 1/20 = f(_midpoint - _valuation) = L / (1 + e^(-k * ((_midpoint - _valuation) - _midpoint)
// (0.05)^-1 = 20 = (L / (1 + e^(-k * (-_valuation))) )^-1 = (1 + e^(-k * -_valuation))/L;
// L = 1;> 20 = (1 + e^(k * valuation)); 20 - 1 = e^(k * valuation);
// 19 = e^(k * 8.5); (log_e 19) = (k * 8.5); (log_e 19)/8.5 = k;
// retrieve sigmoid proportion at _temperature
private _temperature_sigmoid = _sigmoid_L / (1 + _e^(-_sigmoid_k * (_temperature - _sigmoid_midpoint)));
// Weighted average between windchill and heat index based on sigmoid levels, plus +- 4deg randomisation
private _apparent_temperature = ((_temperature_sigmoid * _heatIndex) + ((1 - _temperature_sigmoid) * _chill) + random(8) - 4);
[_apparent_temperature, (_unit getVariable "ACE_airTemperatureBias")] call FUNC(displayAirTemp);