26constexpr double a_ht = 2.53e-5;
27constexpr double b_ht = 5.49e-3;
28constexpr double c_ht = 1.14e-3;
33std::array<double, 3> interpolateAverage(
double lat)
35 std::array<double, 5> a{ 1.2769934e-3, 1.2683230e-3, 1.2465397e-3, 1.2196049e-3, 1.2045996e-3 };
36 std::array<double, 5> b{ 2.9153695e-3, 2.9152299e-3, 2.9288445e-3, 2.9022565e-3, 2.9024912e-3 };
37 std::array<double, 5> c{ 62.610505e-3, 62.837393e-3, 63.721774e-3, 63.824265e-3, 64.258455e-3 };
40 ls.t = std::clamp(ls.t, 0.0, 1.0);
42 return { std::lerp(a.at(ls.l), a.at(ls.u), ls.t),
43 std::lerp(b.at(ls.l), b.at(ls.u), ls.t),
44 std::lerp(c.at(ls.l), c.at(ls.u), ls.t) };
47std::array<double, 3> interpolateAmplitude(
double lat)
49 std::array<double, 5> a{ 0.0000000e-0, 1.2709626e-5, 2.6523662e-5, 3.4000452e-5, 4.1202191e-5 };
50 std::array<double, 5> b{ 0.0000000e-0, 2.1414979e-5, 3.0160779e-5, 7.2562722e-5, 11.723375e-5 };
51 std::array<double, 5> c{ 0.0000000e-0, 9.0128400e-5, 4.3497037e-5, 84.795348e-5, 170.37206e-5 };
54 ls.t = std::clamp(ls.t, 0.0, 1.0);
56 return { std::lerp(a.at(ls.l), a.at(ls.u), ls.t),
57 std::lerp(b.at(ls.l), b.at(ls.u), ls.t),
58 std::lerp(c.at(ls.l), c.at(ls.u), ls.t) };
61std::array<double, 3> interpolateWet(
double lat)
63 std::array<double, 5> a{ 5.8021897e-4, 5.6794847e-4, 5.8118019e-4, 5.9727542e-4, 6.1641693e-4 };
64 std::array<double, 5> b{ 1.4275268e-3, 1.5138625e-3, 1.4572752e-3, 1.5007428e-3, 1.7599082e-3 };
65 std::array<double, 5> c{ 4.3472961e-2, 4.6729510e-2, 4.3908931e-2, 4.4626982e-2, 5.4736038e-2 };
68 ls.t = std::clamp(ls.t, 0.0, 1.0);
70 return { std::lerp(a.at(ls.l), a.at(ls.u), ls.t),
71 std::lerp(b.at(ls.l), b.at(ls.u), ls.t),
72 std::lerp(c.at(ls.l), c.at(ls.u), ls.t) };
76double mappingNormalizedAtZenith(
double elevation,
double a,
double b,
double c)
78 auto sinE = std::sin(elevation);
79 return (1.0 + a / (1.0 + b / (1.0 + c)))
80 / (sinE + a / (sinE + b / (sinE + c)));
95 double year = (doy - 28.0) / 365.25 + (lla_pos(0) < 0.0 ? 0.5 : 0.0);
96 double cosY = std::cos(2 * M_PI * year);
98 double lat = std::abs(lla_pos(0));
100 auto avg = interpolateAverage(lat);
101 auto amp = interpolateAmplitude(lat);
102 double a_d = avg[0] - amp[0] * cosY;
103 double b_d = avg[1] - amp[1] * cosY;
104 double c_d = avg[2] - amp[2] * cosY;
106 double dm = (1.0 / std::sin(elevation) - mappingNormalizedAtZenith(elevation, a_ht, b_ht, c_ht)) * lla_pos(2) / 1e3;
108 return mappingNormalizedAtZenith(elevation, a_d, b_d, c_d) + dm;