private static VincentyFormulaVariables RecalculateσUntilConvergence(IDistance distance, int maxInterations, double tolerance, VincentyFormulaVariables v) { for (var i = 0; i < maxInterations; i++) { v.Cos2σM = Math.Cos(2 * v.σ1 + v.σ); v.Sinσ = Math.Sin(v.σ); v.Cosσ = Math.Cos(v.σ); v.Δσ = v.B * v.Sinσ * (v.Cos2σM + v.B / 4.0 * (v.Cosσ * (-1.0 + 2.0 * Math.Pow(v.Cos2σM, 2.0)) - v.B / 6.0 * v.Cos2σM * (-3.0 + 4.0 * Math.Pow(v.Sinσ, 2.0)) * (-3.0 + 4.0 * Math.Pow(v.Cos2σM, 2.0)))); v.σPrevious = v.σ; v.σ = distance.ToMeters() / (b * v.A) + v.Δσ; var diff = Math.Abs(v.σ - v.σPrevious); if (diff <= tolerance) { break; } } return(v); }
private static VincentyFormulaVariables PrepareσConvergenceLoop(IGeographicCoordinate pointA, IAngle initialBearing, IDistance distance) { VincentyFormulaVariables v = new VincentyFormulaVariables(); v.Sinα1 = Math.Sin(initialBearing.ToRadians()); v.Cosα1 = Math.Cos(initialBearing.ToRadians()); v.TanU1 = (1.0 - f) * Math.Tan(pointA.Latitude.Angle.ToRadians()); v.CosU1 = 1.0 / Math.Sqrt((1 + Math.Pow(v.TanU1, 2.0))); v.SinU1 = v.TanU1 * v.CosU1; v.σ1 = Math.Atan2(v.TanU1, v.Cosα1); v.sinα = v.CosU1 * v.Sinα1; v.CosSqα = 1.0 - Math.Pow(v.sinα, 2.0); v.USquared = v.CosSqα * (Math.Pow(a, 2.0) - Math.Pow(b, 2.0)) / Math.Pow(b, 2.0); v.A = 1 + v.USquared / 16384.0 * (4096.0 + v.USquared * (-768.0 + v.USquared * (320.0 - 175.0 * v.USquared))); v.B = v.USquared / 1024.0 * (256.0 + v.USquared * (-128.0 + v.USquared * (74.0 - 47.0 * v.USquared))); v.σ = distance.ToMeters() / (b * v.A); return(v); }