public static double TrueLongitudeAscendingNode(double JD) { double TrueAscendingNode = MeanLongitudeAscendingNode(JD); double D = MeanElongation(JD); D = CAACoordinateTransformation.DegreesToRadians(D); double M = CAAEarth.SunMeanAnomaly(JD); M = CAACoordinateTransformation.DegreesToRadians(M); double Mdash = MeanAnomaly(JD); Mdash = CAACoordinateTransformation.DegreesToRadians(Mdash); double F = ArgumentOfLatitude(JD); F = CAACoordinateTransformation.DegreesToRadians(F); //Add the principal additive terms TrueAscendingNode -= 1.4979 * Math.Sin(2 * (D - F)); TrueAscendingNode -= 0.1500 * Math.Sin(M); TrueAscendingNode -= 0.1226 * Math.Sin(2 * D); TrueAscendingNode += 0.1176 * Math.Sin(2 * F); TrueAscendingNode -= 0.0801 * Math.Sin(2 * (Mdash - F)); return(CAACoordinateTransformation.MapTo0To360Range(TrueAscendingNode)); }
public static CAASelenographicMoonDetails CalculateSelenographicPositionOfSun(double JD) { double R = CAAEarth.RadiusVector(JD) * 149597970; double Delta = CAAMoon.RadiusVector(JD); double lambda0 = CAASun.ApparentEclipticLongitude(JD); double lambda = CAAMoon.EclipticLongitude(JD); double beta = CAAMoon.EclipticLatitude(JD); double lambdah = CAACoordinateTransformation.MapTo0To360Range(lambda0 + 180 + Delta / R * 57.296 * Math.Cos(CAACoordinateTransformation.DegreesToRadians(beta)) * Math.Sin(CAACoordinateTransformation.DegreesToRadians(lambda0 - lambda))); double betah = Delta / R * beta; //What will be the return value CAASelenographicMoonDetails details = new CAASelenographicMoonDetails(); //Calculate the optical libration double omega = 0; double DeltaU = 0; double sigma = 0; double I = 0; double rho = 0; double ldash0 = 0; double bdash0 = 0; double ldash20 = 0; double bdash20 = 0; double epsilon = 0; CalculateOpticalLibration(JD, lambdah, betah, ref ldash0, ref bdash0, ref ldash20, ref bdash20, ref epsilon, ref omega, ref DeltaU, ref sigma, ref I, ref rho); details.l0 = ldash0 + ldash20; details.b0 = bdash0 + bdash20; details.c0 = CAACoordinateTransformation.MapTo0To360Range(450 - details.l0); return(details); }
public static double TrueLongitudeAscendingNode(double JD) { double TrueAscendingNode = MeanLongitudeAscendingNode(JD); double D = MeanElongation(JD); D = CT.D2R(D); double M = CAAEarth.SunMeanAnomaly(JD); M = CT.D2R(M); double Mdash = MeanAnomaly(JD); Mdash = CT.D2R(Mdash); double F = ArgumentOfLatitude(JD); F = CT.D2R(F); //Add the principal additive terms TrueAscendingNode -= 1.4979 * Math.Sin(2 * (D - F)); TrueAscendingNode -= 0.1500 * Math.Sin(M); TrueAscendingNode -= 0.1226 * Math.Sin(2 * D); TrueAscendingNode += 0.1176 * Math.Sin(2 * F); TrueAscendingNode -= 0.0801 * Math.Sin(2 * (Mdash - F)); return(CT.M360(TrueAscendingNode)); }
public static double EclipticLongitude(double JD) { double Ldash = MeanLongitude(JD); double LdashDegrees = Ldash; Ldash = CT.D2R(Ldash); double D = MeanElongation(JD); D = CT.D2R(D); double M = CAAEarth.SunMeanAnomaly(JD); M = CT.D2R(M); double Mdash = MeanAnomaly(JD); Mdash = CT.D2R(Mdash); double F = ArgumentOfLatitude(JD); F = CT.D2R(F); double E = CAAEarth.Eccentricity(JD); double T = (JD - 2451545) / 36525; double A1 = CT.M360(119.75 + 131.849 * T); A1 = CT.D2R(A1); double A2 = CT.M360(53.09 + 479264.290 * T); A2 = CT.D2R(A2); double A3 = CT.M360(313.45 + 481266.484 * T); A3 = CT.D2R(A3); int nLCoefficients = GFX.g_MoonCoefficients1.Length; Debug.Assert(GFX.g_MoonCoefficients2.Length == nLCoefficients); double SigmaL = 0; for (int i = 0; i < nLCoefficients; i++) { double ThisSigma = GFX.g_MoonCoefficients2[i].A * Math.Sin(GFX.g_MoonCoefficients1[i].D * D + GFX.g_MoonCoefficients1[i].M * M + GFX.g_MoonCoefficients1[i].Mdash * Mdash + GFX.g_MoonCoefficients1[i].F * F); if (GFX.g_MoonCoefficients1[i].M != 0) { ThisSigma *= E; } SigmaL += ThisSigma; } //Finally the additive terms SigmaL += 3958 * Math.Sin(A1); SigmaL += 1962 * Math.Sin(Ldash - F); SigmaL += 318 * Math.Sin(A2); //And finally apply the nutation in longitude double NutationInLong = CAANutation.NutationInLongitude(JD); return(CT.M360(LdashDegrees + SigmaL / 1000000 + NutationInLong / 3600)); }
public static double EclipticLatitude(double JD) { double Ldash = MeanLongitude(JD); Ldash = CT.D2R(Ldash); double D = MeanElongation(JD); D = CT.D2R(D); double M = CAAEarth.SunMeanAnomaly(JD); M = CT.D2R(M); double Mdash = MeanAnomaly(JD); Mdash = CT.D2R(Mdash); double F = ArgumentOfLatitude(JD); F = CT.D2R(F); double E = CAAEarth.Eccentricity(JD); double T = (JD - 2451545) / 36525; double A1 = CT.M360(119.75 + 131.849 * T); A1 = CT.D2R(A1); double A2 = CT.M360(53.09 + 479264.290 * T); A2 = CT.D2R(A2); double A3 = CT.M360(313.45 + 481266.484 * T); A3 = CT.D2R(A3); int nBCoefficients = GFX.g_MoonCoefficients3.Length; Debug.Assert(GFX.g_MoonCoefficients4.Length == nBCoefficients); double SigmaB = 0; for (int i = 0; i < nBCoefficients; i++) { double ThisSigma = GFX.g_MoonCoefficients4[i] * Math.Sin(GFX.g_MoonCoefficients3[i].D * D + GFX.g_MoonCoefficients3[i].M * M + GFX.g_MoonCoefficients3[i].Mdash * Mdash + GFX.g_MoonCoefficients3[i].F * F); if (GFX.g_MoonCoefficients3[i].M != 0) { ThisSigma *= E; } SigmaB += ThisSigma; } //Finally the additive terms SigmaB -= 2235 * Math.Sin(Ldash); SigmaB += 382 * Math.Sin(A3); SigmaB += 175 * Math.Sin(A1 - F); SigmaB += 175 * Math.Sin(A1 + F); SigmaB += 127 * Math.Sin(Ldash - Mdash); SigmaB -= 115 * Math.Sin(Ldash + Mdash); return(SigmaB / 1000000); }
//////////////////////////////// Implementation /////////////////////////////// protected static void CalculateOpticalLibration(double JD, double Lambda, double Beta, ref double ldash, ref double bdash, ref double ldash2, ref double bdash2, ref double epsilon, ref double omega, ref double DeltaU, ref double sigma, ref double I, ref double rho) { //Calculate the initial quantities double Lambdarad = CAACoordinateTransformation.DegreesToRadians(Lambda); double Betarad = CAACoordinateTransformation.DegreesToRadians(Beta); I = CAACoordinateTransformation.DegreesToRadians(1.54242); DeltaU = CAACoordinateTransformation.DegreesToRadians(CAANutation.NutationInLongitude(JD) / 3600); double F = CAACoordinateTransformation.DegreesToRadians(CAAMoon.ArgumentOfLatitude(JD)); omega = CAACoordinateTransformation.DegreesToRadians(CAAMoon.MeanLongitudeAscendingNode(JD)); epsilon = CAANutation.MeanObliquityOfEcliptic(JD) + CAANutation.NutationInObliquity(JD) / 3600; //Calculate the optical librations double W = Lambdarad - DeltaU / 3600 - omega; double A = Math.Atan2(Math.Sin(W) * Math.Cos(Betarad) * Math.Cos(I) - Math.Sin(Betarad) * Math.Sin(I), Math.Cos(W) * Math.Cos(Betarad)); ldash = CAACoordinateTransformation.MapTo0To360Range(CAACoordinateTransformation.RadiansToDegrees(A) - CAACoordinateTransformation.RadiansToDegrees(F)); if (ldash > 180) { ldash -= 360; } bdash = Math.Asin(-Math.Sin(W) * Math.Cos(Betarad) * Math.Sin(I) - Math.Sin(Betarad) * Math.Cos(I)); //Calculate the physical librations double T = (JD - 2451545.0) / 36525; double K1 = 119.75 + 131.849 * T; K1 = CAACoordinateTransformation.DegreesToRadians(K1); double K2 = 72.56 + 20.186 * T; K2 = CAACoordinateTransformation.DegreesToRadians(K2); double M = CAAEarth.SunMeanAnomaly(JD); M = CAACoordinateTransformation.DegreesToRadians(M); double Mdash = CAAMoon.MeanAnomaly(JD); Mdash = CAACoordinateTransformation.DegreesToRadians(Mdash); double D = CAAMoon.MeanElongation(JD); D = CAACoordinateTransformation.DegreesToRadians(D); double E = CAAEarth.Eccentricity(JD); rho = -0.02752 * Math.Cos(Mdash) + -0.02245 * Math.Sin(F) + 0.00684 * Math.Cos(Mdash - 2 * F) + -0.00293 * Math.Cos(2 * F) + -0.00085 * Math.Cos(2 * F - 2 * D) + -0.00054 * Math.Cos(Mdash - 2 * D) + -0.00020 * Math.Sin(Mdash + F) + -0.00020 * Math.Cos(Mdash + 2 * F) + -0.00020 * Math.Cos(Mdash - F) + 0.00014 * Math.Cos(Mdash + 2 * F - 2 * D); sigma = -0.02816 * Math.Sin(Mdash) + 0.02244 * Math.Cos(F) + -0.00682 * Math.Sin(Mdash - 2 * F) + -0.00279 * Math.Sin(2 * F) + -0.00083 * Math.Sin(2 * F - 2 * D) + 0.00069 * Math.Sin(Mdash - 2 * D) + 0.00040 * Math.Cos(Mdash + F) + -0.00025 * Math.Sin(2 * Mdash) + -0.00023 * Math.Sin(Mdash + 2 * F) + 0.00020 * Math.Cos(Mdash - F) + 0.00019 * Math.Sin(Mdash - F) + 0.00013 * Math.Sin(Mdash + 2 * F - 2 * D) + -0.00010 * Math.Cos(Mdash - 3 * F); double tau = 0.02520 * E * Math.Sin(M) + 0.00473 * Math.Sin(2 * Mdash - 2 * F) + -0.00467 * Math.Sin(Mdash) + 0.00396 * Math.Sin(K1) + 0.00276 * Math.Sin(2 * Mdash - 2 * D) + 0.00196 * Math.Sin(omega) + -0.00183 * Math.Cos(Mdash - F) + 0.00115 * Math.Sin(Mdash - 2 * D) + -0.00096 * Math.Sin(Mdash - D) + 0.00046 * Math.Sin(2 * F - 2 * D) + -0.00039 * Math.Sin(Mdash - F) + -0.00032 * Math.Sin(Mdash - M - D) + 0.00027 * Math.Sin(2 * Mdash - M - 2 * D) + 0.00023 * Math.Sin(K2) + -0.00014 * Math.Sin(2 * D) + 0.00014 * Math.Cos(2 * Mdash - 2 * F) + -0.00012 * Math.Sin(Mdash - 2 * F) + -0.00012 * Math.Sin(2 * Mdash) + 0.00011 * Math.Sin(2 * Mdash - 2 * M - 2 * D); ldash2 = -tau + (rho * Math.Cos(A) + sigma * Math.Sin(A)) * Math.Tan(bdash); bdash = CAACoordinateTransformation.RadiansToDegrees(bdash); bdash2 = sigma * Math.Cos(A) - rho * Math.Sin(A); }
public static double ApparentEclipticLongitude(double JD) { double Longitude = GeometricFK5EclipticLongitude(JD); //Apply the correction in longitude due to nutation Longitude += CAACoordinateTransformation.DMSToDegrees(0, 0, CAANutation.NutationInLongitude(JD)); //Apply the correction in longitude due to aberration double R = CAAEarth.RadiusVector(JD); Longitude -= CAACoordinateTransformation.DMSToDegrees(0, 0, 20.4898 / R); return(Longitude); }
public static double RadiusVector(double JD) { double Ldash = MeanLongitude(JD); Ldash = CT.D2R(Ldash); double D = MeanElongation(JD); D = CT.D2R(D); double M = CAAEarth.SunMeanAnomaly(JD); M = CT.D2R(M); double Mdash = MeanAnomaly(JD); Mdash = CT.D2R(Mdash); double F = ArgumentOfLatitude(JD); F = CT.D2R(F); double E = CAAEarth.Eccentricity(JD); double T = (JD - 2451545) / 36525; double A1 = CT.M360(119.75 + 131.849 * T); A1 = CT.D2R(A1); double A2 = CT.M360(53.09 + 479264.290 * T); A2 = CT.D2R(A2); double A3 = CT.M360(313.45 + 481266.484 * T); A3 = CT.D2R(A3); int nRCoefficients = GFX.g_MoonCoefficients1.Length; Debug.Assert(GFX.g_MoonCoefficients2.Length == nRCoefficients); double SigmaR = 0; for (int i = 0; i < nRCoefficients; i++) { double ThisSigma = GFX.g_MoonCoefficients2[i].B * Math.Cos(GFX.g_MoonCoefficients1[i].D * D + GFX.g_MoonCoefficients1[i].M * M + GFX.g_MoonCoefficients1[i].Mdash * Mdash + GFX.g_MoonCoefficients1[i].F * F); if (GFX.g_MoonCoefficients1[i].M != 0) { ThisSigma *= E; } SigmaR += ThisSigma; } return(385000.56 + SigmaR / 1000); }
public static CAA3DCoordinate EclipticRectangularCoordinatesMeanEquinox(double JD) { double Longitude = CAACoordinateTransformation.DegreesToRadians(GeometricFK5EclipticLongitude(JD)); double Latitude = CAACoordinateTransformation.DegreesToRadians(GeometricFK5EclipticLatitude(JD)); double R = CAAEarth.RadiusVector(JD); double epsilon = CAACoordinateTransformation.DegreesToRadians(CAANutation.MeanObliquityOfEcliptic(JD)); CAA3DCoordinate @value = new CAA3DCoordinate(); @value.X = R * Math.Cos(Latitude) * Math.Cos(Longitude); @value.Y = R * (Math.Cos(Latitude) * Math.Sin(Longitude) * Math.Cos(epsilon) - Math.Sin(Latitude) * Math.Sin(epsilon)); @value.Z = R * (Math.Cos(Latitude) * Math.Sin(Longitude) * Math.Sin(epsilon) + Math.Sin(Latitude) * Math.Cos(epsilon)); return(@value); }
public static C3D EclipticRectangularCoordinatesMeanEquinox(double JD) { double Longitude = CT.D2R(GeometricFK5EclipticLongitude(JD)); double Latitude = CT.D2R(GeometricFK5EclipticLatitude(JD)); double R = CAAEarth.RadiusVector(JD); double epsilon = CT.D2R(CAANutation.MeanObliquityOfEcliptic(JD)); C3D @value = new C3D(); @value.X = R * Math.Cos(Latitude) * Math.Cos(Longitude); @value.Y = R * (Math.Cos(Latitude) * Math.Sin(Longitude) * Math.Cos(epsilon) - Math.Sin(Latitude) * Math.Sin(epsilon)); @value.Z = R * (Math.Cos(Latitude) * Math.Sin(Longitude) * Math.Sin(epsilon) + Math.Sin(Latitude) * Math.Cos(epsilon)); return(@value); }
private void ComputeFrameSynodic(RenderContext11 renderContext) { // A synodic frame is a rotating frame of reference in which // the x-axis is the direction between the bodies in a two-body // system. The origin is at the secondary body, and +x points // in the direction opposite the primary. The z-axis is in the orbital // plane and normal to x; it points in the direction of the instantaneous // orbital velocity of the secondary. // The origin is offset by then translation. The five libration points in a // two-body system can be approximated by choosing different offsets. For // example, the Sun-Earth L2 point is approximated by using x = 1,500,000 km, y = 0 and z = 0. WorldMatrix = Matrix3d.Identity; double localScale = (1 / renderContext.NominalRadius) * Scale * MeanRadius; WorldMatrix.Scale(new Vector3d(localScale, localScale, localScale)); WorldMatrix.Rotate(Quaternion.RotationYawPitchRoll((float)((Heading) / 180.0 * Math.PI), (float)(Pitch / 180.0 * Math.PI), (float)(Roll / 180.0 * Math.PI))); WorldMatrix.Translate(Translation / 6371.000); // Currently we assume the Sun-Earth system double jd = SpaceTimeController.JNow; double B = CAACoordinateTransformation.DegreesToRadians(CAAEarth.EclipticLatitude(jd)); double L = CAACoordinateTransformation.DegreesToRadians(CAAEarth.EclipticLongitude(jd)); Vector3d eclPos = new Vector3d(Math.Cos(L) * Math.Cos(B), Math.Sin(L) * Math.Cos(B), Math.Sin(B)); // Just approximate the orbital velocity for now Vector3d eclVel = Vector3d.Cross(eclPos, new Vector3d(0.0, 0.0, 1.0)); eclVel.Normalize(); // Convert to WWT's coordinate convention by swapping Y and Z eclPos = new Vector3d(eclPos.X, eclPos.Z, eclPos.Y); eclVel = new Vector3d(eclVel.X, eclVel.Z, eclVel.Y); Vector3d xaxis = eclPos; Vector3d yaxis = Vector3d.Cross(eclVel, eclPos); Vector3d zaxis = eclVel; Matrix3d rotation = new Matrix3d(xaxis.X, yaxis.X, zaxis.X, 0, xaxis.Y, yaxis.Y, zaxis.Y, 0, xaxis.Z, yaxis.Z, zaxis.Z, 0, 0, 0, 0, 1); // Convert from ecliptic to J2000 EME (equatorial) system double earthObliquity = CAACoordinateTransformation.DegreesToRadians(Coordinates.MeanObliquityOfEcliptic(jd)); rotation = rotation * Matrix3d.RotationX(-earthObliquity); WorldMatrix.Multiply(rotation); }
public static CAA3DCoordinate EclipticRectangularCoordinatesJ2000(double JD) { double Longitude = GeometricEclipticLongitudeJ2000(JD); Longitude = CAACoordinateTransformation.DegreesToRadians(Longitude); double Latitude = GeometricEclipticLatitudeJ2000(JD); Latitude = CAACoordinateTransformation.DegreesToRadians(Latitude); double R = CAAEarth.RadiusVector(JD); CAA3DCoordinate @value = new CAA3DCoordinate(); double coslatitude = Math.Cos(Latitude); @value.X = R * coslatitude * Math.Cos(Longitude); @value.Y = R * coslatitude * Math.Sin(Longitude); @value.Z = R * Math.Sin(Latitude); return(@value); }
public static C3D EclipticRectangularCoordinatesJ2000(double JD) { double Longitude = GeometricEclipticLongitudeJ2000(JD); Longitude = CT.D2R(Longitude); double Latitude = GeometricEclipticLatitudeJ2000(JD); Latitude = CT.D2R(Latitude); double R = CAAEarth.RadiusVector(JD); C3D @value = new C3D(); double coslatitude = Math.Cos(Latitude); @value.X = R * coslatitude * Math.Cos(Longitude); @value.Y = R * coslatitude * Math.Sin(Longitude); @value.Z = R * Math.Sin(Latitude); return(@value); }
//Static methods //////////////////////////////// Implementation /////////////////////////////// public static CAAPhysicalSunDetails Calculate(double JD) { double theta = CAACoordinateTransformation.MapTo0To360Range((JD - 2398220) * 360 / 25.38); double I = 7.25; double K = 73.6667 + 1.3958333 * (JD - 2396758) / 36525; //Calculate the apparent longitude of the sun (excluding the effect of nutation) double L = CAAEarth.EclipticLongitude(JD); double R = CAAEarth.RadiusVector(JD); double SunLong = L + 180 - CAACoordinateTransformation.DMSToDegrees(0, 0, 20.4898 / R); double SunLongDash = SunLong + CAACoordinateTransformation.DMSToDegrees(0, 0, CAANutation.NutationInLongitude(JD)); double epsilon = CAANutation.TrueObliquityOfEcliptic(JD); //Convert to radians epsilon = CAACoordinateTransformation.DegreesToRadians(epsilon); SunLong = CAACoordinateTransformation.DegreesToRadians(SunLong); SunLongDash = CAACoordinateTransformation.DegreesToRadians(SunLongDash); K = CAACoordinateTransformation.DegreesToRadians(K); I = CAACoordinateTransformation.DegreesToRadians(I); theta = CAACoordinateTransformation.DegreesToRadians(theta); double x = Math.Atan(-Math.Cos(SunLong) * Math.Tan(epsilon)); double y = Math.Atan(-Math.Cos(SunLong - K) * Math.Tan(I)); CAAPhysicalSunDetails details = new CAAPhysicalSunDetails(); details.P = CAACoordinateTransformation.RadiansToDegrees(x + y); details.B0 = CAACoordinateTransformation.RadiansToDegrees(Math.Asin(Math.Sin(SunLong - K) * Math.Sin(I))); double eta = Math.Atan(Math.Tan(SunLong - K) * Math.Cos(I)); details.L0 = CAACoordinateTransformation.MapTo0To360Range(CAACoordinateTransformation.RadiansToDegrees(eta - theta)); return(details); }
//Static methods public static CAASaturnMoonsDetails Calculate(double JD) { //Calculate the position of the Sun double sunlong = CAASun.GeometricEclipticLongitude(JD); double sunlongrad = CAACoordinateTransformation.DegreesToRadians(sunlong); double beta = CAASun.GeometricEclipticLatitude(JD); double betarad = CAACoordinateTransformation.DegreesToRadians(beta); double R = CAAEarth.RadiusVector(JD); //Calculate the the light travel time from Saturn to the Earth double DELTA = 9; double PreviousEarthLightTravelTime = 0; double EarthLightTravelTime = CAAElliptical.DistanceToLightTime(DELTA); double JD1 = JD - EarthLightTravelTime; bool bIterate = true; double x = 0; double y = 0; double z = 0; double l = 0; double lrad = 0; double b = 0; double brad = 0; double r = 0; while (bIterate) { //Calculate the position of Jupiter l = CAASaturn.EclipticLongitude(JD1); lrad = CAACoordinateTransformation.DegreesToRadians(l); b = CAASaturn.EclipticLatitude(JD1); brad = CAACoordinateTransformation.DegreesToRadians(b); r = CAASaturn.RadiusVector(JD1); x = r * Math.Cos(brad) * Math.Cos(lrad) + R * Math.Cos(sunlongrad); y = r * Math.Cos(brad) * Math.Sin(lrad) + R * Math.Sin(sunlongrad); z = r * Math.Sin(brad) + R * Math.Sin(betarad); DELTA = Math.Sqrt(x * x + y * y + z * z); EarthLightTravelTime = CAAElliptical.DistanceToLightTime(DELTA); //Prepare for the next loop around bIterate = (Math.Abs(EarthLightTravelTime - PreviousEarthLightTravelTime) > 2E-6); //2E-6 corresponds to 0.17 of a second if (bIterate) { JD1 = JD - EarthLightTravelTime; PreviousEarthLightTravelTime = EarthLightTravelTime; } } //Calculate the details as seen from the earth CAASaturnMoonsDetails details1 = CalculateHelper(JD, sunlongrad, betarad, R); FillInPhenomenaDetails(ref details1.Satellite1); FillInPhenomenaDetails(ref details1.Satellite2); FillInPhenomenaDetails(ref details1.Satellite3); FillInPhenomenaDetails(ref details1.Satellite4); FillInPhenomenaDetails(ref details1.Satellite5); FillInPhenomenaDetails(ref details1.Satellite6); FillInPhenomenaDetails(ref details1.Satellite7); FillInPhenomenaDetails(ref details1.Satellite8); //Calculate the the light travel time from Saturn to the Sun JD1 = JD - EarthLightTravelTime; l = CAASaturn.EclipticLongitude(JD1); lrad = CAACoordinateTransformation.DegreesToRadians(l); b = CAASaturn.EclipticLatitude(JD1); brad = CAACoordinateTransformation.DegreesToRadians(b); r = CAASaturn.RadiusVector(JD1); x = r * Math.Cos(brad) * Math.Cos(lrad); y = r * Math.Cos(brad) * Math.Sin(lrad); z = r * Math.Sin(brad); DELTA = Math.Sqrt(x * x + y * y + z * z); double SunLightTravelTime = CAAElliptical.DistanceToLightTime(DELTA); //Calculate the details as seen from the Sun CAASaturnMoonsDetails details2 = CalculateHelper(JD + SunLightTravelTime - EarthLightTravelTime, sunlongrad, betarad, 0); FillInPhenomenaDetails(ref details2.Satellite1); FillInPhenomenaDetails(ref details2.Satellite2); FillInPhenomenaDetails(ref details2.Satellite3); FillInPhenomenaDetails(ref details2.Satellite4); FillInPhenomenaDetails(ref details2.Satellite5); FillInPhenomenaDetails(ref details2.Satellite6); FillInPhenomenaDetails(ref details2.Satellite7); FillInPhenomenaDetails(ref details2.Satellite8); //Finally transfer the required values from details2 to details1 details1.Satellite1.bInEclipse = details2.Satellite1.bInOccultation; details1.Satellite2.bInEclipse = details2.Satellite2.bInOccultation; details1.Satellite3.bInEclipse = details2.Satellite3.bInOccultation; details1.Satellite4.bInEclipse = details2.Satellite4.bInOccultation; details1.Satellite5.bInEclipse = details2.Satellite5.bInOccultation; details1.Satellite6.bInEclipse = details2.Satellite6.bInOccultation; details1.Satellite7.bInEclipse = details2.Satellite7.bInOccultation; details1.Satellite8.bInEclipse = details2.Satellite8.bInOccultation; details1.Satellite1.bInShadowTransit = details2.Satellite1.bInTransit; details1.Satellite2.bInShadowTransit = details2.Satellite2.bInTransit; details1.Satellite3.bInShadowTransit = details2.Satellite3.bInTransit; details1.Satellite4.bInShadowTransit = details2.Satellite4.bInTransit; details1.Satellite5.bInShadowTransit = details2.Satellite5.bInTransit; details1.Satellite6.bInShadowTransit = details2.Satellite6.bInTransit; details1.Satellite7.bInShadowTransit = details2.Satellite7.bInTransit; details1.Satellite8.bInShadowTransit = details2.Satellite8.bInTransit; return(details1); }
public static double GeometricEclipticLongitudeJ2000(double JD) { return(CT.M360(CAAEarth.EclipticLongitudeJ2000(JD) + 180)); }
public static double GeometricEclipticLongitudeJ2000(double JD) { return(CAACoordinateTransformation.MapTo0To360Range(CAAEarth.EclipticLongitudeJ2000(JD) + 180)); }
public static double GeometricEclipticLatitudeJ2000(double JD) { return(-CAAEarth.EclipticLatitudeJ2000(JD)); }
public static EPD Calculate(double JD, EO @object) { //What will the the return value EPD details = new EPD(); double JD0 = JD; double L0 = 0; double B0 = 0; double R0 = 0; double cosB0 = 0; if (@object != EO.SUN) { L0 = CAAEarth.EclipticLongitude(JD0); B0 = CAAEarth.EclipticLatitude(JD0); R0 = CAAEarth.RadiusVector(JD0); L0 = CT.D2R(L0); B0 = CT.D2R(B0); cosB0 = Math.Cos(B0); } //Calculate the initial values double L = 0; double B = 0; double R = 0; double Lrad; double Brad; double cosB; double cosL; double x; double y; double z; bool bRecalc = true; bool bFirstRecalc = true; double LPrevious = 0; double BPrevious = 0; double RPrevious = 0; while (bRecalc) { switch (@object) { case EO.SUN: { L = CAASun.GeometricEclipticLongitude(JD0); B = CAASun.GeometricEclipticLatitude(JD0); R = CAAEarth.RadiusVector(JD0); break; } case EO.MERCURY: { L = CAAMercury.EclipticLongitude(JD0); B = CAAMercury.EclipticLatitude(JD0); R = CAAMercury.RadiusVector(JD0); break; } case EO.VENUS: { L = CAAVenus.EclipticLongitude(JD0); B = CAAVenus.EclipticLatitude(JD0); R = CAAVenus.RadiusVector(JD0); break; } case EO.MARS: { L = CAAMars.EclipticLongitude(JD0); B = CAAMars.EclipticLatitude(JD0); R = CAAMars.RadiusVector(JD0); break; } case EO.JUPITER: { L = CAAJupiter.EclipticLongitude(JD0); B = CAAJupiter.EclipticLatitude(JD0); R = CAAJupiter.RadiusVector(JD0); break; } case EO.SATURN: { L = CAASaturn.EclipticLongitude(JD0); B = CAASaturn.EclipticLatitude(JD0); R = CAASaturn.RadiusVector(JD0); break; } case EO.URANUS: { L = CAAUranus.EclipticLongitude(JD0); B = CAAUranus.EclipticLatitude(JD0); R = CAAUranus.RadiusVector(JD0); break; } case EO.NEPTUNE: { L = CAANeptune.EclipticLongitude(JD0); B = CAANeptune.EclipticLatitude(JD0); R = CAANeptune.RadiusVector(JD0); break; } case EO.PLUTO: { L = CAAPluto.EclipticLongitude(JD0); B = CAAPluto.EclipticLatitude(JD0); R = CAAPluto.RadiusVector(JD0); break; } default: { Debug.Assert(false); 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 distance = 0; if (@object != EO.SUN) { Lrad = CT.D2R(L); Brad = CT.D2R(B); cosB = Math.Cos(Brad); 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); distance = Math.Sqrt(x * x + y * y + z * z); } else { distance = R; //Distance to the sun from the earth is in fact the radius vector } //Prepare for the next loop around JD0 = JD - ELL.DistanceToLightTime(distance); } } Lrad = CT.D2R(L); Brad = CT.D2R(B); cosB = Math.Cos(Brad); 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); double x2 = x * x; double y2 = y * y; details.ApparentGeocentricLatitude = CT.R2D(Math.Atan2(z, Math.Sqrt(x2 + y2))); details.ApparentGeocentricDistance = Math.Sqrt(x2 + y2 + z * z); details.ApparentGeocentricLongitude = CT.M360(CT.R2D(Math.Atan2(y, x))); details.ApparentLightTime = ELL.DistanceToLightTime(details.ApparentGeocentricDistance); //Adjust for Aberration COR Aberration = ABR.EclipticAberration(details.ApparentGeocentricLongitude, details.ApparentGeocentricLatitude, JD); details.ApparentGeocentricLongitude += Aberration.X; details.ApparentGeocentricLatitude += Aberration.Y; //convert to the FK5 system double DeltaLong = CAAFK5.CorrectionInLongitude(details.ApparentGeocentricLongitude, details.ApparentGeocentricLatitude, JD); details.ApparentGeocentricLatitude += CAAFK5.CorrectionInLatitude(details.ApparentGeocentricLongitude, JD); details.ApparentGeocentricLongitude += DeltaLong; //Correct for nutation double NutationInLongitude = CAANutation.NutationInLongitude(JD); double Epsilon = CAANutation.TrueObliquityOfEcliptic(JD); details.ApparentGeocentricLongitude += CT.DMS2D(0, 0, NutationInLongitude); //Convert to RA and Dec COR ApparentEqu = CT.Ec2Eq(details.ApparentGeocentricLongitude, details.ApparentGeocentricLatitude, Epsilon); details.ApparentGeocentricRA = ApparentEqu.X; details.ApparentGeocentricDeclination = ApparentEqu.Y; return(details); }
//Static methods public static CAAGalileanMoonsDetails Calculate(double JD) { //Calculate the position of the Sun double sunlong = CAASun.GeometricEclipticLongitude(JD); double sunlongrad = CAACoordinateTransformation.DegreesToRadians(sunlong); double beta = CAASun.GeometricEclipticLatitude(JD); double betarad = CAACoordinateTransformation.DegreesToRadians(beta); double R = CAAEarth.RadiusVector(JD); //Calculate the the light travel time from Jupiter to the Earth double DELTA = 5; double PreviousEarthLightTravelTime = 0; double EarthLightTravelTime = CAAElliptical.DistanceToLightTime(DELTA); double JD1 = JD - EarthLightTravelTime; bool bIterate = true; double x = 0; double y = 0; double z = 0; double l = 0; double lrad = 0; double b = 0; double brad = 0; double r = 0; while (bIterate) { //Calculate the position of Jupiter l = CAAJupiter.EclipticLongitude(JD1); lrad = CAACoordinateTransformation.DegreesToRadians(l); b = CAAJupiter.EclipticLatitude(JD1); brad = CAACoordinateTransformation.DegreesToRadians(b); r = CAAJupiter.RadiusVector(JD1); x = r * Math.Cos(brad) * Math.Cos(lrad) + R * Math.Cos(sunlongrad); y = r * Math.Cos(brad) * Math.Sin(lrad) + R * Math.Sin(sunlongrad); z = r * Math.Sin(brad) + R * Math.Sin(betarad); DELTA = Math.Sqrt(x * x + y * y + z * z); EarthLightTravelTime = CAAElliptical.DistanceToLightTime(DELTA); //Prepare for the next loop around bIterate = (Math.Abs(EarthLightTravelTime - PreviousEarthLightTravelTime) > 2E-6); //2E-6 corresponds to 0.17 of a second if (bIterate) { JD1 = JD - EarthLightTravelTime; PreviousEarthLightTravelTime = EarthLightTravelTime; } } //Calculate the details as seen from the earth CAAGalileanMoonsDetails details1 = CalculateHelper(JD, sunlongrad, betarad, R); FillInPhenomenaDetails(ref details1.Satellite1); FillInPhenomenaDetails(ref details1.Satellite2); FillInPhenomenaDetails(ref details1.Satellite3); FillInPhenomenaDetails(ref details1.Satellite4); //Calculate the the light travel time from Jupiter to the Sun JD1 = JD - EarthLightTravelTime; l = CAAJupiter.EclipticLongitude(JD1); lrad = CAACoordinateTransformation.DegreesToRadians(l); b = CAAJupiter.EclipticLatitude(JD1); brad = CAACoordinateTransformation.DegreesToRadians(b); r = CAAJupiter.RadiusVector(JD1); x = r * Math.Cos(brad) * Math.Cos(lrad); y = r * Math.Cos(brad) * Math.Sin(lrad); z = r * Math.Sin(brad); DELTA = Math.Sqrt(x * x + y * y + z * z); double SunLightTravelTime = CAAElliptical.DistanceToLightTime(DELTA); //Calculate the details as seen from the Sun CAAGalileanMoonsDetails details2 = CalculateHelper(JD + SunLightTravelTime - EarthLightTravelTime, sunlongrad, betarad, 0); FillInPhenomenaDetails(ref details2.Satellite1); FillInPhenomenaDetails(ref details2.Satellite2); FillInPhenomenaDetails(ref details2.Satellite3); FillInPhenomenaDetails(ref details2.Satellite4); //Finally transfer the required values from details2 to details1 details1.Satellite1.bInEclipse = details2.Satellite1.bInOccultation; details1.Satellite2.bInEclipse = details2.Satellite2.bInOccultation; details1.Satellite3.bInEclipse = details2.Satellite3.bInOccultation; details1.Satellite4.bInEclipse = details2.Satellite4.bInOccultation; details1.Satellite1.bInShadowTransit = details2.Satellite1.bInTransit; details1.Satellite2.bInShadowTransit = details2.Satellite2.bInTransit; details1.Satellite3.bInShadowTransit = details2.Satellite3.bInTransit; details1.Satellite4.bInShadowTransit = details2.Satellite4.bInTransit; //C++ TO C# CONVERTER WARNING: The following line was determined to be a copy assignment (rather than a reference assignment) - this should be verified and a 'CopyFrom' method should be created if it does not yet exist: //ORIGINAL LINE: details1.Satellite1.ApparentShadowRectangularCoordinates = details2.Satellite1.ApparentRectangularCoordinates; details1.Satellite1.ApparentShadowRectangularCoordinates = details2.Satellite1.ApparentRectangularCoordinates; //C++ TO C# CONVERTER WARNING: The following line was determined to be a copy assignment (rather than a reference assignment) - this should be verified and a 'CopyFrom' method should be created if it does not yet exist: //ORIGINAL LINE: details1.Satellite2.ApparentShadowRectangularCoordinates = details2.Satellite2.ApparentRectangularCoordinates; details1.Satellite2.ApparentShadowRectangularCoordinates = details2.Satellite2.ApparentRectangularCoordinates; //C++ TO C# CONVERTER WARNING: The following line was determined to be a copy assignment (rather than a reference assignment) - this should be verified and a 'CopyFrom' method should be created if it does not yet exist: //ORIGINAL LINE: details1.Satellite3.ApparentShadowRectangularCoordinates = details2.Satellite3.ApparentRectangularCoordinates; details1.Satellite3.ApparentShadowRectangularCoordinates = details2.Satellite3.ApparentRectangularCoordinates; //C++ TO C# CONVERTER WARNING: The following line was determined to be a copy assignment (rather than a reference assignment) - this should be verified and a 'CopyFrom' method should be created if it does not yet exist: //ORIGINAL LINE: details1.Satellite4.ApparentShadowRectangularCoordinates = details2.Satellite4.ApparentRectangularCoordinates; details1.Satellite4.ApparentShadowRectangularCoordinates = details2.Satellite4.ApparentRectangularCoordinates; return(details1); }
//Static methods //////////////////////////////// Implementation /////////////////////////////// public static CAASaturnRingDetails Calculate(double JD) { //What will be the return value CAASaturnRingDetails details = new CAASaturnRingDetails(); double T = (JD - 2451545) / 36525; double T2 = T * T; //Step 1. Calculate the inclination of the plane of the ring and the longitude of the ascending node referred to the ecliptic and mean equinox of the date double i = 28.075216 - 0.012998 * T + 0.000004 * T2; double irad = CT.D2R(i); double omega = 169.508470 + 1.394681 * T + 0.000412 * T2; double omegarad = CT.D2R(omega); //Step 2. Calculate the heliocentric longitude, latitude and radius vector of the Earth in the FK5 system double l0 = CAAEarth.EclipticLongitude(JD); double b0 = CAAEarth.EclipticLatitude(JD); l0 += CAAFK5.CorrectionInLongitude(l0, b0, JD); double l0rad = CT.D2R(l0); b0 += CAAFK5.CorrectionInLatitude(l0, JD); double b0rad = CT.D2R(b0); double R = CAAEarth.RadiusVector(JD); //Step 3. Calculate the corresponding coordinates l,b,r for Saturn but for the instance t-lightraveltime double DELTA = 9; double PreviousEarthLightTravelTime = 0; double EarthLightTravelTime = ELL.DistanceToLightTime(DELTA); double JD1 = JD - EarthLightTravelTime; bool bIterate = true; double x = 0; double y = 0; double z = 0; double l = 0; double b = 0; double r = 0; while (bIterate) { //Calculate the position of Saturn l = CAASaturn.EclipticLongitude(JD1); b = CAASaturn.EclipticLatitude(JD1); l += CAAFK5.CorrectionInLongitude(l, b, JD1); b += CAAFK5.CorrectionInLatitude(l, JD1); double lrad = CT.D2R(l); double brad = CT.D2R(b); r = CAASaturn.RadiusVector(JD1); //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); EarthLightTravelTime = ELL.DistanceToLightTime(DELTA); //Prepare for the next loop around bIterate = (Math.Abs(EarthLightTravelTime - PreviousEarthLightTravelTime) > 2E-6); //2E-6 corresponds to 0.17 of a second if (bIterate) { JD1 = JD - EarthLightTravelTime; PreviousEarthLightTravelTime = EarthLightTravelTime; } } //Step 5. Calculate Saturn's geocentric Longitude and Latitude double lambda = Math.Atan2(y, x); double beta = Math.Atan2(z, Math.Sqrt(x * x + y * y)); //Step 6. Calculate B, a and b details.B = Math.Asin(Math.Sin(irad) * Math.Cos(beta) * Math.Sin(lambda - omegarad) - Math.Cos(irad) * Math.Sin(beta)); details.a = 375.35 / DELTA; details.b = details.a * Math.Sin(Math.Abs(details.B)); details.B = CT.R2D(details.B); //Step 7. Calculate the longitude of the ascending node of Saturn's orbit double N = 113.6655 + 0.8771 * T; double Nrad = CT.D2R(N); double ldash = l - 0.01759 / r; double ldashrad = CT.D2R(ldash); double bdash = b - 0.000764 * Math.Cos(ldashrad - Nrad) / r; double bdashrad = CT.D2R(bdash); //Step 8. Calculate Bdash details.Bdash = CT.R2D(Math.Asin(Math.Sin(irad) * Math.Cos(bdashrad) * Math.Sin(ldashrad - omegarad) - Math.Cos(irad) * Math.Sin(bdashrad))); //Step 9. Calculate DeltaU double U1 = Math.Atan2(Math.Sin(irad) * Math.Sin(bdashrad) + Math.Cos(irad) * Math.Cos(bdashrad) * Math.Sin(ldashrad - omegarad), Math.Cos(bdashrad) * Math.Cos(ldashrad - omegarad)); double U2 = Math.Atan2(Math.Sin(irad) * Math.Sin(beta) + Math.Cos(irad) * Math.Cos(beta) * Math.Sin(lambda - omegarad), Math.Cos(beta) * Math.Cos(lambda - omegarad)); details.DeltaU = CT.R2D(Math.Abs(U1 - U2)); //Step 10. Calculate the Nutations double Obliquity = CAANutation.TrueObliquityOfEcliptic(JD); double NutationInLongitude = CAANutation.NutationInLongitude(JD); //Step 11. Calculate the Ecliptical longitude and latitude of the northern pole of the ring plane double lambda0 = omega - 90; double beta0 = 90 - i; //Step 12. Correct lambda and beta for the aberration of Saturn lambda += CT.D2R(0.005693 * Math.Cos(l0rad - lambda) / Math.Cos(beta)); beta += CT.D2R(0.005693 * Math.Sin(l0rad - lambda) * Math.Sin(beta)); //Step 13. Add nutation in longitude to lambda0 and lambda //double NLrad = CAACoordinateTransformation::DegreesToRadians(NutationInLongitude/3600); lambda = CT.R2D(lambda); lambda += NutationInLongitude / 3600; lambda = CT.M360(lambda); lambda0 += NutationInLongitude / 3600; lambda0 = CT.M360(lambda0); //Step 14. Convert to equatorial coordinates beta = CT.R2D(beta); COR GeocentricEclipticSaturn = CT.Ec2Eq(lambda, beta, Obliquity); double alpha = CT.H2R(GeocentricEclipticSaturn.X); double delta = CT.D2R(GeocentricEclipticSaturn.Y); COR GeocentricEclipticNorthPole = CT.Ec2Eq(lambda0, beta0, Obliquity); double alpha0 = CT.H2R(GeocentricEclipticNorthPole.X); double delta0 = CT.D2R(GeocentricEclipticNorthPole.Y); //Step 15. Calculate the Position angle details.P = CT.R2D(Math.Atan2(Math.Cos(delta0) * Math.Sin(alpha0 - alpha), Math.Sin(delta0) * Math.Cos(delta) - Math.Cos(delta0) * Math.Sin(delta) * Math.Cos(alpha0 - alpha))); return(details); }
//Static methods //////////////////////////////// Implementation /////////////////////////////// public static CAAPhysicalJupiterDetails Calculate(double JD) { //What will be the return value CAAPhysicalJupiterDetails details = new CAAPhysicalJupiterDetails(); //Step 1 double d = JD - 2433282.5; double T1 = d / 36525; double alpha0 = 268.00 + 0.1061 * T1; double alpha0rad = CT.D2R(alpha0); double delta0 = 64.50 - 0.0164 * T1; double delta0rad = CT.D2R(delta0); //Step 2 double W1 = CT.M360(17.710 + 877.90003539 * d); double W2 = CT.M360(16.838 + 870.27003539 * d); //Step 3 double l0 = CAAEarth.EclipticLongitude(JD); double l0rad = CT.D2R(l0); double b0 = CAAEarth.EclipticLatitude(JD); double b0rad = CT.D2R(b0); double R = CAAEarth.RadiusVector(JD); //Step 4 double l = CAAJupiter.EclipticLongitude(JD); double lrad = CT.D2R(l); double b = CAAJupiter.EclipticLatitude(JD); double brad = CT.D2R(b); double r = CAAJupiter.RadiusVector(JD); //Step 5 double x = r * Math.Cos(brad) * Math.Cos(lrad) - R * Math.Cos(l0rad); double y = r * Math.Cos(brad) * Math.Sin(lrad) - R * Math.Sin(l0rad); double z = r * Math.Sin(brad) - R * Math.Sin(b0rad); double DELTA = Math.Sqrt(x * x + y * y + z * z); //Step 6 l -= 0.012990 * DELTA / (r * r); lrad = CT.D2R(l); //Step 7 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); //Step 8 double e0 = CAANutation.MeanObliquityOfEcliptic(JD); double e0rad = CT.D2R(e0); //Step 9 double alphas = Math.Atan2(Math.Cos(e0rad) * Math.Sin(lrad) - Math.Sin(e0rad) * Math.Tan(brad), Math.Cos(lrad)); double deltas = Math.Asin(Math.Cos(e0rad) * Math.Sin(brad) + Math.Sin(e0rad) * Math.Cos(brad) * Math.Sin(lrad)); //Step 10 details.DS = CT.R2D(Math.Asin(-Math.Sin(delta0rad) * Math.Sin(deltas) - Math.Cos(delta0rad) * Math.Cos(deltas) * Math.Cos(alpha0rad - alphas))); //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 = CT.R2D(alpharad); double deltarad = Math.Atan2(v, Math.Sqrt(x * x + u * u)); double delta = CT.R2D(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.DE = CT.R2D(Math.Asin(-Math.Sin(delta0rad) * Math.Sin(deltarad) - Math.Cos(delta0rad) * Math.Cos(deltarad) * Math.Cos(alpha0rad - alpharad))); //Step 13 details.Geometricw1 = CT.M360(W1 - CT.R2D(xi) - 5.07033 * DELTA); details.Geometricw2 = CT.M360(W2 - CT.R2D(xi) - 5.02626 * DELTA); //Step 14 double C = 57.2958 * (2 * r * DELTA + R * R - r * r - DELTA * DELTA) / (4 * r * DELTA); if (Math.Sin(lrad - l0rad) > 0) { details.Apparentw1 = CT.M360(details.Geometricw1 + C); details.Apparentw2 = CT.M360(details.Geometricw2 + C); } else { details.Apparentw1 = CT.M360(details.Geometricw1 - C); details.Apparentw2 = CT.M360(details.Geometricw2 - C); } //Step 15 double NutationInLongitude = CAANutation.NutationInLongitude(JD); double NutationInObliquity = CAANutation.NutationInObliquity(JD); e0 += NutationInObliquity / 3600; e0rad = CT.D2R(e0); //Step 16 alpha += 0.005693 * (Math.Cos(alpharad) * Math.Cos(l0rad) * Math.Cos(e0rad) + Math.Sin(alpharad) * Math.Sin(l0rad)) / Math.Cos(deltarad); alpha = CT.M360(alpha); alpharad = CT.D2R(alpha); delta += 0.005693 * (Math.Cos(l0rad) * Math.Cos(e0rad) * (Math.Tan(e0rad) * Math.Cos(deltarad) - Math.Sin(alpharad) * Math.Sin(deltarad)) + Math.Cos(alpharad) * Math.Sin(deltarad) * Math.Sin(l0rad)); deltarad = CT.D2R(delta); //Step 17 double NutationRA = CAANutation.NutationInRightAscension(alpha / 15, delta, e0, NutationInLongitude, NutationInObliquity); double alphadash = alpha + NutationRA / 3600; double alphadashrad = CT.D2R(alphadash); double NutationDec = CAANutation.NutationInDeclination(alpha / 15, delta, e0, NutationInLongitude, NutationInObliquity); double deltadash = delta + NutationDec / 3600; double deltadashrad = CT.D2R(deltadash); NutationRA = CAANutation.NutationInRightAscension(alpha0 / 15, delta0, e0, NutationInLongitude, NutationInObliquity); double alpha0dash = alpha0 + NutationRA / 3600; double alpha0dashrad = CT.D2R(alpha0dash); NutationDec = CAANutation.NutationInDeclination(alpha0 / 15, delta0, e0, NutationInLongitude, NutationInObliquity); double delta0dash = delta0 + NutationDec / 3600; double delta0dashrad = CT.D2R(delta0dash); //Step 18 details.P = CT.M360(CT.R2D(Math.Atan2(Math.Cos(delta0dashrad) * Math.Sin(alpha0dashrad - alphadashrad), Math.Sin(delta0dashrad) * Math.Cos(deltadashrad) - Math.Cos(delta0dashrad) * Math.Sin(deltadashrad) * Math.Cos(alpha0dashrad - alphadashrad)))); return(details); }
//Static methods //////////////////////////////// Implementation /////////////////////////////// public static CAAPhysicalMarsDetails Calculate(double JD) { //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 = CT.D2R(Lambda0); double Beta0 = 63.2818 - 0.00394 * T; double Beta0rad = CT.D2R(Beta0); //Step 2 double l0 = CAAEarth.EclipticLongitude(JD); double l0rad = CT.D2R(l0); double b0 = CAAEarth.EclipticLatitude(JD); double b0rad = CT.D2R(b0); double R = CAAEarth.RadiusVector(JD); 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 brad = 0; double r = 0; while (bIterate) { double JD2 = JD - LightTravelTime; //Step 3 l = CAAMars.EclipticLongitude(JD2); lrad = CT.D2R(l); b = CAAMars.EclipticLatitude(JD2); brad = CT.D2R(b); r = CAAMars.RadiusVector(JD2); //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 = ELL.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 = CT.R2D(lambdarad); double betarad = Math.Atan2(z, Math.Sqrt(x * x + y * y)); double beta = CT.R2D(betarad); //Step 6 details.DE = CT.R2D(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 = CT.D2R(N); double ldash = l - 0.00697 / r; double ldashrad = CT.D2R(ldash); double bdash = b - 0.000225 * (Math.Cos(lrad - Nrad) / r); double bdashrad = CT.D2R(bdash); //Step 8 details.DS = CT.R2D(Math.Asin(-Math.Sin(Beta0rad) * Math.Sin(bdashrad) - Math.Cos(Beta0rad) * Math.Cos(bdashrad) * Math.Cos(Lambda0rad - ldashrad))); //Step 9 double W = CT.M360(11.504 + 350.89200025 * (JD - LightTravelTime - 2433282.5)); //Step 10 double e0 = CAANutation.MeanObliquityOfEcliptic(JD); double e0rad = CT.D2R(e0); COR PoleEquatorial = CT.Ec2Eq(Lambda0, Beta0, e0); double alpha0rad = CT.H2R(PoleEquatorial.X); double delta0rad = CT.D2R(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 = CT.R2H(alpharad); double deltarad = Math.Atan2(v, Math.Sqrt(x * x + u * u)); double delta = CT.R2D(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 = CT.M360(W - CT.R2D(xi)); //Step 13 double NutationInLongitude = CAANutation.NutationInLongitude(JD); double NutationInObliquity = CAANutation.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; Lambda0rad = CT.D2R(Lambda0); lambda += NutationInLongitude / 3600; lambdarad = CT.D2R(lambda); e0 += NutationInObliquity / 3600; e0rad = CT.D2R(e0rad); //Step 16 COR ApparentPoleEquatorial = CT.Ec2Eq(Lambda0, Beta0, e0); double alpha0dash = CT.H2R(ApparentPoleEquatorial.X); double delta0dash = CT.D2R(ApparentPoleEquatorial.Y); COR ApparentMars = CT.Ec2Eq(lambda, beta, e0); double alphadash = CT.H2R(ApparentMars.X); double deltadash = CT.D2R(ApparentMars.Y); //Step 17 details.P = CT.M360(CT.R2D(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 = CAASun.GeometricEclipticLongitude(JD); double SunBeta = CAASun.GeometricEclipticLatitude(JD); COR SunEquatorial = CT.Ec2Eq(SunLambda, SunBeta, e0); details.X = MIFR.PositionAngle(SunEquatorial.X, SunEquatorial.Y, alpha, delta); //Step 19 details.d = 9.36 / DELTA; details.k = IFR.IlluminatedFraction2(r, R, DELTA); details.q = (1 - details.k) * details.d; return(details); }