Exemplo n.º 1
0
        public static double convertBToThetha(double thetha, ReferenceSystem rs, MathFunc.AngleType angType = MathFunc.AngleType.Radians)
        {
            double phi = 0;

            if (angType == MathFunc.AngleType.Degrees)
            {
                phi = deg2rad(90d - thetha);
            }
            else
            {
                phi = Math.PI / 2d - thetha;
            };
            return(Math.Atan(Math.Tan(phi) * (1d - rs.firstExcentricity_2)));
        }
Exemplo n.º 2
0
        /// <summary>
        /// Генерує повністю нормовані приєднані поліномами Лежандра для ступеня n і порядку від 0 до n, і полярної відстані  coLat
        /// </summary>
        /// <param name="n">Максимальний порядок</param>
        /// <param name="coLat">Полярна відстань theta=90deg-phi</param>
        /// <param name="resType">Одиниці, в яких задана полярна відстань</param>
        /// <returns>масив double[] з поліномами від нуля до n ({P_00,P_10,P_11,P_20,P_21,P_22,P_30,...,P_nn})</returns>
        public static double[] getLegendrePolynomialsMy(int maxDegree, double coLat, MathFunc.AngleType resType = AngleType.Radians)
        {
            func_l  f1 = (l) => { return(Math.Sqrt((2D * l + 1) / (2D * l))); };
            func_l  f2 = (l) => { return(Math.Sqrt(2D * (double)l + 1D)); };
            func_lm W3 = (l, m) => { return(Math.Sqrt((4D * Math.Pow((double)l, 2D) - 1D) / (double)(l * l - m * m))); };

            #region перевірка
            if (resType == MathFunc.AngleType.Degrees)
            {
                deg2rad(ref coLat);
            }
            #endregion
            List <double> res = new List <double> (getArraySize(maxDegree));
            double[][]    tmp = new double[maxDegree + 1][];
            int[][]       indexes = get_nm(maxDegree);
            double        sinColat = Math.Sin(coLat), cosColat = Math.Cos(coLat);
            tmp[0]    = new double[] { 1 };
            tmp[1]    = new double[2];
            tmp[1][1] = Math.Sqrt(3D) * sinColat;
            for (int i = 2; i < tmp.Length; i++)
            {
                tmp[i]    = new double[i + 1];
                tmp[i][i] = f1(i) * sinColat * tmp[i - 1][i - 1];
            }
            int mm = 0;
            for (int i = 1; i < tmp.Length; i++)
            {
                tmp[i][i - 1] = f2(i) * cosColat * tmp[i - 1][i - 1];
                if (i > 1)
                {
                    for (int j = 2; j <= i; j++)
                    {
                        mm         = i - j;
                        tmp[i][mm] = W3(i, mm) * (cosColat * tmp[i - 1][mm] - 1D / W3(i - 1, mm) * tmp[i - 2][mm]);
                    }
                }
            }
            for (int i = 0; i < tmp.Length; i++)
            {
                foreach (var item in tmp[i])
                {
                    res.Add(item);
                }
            }
            return(res.ToArray());
        }
Exemplo n.º 3
0
 /// <summary>
 /// Генерує повністю нормовані приєднані поліномами Лежандра для ступеня n і порядку від 0 до n, і полярної відстані  coLat
 /// </summary>
 /// <param name="i">Максимальний порядок</param>
 /// <param name="d">Полярна відстань d=90deg-phi</param>
 /// <param name="ad">Масив в який буде записано результат, він буде перезаписаний</param>
 /// <param name="angType">Одиниці, в яких задана полярна відстань</param>
 /// <returns>масив double[] з поліномами від нуля до n ({P_00,P_10,P_11,P_20,P_21,P_22,P_30,...,P_nn})</returns>
 public static void getLegendre(int i, double d, out double[] res, MathFunc.AngleType angType = AngleType.Radians)
 {
     #region proverka
     if (angType == MathFunc.AngleType.Degrees)
     {
         deg2rad(ref d);
     }
     #endregion
     int      k_ = ((i + 1) * (i + 2)) / 2;
     double[] ad = new double[k_];
     ad[0] = 1.0D;                       //00
     double d1 = Math.Sin(d);
     double d2 = Math.Cos(d);
     ad[1] = Math.Sqrt(3D) * d1;         //11
     ad[2] = Math.Sqrt(3D) * d2;         //10
     if (i <= 1)
     {
         res = ad;
         return;
     }
     int j = 3;
     int k = 1;
     int l = 2;
     for (int i1 = 2; i1 <= i; i1++)
     {
         int j1 = 2 * i1 + 1;
         int k1 = j1 - 2;
         int l1 = k1 - 2;
         j++;
         ad[j - 1] = (Math.Sqrt((double)j1) / (double)i1) * (Math.Sqrt((double)k1) * d1 * ad[l - 1] - ((double)(i1 - 1) * ad[k - 1]) / Math.Sqrt((double)l1));
         double d3 = Math.Sqrt(k1) * d2;
         double d4 = Math.Sqrt(2D) * d3 * ad[l - 1];
         double d6 = Math.Sqrt(k1) * d1;
         j++;
         if (i1 >= 3)
         {
             d4 += (Math.Sqrt((i1 - 1) * (i1 - 2)) * ad[k]) / Math.Sqrt(l1);
         }
         ad[j - 1] = (Math.Sqrt(j1) * d4) / Math.Sqrt(i1 * (i1 + 1));
         for (int i2 = 2; i2 <= i1; i2++)
         {
             int j2 = i1 + i2;
             int k2 = j2 - 1;
             j++;
             double d5 = d3 * ad[(l + i2) - 2];
             double d7 = d6 * ad[(l + i2) - 1];
             if (i2 + 2 > i1)
             {
                 ad[j - 1] = (Math.Sqrt(j1) * d5) / Math.Sqrt(j2 * k2);
             }
             else
             {
                 d7       -= (Math.Sqrt(k2 * (i1 - i2 - 1)) * ad[(k + i2) - 1]) / Math.Sqrt(l1);
                 ad[j - 1] = (Math.Sqrt(j1) * d7) / Math.Sqrt(j2 * (i1 - i2));
             }
         }
         k += i1 - 1;
         l += i1;
     }
     res = ad;
 }
Exemplo n.º 4
0
        //Формування рядка матриці коефіцієнтів рівнянь поправок
        public static double[] getCoefMatrixLineKoop(ReferenceSystem rs, int n, int[][] t_nm, double r, double coLatitude, double longitude, MathFunc.AngleType angType = AngleType.Radians)
        {
            if (angType == AngleType.Degrees)
            {
                deg2rad(ref longitude);
            }
            List <double> line = new List <double>((getArraySize(n) - 3) * 2 - (rs.maxDegree - 1));

            double[][] legPol = getLegendreP_lm_cos_phi(n, Math.PI / 2d - coLatitude);
            double     u_1 = rs.GM / Math.Pow(rs.a, 3d), u_2 = rs.a / rs.satelliteSphere;

            for (int l = 2; l <= rs.maxDegree; l++)
            {
                double u_3 = u_1 * Math.Pow(u_2, l + 3) * (l + 1) * (l + 2);
                for (int m = 0; m <= l; m++)
                {
                    line.Add(u_3 * legPol[l][m] * Math.Cos((double)m * longitude));
                    if (m != 0)
                    {
                        line.Add(u_3 * legPol[l][m] * Math.Sin((double)m * longitude));
                    }
                }
            }
            return(line.ToArray());
        }
Exemplo n.º 5
0
        /// <summary>
        /// Обчислює масив з коефіцієнтами рядка в матриці
        /// </summary>
        /// <param name="rs">Еліпсоїд</param>
        /// <param name="n">Порядок розвинення</param>
        /// <param name="r">Радіус сфери, до якої віднесені виміри</param>
        /// <param name="coLatitude">Полярний кут tetha = 90deg-phi</param>
        /// <param name="longitude">Довгота</param>
        /// <param name="angType">Одиниці, в яких задано попередні кути</param>
        /// <returns></returns>
        public static double[] getCoefMatrixLine(ReferenceSystem rs, int n, int[][] t_nm, double r, double coLatitude, double longitude, MathFunc.AngleType angType = AngleType.Radians)
        {
            if (angType == AngleType.Degrees)
            {
                deg2rad(ref longitude);
            }
            double[] line = new double[(getArraySize(n) - 3) * 2 - (rs.maxDegree - 1)];
            double   u_1  = rs.GM / (Math.Pow(rs.a, 3d));

            double[] legPol = null;
            getLegendre(n, coLatitude, out legPol, angType);
            double tmp_n     = 0;
            double tmp_m     = 0;
            int    lineIndex = 0;

            for (int i = 0; i <= legPol.Length; i++)
            {
                if (i < 4)
                {
                    continue;
                }
                tmp_n = t_nm[i - 1][0];
                tmp_m = t_nm[i - 1][1];
                double b  = legPol[getArraySize(t_nm[i - 1][0] - 1) + t_nm[i - 1][0] - t_nm[i - 1][1]];
                double a  = (tmp_n + 1D) * (tmp_n + 2D) * Math.Pow(rs.a / rs.satelliteSphere, (double)tmp_n + 3d) * u_1;
                double a1 = a * Math.Cos(tmp_m * longitude);
                line[lineIndex] = a1 * b;
                if (tmp_m > 0)
                {
                    double a2 = a * Math.Sin(tmp_m * longitude);
                    line[lineIndex + 1] = a2 * b;
                    lineIndex          += 2;
                }
                else
                {
                    lineIndex++;
                }
            }
            return(line);
        }
Exemplo n.º 6
0
        /// <summary>
        /// Обчислення градієнту V_zz для заданих координат по моделі "in_model"
        /// </summary>
        public static double getGradient(ReferenceSystem rs, GravityModel in_model, double coLat, double longit, MathFunc.AngleType angType = MathFunc.AngleType.Radians)
        {
            GravityModel gm;

            if (in_model.model_a != rs.a || in_model.model_GM != rs.GM)
            {
                gm = in_model.rescaleModel(rs);
            }
            else
            {
                gm = new GravityModel(in_model);
            };
            if (angType == MathFunc.AngleType.Degrees)
            {
                MathFunc.deg2rad(ref longit);
            }
            double grad = 0;
            double tmp = 0, sum_tmp = 0, sum_tmp_2 = 0;

            double[] legendrePolynoms = null;
            MathFunc.getLegendre(rs.maxDegree, coLat, out legendrePolynoms, angType);
            for (int i = 0; i <= rs.maxDegree; i++)
            {
                int n = MathFunc.getArraySize(i - 1) - 1;
                sum_tmp_2 = 0;
                sum_tmp   = (i + 1) * (i + 2) * Math.Pow(rs.a / rs.satelliteSphere, i + 3);
                for (int m = 0; m < gm.c_coef[i].Length; m++)
                {
                    double a1 = legendrePolynoms[n + m + 1], a2 = gm.c_coef[i][m] * Math.Cos(m * longit), a3 = gm.s_coef[i][m] * Math.Sin(m * longit);
                    double x = a1 * (a2 + a3);
                    sum_tmp_2 += x;
                }
                tmp += sum_tmp * sum_tmp_2;
            }
            grad = rs.GM / Math.Pow(rs.a, 3D) * tmp;
            return(grad);
        }