예제 #1
0
  // 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);
    }
  }
예제 #2
0
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();
}