times function

({double rise, double set, double transit})? times(
  1. double lat,
  2. double lon,
  3. double deltaT,
  4. double h0,
  5. double th0,
  6. List<double> alpha3,
  7. List<double> delta3,
)

Refined rise, transit, set times using 3-day interpolation.

lat, lon observer coords (radians, lon positive west). deltaT in seconds. h0 standard altitude (radians). th0 apparent sidereal time at Greenwich at 0h UT (seconds, [0..86400)). alpha3 right ascensions for day-1, day0, day+1 (radians). delta3 declinations for day-1, day0, day+1 (radians).

Returns seconds of day. Range [0, 86400). Returns null if body never rises.

Implementation

({double rise, double transit, double set})? times(
    double lat, double lon, double deltaT, double h0,
    double th0, List<double> alpha3, List<double> delta3) {
  final rs = approxTimes(lat, lon, h0, th0, alpha3[1], delta3[1]);
  if (rs == null) return null;

  final d3a = Len3(-_secsPerDay, _secsPerDay, alpha3);
  final d3d = Len3(-_secsPerDay, _secsPerDay, delta3);

  // Adjust transit.
  var mTransit = rs.transit;
  {
    final ut = mTransit + deltaT;
    final alpha = d3a.interpolateX(ut);
    final sth0 = _th0(th0, mTransit);
    final h = -((lon + alpha) * _secsPerDeg * 180 / math.pi - sth0);
    mTransit -= h;
  }

  // Adjust rise and set.
  final sLat = math.sin(lat);
  final cLat = math.cos(lat);

  double adjustRS(double m) {
    final ut = m + deltaT;
    final alpha = d3a.interpolateX(ut);
    final delta = d3d.interpolateX(ut);
    final sth0 = _th0(th0, m);
    final h0Calc = -((lon + alpha) * _secsPerDeg * 180 / math.pi - sth0);
    final hRad = (h0Calc / _secsPerDeg) * _d2r;
    final altitude = math.asin(
        sLat * math.sin(delta) + cLat * math.cos(delta) * math.cos(hRad));
    final dm = _secsPerDay *
        (altitude - h0) /
        (math.cos(delta) * cLat * math.sin(hRad) * 2 * math.pi);
    return m + dm;
  }

  return (
    rise: _mod86400(adjustRS(rs.rise)),
    transit: _mod86400(mTransit),
    set: _mod86400(adjustRS(rs.set)),
  );
}