/// <summary> /// Calculates the position of the Sun on the Ecliptic for the given Julian Day /// </summary> /// <param name="n">The Julian Day</param> /// <returns>The position of the sun on the ecliptic</returns> public static GeocentricEclipticSphericalPosition ToGeocentricEclipticSphericalFromJulianDay(this float n) { var L_deg = (280.460f + (0.9856474f * n)).Repeat(360f); var g_deg = (357.528f + (0.9856003f * n)).Repeat(360f); var g_rad = Degrees.Radians(g_deg); var sin_g = Sin(g_rad); var cos_g = Cos(g_rad); var lambda_deg = ((float)(L_deg + (1.915f * sin_g) + (0.020f * 2 * sin_g * cos_g))).Repeat(360); var R = 1.00014f - (0.01671f * cos_g) - (0.00014f * ((cos_g * cos_g) - (sin_g * sin_g))); var ec = new GeocentricEclipticSphericalPosition(0, lambda_deg, (float)R); return(ec); }
/// <summary> /// Convert Equitorial Spherical Position to Horizontal Spherical Position. /// </summary> /// <param name="location">The point on earth</param> /// <param name="n">The Julian day</param> /// <returns>The elevation above the horizon</returns> public static HorizontalSphericalPosition ToHorizontal(this EquitorialSphericalPosition value, LatLngPoint location, float n) { if (value is null) { throw new ArgumentNullException(nameof(value)); } if (location is null) { throw new ArgumentNullException(nameof(location)); } var GMST = (18.697374558f + (24.06570982441908f * n)).Repeat(24); var LST = GMST + Degrees.Hours(location.Longitude); var RA = Degrees.Hours(value.RightAscensionDegrees); var H = Hours.Radians(LST - RA); var sin_H = Sin(H); var cos_H = Cos(H); var lat_rad = Degrees.Radians(location.Latitude); // var lng_rad = lng_deg * Deg2Rad; var delta_rad = Degrees.Radians(value.DeclinationDegrees); var sin_delta = Sin(delta_rad); var cos_delta = Cos(delta_rad); var sin_lat = Sin(lat_rad); var cos_lat = Cos(lat_rad); var sin_alt = (sin_delta * sin_lat) + (cos_delta * cos_lat * cos_H); var cos_alt = Sqrt(1 - (sin_alt * sin_alt)); var sin_azm = sin_H * cos_delta / cos_alt; var cos_azm = (sin_delta - (sin_lat * sin_alt)) / (cos_lat * cos_alt); var altitude_rad = (float)Atan2(sin_alt, cos_alt); var azimuth_rad = (float)Atan2(sin_azm, cos_azm); return(new HorizontalSphericalPosition( Radians.Degrees(altitude_rad), (180 - Radians.Degrees(azimuth_rad)).Repeat(360), value.RadiusAU)); }
/// <summary> /// This calculation is only good for the Sun, as it does not take the Ecliptic Latitude into consideration. /// </summary> /// <param name="n">The Julian Day</param> /// <returns>The position of the son on the equitorial plane</returns> public static EquitorialSphericalPosition ToEquitorial(this GeocentricEclipticSphericalPosition p, float n) { if (p is null) { throw new ArgumentNullException(nameof(p)); } var epsilon_deg = 23.439f - (0.0000004f * n); var epsilon_rad = Degrees.Radians(epsilon_deg); var sin_epsilon = Sin(epsilon_rad); var cos_epsilon = Cos(epsilon_rad); var lambda_rad = Degrees.Radians(p.LongitudeDegrees); var sin_lambda = Sin(lambda_rad); var cos_lambda = Cos(lambda_rad); var alpha_rad = (float)Atan2(cos_epsilon * sin_lambda, cos_lambda); var delta_rad = (float)Asin(sin_epsilon * sin_lambda); return(new EquitorialSphericalPosition( Radians.Degrees(alpha_rad), Radians.Degrees(delta_rad), p.RadiusAU)); }
/// <summary> /// Converts this LatLngPoint to a Universal Transverse Mercator point using the WGS-84 /// datum. The coordinate pair's units will be in meters, and should be usable to make /// distance calculations over short distances. /// </summary> /// <seealso cref="http://www.uwgb.edu/dutchs/usefuldata/utmformulas.htm"/> /// <param name="latlng">The point on Earth to convert to UTM</param> /// <returns>The UTM point</returns> public static UTMPoint ToUTM(this LatLngPoint latlng) { if (latlng is null) { throw new ArgumentNullException(nameof(latlng)); } var hemisphere = latlng.Latitude < 0 ? UTMPoint.GlobeHemisphere.Southern : UTMPoint.GlobeHemisphere.Northern; const double k0 = 0.9996; double phi = Degrees.Radians(latlng.Latitude); var sinPhi = Sin(phi); var cosPhi = Cos(phi); var sin2Phi = 2 * sinPhi * cosPhi; var cos2Phi = (2 * cosPhi * cosPhi) - 1; var sin4Phi = 2 * sin2Phi * cos2Phi; var cos4Phi = (2 * cos2Phi * cos2Phi) - 1; var sin6Phi = (sin4Phi * cos2Phi) + (cos4Phi * sin2Phi); var tanPhi = sinPhi / cosPhi; var ePhi = DatumWGS_84.e * sinPhi; var N = DatumWGS_84.equatorialRadius / Sqrt(1 - (ePhi * ePhi)); var utmz = 1 + (int)Floor((latlng.Longitude + 180) / 6.0); var zcm = 3 + (6.0 * (utmz - 1)) - 180; var A = Degrees.Radians((float)(latlng.Longitude - zcm)) * cosPhi; var M = DatumWGS_84.equatorialRadius * ( (phi * DatumWGS_84.alpha1) - (sin2Phi * DatumWGS_84.alpha2) + (sin4Phi * DatumWGS_84.alpha3) - (sin6Phi * DatumWGS_84.alpha4)); // Easting var T = tanPhi * tanPhi; var C = DatumWGS_84.e0sq * cosPhi * cosPhi; var Asqr = A * A; var Tsqr = T * T; var x0 = 1 - T + C; var x1 = 5 - (18 * T) + Tsqr + (72.0 * C) - (58 * DatumWGS_84.e0sq); var x2 = Asqr * x1 / 120.0; var x3 = (x0 / 6) + x2; var x4 = 1 + (Asqr * x3); var easting = k0 * N * A * x4; easting += DatumWGS_84.E0; // Northing var northing = k0 * (M + (N * tanPhi * (Asqr * ((1 / 2.0) + (Asqr * (((5 - T + (9 * C) + (4 * C * C)) / 24.0) + (Asqr * (61 - (58 * T) + Tsqr + (600 * C) - (330 * DatumWGS_84.e0sq)) / 720.0))))))); if (hemisphere == UTMPoint.GlobeHemisphere.Southern) { northing += DatumWGS_84.FalseNorthing; } return(new UTMPoint( (float)easting, (float)northing, latlng.Altitude, utmz, hemisphere)); }