positions function

List<MoonPosition> positions(
  1. double jde,
  2. Planet earth,
  3. Planet saturn
)

Returns positions of the eight major moons of Saturn.

jde is Julian ephemeris day. earth and saturn are VSOP87 planets. Result units are Saturn radii. Access individual moons via index constants (mimas through iapetus).

Implementation

List<MoonPosition> positions(double jde, Planet earth, Planet saturn) {
  final sol = solar.trueVSOP87(earth, jde);
  final s = sol.lon, beta = sol.lat, rr = sol.range;
  final ss = math.sin(s), cs = math.cos(s);
  final sBeta = math.sin(beta);
  var delta = 9.0;
  var x = 0.0, y = 0.0, z = 0.0;
  var jde2 = jde;

  void f() {
    final tau = lightTime(delta);
    jde2 = jde - tau;
    final satPos = saturn.position(jde2);
    final fk5 = toFK5(satPos.lon, satPos.lat, jde2);
    final l = fk5.lon, b = fk5.lat;
    final sl = math.sin(l), cl = math.cos(l);
    final sb = math.sin(b), cb = math.cos(b);
    x = satPos.range * cb * cl + rr * cs;
    y = satPos.range * cb * sl + rr * ss;
    z = satPos.range * sb + rr * sBeta;
    delta = math.sqrt(x * x + y * y + z * z);
  }

  f();
  f();

  var lambda0 = math.atan2(y, x);
  var beta0 = math.atan(z / math.sqrt(x * x + y * y));

  // Precess to B1950
  final ep = EclipticPrecessor(jdeToJulianYear(jde), 1950.0);
  final precessed = ep.precess(lambda0, beta0);
  lambda0 = precessed.lon;
  beta0 = precessed.lat;

  final q = _Qs(jde2);
  final s4 = [
    _R4(), // index 0 unused
    q.mimasMoon(),
    q.enceladusMoon(),
    q.tethysMoon(),
    q.dioneMoon(),
    q.rheaMoon(),
    q.titanMoon(),
    q.hyperionMoon(),
    q.iapetusMoon(),
  ];

  final xArr = List<double>.filled(9, 0);
  final yArr = List<double>.filled(9, 0);
  final zArr = List<double>.filled(9, 0);

  for (var j = 1; j <= 8; j++) {
    final u = s4[j].lambda - s4[j].omega;
    final w = s4[j].omega - 168.8112 * _d;
    final su = math.sin(u), cu = math.cos(u);
    final sw = math.sin(w), cw = math.cos(w);
    final sGamma = math.sin(s4[j].gamma);
    final cGamma = math.cos(s4[j].gamma);
    final r = s4[j].r;
    xArr[j] = r * (cu * cw - su * cGamma * sw);
    yArr[j] = r * (su * cw * cGamma + cu * sw);
    zArr[j] = r * su * sGamma;
  }
  zArr[0] = 1;

  final sLambda0 = math.sin(lambda0), cLambda0 = math.cos(lambda0);
  final sBeta0 = math.sin(beta0), cBeta0 = math.cos(beta0);

  final aArr = List<double>.filled(9, 0);
  final bArr = List<double>.filled(9, 0);
  final cArr = List<double>.filled(9, 0);

  for (var j = 0; j <= 8; j++) {
    var a = xArr[j];
    var b = q.c1 * yArr[j] - q.s1 * zArr[j];
    final c = q.s1 * yArr[j] + q.c1 * zArr[j];
    final a0 = q.c2 * a - q.s2 * b;
    b = q.s2 * a + q.c2 * b;
    a = a0;

    aArr[j] = a * sLambda0 - b * cLambda0;
    b = a * cLambda0 + b * sLambda0;

    bArr[j] = b * cBeta0 + c * sBeta0;
    cArr[j] = c * cBeta0 - b * sBeta0;
  }

  final dd = math.atan2(aArr[0], cArr[0]);
  final sD = math.sin(dd), cD = math.cos(dd);

  final pos = List<MoonPosition>.filled(8, const MoonPosition(0, 0, 0));
  for (var j = 1; j <= 8; j++) {
    var xj = aArr[j] * cD - cArr[j] * sD;
    final yj = aArr[j] * sD + cArr[j] * cD;
    final zj = bArr[j];
    final dv = xj / s4[j].r;
    xj += zj.abs() / _k[j] * math.sqrt(1 - dv * dv);
    final ww = delta / (delta + zj / 2475);
    pos[j - 1] = MoonPosition(xj * ww, yj * ww, zj);
  }
  return pos;
}