This lab will develop your skills in calling and writing functions.
This page will be available as
http://www.tricity.wsu.edu/~bobl/cpts121/lab05_functions/writeup.html
Calling it up in a browser will allow you to cut-and-paste the templates below into your editor and save editing time.
Plug your thumbdrive into your workstation and, in a MinGW terminal emulator, create a new directory for this lab and cd to it:
$ cd /e/cpts121 $ mkdir lab05 $ cd lab05
As before, keep all your work in this directory.
We'll develop a program crow_fly that computes the distance in kilometers between any two points on Earth, given their latitudes and longitudes. Here's the template:
#include <stdio.h>
#include <math.h> // for M_PI and trig functions
double dmsToRadians(double dms[3])
{
/*
* converts the values in the 3-element array `dms` (degrees,
* minutes, and seconds) to a single double value in radians and
* returns it
*
* pseudocode:
* convert dms[] into a single (fractional) degree value
* convert the degree value to radians and return that value
*/
}
void polarToCartesian(double latitude[3], double longitude[3],
double position[3])
{
/*
* converts `latitude` and `longitude` (both are 3-element --
* degrees, minutes, and seconds -- arrays) to `position`: a
* 3-element double array in Cartesian (x, y, and z) coordinates
* on the unit sphere.
*
* pseudocode:
* convert latitude to a polar angle `theta` using
* dmsToRadians()
* convert longitude to an azimuthal angle `phi` using
* dmsToRadians()
* convert `theta` and `phi` to the x, y, and z components of
* `position`
*/
}
double arcLength(double latitude0[3], double longitude0[3],
double latitude1[3], double longitude1[3])
{
/*
* computes the length (in radians) of an arc ("geodesic") on the
* unit sphere between points (longitude0, latitude0) and
* (longitude1, latitude1)
*
* pseudocode:
* convert `latitude0` and `longitude0` to `position0`
* using polarToCartesian()
* convert `latitude1` and `longitude1` to `position1`
* using polarToCartesian()
* compute the cosine of the arc using the formula below
* use the acos() (arc cosine) math function to convert the
* cosine back to an angle and return it
*/
}
double crowFly(double latitude0[3], double longitude0[3],
double latitude1[3], double longitude1[3])
{
/*
* computes and returns the distance in km from (latitude0,
* longitude0) to (latitude1, longitude1) on the Earth's surface
*
* pseudocode:
* compute the arc length from (latitude0, longitude0) to
* (latitude1, longitude1) using arcLength()
* multiply the arc length by the radius of the Earth (6378 km)
* and return that value
*/
}
int main(void)
{
double latitude0[3], longitude0[3];
double latitude1[3], longitude1[3];
printf(" from latitude (d m s): ");
scanf("%lf %lf %lf", &latitude0[0], &latitude0[1], &latitude0[2]);
printf("from longitude (d m s): ");
scanf("%lf %lf %lf", &longitude0[0], &longitude0[1], &longitude0[2]);
printf(" to latitude (d m s): ");
scanf("%lf %lf %lf", &latitude1[0], &latitude1[1], &latitude1[2]);
printf(" to longitude (d m s): ");
scanf("%lf %lf %lf", &longitude1[0], &longitude1[1], &longitude1[2]);
printf(" distance: %.1f km\n",
crowFly(latitude0, longitude0, latitude1, longitude1));
return 0;
}
The code is available as
http://www.tricity.wsu.edu/~bobl/cpts121/lab05_functions/crow_fly_tplt.c
The main() function is provided. You do not need to change it. There are four other functions you need to implement, as indicated in the comments. Some additional notes:
This function takes a 3-element array containing an angle in degrees, (arc) minutes, and (arc) seconds and converts it to radians, which it returns. Remember that there are 60 seconds in a minute and 60 minutes in a degree and that there are 180 degrees in pi radians.
This function takes a latitude[] and a longitude[], both degree-minute-second 3-arrays, and converts them to radians theta and phi, respectively. These then create the x, y, and z components (in that order) of the position[] array, using these formulae:
x = cosθ cosφy = cosθ sinφz = sinθ
These are all 3D coordinates on a unit sphere (a sphere of radius one).
This function computes the length of an arc on the unit sphere in radians. Given positions p and q (position0 and position1 in the pseudocode), the formula for the arc length is
θ = cos − 1(pxqx + pyqy + pzqz)
This function returns the distance between two points (given their longitudes and latitudes) on the Earth's surface. (This is a very simple function.)
Here's a typical run for the distance between Richland and Pullman:
$ crow_fly
from latitude (d m s): 46 16 47
from longitude (d m s): 119 16 53
to latitude (d m s): 46 44 0
to longitude (d m s): 117 10 0
distance: 169.7 km