/// <summary> /// Converts this UTMPoint to a Latitude/Longitude 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. /// reference: http://www.uwgb.edu/dutchs/usefuldata/utmformulas.htm /// </summary> /// <param name="utm">The UTM point to convert</param> /// <returns>The latitude/longitude</returns> public static LatLngPoint ToLatLng(this UTMPoint utm) { if (utm is null) { throw new ArgumentNullException(nameof(utm)); } var N0 = utm.Hemisphere == UTMPoint.GlobeHemisphere.Northern ? 0.0 : DatumWGS_84.FalseNorthing; var xi = (utm.Y - N0) / (DatumWGS_84.pointScaleFactor * DatumWGS_84.A); var eta = (utm.X - DatumWGS_84.E0) / (DatumWGS_84.pointScaleFactor * DatumWGS_84.A); var xiPrime = xi; var etaPrime = eta; double sigmaPrime = 1; double tauPrime = 0; for (var j = 1; j <= 3; ++j) { var beta = DatumWGS_84.beta[j - 1]; var je2 = 2 * j * xi; var jn2 = 2 * j * eta; var sinje2 = Sin(je2); var coshjn2 = Cosh(jn2); var cosje2 = Cos(je2); var sinhjn2 = Sinh(jn2); xiPrime -= beta * sinje2 * coshjn2; etaPrime -= beta * cosje2 * sinhjn2; sigmaPrime -= 2 * j * beta * cosje2 * coshjn2; tauPrime -= 2 * j * beta * sinje2 * sinhjn2; } var chi = Asin(Sin(xiPrime) / Cosh(etaPrime)); var lat = chi; for (var j = 1; j <= 3; ++j) { lat += DatumWGS_84.delta[j - 1] * Sin(2 * j * chi); } float long0 = (utm.Zone * 6) - 183; var lng = Atan(Sinh(etaPrime) / Cos(xiPrime)); return(new LatLngPoint( Radians.Degrees((float)lat), long0 + Radians.Degrees((float)lng), utm.Z)); }
/// <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)); }