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.