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; } } }
/// <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)); }
/// <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); }