Ejemplo n.º 1
0
        public GeodesicLine(Geodesic g,
                            double lat1, double lon1, double azi1,
                            int caps)
        {
            azi1 = GeoMath.AngNormalize(azi1);
            double salp1, calp1;

            // Guard against underflow in salp0.  Also -0 is converted to +0.
            GeoMath.Sincosd(GeoMath.AngRound(azi1), out salp1, out calp1);
            LineInit(g, lat1, lon1, azi1, salp1, calp1, caps); //TODO: Check this cast
        }
Ejemplo n.º 2
0
        private void LineInit(Geodesic g,
                              double lat1, double lon1,
                              double azi1, double salp1, double calp1,
                              int caps)
        {
            _lat1  = GeoMath.LatFix(lat1);
            _lon1  = lon1;
            _azi1  = azi1;
            _salp1 = salp1;
            _calp1 = calp1;
            _a     = g._a;
            _f     = g._f;
            _b     = g._b;
            _c2    = g._c2;
            _f1    = g._f1;
            // Always allow latitude and azimuth and unrolling of longitude
            _caps = ((int)caps | (int)GeodesicMask.LATITUDE | (int)GeodesicMask.AZIMUTH | (int)GeodesicMask.LONG_UNROLL); //TODO: check this

            double cbet1, sbet1;

            GeoMath.Sincosd(GeoMath.AngRound(_lat1), out sbet1, out cbet1); sbet1 *= _f1;
            // Ensure cbet1 = +epsilon at poles
            GeoMath.Norm(ref sbet1, ref cbet1);
            cbet1 = Math.Max(Geodesic.tiny_, cbet1);
            _dn1  = Math.Sqrt(1 + g._ep2 * GeoMath.Square(sbet1));

            // Evaluate alp0 from sin(alp1) * cos(bet1) = sin(alp0),
            _salp0 = _salp1 * cbet1; // alp0 in [0, pi/2 - |bet1|]
                                     // Alt: calp0 = hypot(sbet1, calp1 * cbet1).  The following
                                     // is slightly better (consider the case salp1 = 0).
            _calp0 = GeoMath.Hypot(_calp1, _salp1 * sbet1);
            // Evaluate sig with tan(bet1) = tan(sig1) * cos(alp1).
            // sig = 0 is nearest northward crossing of equator.
            // With bet1 = 0, alp1 = pi/2, we have sig1 = 0 (equatorial line).
            // With bet1 =  pi/2, alp1 = -pi, sig1 =  pi/2
            // With bet1 = -pi/2, alp1 =  0 , sig1 = -pi/2
            // Evaluate omg1 with tan(omg1) = sin(alp0) * tan(sig1).
            // With alp0 in (0, pi/2], quadrants for sig and omg coincide.
            // No Math.Atan2(0,0) ambiguity at poles since cbet1 = +epsilon.
            // With alp0 = 0, omg1 = 0 for alp1 = 0, omg1 = pi for alp1 = pi.
            _ssig1 = sbet1; _somg1 = _salp0 * sbet1;
            _csig1 = _comg1 = sbet1 != 0 || _calp1 != 0 ? cbet1 * _calp1 : 1;
            GeoMath.Norm(ref _ssig1, ref _csig1); // sig1 in (-pi, pi]
                                                  // Math::norm(_somg1, _comg1); -- don't need to normalize!

            _k2 = GeoMath.Square(_calp0) * g._ep2;
            double eps = _k2 / (2 * (1 + Math.Sqrt(1 + _k2)) + _k2);

            if ((_caps & GeodesicMask.CAP_C1) != 0)
            {
                _C1a  = new double[nC1_ + 1];
                _A1m1 = GeodesicCoeff.A1m1f(eps);
                GeodesicCoeff.C1f(eps, _C1a);
                _B11 = Geodesic.SinCosSeries(true, _ssig1, _csig1, _C1a);
                double s = Math.Sin(_B11), c = Math.Cos(_B11);
                // tau1 = sig1 + B11
                _stau1 = _ssig1 * c + _csig1 * s;
                _ctau1 = _csig1 * c - _ssig1 * s;
                // Not necessary because C1pa reverts C1a
                //    _B11 = -SinCosSeries(true, _stau1, _ctau1, _C1pa, nC1p_);
            }

            if ((_caps & GeodesicMask.CAP_C1p) != 0)
            {
                _C1pa = new double[nC1p_ + 1];
                GeodesicCoeff.C1pf(eps, _C1pa);
            }

            if ((_caps & GeodesicMask.CAP_C2) != 0)
            {
                _C2a  = new double[nC2_ + 1];
                _A2m1 = GeodesicCoeff.A2m1f(eps);
                GeodesicCoeff.C2f(eps, _C2a);
                _B21 = Geodesic.SinCosSeries(true, _ssig1, _csig1, _C2a);
            }

            if ((_caps & GeodesicMask.CAP_C3) != 0)
            {
                _C3a = new double[nC3_];
                g.C3f(eps, _C3a);
                _A3c = -_f *_salp0 *g.A3f(eps);

                _B31 = Geodesic.SinCosSeries(true, _ssig1, _csig1, _C3a);
            }

            if ((_caps & GeodesicMask.CAP_C4) != 0)
            {
                _C4a = new double[nC4_];
                g.C4f(eps, _C4a);
                // Multiplier = a^2 * e^2 * cos(alpha0) * sin(alpha0)
                _A4  = GeoMath.Square(_a) * _calp0 * _salp0 * g._e2;
                _B41 = Geodesic.SinCosSeries(false, _ssig1, _csig1, _C4a);
            }

            _a13 = _s13 = double.NaN;
        }