crossingParallels method

List<double> crossingParallels({
  1. required Coordinate startPoint,
  2. required Coordinate endPoint,
  3. required double latitude,
})

This function returns the pair of meridians at which a great circle defined by two points crosses the given latitude. If the great circle doesn't reach the given latitude, empty list is returned.

The maximum latitude is independent of longitude; it will be the same for all points on a given latitude.

startPoint Initial coordinates endPoint Final coordinates latitude Latitude crossings are to be determined for. Returns Array containing { lon1, lon2 } or null if given latitude not reached.

final istCoordinates = Coordinate(41.28111111, 28.75333333); // The coordinates of Istanbul Airport
final jfkCoordinates = Coordinate(40.63980103, -73.77890015); // The coordinates of New York JFK Airport
final latitude = 60.0; // means 60 degrees north
final crossingParallels = greatCircle.crossingParallels(istCoordinates, jfkCoordinates, latitude);

Implementation

List<double> crossingParallels(
    {required Coordinate startPoint,
    required Coordinate endPoint,
    required double latitude}) {
  if (startPoint == endPoint) return [];
  final latInRads = latitude.toRadians();
  final lat1 = startPoint.latitude.toRadians();
  final lat2 = endPoint.latitude.toRadians();
  final lon1 = startPoint.longitude.toRadians();
  final lon2 = endPoint.longitude.toRadians();

  final double deltaLon = lon2 - lon1;
  final double x = sin(lat1) * cos(lat2) * cos(latInRads) * sin(deltaLon);
  final double y = sin(lat1) * cos(lat2) * cos(latInRads) * cos(deltaLon) -
      cos(lat1) * sin(lat2) * cos(latInRads);
  final double z = cos(lat1) * cos(lat2) * sin(latInRads) * sin(deltaLon);

  if (z * z > x * x + y * y) return [];

  final double deltaM = atan2(-y, x);
  final double deltaLoni = acos(z / sqrt(x * x + y * y));

  final double deltaI1 = lon1 + deltaM - deltaLoni;
  final double deltaI2 = lat1 + deltaM + deltaLoni;

  return [deltaI1.toDegrees().wrap180(), deltaI2.toDegrees().wrap180()];
}