public static MoonFracPhaseAngle GetMoonIllumination(DateTime dt)
            {
                double        d     = JulianDays(dt);
                RaDec         s     = SunCoords(d);
                MoonRaDecDist m     = MoonCoords(d);
                double        sdist = 149598000; // distance from Earth to Sun in km
                double        phi   = Math.Acos(Math.Sin(s.dec) * Math.Sin(m.dec) + Math.Cos(s.dec) * Math.Cos(m.dec) * Math.Cos(s.ra - m.ra));
                double        inc   = Math.Atan2(sdist * Math.Sin(phi), m.dist - sdist * Math.Cos(phi));
                double        angle = Math.Atan2(Math.Cos(s.dec) * Math.Sin(s.ra - m.ra), Math.Sin(s.dec) * Math.Cos(m.dec) -
                                                 Math.Cos(s.dec) * Math.Sin(m.dec) * Math.Cos(s.ra - m.ra));

                return(new MoonFracPhaseAngle {
                    fraction = (1 + Math.Cos(inc)) / 2, phase = 0.5 + 0.5 * inc * (angle < 0 ? -1 : 1) / PI, angle = angle
                });
            }
            public static MoonAzAltDistPa GetMoonPosition(DateTime dt, double lat, double lng)
            {
                double lw  = rad * -lng;
                double phi = rad * lat;
                double d   = JulianDays(dt);

                MoonRaDecDist c = MoonCoords(d);
                double        H = SiderealTime(d, lw) - c.ra;
                double        h = Altitude(H, phi, c.dec);
                // formula 14.1 of "Astronomical Algorithms" 2nd edition by Jean Meeus (Willmann-Bell, Richmond) 1998.
                double pa = Math.Atan2(Math.Sin(H), Math.Tan(phi) * Math.Cos(c.dec) - Math.Sin(c.dec) * Math.Cos(H));

                h += AstroRefraction(h); // altitude correction for refraction
                return(new MoonAzAltDistPa {
                    azimuth = Azimuth(H, phi, c.dec), altitude = h, distance = c.dist, parallacticAngle = pa
                });
            }