geocentricDirection function

({Vector3 direction, double distance}) geocentricDirection(
  1. Ephemeris ephemeris,
  2. int target,
  3. double jdTT, {
  4. Corrections corrections = const Corrections(),
})

Direction (unit vector in the GCRS/ICRF frame) and distance (km) from the Earth's centre to body target at jdTT, with corrections applied (except nutation, which only affects the rotation to the frame of date).

Implementation

({Vector3 direction, double distance}) geocentricDirection(
  Ephemeris ephemeris,
  int target,
  double jdTT, {
  Corrections corrections = const Corrections(),
}) {
  final et = (jdTT + tdbMinusTT(jdTT) / 86400 - j2000) * 86400;
  final earth = ephemeris.state(Naif.earth, Naif.solarSystemBarycenter, et);

  // Czas światła: ciało oglądamy tam, gdzie było τ sekund temu,
  // τ = odległość / c; kilka przybliżeń wystarcza do nanosekund.
  var tau = 0.0;
  var body = ephemeris.state(target, Naif.solarSystemBarycenter, et).position;
  if (corrections.lightTime) {
    for (var i = 0; i < 10; i++) {
      final next = (body - earth.position).length / speedOfLight;
      body = ephemeris
          .state(target, Naif.solarSystemBarycenter, et - next)
          .position;
      final done = (next - tau).abs() < 1e-9;
      tau = next;
      if (done) break;
    }
  }
  final geocentric = body - earth.position;
  final distance = geocentric.length;
  var direction = geocentric.unit;

  if (corrections.deflection && target != Naif.sun) {
    final sun = ephemeris
        .state(Naif.sun, Naif.solarSystemBarycenter, et - tau)
        .position;
    // Ciało schowane za tarczą Słońca: jego światło do nas nie dociera,
    // więc ugięcia nie liczymy (tak samo robi NASA JPL Horizons).
    if (!_behindSun(geocentric, sun - earth.position)) {
      direction = deflectLight(direction, body - sun, earth.position - sun);
    }
  }
  if (corrections.aberration) {
    direction = aberrate(direction, earth.velocity * (1 / speedOfLight));
  }
  return (direction: direction, distance: distance);
}