Logo Search packages:      
Sourcecode: hamlib version File versions  Download package

int HAMLIB_API qrb ( double  lon1,
double  lat1,
double  lon2,
double  lat2,
double *  distance,
double *  azimuth 
)

Calculate the distance and bearing between two points.

Parameters:
lon1 The local Longitude, decimal degrees
lat1 The local Latitude, decimal degrees
lon2 The remote Longitude, decimal degrees
lat2 The remote Latitude, decimal degrees
distance Pointer for the distance, km
azimuth Pointer for the bearing, decimal degrees
Calculate the QRB between lon1, lat1 and lon2, lat2.

This version will calculate the QRB to a precision sufficient for 12 character locators. Antipodal points, which are easily calculated, are considered equidistant and the bearing is simply resolved to be true north (0.0).

Return values:
-RIG_EINVAL if NULL pointer passed or lat and lon values exceed -90 to 90 or -180 to 180.
RIG_OK if calculations are successful.
Returns:
The distance in kilometers and azimuth in decimal degrees for the short path are stored in distance and azimuth.
See also:
distance_long_path(), azimuth_long_path()

Definition at line 481 of file locator.c.

References RIG_EINVAL, and RIG_OK.

                                                                                                          {
      double delta_long, tmp, arc, az;

      /* bail if NULL pointers passed */
      if (!distance || !azimuth)
            return -RIG_EINVAL;

      if ((lat1 > 90.0 || lat1 < -90.0) || (lat2 > 90.0 || lat2 < -90.0))
            return -RIG_EINVAL;

      if ((lon1 > 180.0 || lon1 < -180.0) || (lon2 > 180.0 || lon2 < -180.0))
            return -RIG_EINVAL;

      /* Prevent ACOS() Domain Error */
      if (lat1 == 90.0)
            lat1 = 89.999999999;
      else if (lat1 == -90.0)
            lat1 = -89.999999999;

      if (lat2 == 90.0)
            lat2 = 89.999999999;
      else if (lat2 == -90.0)
            lat2 = -89.999999999;

      /* Convert variables to Radians */
      lat1  /= RADIAN;
      lon1  /= RADIAN;
      lat2  /= RADIAN;
      lon2  /= RADIAN;

      delta_long = lon2 - lon1;

      tmp = sin(lat1) * sin(lat2) + cos(lat1) * cos(lat2) * cos(delta_long);

      if (tmp > .999999999999999) {
            /* Station points coincide, use an Omni! */
            *distance = 0.0;
            *azimuth = 0.0;
            return RIG_OK;
      }

      if (tmp < -.999999) {
            /*
             * points are antipodal, it's straight down.
             * Station is equal distance in all Azimuths.
             * So take 180 Degrees of arc times 60 nm,
             * and you get 10800 nm, or whatever units...
             */
            *distance = 180.0 * ARC_IN_KM;
            *azimuth = 0.0;
            return RIG_OK;
      }

      arc = acos(tmp);

      /*
       * One degree of arc is 60 Nautical miles
       * at the surface of the earth, 111.2 km, or 69.1 sm
       * This method is easier than the one in the handbook
       */

      /* Short Path */
      *distance = ARC_IN_KM * RADIAN * arc;

      /* This formula seems to work with very small distances
       *
       * I found it on the Web at:
       * http://williams.best.vwh.net/avform.htm#Crs
       *
       * Strangely, all the computed values were negative thus the
       * sign reversal below.
       * - N0NB
       */
      az = RADIAN * fmod(atan2(sin(lon1 - lon2) * cos(lat2),
                         cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(lon1 - lon2)), 2 * M_PI);
      if (lon1 > lon2) {
            az -= 360.;
            *azimuth = -az;
      } else {
            if (az >= 0.0)
                  *azimuth = az;
            else
                  *azimuth = -az;
      }
      return RIG_OK;
}


Generated by  Doxygen 1.6.0   Back to index