/// <summary>
        /// Обратная геодезическая задача (Vincenty's formula)
        /// </summary>
        /// <param name="B1"></param>
        /// <param name="L1"></param>
        /// <param name="B2"></param>
        /// <param name="L2"></param>
        /// <param name="S"></param>
        /// <param name="A12"></param>
        /// <param name="A21"></param>
        public static void InverseProblemVincenty(double B1, double L1, double B2, double L2, Ellipsoid ellipsoid, out double S, out double A12, out double A21)
        {
            //широта, долгота в радианы
            //B1 *= PI / 180;
            //L1 *= PI / 180;
            //B2 *= PI / 180;
            //L2 *= PI / 180;

            //приведенная широта
            double U1 = Atan((1 - ellipsoid.f) * Tan(B1));
            double U2 = Atan((1 - ellipsoid.f) * Tan(B2));

            double L = L2 - L1;

            double λ = L;

            double λ1;
            double sigma;
            //косинус квадрат
            double cos2_alpha;
            //cos(2*sigma_m)
            double cos_2sigma;

            do
            {
                λ1 = λ;
                double sin_sigma = Sqrt(Pow(Cos(U2) * Sin(λ), 2) + Pow(Cos(U1) * Sin(U2) - Sin(U1) * Cos(U2) * Cos(λ), 2));
                double cos_sigma = Sin(U1) * Sin(U2) + Cos(U1) * Cos(U2) * Cos(λ);
                sigma = Atan(sin_sigma / cos_sigma);

                double sin_alpha = (Cos(U1) * Cos(U2) * Sin(λ)) / sin_sigma;

                //косинус квадрат
                cos2_alpha = 1 - Pow(sin_alpha, 2);

                cos_2sigma = Cos(sigma) - (2 * Sin(U1) * Sin(U2)) / cos2_alpha;

                double C = ellipsoid.f / 16 * cos2_alpha * (4 + ellipsoid.f * (4 - 3 * cos2_alpha));

                λ = L + (1 - C) * ellipsoid.f * sin_alpha * (sigma + C * sin_sigma * (cos_2sigma + C * cos_sigma * (-1 + 2 * Pow(cos_2sigma, 2))));
            }while (Abs(λ - λ1) > 1E-14);


            double u2         = cos2_alpha * (Pow(ellipsoid.a, 2) - Pow(ellipsoid.b, 2)) / Pow(ellipsoid.b, 2);
            double A          = 1 + u2 / 16384 * (4096 + u2 * (-768 + u2 * (320 - 175 * u2)));           //было 320 * 175
            double B          = u2 / 1024 * (256 + u2 * (-128 + u2 * (74 - 47 * u2)));
            double deltaSigma = B * Sin(sigma) * (cos_2sigma + B / 4.0 * (
                                                      Cos(sigma) * (-1 + 2 * Pow(cos_2sigma, 2)) -
                                                      B / 6 * cos_2sigma * (-3 + 4 * Pow(Sin(sigma), 2)) * (-3 + 4 * Pow(cos_2sigma, 2))));

            S = ellipsoid.b * A * (sigma - deltaSigma);

            A12 = Atan((Cos(U2) * Sin(λ)) / (Cos(U1) * Sin(U2) - Sin(U1) * Cos(U2) * Cos(λ)));

            A21 = Atan((Cos(U1) * Sin(λ)) / (-Sin(U1) * Cos(U2) + Cos(U1) * Sin(U2) * Cos(λ)));

            A12 *= 180 / PI;
            A21  = A21 * 180 / PI + 180;
        }
Exemplo n.º 2
0
 /// <summary>
 /// Инициализирует новый экземпляр класса <see cref="CoordinateConverter"/>.
 /// </summary>
 /// <param name="ellipsoid"> Эллипсоид, на котором выполняется преобразование координат. </param>
 public CoordinateConverter(Ellipsoid ellipsoid)
 {
     this.ell = ellipsoid;
 }