getMoonLocation function

LatLng getMoonLocation(
  1. DateTime utcNow
)

Calculates the Moon position on a given UTC time.

Implementation

LatLng getMoonLocation(DateTime utcNow) {
  final coef = <double>[0, 0, 0, 0, 0];
  final gst = _toGreenwichMeanSiderealTime(utcNow);

  // -----------------'
  // Initialisations '
  // -----------------'
  var b0 = 0.0;
  var l0 = 0.0;
  var r0 = 0.0;
  final t = _toJulian(utcNow) / 36525.0;
  final t2 = t * t;
  final t3 = t2 * t;
  final t4 = t3 * t;

  // Longitude moyenne de la Lune
  final ll = _deg2rad *
      ((218.3164477 +
              481267.88123421 * t -
              0.0015786 * t2 +
              t3 / 538841.0 -
              t4 / 65194000.0) %
          _t360);

  // Elongation moyenne de la Lune
  coef[0] = _deg2rad *
      ((297.8501921 +
              445267.1114034 * t -
              0.0018819 * t2 +
              t3 / 545868.0 -
              t4 / 113065000.0) %
          _t360);

  // Anomalie moyenne du Soleil
  coef[1] = _deg2rad *
      ((357.5291092 + 35999.0502909 * t - 0.0001536 * t2 + t3 / 24490000.0) %
          _t360);

  // Anomalie moyenne de la Lune
  coef[2] = _deg2rad *
      ((134.9633964 +
              477198.8675055 * t +
              0.0087414 * t2 +
              t3 / 69699.0 -
              t4 / 14712000.0) %
          _t360);

  // Argument de latitude de la Lune
  coef[3] = _deg2rad *
      ((93.272095 +
              483202.0175233 * t -
              0.0036539 * t2 -
              t3 / 3526000.0 +
              t4 / 863310000.0) %
          _t360);

  coef[4] = 1.0 - 0.002516 * t - 0.0000074 * t2;

  // ---------------------'
  // Corps de la methode '
  // ---------------------'
  for (var i = 0; i <= 59; i++) {
    var ang1 = 0.0;
    var ang2 = 0.0;
    var fact1 = 1.0;
    var fact2 = 1.0;
    for (var j = 0; j <= 3; j++) {
      ang1 += coef[j] * _tabCoef1[i][j];
      ang2 += coef[j] * _tabCoef2[i][j];
    }
    if (_tabCoef1[i][1] != 0) {
      fact1 = pow(coef[4], (_tabCoef1[i][1]).abs()).toDouble();
    }
    if (_tabCoef2[i][1] != 0) {
      fact2 = pow(coef[4], (_tabCoef2[i][1]).abs()).toDouble();
    }
    // Terme en longitude
    l0 += _tabLon[i] * fact1 * sin(ang1);

    // Terme en distance
    r0 += _tabDist[i] * fact1 * cos(ang1);

    // Terme en latitude
    b0 += _tabLat[i] * fact2 * sin(ang2);
  }

  // Principaux termes planetaires
  final a1 = _deg2rad * ((119.75 + 131.849 * t) % _t360);
  final a2 = _deg2rad * ((53.09 + 479264.29 * t) % _t360);
  final a3 = _deg2rad * ((313.45 + 481266.484 * t) % _t360);
  l0 += 3958.0 * sin(a1) + 1962.0 * sin(ll - coef[3]) + 318.0 * sin(a2);
  b0 += -2235.0 * sin(ll) +
      382.0 * sin(a3) +
      175.0 * (sin(a1 - coef[3]) + sin(a1 + coef[3])) +
      127.0 * sin(ll - coef[2]) -
      115.0 * sin(ll + coef[2]);

  // Coordonnees ecliptiques en repere spherique
  final lv = ll + _deg2rad * l0 * 0.000001;
  final bt = _deg2rad * b0 * 0.000001;
  final rp = 385000.56 + r0 * 0.001;

  final cb = cos(bt);
  final sb = sin(bt);
  final obliquite = _deg2rad *
      (84381.448 - 46.815 * t - 0.00059 * t2 + 0.001813 * t3) *
      _degPerArcsec;
  final ce = cos(obliquite);
  final se = sin(obliquite);
  final xx = rp * cb * sin(lv);

  final moonX = rp * cb * cos(lv);
  final moonY = xx * ce - rp * se * sb;
  final moonZ = xx * se + rp * ce * sb;

  final latlng = _toLatLng(gst, moonX, moonY, moonZ);

  return latlng;
}