public RadianAngle GetBearingTo(GeoCoordinate destination) { if (IsEmpty) { throw new ArgumentException("Cannot compute bearing from unknown coordinate."); } if (destination.IsEmpty) { throw new ArgumentException("Cannot compute bearing to unknown coordinate."); } var φ1 = LatitudeRadians; var λ1 = LongitudeRadians; var φ2 = destination.LatitudeRadians; var λ2 = destination.LongitudeRadians; var Δλ = λ2 - λ1; number y = MathA.Sin(Δλ) * MathA.Cos(φ2); number x = MathA.Cos(φ1) * MathA.Sin(φ2) - MathA.Sin(φ1) * MathA.Cos(φ2) * MathA.Cos(Δλ); return(MathA.Atan2(y, x)); }
public GeoCoordinate GetDestinationPoint(Length distance, RadianAngle bearing) { if (IsEmpty) { throw new ArgumentException("Cannot compute destination point from unknown coordinate."); } var φ1 = LatitudeRadians; var λ1 = LongitudeRadians; var δ = new RadianAngle(distance / EarthRadius); var φ2 = MathA.Asin(MathA.Sin(φ1) * MathA.Cos(δ) + MathA.Cos(φ1) * MathA.Sin(δ) * MathA.Cos(bearing)); number y = MathA.Sin(bearing) * MathA.Sin(δ) * MathA.Cos(φ1); number x = MathA.Cos(δ) - MathA.Sin(φ1) * MathA.Sin(φ2); var Δλ = MathA.Atan2(y, x); var λ2 = λ1 + Δλ; // Normalize longitude to range -π ... +π (that is, -180° ... +180°) λ2 = (λ2 + 3 * RadianAngle.PI) % (2 * Constants.PI) - RadianAngle.PI; return(new GeoCoordinate(φ2, λ2)); }
public Length GetDistanceTo(GeoCoordinate destination) { if (IsEmpty) { throw new ArgumentException("Cannot compute distance from unknown coordinate."); } if (destination.IsEmpty) { throw new ArgumentException("Cannot compute distance to unknown coordinate."); } var φ1 = LatitudeRadians; var λ1 = LongitudeRadians; var φ2 = destination.LatitudeRadians; var λ2 = destination.LongitudeRadians; var Δφ = φ2 - φ1; var Δλ = λ2 - λ1; number a = MathA.Sin(Δφ * Constants.Half) * MathA.Sin(Δφ * Constants.Half) + MathA.Cos(φ1) * MathA.Cos(φ2) * MathA.Sin(Δλ * Constants.Half) * MathA.Sin(Δλ * Constants.Half); number c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a)); return(c * EarthRadius); }