Exemplo n.º 1
0
        public Redfearn(Ellipsoid ellipsoid, Projection projection, int zone)
        {
            this.ellipsoid = ellipsoid;
            this.projection = projection;
            this.zone = zone;

            double lon_zero_degrees = projection.first_lon +
              projection.zone_width / 2.0 + projection.zone_width *
              (zone - projection.first_zone);
            lon_zero = Math.PI * lon_zero_degrees / 180.0;

            PrecalculateMeridianDistance();
        }
Exemplo n.º 2
0
        public static void CalculateDistanceAndBearing(Position a, Position b, Ellipsoid e, out double distance, out Angle bearing)
        {
            if (PointsEqual(a, b, 1e-12))
            {
                distance = 0.0;
                bearing = Angle.FromAngleInDegrees(0.0);
            }

            double lambda = Radians(b.Longitude - a.Longitude);
            double last_lambda = 2 * Math.PI;

            double U1 = Math.Atan((1 - e.F) * Math.Tan(Radians(a.Latitude)));
            double U2 = Math.Atan((1 - e.F) * Math.Tan(Radians(b.Latitude)));

            double sin_U1 = Math.Sin(U1);
            double sin_U2 = Math.Sin(U2);
            double cos_U1 = Math.Cos(U1);
            double cos_U2 = Math.Cos(U2);

            double alpha, sin_sigma, cos_sigma, sigma, cos_2sigma_m, sqr_cos_2sigma_m;

            int loop_limit = 30;

            const double threshold = 1e-12;

            do {
                double sin_lambda = Math.Sin(lambda);
                double cos_lambda = Math.Cos(lambda);

               	sin_sigma =
               	  Math.Sqrt(
               		   Math.Pow(cos_U2 * sin_lambda, 2) +
               		   Math.Pow(cos_U1 * sin_U2 - sin_U1 * cos_U2 * cos_lambda, 2)
               		  );

               	cos_sigma = sin_U1 * sin_U2 + cos_U1 * cos_U2 * cos_lambda;
               	sigma = Math.Atan2(sin_sigma, cos_sigma);
               	alpha = Math.Asin(cos_U1 * cos_U2 * sin_lambda / sin_sigma);
               	double sqr_cos_alpha = Math.Pow(Math.Cos(alpha), 2);
               	cos_2sigma_m = cos_sigma - 2 * sin_U1 * sin_U2 / sqr_cos_alpha;
                sqr_cos_2sigma_m = Math.Pow(cos_2sigma_m, 2);
               	double C = e.F / 16 * sqr_cos_alpha * (4 + e.F * (4 - 3 * sqr_cos_alpha));

               	last_lambda = lambda;
               	lambda =
               		Radians(b.Longitude - a.Longitude) + (1 - C) * e.F * Math.Sin(alpha) *
               		(sigma + C * sin_sigma *
                   		(cos_2sigma_m + C * cos_sigma * (-1 + 2 * sqr_cos_2sigma_m))
                   	);

               	loop_limit -= 1;
            } while (Math.Abs(lambda - last_lambda) > threshold && loop_limit > 0);

            // As in Vincenty 1975, "The inverse formula may give no
            // solution over a line between two nearly antipodal points":
            if (loop_limit == 0)
            {
                distance = double.NaN;
                bearing = Angle.FromAngleInDegrees(0.0);

                return;
            }

            double sqr_u = Math.Pow(Math.Cos(alpha), 2) *
                (e.A * e.A - e.B * e.B) / (e.B * e.B);
            double A = 1 + sqr_u / 16384 * (4096 + sqr_u * (-768 + sqr_u * (320 - 175 * sqr_u)));
            double B = sqr_u / 1024 * (256 + sqr_u * (-128 + sqr_u * (74 - 47 * sqr_u)));
            double delta_sigma =
                B * sin_sigma *
                (cos_2sigma_m + B / 4 *
                 (cos_sigma * (-1 + 2 * sqr_cos_2sigma_m) -
                    B / 6 *	cos_2sigma_m * (-3 + 4 * Math.Pow(sin_sigma, 2)) *
                        (-3 + 4 * sqr_cos_2sigma_m)
                ));

            distance = e.B * A * (sigma - delta_sigma);
            bearing = Angle.FromHeadingInDegrees(180.0 / Math.PI *
                Math.Atan2(cos_U2 * Math.Sin(lambda), cos_U1 * sin_U2 - sin_U1 * cos_U2 * Math.Cos(lambda)));
        }
Exemplo n.º 3
0
        // Calculates the distance between two points, using the method
        // described in:
        //
        //     Vincenty, T. Direct and Inverse Solutions of Geodesics of the
        //       Ellipsoid with Applications of Nested Equations, Survey Review,
        //       No. 176, 1975.
        //
        // Points that are nearly antipodal yield no solution; a
        // Double.NaN is returned.
        public static double CalculateDistance(Position a, Position b, Ellipsoid e)
        {
            double distance;
            Angle bearing;

            CalculateDistanceAndBearing(a, b, e, out distance, out bearing);

            return distance;
        }