// Compute and log the measured periods of the moons. void LogPeriods(Ephemeris<KSP> const& ephemeris) { auto const position = [this, &ephemeris]( not_null<MassiveBody const*> body, Instant const& t) { return ephemeris.trajectory(body)->EvaluatePosition(t, nullptr); }; auto const barycentre = [this, &position](Instant const& t) { BarycentreCalculator<Position<KSP>, Mass> result; for (auto const body : jool_system_) { result.Add(position(body, t), body->mass()); } return result.Get(); }; auto const barycentric_position = [this, &barycentre, &ephemeris, &position]( not_null<MassiveBody const*> body, Instant const& t) { return position(body, t) - barycentre(t); }; for (auto const moon : {laythe_, vall_, tylo_}) { auto const moon_y = [this, &barycentric_position, moon](Instant const& t) { return barycentric_position(moon, t).coordinates().y; }; LOG(INFO) << (moon == laythe_ ? "Laythe" : moon == vall_ ? "Vall" : "Tylo"); Sign const s0(moon_y(game_epoch_)); Instant t0 = game_epoch_; Time const Δt = 45 * Minute; while (Sign(moon_y(t0)) == s0) { t0 += Δt; } // The moon crosses the xz plane between t0 and t0 - Δt. Instant t1 = t0; int const orbits = moon == laythe_ ? 8 : moon == vall_ ? 4 : 2; for (int i = 0; i < orbits; ++i) { while (Sign(moon_y(t1)) != s0) { t1 += Δt; } // The crossing of the xz plane halfway through the orbit occurs between // t1 and t1 - Δt. while (Sign(moon_y(t1)) == s0) { t1 += Δt; } // The |i|th orbit ends between t1 and t1 - Δt. } Time const actual_period = (Bisect(moon_y, t1 - Δt, t1) - Bisect(moon_y, t0 - Δt, t0)) / orbits; Time const expected_period = (2 * π * Radian) / *elements_[moon].mean_motion; LOG(INFO) << "actual period : " << actual_period; LOG(INFO) << "expected period : " << expected_period; LOG(INFO) << "error : " << RelativeError(expected_period, actual_period); } }
T Barycentre(std::vector<T> const& ts, std::vector<Scalar> const& weights) { CHECK_EQ(ts.size(), weights.size()) << "Ts and weights of unequal sizes"; CHECK(!ts.empty()) << "Empty input"; BarycentreCalculator<T, Scalar> calculator; for (std::size_t i = 0; i < ts.size(); ++i) { calculator.Add(ts[i], weights[i]); } return calculator.Get(); }