private static DirectResult Direct(double lat1, double lon1, double crs12, double d12) { const double eps = 0.00000000005; double lon; if ((MathEx.Abs(MathEx.Cos(lat1)) < eps) && !(MathEx.Abs(MathEx.Sin(crs12)) < eps)) { throw new ArgumentException("Only N-S courses are meaningful, starting at a pole!"); } double lat = MathEx.Asin(MathEx.Sin(lat1) * MathEx.Cos(d12) + MathEx.Cos(lat1) * MathEx.Sin(d12) * MathEx.Cos(crs12)); if (MathEx.Abs(MathEx.Cos(lat)) < eps) { lon = 0.0; //endpoint a pole } else { double dlon = MathEx.Atan2(MathEx.Sin(crs12) * MathEx.Sin(d12) * MathEx.Cos(lat1), MathEx.Cos(d12) - MathEx.Sin(lat1) * MathEx.Sin(lat)); lon = Mod(lon1 - dlon + MathEx.PI, 2 * MathEx.PI) - MathEx.PI; } DirectResult outValue = new DirectResult { _lat = lat, _lon = lon }; return(outValue); }
private GeoLatLng ComputeFormDir(GeoLatLng pt1, double distance, double crs) { //get select values double lat2, lon2; /* Input and validate data */ double lat1 = pt1.LatRadians(); double lon1 = -pt1.LngRadians(); double d12 = distance; double dc = _currentUnit == UNIT_NM ? 1 : 1.852; d12 /= dc; double crs12 = crs * MathEx.PI / 180.0; if (_currentEarthMode == EARTH_MODEL_SPHERE) { // spherical code d12 /= (180 * 60 / MathEx.PI); // in radians DirectResult cd = Direct(lat1, lon1, crs12, d12); lat2 = cd._lat * (180 / MathEx.PI); lon2 = cd._lon * (180 / MathEx.PI); } else { // elliptic code// ellipse uses East negative DirectResult cde = DirectEll(lat1, -lon1, crs12, d12, _currentEarthMode); lat2 = cde._lat * (180 / MathEx.PI); lon2 = -cde._lon * (180 / MathEx.PI);// ellipse uses East negative } double retLat = lat2; double retLon = -lon2; return(new GeoLatLng(retLat, retLon)); }
private static DirectResult DirectEll(double glat1, double glon1, double faz, double s, int ellipse) { // glat1 initial geodetic latitude in radians N positive // glon1 initial geodetic longitude in radians E positive // faz forward azimuth in radians // s Distance in units of a (=nm) const double eps = 0.00000000005; double b; double sy = 0, cy = 0, cz = 0, e = 0; if ((MathEx.Abs(MathEx.Cos(glat1)) < eps) && !(MathEx.Abs(MathEx.Sin(faz)) < eps)) { throw new ArgumentException("Only N-S courses are meaningful, starting at a pole!"); } double a = EarthModel[ellipse][0]; double f = 1 / EarthModel[ellipse][1]; double r = 1 - f; double tu = r * MathEx.Tan(glat1); double sf = MathEx.Sin(faz); double cf = MathEx.Cos(faz); if (cf == 0) { b = 0.0; } else { b = 2.0 * Atan2(tu, cf); } double cu = 1.0 / MathEx.Sqrt(1 + tu * tu); double su = tu * cu; double sa = cu * sf; double c2A = 1 - sa * sa; double x = 1.0 + MathEx.Sqrt(1.0 + c2A * (1.0 / (r * r) - 1.0)); x = (x - 2.0) / x; double c = 1.0 - x; c = (x * x / 4.0 + 1.0) / c; double d = (0.375 * x * x - 1.0) * x; tu = s / (r * a * c); double y = tu; c = y + 1; while (MathEx.Abs(y - c) > eps) { sy = MathEx.Sin(y); cy = MathEx.Cos(y); cz = MathEx.Cos(b + y); e = 2.0 * cz * cz - 1.0; c = y; x = e * cy; y = e + e - 1.0; y = (((sy * sy * 4.0 - 3.0) * y * cz * d / 6.0 + x) * d / 4.0 - cz) * sy * d + tu; } b = cu * cy * cf - su * sy; c = r * MathEx.Sqrt(sa * sa + b * b); d = su * cy + cu * sy * cf; double glat2 = Modlat(Atan2(d, c)); c = cu * cy - su * sy * cf; x = Atan2(sy * sf, c); c = ((-3.0 * c2A + 4.0) * f + 4.0) * c2A * f / 16.0; d = ((e * cy * c + cz) * sy * c + y) * sa; double glon2 = Modlon(glon1 + x - (1.0 - c) * d * f); double baz = Modcrs(Atan2(sa, b) + MathEx.PI); DirectResult outValue = new DirectResult {_lat = glat2, _lon = glon2, _crs21 = baz}; return outValue; }
private static DirectResult Direct(double lat1, double lon1, double crs12, double d12) { const double eps = 0.00000000005; double lon; if ((MathEx.Abs(MathEx.Cos(lat1)) < eps) && !(MathEx.Abs(MathEx.Sin(crs12)) < eps)) { throw new ArgumentException("Only N-S courses are meaningful, starting at a pole!"); } double lat = MathEx.Asin(MathEx.Sin(lat1) * MathEx.Cos(d12) + MathEx.Cos(lat1) * MathEx.Sin(d12) * MathEx.Cos(crs12)); if (MathEx.Abs(MathEx.Cos(lat)) < eps) { lon = 0.0; //endpoint a pole } else { double dlon = MathEx.Atan2(MathEx.Sin(crs12) * MathEx.Sin(d12) * MathEx.Cos(lat1), MathEx.Cos(d12) - MathEx.Sin(lat1) * MathEx.Sin(lat)); lon = Mod(lon1 - dlon + MathEx.PI, 2 * MathEx.PI) - MathEx.PI; } DirectResult outValue = new DirectResult {_lat = lat, _lon = lon}; return outValue; }
private static DirectResult DirectEll(double glat1, double glon1, double faz, double s, int ellipse) { // glat1 initial geodetic latitude in radians N positive // glon1 initial geodetic longitude in radians E positive // faz forward azimuth in radians // s Distance in units of a (=nm) const double eps = 0.00000000005; double b; double sy = 0, cy = 0, cz = 0, e = 0; if ((MathEx.Abs(MathEx.Cos(glat1)) < eps) && !(MathEx.Abs(MathEx.Sin(faz)) < eps)) { throw new ArgumentException("Only N-S courses are meaningful, starting at a pole!"); } double a = EarthModel[ellipse][0]; double f = 1 / EarthModel[ellipse][1]; double r = 1 - f; double tu = r * MathEx.Tan(glat1); double sf = MathEx.Sin(faz); double cf = MathEx.Cos(faz); if (cf == 0) { b = 0.0; } else { b = 2.0 * Atan2(tu, cf); } double cu = 1.0 / MathEx.Sqrt(1 + tu * tu); double su = tu * cu; double sa = cu * sf; double c2A = 1 - sa * sa; double x = 1.0 + MathEx.Sqrt(1.0 + c2A * (1.0 / (r * r) - 1.0)); x = (x - 2.0) / x; double c = 1.0 - x; c = (x * x / 4.0 + 1.0) / c; double d = (0.375 * x * x - 1.0) * x; tu = s / (r * a * c); double y = tu; c = y + 1; while (MathEx.Abs(y - c) > eps) { sy = MathEx.Sin(y); cy = MathEx.Cos(y); cz = MathEx.Cos(b + y); e = 2.0 * cz * cz - 1.0; c = y; x = e * cy; y = e + e - 1.0; y = (((sy * sy * 4.0 - 3.0) * y * cz * d / 6.0 + x) * d / 4.0 - cz) * sy * d + tu; } b = cu * cy * cf - su * sy; c = r * MathEx.Sqrt(sa * sa + b * b); d = su * cy + cu * sy * cf; double glat2 = Modlat(Atan2(d, c)); c = cu * cy - su * sy * cf; x = Atan2(sy * sf, c); c = ((-3.0 * c2A + 4.0) * f + 4.0) * c2A * f / 16.0; d = ((e * cy * c + cz) * sy * c + y) * sa; double glon2 = Modlon(glon1 + x - (1.0 - c) * d * f); double baz = Modcrs(Atan2(sa, b) + MathEx.PI); DirectResult outValue = new DirectResult { _lat = glat2, _lon = glon2, _crs21 = baz }; return(outValue); }