home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HAM Radio 3
/
hamradioversion3.0examsandprograms1992.iso
/
math
/
gc103
/
gc103.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-01-03
|
5KB
|
193 lines
/*
* 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 <stdio.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
/* 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 */