public static CAAPhysicalMarsDetails Calculate(double JD, bool bHighPrecision)
        {
            //What will be the return value
            CAAPhysicalMarsDetails details = new CAAPhysicalMarsDetails();

            //Step 1
            double T          = (JD - 2451545) / 36525;
            double Lambda0    = 352.9065 + 1.17330 * T;
            double Lambda0rad = AASCoordinateTransformation.DegreesToRadians(Lambda0);
            double Beta0      = 63.2818 - 0.00394 * T;
            double Beta0rad   = AASCoordinateTransformation.DegreesToRadians(Beta0);

            //Step 2
            double l0    = AASEarth.EclipticLongitude(JD, bHighPrecision);
            double l0rad = AASCoordinateTransformation.DegreesToRadians(l0);
            double b0    = AASEarth.EclipticLatitude(JD, bHighPrecision);
            double b0rad = AASCoordinateTransformation.DegreesToRadians(b0);
            double R     = AASEarth.RadiusVector(JD, bHighPrecision);

            double PreviousLightTravelTime = 0;
            double LightTravelTime         = 0;
            double x        = 0;
            double y        = 0;
            double z        = 0;
            bool   bIterate = true;
            double DELTA    = 0;
            double l        = 0;
            double lrad     = 0;
            double b        = 0;
            double r        = 0;

            while (bIterate)
            {
                double JD2 = JD - LightTravelTime;

                //Step 3
                l    = AASMars.EclipticLongitude(JD2, bHighPrecision);
                lrad = AASCoordinateTransformation.DegreesToRadians(l);
                b    = AASMars.EclipticLatitude(JD2, bHighPrecision);
                double brad = AASCoordinateTransformation.DegreesToRadians(b);
                r = AASMars.RadiusVector(JD2, bHighPrecision);

                //Step 4
                x               = r * Math.Cos(brad) * Math.Cos(lrad) - R * Math.Cos(l0rad);
                y               = r * Math.Cos(brad) * Math.Sin(lrad) - R * Math.Sin(l0rad);
                z               = r * Math.Sin(brad) - R * Math.Sin(b0rad);
                DELTA           = Math.Sqrt(x * x + y * y + z * z);
                LightTravelTime = AASElliptical.DistanceToLightTime(DELTA);

                //Prepare for the next loop around
                bIterate = (Math.Abs(LightTravelTime - PreviousLightTravelTime) > 2E-6); //2E-6 correponds to 0.17 of a second
                if (bIterate)
                {
                    PreviousLightTravelTime = LightTravelTime;
                }
            }

            //Step 5
            double lambdarad = Math.Atan2(y, x);
            double lambda    = AASCoordinateTransformation.RadiansToDegrees(lambdarad);
            double betarad   = Math.Atan2(z, Math.Sqrt(x * x + y * y));
            double beta      = AASCoordinateTransformation.RadiansToDegrees(betarad);

            //Step 6
            details.DE = AASCoordinateTransformation.RadiansToDegrees(Math.Asin(-Math.Sin(Beta0rad) * Math.Sin(betarad) - Math.Cos(Beta0rad) * Math.Cos(betarad) * Math.Cos(Lambda0rad - lambdarad)));

            //Step 7
            double N    = 49.5581 + 0.7721 * T;
            double Nrad = AASCoordinateTransformation.DegreesToRadians(N);

            double ldash    = l - 0.00697 / r;
            double ldashrad = AASCoordinateTransformation.DegreesToRadians(ldash);
            double bdash    = b - 0.000225 * (Math.Cos(lrad - Nrad) / r);
            double bdashrad = AASCoordinateTransformation.DegreesToRadians(bdash);

            //Step 8
            details.DS = AASCoordinateTransformation.RadiansToDegrees(Math.Asin(-Math.Sin(Beta0rad) * Math.Sin(bdashrad) - Math.Cos(Beta0rad) * Math.Cos(bdashrad) * Math.Cos(Lambda0rad - ldashrad)));

            //Step 9
            double W = AASCoordinateTransformation.MapTo0To360Range(11.504 + 350.89200025 * (JD - LightTravelTime - 2433282.5));

            //Step 10
            double          e0             = AASNutation.MeanObliquityOfEcliptic(JD);
            double          e0rad          = AASCoordinateTransformation.DegreesToRadians(e0);
            AAS2DCoordinate PoleEquatorial = AASCoordinateTransformation.Ecliptic2Equatorial(Lambda0, Beta0, e0);
            double          alpha0rad      = AASCoordinateTransformation.HoursToRadians(PoleEquatorial.X);
            double          delta0rad      = AASCoordinateTransformation.DegreesToRadians(PoleEquatorial.Y);

            //Step 11
            double u        = y * Math.Cos(e0rad) - z * Math.Sin(e0rad);
            double v        = y * Math.Sin(e0rad) + z * Math.Cos(e0rad);
            double alpharad = Math.Atan2(u, x);
            double alpha    = AASCoordinateTransformation.RadiansToHours(alpharad);
            double deltarad = Math.Atan2(v, Math.Sqrt(x * x + u * u));
            double delta    = AASCoordinateTransformation.RadiansToDegrees(deltarad);
            double xi       = Math.Atan2(Math.Sin(delta0rad) * Math.Cos(deltarad) * Math.Cos(alpha0rad - alpharad) - Math.Sin(deltarad) * Math.Cos(delta0rad), Math.Cos(deltarad) * Math.Sin(alpha0rad - alpharad));

            //Step 12
            details.w = AASCoordinateTransformation.MapTo0To360Range(W - AASCoordinateTransformation.RadiansToDegrees(xi));

            //Step 13
            double NutationInLongitude = AASNutation.NutationInLongitude(JD);
            double NutationInObliquity = AASNutation.NutationInObliquity(JD);

            //Step 14
            lambda += 0.005693 * Math.Cos(l0rad - lambdarad) / Math.Cos(betarad);
            beta   += 0.005693 * Math.Sin(l0rad - lambdarad) * Math.Sin(betarad);

            //Step 15
            Lambda0 += NutationInLongitude / 3600;
            lambda  += NutationInLongitude / 3600;
            e0      += NutationInObliquity / 3600;

            //Step 16
            AAS2DCoordinate ApparentPoleEquatorial = AASCoordinateTransformation.Ecliptic2Equatorial(Lambda0, Beta0, e0);
            double          alpha0dash             = AASCoordinateTransformation.HoursToRadians(ApparentPoleEquatorial.X);
            double          delta0dash             = AASCoordinateTransformation.DegreesToRadians(ApparentPoleEquatorial.Y);
            AAS2DCoordinate ApparentMars           = AASCoordinateTransformation.Ecliptic2Equatorial(lambda, beta, e0);
            double          alphadash = AASCoordinateTransformation.HoursToRadians(ApparentMars.X);
            double          deltadash = AASCoordinateTransformation.DegreesToRadians(ApparentMars.Y);

            //Step 17
            details.P = AASCoordinateTransformation.MapTo0To360Range(AASCoordinateTransformation.RadiansToDegrees(Math.Atan2(Math.Cos(delta0dash) * Math.Sin(alpha0dash - alphadash), Math.Sin(delta0dash) * Math.Cos(deltadash) - Math.Cos(delta0dash) * Math.Sin(deltadash) * Math.Cos(alpha0dash - alphadash))));

            //Step 18
            double          SunLambda     = AASSun.GeometricEclipticLongitude(JD, bHighPrecision);
            double          SunBeta       = AASSun.GeometricEclipticLatitude(JD, bHighPrecision);
            AAS2DCoordinate SunEquatorial = AASCoordinateTransformation.Ecliptic2Equatorial(SunLambda, SunBeta, e0);

            details.X = AASMoonIlluminatedFraction.PositionAngle(SunEquatorial.X, SunEquatorial.Y, alpha, delta);

            //Step 19
            details.d = 9.36 / DELTA;
            details.k = AASIlluminatedFraction.IlluminatedFraction(r, R, DELTA);
            details.q = (1 - details.k) * details.d;

            return(details);
        }
Esempio n. 2
0
        public static AASEllipticalPlanetaryDetails Calculate(double JD, AASEllipticalObject ellipticalObject, bool bHighPrecision)
        {
            //What will the the return value
            AASEllipticalPlanetaryDetails details = new AASEllipticalPlanetaryDetails();

            //Calculate the position of the earth first
            double JD0 = JD;
            double L0  = AASEarth.EclipticLongitude(JD0, bHighPrecision);
            double B0  = AASEarth.EclipticLatitude(JD0, bHighPrecision);
            double R0  = AASEarth.RadiusVector(JD0, bHighPrecision);

            L0 = AASCoordinateTransformation.DegreesToRadians(L0);
            B0 = AASCoordinateTransformation.DegreesToRadians(B0);
            double cosB0 = Math.Cos(B0);

            //Iterate to find the positions adjusting for light-time correction if required
            double L = 0;
            double B = 0;
            double R = 0;

            if (ellipticalObject != AASEllipticalObject.SUN)
            {
                bool   bRecalc      = true;
                bool   bFirstRecalc = true;
                double LPrevious    = 0;
                double BPrevious    = 0;
                double RPrevious    = 0;

                while (bRecalc)
                {
                    switch (ellipticalObject)
                    {
                    case AASEllipticalObject.SUN:

                        L = AASSun.GeometricEclipticLongitude(JD0, bHighPrecision);
                        B = AASSun.GeometricEclipticLatitude(JD0, bHighPrecision);
                        R = AASEarth.RadiusVector(JD0, bHighPrecision);
                        break;

                    case AASEllipticalObject.MERCURY:

                        L = AASMercury.EclipticLongitude(JD0, bHighPrecision);
                        B = AASMercury.EclipticLatitude(JD0, bHighPrecision);
                        R = AASMercury.RadiusVector(JD0, bHighPrecision);
                        break;

                    case AASEllipticalObject.VENUS:

                        L = AASVenus.EclipticLongitude(JD0, bHighPrecision);
                        B = AASVenus.EclipticLatitude(JD0, bHighPrecision);
                        R = AASVenus.RadiusVector(JD0, bHighPrecision);
                        break;

                    case AASEllipticalObject.MARS:

                        L = AASMars.EclipticLongitude(JD0, bHighPrecision);
                        B = AASMars.EclipticLatitude(JD0, bHighPrecision);
                        R = AASMars.RadiusVector(JD0, bHighPrecision);
                        break;

                    case AASEllipticalObject.JUPITER:

                        L = AASJupiter.EclipticLongitude(JD0, bHighPrecision);
                        B = AASJupiter.EclipticLatitude(JD0, bHighPrecision);
                        R = AASJupiter.RadiusVector(JD0, bHighPrecision);
                        break;

                    case AASEllipticalObject.SATURN:

                        L = AASSaturn.EclipticLongitude(JD0, bHighPrecision);
                        B = AASSaturn.EclipticLatitude(JD0, bHighPrecision);
                        R = AASSaturn.RadiusVector(JD0, bHighPrecision);
                        break;

                    case AASEllipticalObject.URANUS:

                        L = AASUranus.EclipticLongitude(JD0, bHighPrecision);
                        B = AASUranus.EclipticLatitude(JD0, bHighPrecision);
                        R = AASUranus.RadiusVector(JD0, bHighPrecision);
                        break;

                    case AASEllipticalObject.NEPTUNE:

                        L = AASNeptune.EclipticLongitude(JD0, bHighPrecision);
                        B = AASNeptune.EclipticLatitude(JD0, bHighPrecision);
                        R = AASNeptune.RadiusVector(JD0, bHighPrecision);
                        break;

                    case AASEllipticalObject.PLUTO:

                        L = AASPluto.EclipticLongitude(JD0);
                        B = AASPluto.EclipticLatitude(JD0);
                        R = AASPluto.RadiusVector(JD0);
                        break;

                    default:
                        break;
                    }

                    if (!bFirstRecalc)
                    {
                        bRecalc   = ((Math.Abs(L - LPrevious) > 0.00001) || (Math.Abs(B - BPrevious) > 0.00001) || (Math.Abs(R - RPrevious) > 0.000001));
                        LPrevious = L;
                        BPrevious = B;
                        RPrevious = R;
                    }
                    else
                    {
                        bFirstRecalc = false;
                    }

                    //Calculate the new value
                    if (bRecalc)
                    {
                        double Lrad     = AASCoordinateTransformation.DegreesToRadians(L);
                        double Brad     = AASCoordinateTransformation.DegreesToRadians(B);
                        double cosB     = Math.Cos(Brad);
                        double cosL     = Math.Cos(Lrad);
                        double x1       = R * cosB * cosL - R0 * cosB0 * Math.Cos(L0);
                        double y1       = R * cosB * Math.Sin(Lrad) - R0 * cosB0 * Math.Sin(L0);
                        double z1       = R * Math.Sin(Brad) - R0 * Math.Sin(B0);
                        double distance = Math.Sqrt(x1 * x1 + y1 * y1 + z1 * z1);

                        //Prepare for the next loop around
                        JD0 = JD - AASElliptical.DistanceToLightTime(distance);
                    }
                }
            }

            double x = 0;
            double y = 0;
            double z = 0;

            if (ellipticalObject != AASEllipticalObject.SUN)
            {
                double Lrad = AASCoordinateTransformation.DegreesToRadians(L);
                double Brad = AASCoordinateTransformation.DegreesToRadians(B);
                double cosB = Math.Cos(Brad);
                double cosL = Math.Cos(Lrad);

                x = R * cosB * cosL - R0 * cosB0 * Math.Cos(L0);
                y = R * cosB * Math.Sin(Lrad) - R0 * cosB0 * Math.Sin(L0);
                z = R * Math.Sin(Brad) - R0 * Math.Sin(B0);
            }
            else
            {
                x = -R0 *cosB0 *Math.Cos(L0);

                y = -R0 *cosB0 *Math.Sin(L0);

                z = -R0 *Math.Sin(B0);
            }

            double x2 = x * x;
            double y2 = y * y;

            details.ApparentGeocentricLatitude  = AASCoordinateTransformation.RadiansToDegrees(Math.Atan2(z, Math.Sqrt(x2 + y2)));
            details.ApparentGeocentricDistance  = Math.Sqrt(x2 + y2 + z * z);
            details.ApparentGeocentricLongitude = AASCoordinateTransformation.MapTo0To360Range(AASCoordinateTransformation.RadiansToDegrees(Math.Atan2(y, x)));
            details.ApparentLightTime           = AASElliptical.DistanceToLightTime(details.ApparentGeocentricDistance);

            //Adjust for Aberration
            AAS2DCoordinate Aberration = AASAberration.EclipticAberration(details.ApparentGeocentricLongitude, details.ApparentGeocentricLatitude, JD, bHighPrecision);

            details.ApparentGeocentricLongitude += Aberration.X;
            details.ApparentGeocentricLatitude  += Aberration.Y;

            //convert to the FK5 system
            double DeltaLong = AASFK5.CorrectionInLongitude(details.ApparentGeocentricLongitude, details.ApparentGeocentricLatitude, JD);

            details.ApparentGeocentricLatitude  += AASFK5.CorrectionInLatitude(details.ApparentGeocentricLongitude, JD);
            details.ApparentGeocentricLongitude += DeltaLong;

            //Correct for nutation
            double NutationInLongitude = AASNutation.NutationInLongitude(JD);
            double Epsilon             = AASNutation.TrueObliquityOfEcliptic(JD);

            details.ApparentGeocentricLongitude += AASCoordinateTransformation.DMSToDegrees(0, 0, NutationInLongitude);

            //Convert to RA and Dec
            AAS2DCoordinate ApparentEqu = AASCoordinateTransformation.Ecliptic2Equatorial(details.ApparentGeocentricLongitude, details.ApparentGeocentricLatitude, Epsilon);

            details.ApparentGeocentricRA          = ApparentEqu.X;
            details.ApparentGeocentricDeclination = ApparentEqu.Y;

            return(details);
        }