anglesFromArmc function

Angles anglesFromArmc(
  1. double armc,
  2. double latitude,
  3. double obliquity
)

Ascendant and MC for sidereal time armc (right ascension of the meridian), latitude and ecliptic obliquity – all in degrees.

Pure spherical geometry, no time or ephemeris. Beyond the polar circle the ascendant is the one of the two intersections of the ecliptic with the horizon that lies east of the meridian.

Implementation

Angles anglesFromArmc(double armc, double latitude, double obliquity) {
  final a = armc * _radian;
  final f = latitude * _radian;
  final e = obliquity * _radian;

  // Układ równika prawdziwego daty: oś x – punkt Barana, oś z – biegun
  // północny świata.
  final zenith = Vector3(
    math.cos(f) * math.cos(a),
    math.cos(f) * math.sin(a),
    math.sin(f),
  );
  final east = Vector3(-math.sin(a), math.cos(a), 0);
  final eclipticPole = Vector3(0, -math.sin(e), math.cos(e));

  // Przecięcia ekliptyki z horyzontem leżą w kierunkach ±k × z
  // (k – biegun ekliptyki, z – zenit, biegun horyzontu).
  var v = eclipticPole.cross(zenith);
  if (v.dot(east) < 0) v = v * -1;
  final onEcliptic = v.rotateX(e);
  final ascendant = math.atan2(onEcliptic.y, onEcliptic.x) / _radian;

  // MC: λ = atan2(sin ARMC, cos ARMC · cos ε).
  final midheaven =
      math.atan2(math.sin(a), math.cos(a) * math.cos(e)) / _radian;

  return Angles(
    ascendant: _normalize(ascendant),
    midheaven: _normalize(midheaven),
    armc: _normalize(armc),
  );
}