public static Angle rhumbAzimuth(LatLon p1,LatLon p2){
  if (p1 == null || p2 == null) {
    throw new IllegalArgumentException("LatLon Is Null");
  }
  double lat1=p1.getLatitude().radians;
  double lon1=p1.getLongitude().radians;
  double lat2=p2.getLatitude().radians;
  double lon2=p2.getLongitude().radians;
  if (lat1 == lat2 && lon1 == lon2)   return Angle.ZERO;
  double dLon=lon2 - lon1;
  double dPhi=Math.log(Math.tan(lat2 / 2.0 + Math.PI / 4.0) / Math.tan(lat1 / 2.0 + Math.PI / 4.0));
  if (Math.abs(dLon) > Math.PI) {
    dLon=dLon > 0 ? -(2 * Math.PI - dLon) : (2 * Math.PI + dLon);
  }
  double azimuthRadians=Math.atan2(dLon,dPhi);
  return Double.isNaN(azimuthRadians) ? Angle.ZERO : Angle.fromRadians(azimuthRadians);
}

public static Angle rhumbAzimuth ( LatLon p1 , LatLon p2 ) { if ( p1 == null || p2 == null ) { throw new IllegalArgumentException ( "LatLon Is Null" ) ; } double lat1 = p1 . getLatitude ( ) . radians ; double lon1 = p1 . getLongitude ( ) . radians ; double lat2 = p2 . getLatitude ( ) . radians ; double lon2 = p2 . getLongitude ( ) . radians ; if ( lat1 == lat2 && lon1 == lon2 ) return Angle . ZERO ; double dLon = lon2 - lon1 ; double dPhi = Math . log ( Math . tan ( lat2 / 2.0 + Math . PI / 4.0 ) / Math . tan ( lat1 / 2.0 + Math . PI / 4.0 ) ) ; if ( Math . abs ( dLon ) > Math . PI ) { dLon = dLon > 0 ? - ( 2 * Math . PI - dLon ) : ( 2 * Math . PI + dLon ) ; } double azimuthRadians = Math . atan2 ( dLon , dPhi ) ; return Double . isNaN ( azimuthRadians ) ? Angle . ZERO : Angle . fromRadians ( azimuthRadians ) ; }
computes the azimuth angle ( clockwise from north ) of a rhumb line ( a line of constant heading ) between two locations .
