Exemplo n.º 1
0
        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);
        }
Exemplo n.º 2
0
        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;
        }
Exemplo n.º 5
0
        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);
        }