/* * gc.c * * Great Circle. This program is used to determine bearing * and range to a station given latitude and longitude. * * Ver 1.03 By S. R. Sampson, N5OWK * Public Domain (p) November 1989 * * Ref: Air Force Manual 51-40, "Air Navigation", 1 February 1987 * * Usage examples: * * gc 35.19n97.27w 0s0e (Moore to Prime/Equator) * gc 35.19N97.27W 38.51n77.02W (Moore to Washington D.C.) * gc 33.56n118.24w 55.45n37.35e (L.A. to Moscow U.S.S.R.) * gc 35N70W 35N71W (No decimal points used) */ /* Includes */ #include #include #include #include /* Defines */ #define RADIAN (180.0 / M_PI) /* Globals */ double tmp, dist, range, bearing, QTH_Lat, QTH_Long, DEST_Lat, DEST_Long, Delta_Long; /* Simple Declare, No Prototypes */ /* * Error routine */ void err(type) int type; { switch(type) { case 1: printf("\007Latitude Out of Range (90N to 90S)\n"); break; case 2: printf("\007Longitude Out of Range (180W to 180E)\n"); break; case 3: printf("\007Minutes Out of Range (0 to 59)\n"); } exit(1); } /* * Convert Degrees and Minutes to Decimal */ double dm2dec(n) double n; { double t; t = (int)n; n -= t; n /= .60; if (n >= 1.0) err(3); return (n + t); } /* * Parse the input line * * dd(.mm)[NnSs]ddd(.mm)[EeWw] */ void parse(s, lat, lon) char *s; double *lat, *lon; { register char *i, *t; int l; l = strlen(s); for (i = s; i < (s + l); ++i) { switch(toupper(*i)) { case 'N': *i = '\0'; t = i + 1; *lat = atof(s); break; case 'S': *i = '\0'; t = i + 1; *lat = -atof(s); break; case 'E': *i = '\0'; *lon = -atof(t); break; case 'W': *i = '\0'; *lon = atof(t); } } *lat = dm2dec(*lat); *lon = dm2dec(*lon); if (*lat > 90.0 || *lat < -90.0) err(1); if (*lon > 180.0 || *lon < -180.0) err(2); /* Prevent ACOS() Domain Error */ if (*lat == 90.0) *lat = 89.9; if (*lat == -90.0) *lat = -89.9; } main(argc, argv) register int argc; register char **argv; { if (argc != 3) { printf("Usage: gc station1 station2\n\n"); printf("This program computes Great Circle Bearing and Range\n"); printf("given the latitude and longitude (degrees and minutes).\n\n"); printf("You must input the lat/long of the two stations.\n"); printf("The output will then be relative from station1 to station2.\n\n"); printf("Input the two station lat/longs using the following format:\n\n"); printf("\tdd.mmHddd.mmG lead/lagging zeros can be left out.\n\n"); printf("d = Degrees, m = Minutes, H = Hemisphere (N or S), G = Greenwich (W or E)\n"); exit(1); } /* Process the command line data */ parse(argv[1], &QTH_Lat, &QTH_Long); parse(argv[2], &DEST_Lat, &DEST_Long); /* Compute the Bearing and Range, From the Formula in Chapter 23 */ Delta_Long = DEST_Long - QTH_Long; QTH_Lat /= RADIAN; /* Convert variables to Radians */ QTH_Long /= RADIAN; DEST_Lat /= RADIAN; Delta_Long /= RADIAN; tmp = (sin(QTH_Lat) * sin(DEST_Lat)) + (cos(QTH_Lat) * cos(DEST_Lat) * cos(Delta_Long)); dist = acos(tmp); range = 60.0 * (dist * RADIAN); tmp = (sin(DEST_Lat) - (sin(QTH_Lat) * cos(dist))) / (sin(dist) * cos(QTH_Lat)); bearing = acos(tmp) * RADIAN; if (Delta_Long > 0.0) bearing = 360.0 - bearing; /* Computations complete, show answer */ printf("\nBearing is %.0f Degrees for %.0f Nautical Miles\n", bearing, range); exit(0); } /* EOF */