The main( ) Way-Point File Scanning Function
This file contains all the C code for my demo flight system which flies an ideal aircraft from Stansted (London) to Ringway (Manchester). It displays point features (or nodes) on the Earth's surface from their latitudes and longitudes. The screen represents a spheroidal section of the earth's surface rather than a `projected' map. Unlike a map projection, therefore, all the variables; range, bearing, shape and area are therefore correct. Note: the RandB() function is in the file RandB.C.
#include <graph.h>
#include <math.h>
#include <stdio.h>
extern double DegRad(char *p, int l); //in RandB.C
extern char *RadDeg(double c); //in RandB.C
extern double RandB(double RefLat, double RefLng, int Swap);
extern GndTrk(); //in file GndTrk.C
extern int *RBtoXY(float s);
extern int MapInit();
extern ShowNode(int *q, char *n); //in file NodeTilt.C
char *RadKm(double d, int e);
#define Pi 3.1415926535
#define TwoPi 6.283185307
#define CITIES 24 //Nš of cities (sizeof city array)
#define CITYRL 81 //80 data bytes + \0 terminator
#define OBSERVER 5 //City Nš of observer
#define LATBYTE 17 //Byte Nš of lat within city record
#define LNGBYTE 28 //Byte Nš of lng within city record
#define SCALE .5 //Map scale in km per X-pixel
#define VEH_SPEED 1000 //Vehicle speed in Km/hr
#define WINDOW_WIDTH 200 //½-width of map window (pixels)
#define KMH_RADS .4363323129861111E-7 //km/hr to rad/sec
char city[CITYRL]; //Holds data relating to one city
// THE FOLLOWING VARIABLES ARE SCALED IN EARTH-RADIANS
double
ObsLat, //Observer's (or vehicle's) current latitude
ObsLng, //Observer's (or vehicle's) current longitude
RefLat, //Reference-point's (or city's) latitude
RefLng, //Reference-point's (or city's) longitude
MaxRng, //Cosine of maximum range we are interested in
ObsVel, //Observer's current velocity (radians/sec)
ObsHdg, //Observer's current heading (radians)
ObsRot, //Observer's rate of turn (radians/sec)
DstLat, //Latitude of destination (or way point)
DstLng, //Longitude of destination (or way point)
Range, //Range of Reference object from observer
Bearing, //Bearing of Reference object from observer
CosRng, //Cosine of the range
CosBrg, //Cosine of the bearing
TanBrg, //Tangent of the bearing
ReqHdg, //Required Heading to come smoothly on to radial
Radial; //Radial which vehicle must endeavour to follow
The following is the basis for the dLat test which determines the approximate in-window range before RandB() is used. The size of a latitude-radian is fixed at 40,000 / 2pi kilometres. The size of a Longitude-radian varies with latitude.
double window_height = WINDOW_WIDTH * SCALE * Pi / 20000;
double window_width;
main() {
int active = 1; //loop active
int trigger = 1; //first-time-through trigger
static char *p,
*q = city + CITYRL; //Ptr to byte after last byte
static int i;
static long fp; //file position pointer
static FILE *fh; //declare file handle pointer
static double mrofi, //Maximum range of interest =
*d, *r; // ½(width of map window)
double x, dlat, dlng; /* lat/long difference between
observer and observed */
MapInit(); //perform the map initialisation
trigger = 0; //set 'initialisation done'
/* Set up observer's name & co-ordinates in same
format as the city data is presented in disk file.
Load them into elements [0]& [1] of coords array */
p = "DESTINATION 53.28.100N 002:31.850W";
DstLat = DegRad(p + LATBYTE,0);
DstLng = DegRad(p + LNGBYTE,1);
p = "OBSERVER 51:52.000N 000:11.000E";
ObsLat = DegRad(p + LATBYTE,0);
ObsLng = DegRad(p + LNGBYTE,1);
/* This `leg' of the journey, ie the Destination Radial
on which vehicle must try to travel, is the bearing
of the origin from the destination's point of view: */
MaxRng = -1;
Radial = RandB(DstLat, DstLng, 1);
ObsVel = VEH_SPEED * KMH_RADS; /* Observer's speed
(radians/sec) */
ObsHdg = 1.5; //Observer's heading (radians)
/* Set max range at which a city is of interest. Root 2
times (window_height) is the radius of the smallest
circle within which the square window will fit. */
MaxRng = (mrofi = cos(1.414213562 * window_height));
/* Open disk file containing names and co-ordinates of
cities to be displayed as reference points for the
observer and allocate a 4k buffer to the file. */
fh = fopen("WayPts.DAT", "r");
setvbuf(fh, NULL, _IOFBF, 4096);
/* Skip over the column titles at the beginning of the
file and set the file pointer to the start of the data
for the first city. */
fseek(fh, fp = CITYRL, SEEK_SET);
i = 0; //Set index to the first city in the list.
while(active) { //while scan OK and no key hit
if(kbhit()) active = 0; //if key struck, kill program
else {
/ *Compute range & bearing of each city to be displayed
in the map window */
if (i <= CITIES) { //If not all cities done
/* Advance to [next] city in list, get its Earth
co-ordinates and convert them from degrees and
minutes to radians. */
i++;
for(p = city; p <= q; p++) *p = getc(fh);
RefLat = DegRad(city + LATBYTE,0);
RefLng = DegRad(city + LNGBYTE,1);
/* Provided the centre of the map window is not at one
of the poles, make the East-West aperture of map
window equal to its North-South aperture (expressed
in great-circle radians) times the cosine of the
latitude of the window's centre (ie of observer) */
window_width = window_height;
if((x = cos(ObsLat)) > 0) window_width /= x;
/* Compute the latitude offset and longitude offset of
the city from the centre of the map window */
dlat = fabs(RefLat - ObsLat);
if (dlat > Pi) dlat = TwoPi - dlat;
dlng = fabs(RefLng - ObsLng);
if (dlng > Pi) dlng = TwoPi - dlng;
/* Test if city is approximately within range of map
window first by seeing if its latitude offset is
within window's vertical (north-south) limits, if
so, see if its longitude offset is within the map
window's horizontal (east-west) limits */
if ((dlat <= window_height) && (dlng <= window_width )) {
/* if the city is known to be within the map window,
or at least close to the map window's boundary,
compute its range and bearing. If the RandB()
function found its range to be within 'maximum
range of interest' given in coords[4], then
compute its screen x, y co-ordinates and display
the city's position and name in the map window */
RandB(RefLat, RefLng, 0);
if(Range > 0) ShowNode(RBtoXY(SCALE), city);
}
}
/* Display the graticule and swap the display and active
graphics pages etc. */
else {
MaxRng = -1; //Disable range limit for RandB()
GndTrk(); //Advance observer's position
MaxRng = mrofi; //Reset Max Rng to window radius
ShowData();
fseek(fh, fp, SEEK_SET); //Re-initialise file pointer
i = 0; //Set to re-start display cycle
}
}
}
}
This page's parent within this Web Site. About this Web Site. Its home page. Email its Author.