예제 #1
0
        private void Lengths(EllipticFunction E,
                             double sig12,
                             double ssig1, double csig1, double dn1,
                             double ssig2, double csig2, double dn2,
                             double cbet1, double cbet2, GeodesicFlags outmask,
                             out double s12b, out double m12b, out double m0,
                             out double M12, out double M21)
        {
            // Return m12b = (reduced length)/_b; also calculate s12b = distance/_b,
            // and m0 = coefficient of secular term in expression for reduced length.
            s12b = m12b = m0 = M12 = M21 = double.NaN;

            outmask = outmask.Flags();
            // outmask & DISTANCE: set s12b
            // outmask & REDUCEDLENGTH: set m12b & m0
            // outmask & GEODESICSCALE: set M12 & M21

            // It's OK to have repeated dummy arguments,
            // e.g., s12b = m0 = M12 = M21 = dummy

            if (outmask.HasAny(GeodesicFlags.Distance))
            {
                // Missing a factor of _b
                s12b = E.E() / (PI / 2) *
                       (sig12 + (E.DeltaE(ssig2, csig2, dn2) - E.DeltaE(ssig1, csig1, dn1)));
            }
            if (outmask.HasAny(GeodesicFlags.ReducedLength | GeodesicFlags.GeodesicScale))
            {
                double
                    m0x = -E.K2 * E.D() / (PI / 2),
                    J12 = m0x *
                          (sig12 + (E.DeltaD(ssig2, csig2, dn2) - E.DeltaD(ssig1, csig1, dn1)));
                if (outmask.HasAny(GeodesicFlags.ReducedLength))
                {
                    m0 = m0x;
                    // Missing a factor of _b.  Add parens around (csig1 * ssig2) and
                    // (ssig1 * csig2) to ensure accurate cancellation in the case of
                    // coincident points.
                    m12b = dn2 * (csig1 * ssig2) - dn1 * (ssig1 * csig2) -
                           csig1 * csig2 * J12;
                }
                if (outmask.HasAny(GeodesicFlags.GeodesicScale))
                {
                    var csig12 = csig1 * csig2 + ssig1 * ssig2;
                    var t      = _ep2 * (cbet1 - cbet2) * (cbet1 + cbet2) / (dn1 + dn2);
                    M12 = csig12 + (t * ssig2 - csig2 * J12) * ssig1 / dn1;
                    M21 = csig12 - (t * ssig1 - csig1 * J12) * ssig2 / dn2;
                }
            }
        }
예제 #2
0
        /// <inheritdoc/>
        public override IGeodesicLine InverseLine(double lat1, double lon1, double lat2, double lon2, GeodesicFlags caps = GeodesicFlags.All)
        {
            double
                a12 = GenInverse(lat1, lon1, lat2, lon2,
                                 // No need to specify AZIMUTH here
                                 0u, out _, out var salp1, out var calp1, out var salp2, out var calp2,
                                 out _, out _, out _, out _),
                azi1 = Atan2d(salp1, calp1);

            // Ensure that a12 can be converted to a distance
            if (caps.Flags().HasAny(GeodesicFlags.DistanceIn))
            {
                caps |= GeodesicFlags.Distance;
            }
            return(new GeodesicLineExact(this, lat1, lon1, azi1, salp1, calp1, caps, true, a12));
        }
예제 #3
0
        /// <inheritdoc/>
        public override double GenInverse(double lat1, double lon1, double lat2, double lon2,
                                          GeodesicFlags outmask,
                                          out double s12, out double azi1, out double azi2,
                                          out double m12, out double M12, out double M21, out double S12)
        {
            outmask = outmask.Flags();
            var a12 = GenInverse(lat1, lon1, lat2, lon2,
                                 outmask, out s12, out var salp1, out var calp1, out var salp2, out var calp2,
                                 out m12, out M12, out M21, out S12);

            if (outmask.HasAny(GeodesicFlags.Azimuth))
            {
                azi1 = Atan2d(salp1, calp1);
                azi2 = Atan2d(salp2, calp2);
            }
            else
            {
                azi1 = azi2 = double.NaN;
            }

            return(a12);
        }